parent
00aee73692
commit
9f0b1a9bc6
@ -146,3 +146,58 @@ the PEM encoded certificate, and `signature`, which is the previously calculates
|
||||
signature for the data, in the `signature_format` which can be `'binary'`, `'hex'` or `'base64'`.
|
||||
|
||||
Returns true or false depending on the validity of the signature for the data and public key.
|
||||
|
||||
### crypto.createDiffieHellman(prime_length)
|
||||
|
||||
Creates a Diffie-Hellman key exchange object and generates a prime of the
|
||||
given bit length. The generator used is `2`.
|
||||
|
||||
### crypto.createDiffieHellman(prime, encoding='binary')
|
||||
|
||||
Creates a Diffie-Hellman key exchange object using the supplied prime. The
|
||||
generator used is `2`. Encoding can be `'binary'`, `'hex'`, or `'base64'`.
|
||||
|
||||
### diffieHellman.generateKeys(encoding='binary')
|
||||
|
||||
Generates private and public Diffie-Hellman key values, and returns the
|
||||
public key in the specified encoding. This key should be transferred to the
|
||||
other party. Encoding can be `'binary'`, `'hex'`, or `'base64'`.
|
||||
|
||||
### diffieHellman.computeSecret(other_public_key, input_encoding='binary', output_encoding=input_encoding)
|
||||
|
||||
Computes the shared secret using `other_public_key` as the other party's
|
||||
public key and returns the computed shared secret. Supplied key is
|
||||
interpreted using specified `input_encoding`, and secret is encoded using
|
||||
specified `output_encoding`. Encodings can be `'binary'`, `'hex'`, or
|
||||
`'base64'`. If no output encoding is given, the input encoding is used as
|
||||
output encoding.
|
||||
|
||||
### diffieHellman.getPrime(encoding='binary')
|
||||
|
||||
Returns the Diffie-Hellman prime in the specified encoding, which can be
|
||||
`'binary'`, `'hex'`, or `'base64'`.
|
||||
|
||||
### diffieHellman.getGenerator(encoding='binary')
|
||||
|
||||
Returns the Diffie-Hellman prime in the specified encoding, which can be
|
||||
`'binary'`, `'hex'`, or `'base64'`.
|
||||
|
||||
### diffieHellman.getPublicKey(encoding='binary')
|
||||
|
||||
Returns the Diffie-Hellman public key in the specified encoding, which can
|
||||
be `'binary'`, `'hex'`, or `'base64'`.
|
||||
|
||||
### diffieHellman.getPrivateKey(encoding='binary')
|
||||
|
||||
Returns the Diffie-Hellman private key in the specified encoding, which can
|
||||
be `'binary'`, `'hex'`, or `'base64'`.
|
||||
|
||||
### diffieHellman.setPublicKey(public_key, encoding='binary')
|
||||
|
||||
Sets the Diffie-Hellman public key. Key encoding can be `'binary'`, `'hex'`,
|
||||
or `'base64'`.
|
||||
|
||||
### diffieHellman.setPrivateKey(public_key, encoding='binary')
|
||||
|
||||
Sets the Diffie-Hellman private key. Key encoding can be `'binary'`, `'hex'`, or `'base64'`.
|
||||
|
||||
|
@ -29,6 +29,7 @@ try {
|
||||
var Decipher = binding.Decipher;
|
||||
var Sign = binding.Sign;
|
||||
var Verify = binding.Verify;
|
||||
var DiffieHellman = binding.DiffieHellman;
|
||||
var crypto = true;
|
||||
} catch (e) {
|
||||
|
||||
@ -139,3 +140,15 @@ exports.Verify = Verify;
|
||||
exports.createVerify = function(algorithm) {
|
||||
return (new Verify).init(algorithm);
|
||||
};
|
||||
|
||||
exports.DiffieHellman = DiffieHellman;
|
||||
exports.createDiffieHellman = function(size_or_key, enc) {
|
||||
if (!size_or_key) {
|
||||
return new DiffieHellman();
|
||||
} else if (!enc) {
|
||||
return new DiffieHellman(size_or_key);
|
||||
} else {
|
||||
return new DiffieHellman(size_or_key, enc);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3053,7 +3053,517 @@ class Verify : public ObjectWrap {
|
||||
|
||||
};
|
||||
|
||||
class DiffieHellman : public ObjectWrap {
|
||||
public:
|
||||
static void Initialize(v8::Handle<v8::Object> target) {
|
||||
HandleScope scope;
|
||||
|
||||
Local<FunctionTemplate> t = FunctionTemplate::New(New);
|
||||
|
||||
t->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "generateKeys", GenerateKeys);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "computeSecret", ComputeSecret);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getPrime", GetPrime);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getGenerator", GetGenerator);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getPublicKey", GetPublicKey);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "getPrivateKey", GetPrivateKey);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "setPublicKey", SetPublicKey);
|
||||
NODE_SET_PROTOTYPE_METHOD(t, "setPrivateKey", SetPrivateKey);
|
||||
|
||||
target->Set(String::NewSymbol("DiffieHellman"), t->GetFunction());
|
||||
}
|
||||
|
||||
bool Init(int primeLength) {
|
||||
dh = DH_new();
|
||||
DH_generate_parameters_ex(dh, primeLength, DH_GENERATOR_2, 0);
|
||||
bool result = VerifyContext();
|
||||
if (!result) return false;
|
||||
initialised_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Init(unsigned char* p, int p_len) {
|
||||
dh = DH_new();
|
||||
dh->p = BN_bin2bn(p, p_len, 0);
|
||||
dh->g = BN_new();
|
||||
if (!BN_set_word(dh->g, 2)) return false;
|
||||
bool result = VerifyContext();
|
||||
if (!result) return false;
|
||||
initialised_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
static Handle<Value> New(const Arguments& args) {
|
||||
HandleScope scope;
|
||||
|
||||
DiffieHellman* diffieHellman = new DiffieHellman();
|
||||
bool initialized = false;
|
||||
|
||||
if (args.Length() > 0) {
|
||||
if (args[0]->IsInt32()) {
|
||||
diffieHellman->Init(args[0]->Int32Value());
|
||||
initialized = true;
|
||||
} else {
|
||||
if (args[0]->IsString()) {
|
||||
char* buf;
|
||||
int len;
|
||||
if (args.Length() > 1 && args[1]->IsString()) {
|
||||
len = DecodeWithEncoding(args[0], args[1], &buf);
|
||||
} else {
|
||||
len = DecodeBinary(args[0], &buf);
|
||||
}
|
||||
|
||||
if (len == -1) {
|
||||
delete[] buf;
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("Invalid argument")));
|
||||
} else {
|
||||
diffieHellman->Init(reinterpret_cast<unsigned char*>(buf), len);
|
||||
delete[] buf;
|
||||
initialized = true;
|
||||
}
|
||||
} else if (Buffer::HasInstance(args[0])) {
|
||||
Local<Object> buffer = args[0]->ToObject();
|
||||
diffieHellman->Init(
|
||||
reinterpret_cast<unsigned char*>(Buffer::Data(buffer)),
|
||||
Buffer::Length(buffer));
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!initialized) {
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("Initialization failed")));
|
||||
}
|
||||
|
||||
diffieHellman->Wrap(args.This());
|
||||
|
||||
return args.This();
|
||||
}
|
||||
|
||||
static Handle<Value> GenerateKeys(const Arguments& args) {
|
||||
DiffieHellman* diffieHellman =
|
||||
ObjectWrap::Unwrap<DiffieHellman>(args.This());
|
||||
|
||||
HandleScope scope;
|
||||
|
||||
if (!diffieHellman->initialised_) {
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("Not initialized")));
|
||||
}
|
||||
|
||||
if (!DH_generate_key(diffieHellman->dh)) {
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("Key generation failed")));
|
||||
}
|
||||
|
||||
Local<Value> outString;
|
||||
|
||||
int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
|
||||
char* data = new char[dataSize];
|
||||
BN_bn2bin(diffieHellman->dh->pub_key,
|
||||
reinterpret_cast<unsigned char*>(data));
|
||||
|
||||
if (args.Length() > 0 && args[0]->IsString()) {
|
||||
outString = EncodeWithEncoding(args[0], data, dataSize);
|
||||
} else {
|
||||
outString = Encode(data, dataSize, BINARY);
|
||||
}
|
||||
delete[] data;
|
||||
|
||||
return scope.Close(outString);
|
||||
}
|
||||
|
||||
static Handle<Value> GetPrime(const Arguments& args) {
|
||||
DiffieHellman* diffieHellman =
|
||||
ObjectWrap::Unwrap<DiffieHellman>(args.This());
|
||||
|
||||
HandleScope scope;
|
||||
|
||||
if (!diffieHellman->initialised_) {
|
||||
return ThrowException(Exception::Error(String::New("Not initialized")));
|
||||
}
|
||||
|
||||
int dataSize = BN_num_bytes(diffieHellman->dh->p);
|
||||
char* data = new char[dataSize];
|
||||
BN_bn2bin(diffieHellman->dh->p, reinterpret_cast<unsigned char*>(data));
|
||||
|
||||
Local<Value> outString;
|
||||
|
||||
if (args.Length() > 0 && args[0]->IsString()) {
|
||||
outString = EncodeWithEncoding(args[0], data, dataSize);
|
||||
} else {
|
||||
outString = Encode(data, dataSize, BINARY);
|
||||
}
|
||||
|
||||
delete[] data;
|
||||
|
||||
return scope.Close(outString);
|
||||
}
|
||||
|
||||
static Handle<Value> GetGenerator(const Arguments& args) {
|
||||
DiffieHellman* diffieHellman =
|
||||
ObjectWrap::Unwrap<DiffieHellman>(args.This());
|
||||
|
||||
HandleScope scope;
|
||||
|
||||
if (!diffieHellman->initialised_) {
|
||||
return ThrowException(Exception::Error(String::New("Not initialized")));
|
||||
}
|
||||
|
||||
int dataSize = BN_num_bytes(diffieHellman->dh->g);
|
||||
char* data = new char[dataSize];
|
||||
BN_bn2bin(diffieHellman->dh->g, reinterpret_cast<unsigned char*>(data));
|
||||
|
||||
Local<Value> outString;
|
||||
|
||||
if (args.Length() > 0 && args[0]->IsString()) {
|
||||
outString = EncodeWithEncoding(args[0], data, dataSize);
|
||||
} else {
|
||||
outString = Encode(data, dataSize, BINARY);
|
||||
}
|
||||
|
||||
delete[] data;
|
||||
|
||||
return scope.Close(outString);
|
||||
}
|
||||
|
||||
static Handle<Value> GetPublicKey(const Arguments& args) {
|
||||
DiffieHellman* diffieHellman =
|
||||
ObjectWrap::Unwrap<DiffieHellman>(args.This());
|
||||
|
||||
HandleScope scope;
|
||||
|
||||
if (!diffieHellman->initialised_) {
|
||||
return ThrowException(Exception::Error(String::New("Not initialized")));
|
||||
}
|
||||
|
||||
if (diffieHellman->dh->pub_key == NULL) {
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("No public key - did you forget to generate one?")));
|
||||
}
|
||||
|
||||
int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
|
||||
char* data = new char[dataSize];
|
||||
BN_bn2bin(diffieHellman->dh->pub_key,
|
||||
reinterpret_cast<unsigned char*>(data));
|
||||
|
||||
Local<Value> outString;
|
||||
|
||||
if (args.Length() > 0 && args[0]->IsString()) {
|
||||
outString = EncodeWithEncoding(args[0], data, dataSize);
|
||||
} else {
|
||||
outString = Encode(data, dataSize, BINARY);
|
||||
}
|
||||
|
||||
delete[] data;
|
||||
|
||||
return scope.Close(outString);
|
||||
}
|
||||
|
||||
static Handle<Value> GetPrivateKey(const Arguments& args) {
|
||||
DiffieHellman* diffieHellman =
|
||||
ObjectWrap::Unwrap<DiffieHellman>(args.This());
|
||||
|
||||
HandleScope scope;
|
||||
|
||||
if (!diffieHellman->initialised_) {
|
||||
return ThrowException(Exception::Error(String::New("Not initialized")));
|
||||
}
|
||||
|
||||
if (diffieHellman->dh->priv_key == NULL) {
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("No private key - did you forget to generate one?")));
|
||||
}
|
||||
|
||||
int dataSize = BN_num_bytes(diffieHellman->dh->priv_key);
|
||||
char* data = new char[dataSize];
|
||||
BN_bn2bin(diffieHellman->dh->priv_key,
|
||||
reinterpret_cast<unsigned char*>(data));
|
||||
|
||||
Local<Value> outString;
|
||||
|
||||
if (args.Length() > 0 && args[0]->IsString()) {
|
||||
outString = EncodeWithEncoding(args[0], data, dataSize);
|
||||
} else {
|
||||
outString = Encode(data, dataSize, BINARY);
|
||||
}
|
||||
|
||||
delete[] data;
|
||||
|
||||
return scope.Close(outString);
|
||||
}
|
||||
|
||||
static Handle<Value> ComputeSecret(const Arguments& args) {
|
||||
HandleScope scope;
|
||||
|
||||
DiffieHellman* diffieHellman =
|
||||
ObjectWrap::Unwrap<DiffieHellman>(args.This());
|
||||
|
||||
if (!diffieHellman->initialised_) {
|
||||
return ThrowException(Exception::Error(String::New("Not initialized")));
|
||||
}
|
||||
|
||||
BIGNUM* key = 0;
|
||||
|
||||
if (args.Length() == 0) {
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("First argument must be other party's public key")));
|
||||
} else {
|
||||
if (args[0]->IsString()) {
|
||||
char* buf;
|
||||
int len;
|
||||
if (args.Length() > 1) {
|
||||
len = DecodeWithEncoding(args[0], args[1], &buf);
|
||||
} else {
|
||||
len = DecodeBinary(args[0], &buf);
|
||||
}
|
||||
if (len == -1) {
|
||||
delete[] buf;
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("Invalid argument")));
|
||||
}
|
||||
key = BN_bin2bn(reinterpret_cast<unsigned char*>(buf), len, 0);
|
||||
delete[] buf;
|
||||
} else if (Buffer::HasInstance(args[0])) {
|
||||
Local<Object> buffer = args[0]->ToObject();
|
||||
key = BN_bin2bn(
|
||||
reinterpret_cast<unsigned char*>(Buffer::Data(buffer)),
|
||||
Buffer::Length(buffer), 0);
|
||||
} else {
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("First argument must be other party's public key")));
|
||||
}
|
||||
}
|
||||
|
||||
int dataSize = DH_size(diffieHellman->dh);
|
||||
char* data = new char[dataSize];
|
||||
|
||||
int size = DH_compute_key(reinterpret_cast<unsigned char*>(data),
|
||||
key, diffieHellman->dh);
|
||||
BN_free(key);
|
||||
|
||||
Local<Value> outString;
|
||||
|
||||
if (size == -1) {
|
||||
int checkResult;
|
||||
if (!DH_check_pub_key(diffieHellman->dh, key, &checkResult)) {
|
||||
return ThrowException(Exception::Error(String::New("Invalid key")));
|
||||
} else if (checkResult) {
|
||||
if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) {
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("Supplied key is too small")));
|
||||
} else if (checkResult & DH_CHECK_PUBKEY_TOO_LARGE) {
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("Supplied key is too large")));
|
||||
} else {
|
||||
return ThrowException(Exception::Error(String::New("Invalid key")));
|
||||
}
|
||||
} else {
|
||||
return ThrowException(Exception::Error(String::New("Invalid key")));
|
||||
}
|
||||
} else {
|
||||
if (args.Length() > 2 && args[2]->IsString()) {
|
||||
outString = EncodeWithEncoding(args[2], data, dataSize);
|
||||
} else if (args.Length() > 1 && args[1]->IsString()) {
|
||||
outString = EncodeWithEncoding(args[1], data, dataSize);
|
||||
} else {
|
||||
outString = Encode(data, dataSize, BINARY);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] data;
|
||||
return scope.Close(outString);
|
||||
}
|
||||
|
||||
static Handle<Value> SetPublicKey(const Arguments& args) {
|
||||
HandleScope scope;
|
||||
|
||||
DiffieHellman* diffieHellman =
|
||||
ObjectWrap::Unwrap<DiffieHellman>(args.This());
|
||||
|
||||
if (!diffieHellman->initialised_) {
|
||||
return ThrowException(Exception::Error(String::New("Not initialized")));
|
||||
}
|
||||
|
||||
if (args.Length() == 0) {
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("First argument must be public key")));
|
||||
} else {
|
||||
if (args[0]->IsString()) {
|
||||
char* buf;
|
||||
int len;
|
||||
if (args.Length() > 1) {
|
||||
len = DecodeWithEncoding(args[0], args[1], &buf);
|
||||
} else {
|
||||
len = DecodeBinary(args[0], &buf);
|
||||
}
|
||||
if (len == -1) {
|
||||
delete[] buf;
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("Invalid argument")));
|
||||
}
|
||||
diffieHellman->dh->pub_key =
|
||||
BN_bin2bn(reinterpret_cast<unsigned char*>(buf), len, 0);
|
||||
delete[] buf;
|
||||
} else if (Buffer::HasInstance(args[0])) {
|
||||
Local<Object> buffer = args[0]->ToObject();
|
||||
diffieHellman->dh->pub_key =
|
||||
BN_bin2bn(
|
||||
reinterpret_cast<unsigned char*>(Buffer::Data(buffer)),
|
||||
Buffer::Length(buffer), 0);
|
||||
} else {
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("First argument must be public key")));
|
||||
}
|
||||
}
|
||||
|
||||
return args.This();
|
||||
}
|
||||
|
||||
static Handle<Value> SetPrivateKey(const Arguments& args) {
|
||||
HandleScope scope;
|
||||
|
||||
DiffieHellman* diffieHellman =
|
||||
ObjectWrap::Unwrap<DiffieHellman>(args.This());
|
||||
|
||||
if (!diffieHellman->initialised_) {
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("Not initialized")));
|
||||
}
|
||||
|
||||
if (args.Length() == 0) {
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("First argument must be private key")));
|
||||
} else {
|
||||
if (args[0]->IsString()) {
|
||||
char* buf;
|
||||
int len;
|
||||
if (args.Length() > 1) {
|
||||
len = DecodeWithEncoding(args[0], args[1], &buf);
|
||||
} else {
|
||||
len = DecodeBinary(args[0], &buf);
|
||||
}
|
||||
if (len == -1) {
|
||||
delete[] buf;
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("Invalid argument")));
|
||||
}
|
||||
diffieHellman->dh->priv_key =
|
||||
BN_bin2bn(reinterpret_cast<unsigned char*>(buf), len, 0);
|
||||
delete[] buf;
|
||||
} else if (Buffer::HasInstance(args[0])) {
|
||||
Local<Object> buffer = args[0]->ToObject();
|
||||
diffieHellman->dh->priv_key =
|
||||
BN_bin2bn(
|
||||
reinterpret_cast<unsigned char*>(Buffer::Data(buffer)),
|
||||
Buffer::Length(buffer), 0);
|
||||
} else {
|
||||
return ThrowException(Exception::Error(
|
||||
String::New("First argument must be private key")));
|
||||
}
|
||||
}
|
||||
|
||||
return args.This();
|
||||
}
|
||||
|
||||
DiffieHellman() : ObjectWrap() {
|
||||
initialised_ = false;
|
||||
dh = NULL;
|
||||
}
|
||||
|
||||
~DiffieHellman() {
|
||||
if (dh != NULL) {
|
||||
DH_free(dh);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool VerifyContext() {
|
||||
int codes;
|
||||
if (!DH_check(dh, &codes)) return false;
|
||||
if (codes & DH_CHECK_P_NOT_SAFE_PRIME) return false;
|
||||
if (codes & DH_CHECK_P_NOT_PRIME) return false;
|
||||
if (codes & DH_UNABLE_TO_CHECK_GENERATOR) return false;
|
||||
if (codes & DH_NOT_SUITABLE_GENERATOR) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int DecodeBinary(Handle<Value> str, char** buf) {
|
||||
int len = DecodeBytes(str);
|
||||
*buf = new char[len];
|
||||
int written = DecodeWrite(*buf, len, str, BINARY);
|
||||
if (written != len) {
|
||||
return -1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static int DecodeWithEncoding(Handle<Value> str, Handle<Value> enc,
|
||||
char** buf) {
|
||||
int len = DecodeBinary(str, buf);
|
||||
if (len == -1) {
|
||||
return len;
|
||||
}
|
||||
String::Utf8Value encoding(enc->ToString());
|
||||
char* retbuf = 0;
|
||||
int retlen;
|
||||
|
||||
if (strcasecmp(*encoding, "hex") == 0) {
|
||||
HexDecode((unsigned char*)*buf, len, &retbuf, &retlen);
|
||||
|
||||
} else if (strcasecmp(*encoding, "base64") == 0) {
|
||||
unbase64((unsigned char*)*buf, len, &retbuf, &retlen);
|
||||
|
||||
} else if (strcasecmp(*encoding, "binary") == 0) {
|
||||
// Binary - do nothing
|
||||
} else {
|
||||
fprintf(stderr, "node-crypto : Diffie-Hellman parameter encoding "
|
||||
"can be binary, hex or base64\n");
|
||||
}
|
||||
|
||||
if (retbuf != 0) {
|
||||
delete [] *buf;
|
||||
*buf = retbuf;
|
||||
len = retlen;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static Local<Value> EncodeWithEncoding(Handle<Value> enc, char* buf,
|
||||
int len) {
|
||||
HandleScope scope;
|
||||
|
||||
Local<Value> outString;
|
||||
String::Utf8Value encoding(enc->ToString());
|
||||
char* retbuf;
|
||||
int retlen;
|
||||
if (strcasecmp(*encoding, "hex") == 0) {
|
||||
// Hex encoding
|
||||
HexEncode(reinterpret_cast<unsigned char*>(buf), len, &retbuf, &retlen);
|
||||
outString = Encode(retbuf, retlen, BINARY);
|
||||
delete [] retbuf;
|
||||
} else if (strcasecmp(*encoding, "base64") == 0) {
|
||||
base64(reinterpret_cast<unsigned char*>(buf), len, &retbuf, &retlen);
|
||||
outString = Encode(retbuf, retlen, BINARY);
|
||||
delete [] retbuf;
|
||||
} else if (strcasecmp(*encoding, "binary") == 0) {
|
||||
outString = Encode(buf, len, BINARY);
|
||||
} else {
|
||||
fprintf(stderr, "node-crypto : Diffie-Hellman parameter encoding "
|
||||
"can be binary, hex or base64\n");
|
||||
}
|
||||
|
||||
return scope.Close(outString);
|
||||
}
|
||||
|
||||
bool initialised_;
|
||||
DH* dh;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -3070,6 +3580,7 @@ void InitCrypto(Handle<Object> target) {
|
||||
Connection::Initialize(target);
|
||||
Cipher::Initialize(target);
|
||||
Decipher::Initialize(target);
|
||||
DiffieHellman::Initialize(target);
|
||||
Hmac::Initialize(target);
|
||||
Hash::Initialize(target);
|
||||
Sign::Initialize(target);
|
||||
|
@ -144,3 +144,31 @@ assert.equal(txt, plaintext, 'encryption and decryption with key and iv');
|
||||
assert.throws(function() {
|
||||
crypto.createHash('sha1').update({foo: 'bar'});
|
||||
}, /string or buffer/);
|
||||
|
||||
// Test Diffie-Hellman with two parties sharing a secret,
|
||||
// using various encodings as we go along
|
||||
var dh1 = crypto.createDiffieHellman(256);
|
||||
var p1 = dh1.getPrime('base64');
|
||||
var dh2 = crypto.createDiffieHellman(p1, 'base64');
|
||||
var key1 = dh1.generateKeys();
|
||||
var key2 = dh2.generateKeys('hex');
|
||||
var secret1 = dh1.computeSecret(key2, 'hex', 'base64');
|
||||
var secret2 = dh2.computeSecret(key1, 'binary', 'base64');
|
||||
|
||||
assert.equal(secret1, secret2);
|
||||
|
||||
// Create "another dh1" using generated keys from dh1,
|
||||
// and compute secret again
|
||||
var dh3 = crypto.createDiffieHellman(p1, 'base64');
|
||||
var privkey1 = dh1.getPrivateKey();
|
||||
dh3.setPublicKey(key1);
|
||||
dh3.setPrivateKey(privkey1);
|
||||
|
||||
assert.equal(dh1.getPrime(), dh3.getPrime());
|
||||
assert.equal(dh1.getGenerator(), dh3.getGenerator());
|
||||
assert.equal(dh1.getPublicKey(), dh3.getPublicKey());
|
||||
assert.equal(dh1.getPrivateKey(), dh3.getPrivateKey());
|
||||
|
||||
var secret3 = dh3.computeSecret(key2, 'hex', 'base64');
|
||||
|
||||
assert.equal(secret1, secret3);
|
||||
|
Loading…
x
Reference in New Issue
Block a user