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'`.
|
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.
|
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 Decipher = binding.Decipher;
|
||||||
var Sign = binding.Sign;
|
var Sign = binding.Sign;
|
||||||
var Verify = binding.Verify;
|
var Verify = binding.Verify;
|
||||||
|
var DiffieHellman = binding.DiffieHellman;
|
||||||
var crypto = true;
|
var crypto = true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
||||||
@ -139,3 +140,15 @@ exports.Verify = Verify;
|
|||||||
exports.createVerify = function(algorithm) {
|
exports.createVerify = function(algorithm) {
|
||||||
return (new Verify).init(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);
|
Connection::Initialize(target);
|
||||||
Cipher::Initialize(target);
|
Cipher::Initialize(target);
|
||||||
Decipher::Initialize(target);
|
Decipher::Initialize(target);
|
||||||
|
DiffieHellman::Initialize(target);
|
||||||
Hmac::Initialize(target);
|
Hmac::Initialize(target);
|
||||||
Hash::Initialize(target);
|
Hash::Initialize(target);
|
||||||
Sign::Initialize(target);
|
Sign::Initialize(target);
|
||||||
|
@ -144,3 +144,31 @@ assert.equal(txt, plaintext, 'encryption and decryption with key and iv');
|
|||||||
assert.throws(function() {
|
assert.throws(function() {
|
||||||
crypto.createHash('sha1').update({foo: 'bar'});
|
crypto.createHash('sha1').update({foo: 'bar'});
|
||||||
}, /string or buffer/);
|
}, /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