diff options
author | Tobias Nießen <tniessen@tnie.de> | 2017-03-06 00:41:26 +0100 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2017-04-01 13:27:52 +0200 |
commit | 0e710aada401b1cf89b284d8469d112ddf277fe0 (patch) | |
tree | 446fc73f722084de1ea667273f5a2c1d8612be1f /lib/crypto.js | |
parent | c68da89694b1ff4682131ed6b825e596188cc4ed (diff) | |
download | android-node-v8-0e710aada401b1cf89b284d8469d112ddf277fe0.tar.gz android-node-v8-0e710aada401b1cf89b284d8469d112ddf277fe0.tar.bz2 android-node-v8-0e710aada401b1cf89b284d8469d112ddf277fe0.zip |
crypto: add sign/verify support for RSASSA-PSS
Adds support for the PSS padding scheme. Until now, the sign/verify
functions used the old EVP_Sign*/EVP_Verify* OpenSSL API, making it
impossible to change the padding scheme. Fixed by first computing the
message digest and then signing/verifying with a custom EVP_PKEY_CTX,
allowing us to specify options such as the padding scheme and the PSS
salt length.
Fixes: https://github.com/nodejs/node/issues/1127
PR-URL: https://github.com/nodejs/node/pull/11705
Reviewed-By: Shigeki Ohtsu <ohtsu@ohtsu.org>
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'lib/crypto.js')
-rw-r--r-- | lib/crypto.js | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/lib/crypto.js b/lib/crypto.js index 662ddef60e..3e7ed5e9c8 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -304,7 +304,28 @@ Sign.prototype.sign = function sign(options, encoding) { var key = options.key || options; var passphrase = options.passphrase || null; - var ret = this._handle.sign(toBuf(key), null, passphrase); + + // Options specific to RSA + var rsaPadding = constants.RSA_PKCS1_PADDING; + if (options.hasOwnProperty('padding')) { + if (options.padding === options.padding >> 0) { + rsaPadding = options.padding; + } else { + throw new TypeError('padding must be an integer'); + } + } + + var pssSaltLength = constants.RSA_PSS_SALTLEN_AUTO; + if (options.hasOwnProperty('saltLength')) { + if (options.saltLength === options.saltLength >> 0) { + pssSaltLength = options.saltLength; + } else { + throw new TypeError('saltLength must be an integer'); + } + } + + var ret = this._handle.sign(toBuf(key), null, passphrase, rsaPadding, + pssSaltLength); encoding = encoding || exports.DEFAULT_ENCODING; if (encoding && encoding !== 'buffer') @@ -330,9 +351,31 @@ util.inherits(Verify, stream.Writable); Verify.prototype._write = Sign.prototype._write; Verify.prototype.update = Sign.prototype.update; -Verify.prototype.verify = function verify(object, signature, sigEncoding) { +Verify.prototype.verify = function verify(options, signature, sigEncoding) { + var key = options.key || options; sigEncoding = sigEncoding || exports.DEFAULT_ENCODING; - return this._handle.verify(toBuf(object), toBuf(signature, sigEncoding)); + + // Options specific to RSA + var rsaPadding = constants.RSA_PKCS1_PADDING; + if (options.hasOwnProperty('padding')) { + if (options.padding === options.padding >> 0) { + rsaPadding = options.padding; + } else { + throw new TypeError('padding must be an integer'); + } + } + + var pssSaltLength = constants.RSA_PSS_SALTLEN_AUTO; + if (options.hasOwnProperty('saltLength')) { + if (options.saltLength === options.saltLength >> 0) { + pssSaltLength = options.saltLength; + } else { + throw new TypeError('saltLength must be an integer'); + } + } + + return this._handle.verify(toBuf(key), toBuf(signature, sigEncoding), null, + rsaPadding, pssSaltLength); }; function rsaPublic(method, defaultPadding) { |