nodejs/lib/internal/crypto/diffiehellman.js
Bryan English 26174fcfe1 crypto: expose ECDH class
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>
2017-09-27 13:42:30 -07:00

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
};