For consistency with the rest of the crypto classes, exposes the ECDH class. Originally, only the createECDH function was exposed, and there was no real reason to hide the class. PR-URL: https://github.com/nodejs/node/pull/8188 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
220 lines
5.8 KiB
JavaScript
220 lines
5.8 KiB
JavaScript
'use strict';
|
|
|
|
const { Buffer } = require('buffer');
|
|
const errors = require('internal/errors');
|
|
const {
|
|
getDefaultEncoding,
|
|
toBuf
|
|
} = require('internal/crypto/util');
|
|
const {
|
|
DiffieHellman: _DiffieHellman,
|
|
DiffieHellmanGroup: _DiffieHellmanGroup,
|
|
ECDH: _ECDH
|
|
} = process.binding('crypto');
|
|
const {
|
|
POINT_CONVERSION_COMPRESSED,
|
|
POINT_CONVERSION_HYBRID,
|
|
POINT_CONVERSION_UNCOMPRESSED
|
|
} = process.binding('constants').crypto;
|
|
|
|
const DH_GENERATOR = 2;
|
|
|
|
function DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding) {
|
|
if (!(this instanceof DiffieHellman))
|
|
return new DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding);
|
|
|
|
if (typeof sizeOrKey !== 'number' &&
|
|
typeof sizeOrKey !== 'string' &&
|
|
!ArrayBuffer.isView(sizeOrKey)) {
|
|
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'sizeOrKey',
|
|
['number', 'string', 'Buffer', 'TypedArray',
|
|
'DataView']);
|
|
}
|
|
|
|
if (keyEncoding) {
|
|
if (typeof keyEncoding !== 'string' ||
|
|
(!Buffer.isEncoding(keyEncoding) && keyEncoding !== 'buffer')) {
|
|
genEncoding = generator;
|
|
generator = keyEncoding;
|
|
keyEncoding = false;
|
|
}
|
|
}
|
|
|
|
const encoding = getDefaultEncoding();
|
|
keyEncoding = keyEncoding || encoding;
|
|
genEncoding = genEncoding || encoding;
|
|
|
|
if (typeof sizeOrKey !== 'number')
|
|
sizeOrKey = toBuf(sizeOrKey, keyEncoding);
|
|
|
|
if (!generator)
|
|
generator = DH_GENERATOR;
|
|
else if (typeof generator !== 'number')
|
|
generator = toBuf(generator, genEncoding);
|
|
|
|
this._handle = new _DiffieHellman(sizeOrKey, generator);
|
|
Object.defineProperty(this, 'verifyError', {
|
|
enumerable: true,
|
|
value: this._handle.verifyError,
|
|
writable: false
|
|
});
|
|
}
|
|
|
|
|
|
function DiffieHellmanGroup(name) {
|
|
if (!(this instanceof DiffieHellmanGroup))
|
|
return new DiffieHellmanGroup(name);
|
|
this._handle = new _DiffieHellmanGroup(name);
|
|
Object.defineProperty(this, 'verifyError', {
|
|
enumerable: true,
|
|
value: this._handle.verifyError,
|
|
writable: false
|
|
});
|
|
}
|
|
|
|
|
|
DiffieHellmanGroup.prototype.generateKeys =
|
|
DiffieHellman.prototype.generateKeys =
|
|
dhGenerateKeys;
|
|
|
|
function dhGenerateKeys(encoding) {
|
|
var keys = this._handle.generateKeys();
|
|
encoding = encoding || getDefaultEncoding();
|
|
if (encoding && encoding !== 'buffer')
|
|
keys = keys.toString(encoding);
|
|
return keys;
|
|
}
|
|
|
|
|
|
DiffieHellmanGroup.prototype.computeSecret =
|
|
DiffieHellman.prototype.computeSecret =
|
|
dhComputeSecret;
|
|
|
|
function dhComputeSecret(key, inEnc, outEnc) {
|
|
const encoding = getDefaultEncoding();
|
|
inEnc = inEnc || encoding;
|
|
outEnc = outEnc || encoding;
|
|
var ret = this._handle.computeSecret(toBuf(key, inEnc));
|
|
if (outEnc && outEnc !== 'buffer')
|
|
ret = ret.toString(outEnc);
|
|
return ret;
|
|
}
|
|
|
|
|
|
DiffieHellmanGroup.prototype.getPrime =
|
|
DiffieHellman.prototype.getPrime =
|
|
dhGetPrime;
|
|
|
|
function dhGetPrime(encoding) {
|
|
var prime = this._handle.getPrime();
|
|
encoding = encoding || getDefaultEncoding();
|
|
if (encoding && encoding !== 'buffer')
|
|
prime = prime.toString(encoding);
|
|
return prime;
|
|
}
|
|
|
|
|
|
DiffieHellmanGroup.prototype.getGenerator =
|
|
DiffieHellman.prototype.getGenerator =
|
|
dhGetGenerator;
|
|
|
|
function dhGetGenerator(encoding) {
|
|
var generator = this._handle.getGenerator();
|
|
encoding = encoding || getDefaultEncoding();
|
|
if (encoding && encoding !== 'buffer')
|
|
generator = generator.toString(encoding);
|
|
return generator;
|
|
}
|
|
|
|
|
|
DiffieHellmanGroup.prototype.getPublicKey =
|
|
DiffieHellman.prototype.getPublicKey =
|
|
dhGetPublicKey;
|
|
|
|
function dhGetPublicKey(encoding) {
|
|
var key = this._handle.getPublicKey();
|
|
encoding = encoding || getDefaultEncoding();
|
|
if (encoding && encoding !== 'buffer')
|
|
key = key.toString(encoding);
|
|
return key;
|
|
}
|
|
|
|
|
|
DiffieHellmanGroup.prototype.getPrivateKey =
|
|
DiffieHellman.prototype.getPrivateKey =
|
|
dhGetPrivateKey;
|
|
|
|
function dhGetPrivateKey(encoding) {
|
|
var key = this._handle.getPrivateKey();
|
|
encoding = encoding || getDefaultEncoding();
|
|
if (encoding && encoding !== 'buffer')
|
|
key = key.toString(encoding);
|
|
return key;
|
|
}
|
|
|
|
|
|
DiffieHellman.prototype.setPublicKey = function setPublicKey(key, encoding) {
|
|
encoding = encoding || getDefaultEncoding();
|
|
this._handle.setPublicKey(toBuf(key, encoding));
|
|
return this;
|
|
};
|
|
|
|
|
|
DiffieHellman.prototype.setPrivateKey = function setPrivateKey(key, encoding) {
|
|
encoding = encoding || getDefaultEncoding();
|
|
this._handle.setPrivateKey(toBuf(key, encoding));
|
|
return this;
|
|
};
|
|
|
|
|
|
function ECDH(curve) {
|
|
if (!(this instanceof ECDH))
|
|
return new ECDH(curve);
|
|
|
|
if (typeof curve !== 'string')
|
|
throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'curve', 'string');
|
|
|
|
this._handle = new _ECDH(curve);
|
|
}
|
|
|
|
ECDH.prototype.computeSecret = DiffieHellman.prototype.computeSecret;
|
|
ECDH.prototype.setPrivateKey = DiffieHellman.prototype.setPrivateKey;
|
|
ECDH.prototype.setPublicKey = DiffieHellman.prototype.setPublicKey;
|
|
ECDH.prototype.getPrivateKey = DiffieHellman.prototype.getPrivateKey;
|
|
|
|
ECDH.prototype.generateKeys = function generateKeys(encoding, format) {
|
|
this._handle.generateKeys();
|
|
|
|
return this.getPublicKey(encoding, format);
|
|
};
|
|
|
|
ECDH.prototype.getPublicKey = function getPublicKey(encoding, format) {
|
|
var f;
|
|
if (format) {
|
|
if (typeof format === 'number')
|
|
f = format;
|
|
if (format === 'compressed')
|
|
f = POINT_CONVERSION_COMPRESSED;
|
|
else if (format === 'hybrid')
|
|
f = POINT_CONVERSION_HYBRID;
|
|
// Default
|
|
else if (format === 'uncompressed')
|
|
f = POINT_CONVERSION_UNCOMPRESSED;
|
|
else
|
|
throw new errors.TypeError('ERR_CRYPTO_ECDH_INVALID_FORMAT', format);
|
|
} else {
|
|
f = POINT_CONVERSION_UNCOMPRESSED;
|
|
}
|
|
var key = this._handle.getPublicKey(f);
|
|
encoding = encoding || getDefaultEncoding();
|
|
if (encoding && encoding !== 'buffer')
|
|
key = key.toString(encoding);
|
|
return key;
|
|
};
|
|
|
|
module.exports = {
|
|
DiffieHellman,
|
|
DiffieHellmanGroup,
|
|
ECDH
|
|
};
|