mirror of
https://github.com/nodejs/node.git
synced 2024-12-01 16:10:02 +01:00
6561274d23
Private keys may be used along with publicEncrypt since the private key includes the public one. This adds the ability to use encrypted private keys which previously threw an error. This commit also makes sure the user exposed functions have names. PR-URL: https://github.com/iojs/io.js/pull/626 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
689 lines
19 KiB
JavaScript
689 lines
19 KiB
JavaScript
// Note: In 0.8 and before, crypto functions all defaulted to using
|
|
// binary-encoded strings rather than buffers.
|
|
|
|
'use strict';
|
|
|
|
exports.DEFAULT_ENCODING = 'buffer';
|
|
|
|
try {
|
|
var binding = process.binding('crypto');
|
|
var randomBytes = binding.randomBytes;
|
|
var getCiphers = binding.getCiphers;
|
|
var getHashes = binding.getHashes;
|
|
} catch (e) {
|
|
throw new Error('node.js not compiled with openssl crypto support.');
|
|
}
|
|
|
|
const constants = require('constants');
|
|
const stream = require('stream');
|
|
const util = require('util');
|
|
|
|
const DH_GENERATOR = 2;
|
|
|
|
// This is here because many functions accepted binary strings without
|
|
// any explicit encoding in older versions of node, and we don't want
|
|
// to break them unnecessarily.
|
|
function toBuf(str, encoding) {
|
|
encoding = encoding || 'binary';
|
|
if (typeof str === 'string') {
|
|
if (encoding === 'buffer')
|
|
encoding = 'binary';
|
|
str = new Buffer(str, encoding);
|
|
}
|
|
return str;
|
|
}
|
|
exports._toBuf = toBuf;
|
|
|
|
|
|
const assert = require('assert');
|
|
const StringDecoder = require('string_decoder').StringDecoder;
|
|
|
|
|
|
function LazyTransform(options) {
|
|
this._options = options;
|
|
}
|
|
util.inherits(LazyTransform, stream.Transform);
|
|
|
|
[
|
|
'_readableState',
|
|
'_writableState',
|
|
'_transformState'
|
|
].forEach(function(prop, i, props) {
|
|
Object.defineProperty(LazyTransform.prototype, prop, {
|
|
get: function() {
|
|
stream.Transform.call(this, this._options);
|
|
this._writableState.decodeStrings = false;
|
|
this._writableState.defaultEncoding = 'binary';
|
|
return this[prop];
|
|
},
|
|
set: function(val) {
|
|
Object.defineProperty(this, prop, {
|
|
value: val,
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true
|
|
});
|
|
},
|
|
configurable: true,
|
|
enumerable: true
|
|
});
|
|
});
|
|
|
|
|
|
exports.createHash = exports.Hash = Hash;
|
|
function Hash(algorithm, options) {
|
|
if (!(this instanceof Hash))
|
|
return new Hash(algorithm, options);
|
|
this._handle = new binding.Hash(algorithm);
|
|
LazyTransform.call(this, options);
|
|
}
|
|
|
|
util.inherits(Hash, LazyTransform);
|
|
|
|
Hash.prototype._transform = function(chunk, encoding, callback) {
|
|
this._handle.update(chunk, encoding);
|
|
callback();
|
|
};
|
|
|
|
Hash.prototype._flush = function(callback) {
|
|
this.push(this._handle.digest());
|
|
callback();
|
|
};
|
|
|
|
Hash.prototype.update = function(data, encoding) {
|
|
encoding = encoding || exports.DEFAULT_ENCODING;
|
|
if (encoding === 'buffer' && typeof data === 'string')
|
|
encoding = 'binary';
|
|
this._handle.update(data, encoding);
|
|
return this;
|
|
};
|
|
|
|
|
|
Hash.prototype.digest = function(outputEncoding) {
|
|
outputEncoding = outputEncoding || exports.DEFAULT_ENCODING;
|
|
return this._handle.digest(outputEncoding);
|
|
};
|
|
|
|
|
|
exports.createHmac = exports.Hmac = Hmac;
|
|
|
|
function Hmac(hmac, key, options) {
|
|
if (!(this instanceof Hmac))
|
|
return new Hmac(hmac, key, options);
|
|
this._handle = new binding.Hmac();
|
|
this._handle.init(hmac, toBuf(key));
|
|
LazyTransform.call(this, options);
|
|
}
|
|
|
|
util.inherits(Hmac, LazyTransform);
|
|
|
|
Hmac.prototype.update = Hash.prototype.update;
|
|
Hmac.prototype.digest = Hash.prototype.digest;
|
|
Hmac.prototype._flush = Hash.prototype._flush;
|
|
Hmac.prototype._transform = Hash.prototype._transform;
|
|
|
|
|
|
function getDecoder(decoder, encoding) {
|
|
if (encoding === 'utf-8') encoding = 'utf8'; // Normalize encoding.
|
|
decoder = decoder || new StringDecoder(encoding);
|
|
assert(decoder.encoding === encoding, 'Cannot change encoding');
|
|
return decoder;
|
|
}
|
|
|
|
|
|
exports.createCipher = exports.Cipher = Cipher;
|
|
function Cipher(cipher, password, options) {
|
|
if (!(this instanceof Cipher))
|
|
return new Cipher(cipher, password, options);
|
|
this._handle = new binding.CipherBase(true);
|
|
|
|
this._handle.init(cipher, toBuf(password));
|
|
this._decoder = null;
|
|
|
|
LazyTransform.call(this, options);
|
|
}
|
|
|
|
util.inherits(Cipher, LazyTransform);
|
|
|
|
Cipher.prototype._transform = function(chunk, encoding, callback) {
|
|
this.push(this._handle.update(chunk, encoding));
|
|
callback();
|
|
};
|
|
|
|
Cipher.prototype._flush = function(callback) {
|
|
try {
|
|
this.push(this._handle.final());
|
|
} catch (e) {
|
|
callback(e);
|
|
return;
|
|
}
|
|
callback();
|
|
};
|
|
|
|
Cipher.prototype.update = function(data, inputEncoding, outputEncoding) {
|
|
inputEncoding = inputEncoding || exports.DEFAULT_ENCODING;
|
|
outputEncoding = outputEncoding || exports.DEFAULT_ENCODING;
|
|
|
|
var ret = this._handle.update(data, inputEncoding);
|
|
|
|
if (outputEncoding && outputEncoding !== 'buffer') {
|
|
this._decoder = getDecoder(this._decoder, outputEncoding);
|
|
ret = this._decoder.write(ret);
|
|
}
|
|
|
|
return ret;
|
|
};
|
|
|
|
|
|
Cipher.prototype.final = function(outputEncoding) {
|
|
outputEncoding = outputEncoding || exports.DEFAULT_ENCODING;
|
|
var ret = this._handle.final();
|
|
|
|
if (outputEncoding && outputEncoding !== 'buffer') {
|
|
this._decoder = getDecoder(this._decoder, outputEncoding);
|
|
ret = this._decoder.end(ret);
|
|
}
|
|
|
|
return ret;
|
|
};
|
|
|
|
|
|
Cipher.prototype.setAutoPadding = function(ap) {
|
|
this._handle.setAutoPadding(ap);
|
|
return this;
|
|
};
|
|
|
|
Cipher.prototype.getAuthTag = function() {
|
|
return this._handle.getAuthTag();
|
|
};
|
|
|
|
|
|
Cipher.prototype.setAuthTag = function(tagbuf) {
|
|
this._handle.setAuthTag(tagbuf);
|
|
};
|
|
|
|
Cipher.prototype.setAAD = function(aadbuf) {
|
|
this._handle.setAAD(aadbuf);
|
|
};
|
|
|
|
exports.createCipheriv = exports.Cipheriv = Cipheriv;
|
|
function Cipheriv(cipher, key, iv, options) {
|
|
if (!(this instanceof Cipheriv))
|
|
return new Cipheriv(cipher, key, iv, options);
|
|
this._handle = new binding.CipherBase(true);
|
|
this._handle.initiv(cipher, toBuf(key), toBuf(iv));
|
|
this._decoder = null;
|
|
|
|
LazyTransform.call(this, options);
|
|
}
|
|
|
|
util.inherits(Cipheriv, LazyTransform);
|
|
|
|
Cipheriv.prototype._transform = Cipher.prototype._transform;
|
|
Cipheriv.prototype._flush = Cipher.prototype._flush;
|
|
Cipheriv.prototype.update = Cipher.prototype.update;
|
|
Cipheriv.prototype.final = Cipher.prototype.final;
|
|
Cipheriv.prototype.setAutoPadding = Cipher.prototype.setAutoPadding;
|
|
Cipheriv.prototype.getAuthTag = Cipher.prototype.getAuthTag;
|
|
Cipheriv.prototype.setAuthTag = Cipher.prototype.setAuthTag;
|
|
Cipheriv.prototype.setAAD = Cipher.prototype.setAAD;
|
|
|
|
exports.createDecipher = exports.Decipher = Decipher;
|
|
function Decipher(cipher, password, options) {
|
|
if (!(this instanceof Decipher))
|
|
return new Decipher(cipher, password, options);
|
|
|
|
this._handle = new binding.CipherBase(false);
|
|
this._handle.init(cipher, toBuf(password));
|
|
this._decoder = null;
|
|
|
|
LazyTransform.call(this, options);
|
|
}
|
|
|
|
util.inherits(Decipher, LazyTransform);
|
|
|
|
Decipher.prototype._transform = Cipher.prototype._transform;
|
|
Decipher.prototype._flush = Cipher.prototype._flush;
|
|
Decipher.prototype.update = Cipher.prototype.update;
|
|
Decipher.prototype.final = Cipher.prototype.final;
|
|
Decipher.prototype.finaltol = Cipher.prototype.final;
|
|
Decipher.prototype.setAutoPadding = Cipher.prototype.setAutoPadding;
|
|
Decipher.prototype.getAuthTag = Cipher.prototype.getAuthTag;
|
|
Decipher.prototype.setAuthTag = Cipher.prototype.setAuthTag;
|
|
Decipher.prototype.setAAD = Cipher.prototype.setAAD;
|
|
|
|
|
|
exports.createDecipheriv = exports.Decipheriv = Decipheriv;
|
|
function Decipheriv(cipher, key, iv, options) {
|
|
if (!(this instanceof Decipheriv))
|
|
return new Decipheriv(cipher, key, iv, options);
|
|
|
|
this._handle = new binding.CipherBase(false);
|
|
this._handle.initiv(cipher, toBuf(key), toBuf(iv));
|
|
this._decoder = null;
|
|
|
|
LazyTransform.call(this, options);
|
|
}
|
|
|
|
util.inherits(Decipheriv, LazyTransform);
|
|
|
|
Decipheriv.prototype._transform = Cipher.prototype._transform;
|
|
Decipheriv.prototype._flush = Cipher.prototype._flush;
|
|
Decipheriv.prototype.update = Cipher.prototype.update;
|
|
Decipheriv.prototype.final = Cipher.prototype.final;
|
|
Decipheriv.prototype.finaltol = Cipher.prototype.final;
|
|
Decipheriv.prototype.setAutoPadding = Cipher.prototype.setAutoPadding;
|
|
Decipheriv.prototype.getAuthTag = Cipher.prototype.getAuthTag;
|
|
Decipheriv.prototype.setAuthTag = Cipher.prototype.setAuthTag;
|
|
Decipheriv.prototype.setAAD = Cipher.prototype.setAAD;
|
|
|
|
|
|
|
|
exports.createSign = exports.Sign = Sign;
|
|
function Sign(algorithm, options) {
|
|
if (!(this instanceof Sign))
|
|
return new Sign(algorithm, options);
|
|
this._handle = new binding.Sign();
|
|
this._handle.init(algorithm);
|
|
|
|
stream.Writable.call(this, options);
|
|
}
|
|
|
|
util.inherits(Sign, stream.Writable);
|
|
|
|
Sign.prototype._write = function(chunk, encoding, callback) {
|
|
this._handle.update(chunk, encoding);
|
|
callback();
|
|
};
|
|
|
|
Sign.prototype.update = Hash.prototype.update;
|
|
|
|
Sign.prototype.sign = function(options, encoding) {
|
|
if (!options)
|
|
throw new Error('No key provided to sign');
|
|
|
|
var key = options.key || options;
|
|
var passphrase = options.passphrase || null;
|
|
var ret = this._handle.sign(toBuf(key), null, passphrase);
|
|
|
|
encoding = encoding || exports.DEFAULT_ENCODING;
|
|
if (encoding && encoding !== 'buffer')
|
|
ret = ret.toString(encoding);
|
|
|
|
return ret;
|
|
};
|
|
|
|
|
|
|
|
exports.createVerify = exports.Verify = Verify;
|
|
function Verify(algorithm, options) {
|
|
if (!(this instanceof Verify))
|
|
return new Verify(algorithm, options);
|
|
|
|
this._handle = new binding.Verify;
|
|
this._handle.init(algorithm);
|
|
|
|
stream.Writable.call(this, options);
|
|
}
|
|
|
|
util.inherits(Verify, stream.Writable);
|
|
|
|
Verify.prototype._write = Sign.prototype._write;
|
|
Verify.prototype.update = Sign.prototype.update;
|
|
|
|
Verify.prototype.verify = function(object, signature, sigEncoding) {
|
|
sigEncoding = sigEncoding || exports.DEFAULT_ENCODING;
|
|
return this._handle.verify(toBuf(object), toBuf(signature, sigEncoding));
|
|
};
|
|
|
|
function rsaPublic(method, defaultPadding) {
|
|
return function(options, buffer) {
|
|
var key = options.key || options;
|
|
var padding = options.padding || defaultPadding;
|
|
var passphrase = options.passphrase || null;
|
|
return method(toBuf(key), buffer, padding, passphrase);
|
|
};
|
|
}
|
|
|
|
function rsaPrivate(method, defaultPadding) {
|
|
return function(options, buffer) {
|
|
var key = options.key || options;
|
|
var passphrase = options.passphrase || null;
|
|
var padding = options.padding || defaultPadding;
|
|
return method(toBuf(key), buffer, padding, passphrase);
|
|
};
|
|
}
|
|
|
|
exports.publicEncrypt = rsaPublic(binding.publicEncrypt,
|
|
constants.RSA_PKCS1_OAEP_PADDING);
|
|
exports.publicDecrypt = rsaPublic(binding.publicDecrypt,
|
|
constants.RSA_PKCS1_PADDING);
|
|
exports.privateEncrypt = rsaPrivate(binding.privateEncrypt,
|
|
constants.RSA_PKCS1_PADDING);
|
|
exports.privateDecrypt = rsaPrivate(binding.privateDecrypt,
|
|
constants.RSA_PKCS1_OAEP_PADDING);
|
|
|
|
|
|
exports.createDiffieHellman = exports.DiffieHellman = DiffieHellman;
|
|
|
|
function DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding) {
|
|
if (!(this instanceof DiffieHellman))
|
|
return new DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding);
|
|
|
|
if (!(sizeOrKey instanceof Buffer) &&
|
|
typeof sizeOrKey !== 'number' &&
|
|
typeof sizeOrKey !== 'string')
|
|
throw new TypeError('First argument should be number, string or Buffer');
|
|
|
|
if (keyEncoding) {
|
|
if (typeof keyEncoding !== 'string' ||
|
|
(!Buffer.isEncoding(keyEncoding) && keyEncoding !== 'buffer')) {
|
|
genEncoding = generator;
|
|
generator = keyEncoding;
|
|
keyEncoding = false;
|
|
}
|
|
}
|
|
|
|
keyEncoding = keyEncoding || exports.DEFAULT_ENCODING;
|
|
genEncoding = genEncoding || exports.DEFAULT_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 binding.DiffieHellman(sizeOrKey, generator);
|
|
Object.defineProperty(this, 'verifyError', {
|
|
enumerable: true,
|
|
value: this._handle.verifyError,
|
|
writable: false
|
|
});
|
|
}
|
|
|
|
|
|
exports.DiffieHellmanGroup =
|
|
exports.createDiffieHellmanGroup =
|
|
exports.getDiffieHellman = DiffieHellmanGroup;
|
|
|
|
function DiffieHellmanGroup(name) {
|
|
if (!(this instanceof DiffieHellmanGroup))
|
|
return new DiffieHellmanGroup(name);
|
|
this._handle = new binding.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 || exports.DEFAULT_ENCODING;
|
|
if (encoding && encoding !== 'buffer')
|
|
keys = keys.toString(encoding);
|
|
return keys;
|
|
}
|
|
|
|
|
|
DiffieHellmanGroup.prototype.computeSecret =
|
|
DiffieHellman.prototype.computeSecret =
|
|
dhComputeSecret;
|
|
|
|
function dhComputeSecret(key, inEnc, outEnc) {
|
|
inEnc = inEnc || exports.DEFAULT_ENCODING;
|
|
outEnc = outEnc || exports.DEFAULT_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 || exports.DEFAULT_ENCODING;
|
|
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 || exports.DEFAULT_ENCODING;
|
|
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 || exports.DEFAULT_ENCODING;
|
|
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 || exports.DEFAULT_ENCODING;
|
|
if (encoding && encoding !== 'buffer')
|
|
key = key.toString(encoding);
|
|
return key;
|
|
}
|
|
|
|
|
|
DiffieHellman.prototype.setPublicKey = function(key, encoding) {
|
|
encoding = encoding || exports.DEFAULT_ENCODING;
|
|
this._handle.setPublicKey(toBuf(key, encoding));
|
|
return this;
|
|
};
|
|
|
|
|
|
DiffieHellman.prototype.setPrivateKey = function(key, encoding) {
|
|
encoding = encoding || exports.DEFAULT_ENCODING;
|
|
this._handle.setPrivateKey(toBuf(key, encoding));
|
|
return this;
|
|
};
|
|
|
|
|
|
function ECDH(curve) {
|
|
if (typeof curve !== 'string')
|
|
throw new TypeError('curve should be a string');
|
|
|
|
this._handle = new binding.ECDH(curve);
|
|
}
|
|
|
|
exports.createECDH = function createECDH(curve) {
|
|
return 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 = constants.POINT_CONVERSION_COMPRESSED;
|
|
else if (format === 'hybrid')
|
|
f = constants.POINT_CONVERSION_HYBRID;
|
|
// Default
|
|
else if (format === 'uncompressed')
|
|
f = constants.POINT_CONVERSION_UNCOMPRESSED;
|
|
else
|
|
throw TypeError('Bad format: ' + format);
|
|
} else {
|
|
f = constants.POINT_CONVERSION_UNCOMPRESSED;
|
|
}
|
|
var key = this._handle.getPublicKey(f);
|
|
encoding = encoding || exports.DEFAULT_ENCODING;
|
|
if (encoding && encoding !== 'buffer')
|
|
key = key.toString(encoding);
|
|
return key;
|
|
};
|
|
|
|
|
|
|
|
exports.pbkdf2 = function(password,
|
|
salt,
|
|
iterations,
|
|
keylen,
|
|
digest,
|
|
callback) {
|
|
if (typeof digest === 'function') {
|
|
callback = digest;
|
|
digest = undefined;
|
|
}
|
|
|
|
if (typeof callback !== 'function')
|
|
throw new Error('No callback provided to pbkdf2');
|
|
|
|
return pbkdf2(password, salt, iterations, keylen, digest, callback);
|
|
};
|
|
|
|
|
|
exports.pbkdf2Sync = function(password, salt, iterations, keylen, digest) {
|
|
return pbkdf2(password, salt, iterations, keylen, digest);
|
|
};
|
|
|
|
|
|
function pbkdf2(password, salt, iterations, keylen, digest, callback) {
|
|
password = toBuf(password);
|
|
salt = toBuf(salt);
|
|
|
|
if (exports.DEFAULT_ENCODING === 'buffer')
|
|
return binding.PBKDF2(password, salt, iterations, keylen, digest, callback);
|
|
|
|
// at this point, we need to handle encodings.
|
|
var encoding = exports.DEFAULT_ENCODING;
|
|
if (callback) {
|
|
var next = function(er, ret) {
|
|
if (ret)
|
|
ret = ret.toString(encoding);
|
|
callback(er, ret);
|
|
};
|
|
binding.PBKDF2(password, salt, iterations, keylen, digest, next);
|
|
} else {
|
|
var ret = binding.PBKDF2(password, salt, iterations, keylen, digest);
|
|
return ret.toString(encoding);
|
|
}
|
|
}
|
|
|
|
|
|
exports.Certificate = Certificate;
|
|
|
|
function Certificate() {
|
|
if (!(this instanceof Certificate))
|
|
return new Certificate();
|
|
|
|
this._handle = new binding.Certificate();
|
|
}
|
|
|
|
|
|
Certificate.prototype.verifySpkac = function(object) {
|
|
return this._handle.verifySpkac(object);
|
|
};
|
|
|
|
|
|
Certificate.prototype.exportPublicKey = function(object, encoding) {
|
|
return this._handle.exportPublicKey(toBuf(object, encoding));
|
|
};
|
|
|
|
|
|
Certificate.prototype.exportChallenge = function(object, encoding) {
|
|
return this._handle.exportChallenge(toBuf(object, encoding));
|
|
};
|
|
|
|
|
|
exports.setEngine = function setEngine(id, flags) {
|
|
if (typeof id !== 'string')
|
|
throw new TypeError('id should be a string');
|
|
|
|
if (flags && typeof flags !== 'number')
|
|
throw new TypeError('flags should be a number, if present');
|
|
flags = flags >>> 0;
|
|
|
|
// Use provided engine for everything by default
|
|
if (flags === 0)
|
|
flags = constants.ENGINE_METHOD_ALL;
|
|
|
|
return binding.setEngine(id, flags);
|
|
};
|
|
|
|
exports.randomBytes = exports.pseudoRandomBytes = randomBytes;
|
|
|
|
exports.rng = exports.prng = randomBytes;
|
|
|
|
exports.getCiphers = function() {
|
|
return filterDuplicates(getCiphers.call(null, arguments));
|
|
};
|
|
|
|
|
|
exports.getHashes = function() {
|
|
return filterDuplicates(getHashes.call(null, arguments));
|
|
|
|
};
|
|
|
|
|
|
function filterDuplicates(names) {
|
|
// Drop all-caps names in favor of their lowercase aliases,
|
|
// for example, 'sha1' instead of 'SHA1'.
|
|
var ctx = {};
|
|
names.forEach(function(name) {
|
|
var key = name;
|
|
if (/^[0-9A-Z\-]+$/.test(key)) key = key.toLowerCase();
|
|
if (!ctx.hasOwnProperty(key) || ctx[key] < name)
|
|
ctx[key] = name;
|
|
});
|
|
|
|
return Object.getOwnPropertyNames(ctx).map(function(key) {
|
|
return ctx[key];
|
|
}).sort();
|
|
}
|
|
|
|
// Legacy API
|
|
exports.__defineGetter__('createCredentials', util.deprecate(function() {
|
|
return require('tls').createSecureContext;
|
|
}, 'createCredentials() is deprecated, use tls.createSecureContext instead'));
|
|
|
|
exports.__defineGetter__('Credentials', util.deprecate(function() {
|
|
return require('tls').SecureContext;
|
|
}, 'Credentials is deprecated, use tls.createSecureContext instead'));
|