This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

crypto: add function getDiffieHellman()

Returns a well known, predefined RFC group.
  • Loading branch information...
Tomasz Buchert authored and bnoordhuis committed Jan 22, 2012
1 parent 19133ca commit c6a04ce78f9fcc07bc1ae108c402fba508344202
Showing with 544 additions and 1 deletion.
  1. +30 −0 doc/api/crypto.markdown
  2. +4 −0 lib/crypto.js
  3. +54 −1 src/node_crypto.cc
  4. +386 −0 src/node_crypto_groups.h
  5. +70 −0 test/simple/test-crypto-dh.js
@@ -264,6 +264,36 @@ or `'base64'`. Defaults to `'binary'`.
Sets the Diffie-Hellman private key. Key encoding can be `'binary'`, `'hex'`,
or `'base64'`. Defaults to `'binary'`.
### crypto.getDiffieHellman(group_name)
Creates a predefined Diffie-Hellman key exchange object.
The supported groups are: `'modp1'`, `'modp2'`, `'modp5'`
(defined in [RFC 2412](http://www.rfc-editor.org/rfc/rfc2412.txt ))
and `'modp14'`, `'modp15'`, `'modp16'`, `'modp17'`, `'modp18'`
(defined in [RFC 3526](http://www.rfc-editor.org/rfc/rfc3526.txt )).
The returned object mimics the interface of objects created by
[crypto.createDiffieHellman()](#crypto.createDiffieHellman) above, but
will not allow to change the keys (with
[diffieHellman.setPublicKey()](#diffieHellman.setPublicKey) for example).
The advantage of using this routine is that the parties don't have to
generate nor exchange group modulus beforehand, saving both processor and
communication time.
Example (obtaining a shared secret):
var crypto = require('crypto');
var alice = crypto.getDiffieHellman('modp5');
var bob = crypto.getDiffieHellman('modp5');
alice.generateKeys();
bob.generateKeys();
var alice_secret = alice.computeSecret(bob.getPublicKey(), 'binary', 'hex');
var bob_secret = bob.computeSecret(alice.getPublicKey(), 'binary', 'hex');
/* alice_secret and bob_secret should be the same */
console.log(alice_secret == bob_secret);
### pbkdf2(password, salt, iterations, keylen, callback)
Asynchronous PBKDF2 applies pseudorandom function HMAC-SHA1 to derive
@@ -30,6 +30,7 @@ try {
var Sign = binding.Sign;
var Verify = binding.Verify;
var DiffieHellman = binding.DiffieHellman;
var DiffieHellmanGroup = binding.DiffieHellmanGroup;
var PBKDF2 = binding.PBKDF2;
var randomBytes = binding.randomBytes;
var pseudoRandomBytes = binding.pseudoRandomBytes;
@@ -173,6 +174,9 @@ exports.createDiffieHellman = function(size_or_key, enc) {
}
};
exports.getDiffieHellman = function(group_name) {
return new DiffieHellmanGroup(group_name);
};
exports.pbkdf2 = PBKDF2;
@@ -20,6 +20,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <node_crypto.h>
#include <node_crypto_groups.h>
#include <v8.h>
#include <node.h>
@@ -3535,6 +3536,18 @@ class DiffieHellman : public ObjectWrap {
NODE_SET_PROTOTYPE_METHOD(t, "setPrivateKey", SetPrivateKey);
target->Set(String::NewSymbol("DiffieHellman"), t->GetFunction());
Local<FunctionTemplate> t2 = FunctionTemplate::New(DiffieHellmanGroup);
t2->InstanceTemplate()->SetInternalFieldCount(1);
NODE_SET_PROTOTYPE_METHOD(t2, "generateKeys", GenerateKeys);
NODE_SET_PROTOTYPE_METHOD(t2, "computeSecret", ComputeSecret);
NODE_SET_PROTOTYPE_METHOD(t2, "getPrime", GetPrime);
NODE_SET_PROTOTYPE_METHOD(t2, "getGenerator", GetGenerator);
NODE_SET_PROTOTYPE_METHOD(t2, "getPublicKey", GetPublicKey);
NODE_SET_PROTOTYPE_METHOD(t2, "getPrivateKey", GetPrivateKey);
target->Set(String::NewSymbol("DiffieHellmanGroup"), t2->GetFunction());
}
bool Init(int primeLength) {
@@ -3557,7 +3570,48 @@ class DiffieHellman : public ObjectWrap {
return true;
}
bool Init(unsigned char* p, int p_len, unsigned char* g, int g_len) {
dh = DH_new();
dh->p = BN_bin2bn(p, p_len, 0);
dh->g = BN_bin2bn(g, g_len, 0);
initialised_ = true;
return true;
}
protected:
static Handle<Value> DiffieHellmanGroup(const Arguments& args) {
HandleScope scope;
DiffieHellman* diffieHellman = new DiffieHellman();
if (args.Length() != 1 || !args[0]->IsString()) {
return ThrowException(Exception::Error(
String::New("No group name given")));
}
String::Utf8Value group_name(args[0]->ToString());
modp_group* it = modp_groups;
while(it->name != NULL) {
if (!strcasecmp(*group_name, it->name))
break;
it++;
}
if (it->name != NULL) {
diffieHellman->Init(it->prime, it->prime_size,
it->gen, it->gen_size);
} else {
return ThrowException(Exception::Error(
String::New("Unknown group")));
}
diffieHellman->Wrap(args.This());
return args.This();
}
static Handle<Value> New(const Arguments& args) {
HandleScope scope;
@@ -4375,4 +4429,3 @@ void InitCrypto(Handle<Object> target) {
} // namespace node
NODE_MODULE(node_crypto, node::crypto::InitCrypto)
Oops, something went wrong.

0 comments on commit c6a04ce

Please sign in to comment.