| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3822,10 +3822,13 @@ added: v10.0.0 | |||
| 3822 | 3822 | Enables the FIPS compliant crypto provider in a FIPS-enabled Node.js build. | |
| 3823 | 3823 | Throws an error if FIPS mode is not available. | |
| 3824 | 3824 | ||
| 3825 | - ### `crypto.sign(algorithm, data, key)` | ||
| 3825 | + ### `crypto.sign(algorithm, data, key[, callback])` | ||
| 3826 | 3826 | <!-- YAML | |
| 3827 | 3827 | added: v12.0.0 | |
| 3828 | 3828 | changes: | |
| 3829 | + - version: REPLACEME | ||
| 3830 | + pr-url: https://github.com/nodejs/node/pull/37500 | ||
| 3831 | + description: Optional callback argument added. | ||
| 3829 | 3832 | - version: | |
| 3830 | 3833 | - v13.2.0 | |
| 3831 | 3834 | - v12.16.0 | |
@@ -3837,7 +3840,10 @@ changes: | |||
| 3837 | 3840 | * `algorithm` {string | null | undefined} | |
| 3838 | 3841 | * `data` {ArrayBuffer|Buffer|TypedArray|DataView} | |
| 3839 | 3842 | * `key` {Object|string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject|CryptoKey} | |
| 3840 | - * Returns: {Buffer} | ||
| 3843 | + * `callback` {Function} | ||
| 3844 | + * `err` {Error} | ||
| 3845 | + * `signature` {Buffer} | ||
| 3846 | + * Returns: {Buffer} if the `callback` function is not provided. | ||
| 3841 | 3847 | <!--lint enable maximum-line-length remark-lint--> | |
| 3842 | 3848 | ||
| 3843 | 3849 | Calculates and returns the signature for `data` using the given private key and | |
@@ -3864,6 +3870,8 @@ additional properties can be passed: | |||
| 3864 | 3870 | size, `crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN` (default) sets it to the | |
| 3865 | 3871 | maximum permissible value. | |
| 3866 | 3872 | ||
| 3873 | + If the `callback` function is provided this function uses libuv's threadpool. | ||
| 3874 | + | ||
| 3867 | 3875 | ### `crypto.timingSafeEqual(a, b)` | |
| 3868 | 3876 | <!-- YAML | |
| 3869 | 3877 | added: v6.6.0 | |
@@ -3894,10 +3902,13 @@ Use of `crypto.timingSafeEqual` does not guarantee that the *surrounding* code | |||
| 3894 | 3902 | is timing-safe. Care should be taken to ensure that the surrounding code does | |
| 3895 | 3903 | not introduce timing vulnerabilities. | |
| 3896 | 3904 | ||
| 3897 | - ### `crypto.verify(algorithm, data, key, signature)` | ||
| 3905 | + ### `crypto.verify(algorithm, data, key, signature[, callback])` | ||
| 3898 | 3906 | <!-- YAML | |
| 3899 | 3907 | added: v12.0.0 | |
| 3900 | 3908 | changes: | |
| 3909 | + - version: REPLACEME | ||
| 3910 | + pr-url: https://github.com/nodejs/node/pull/37500 | ||
| 3911 | + description: Optional callback argument added. | ||
| 3901 | 3912 | - version: v15.0.0 | |
| 3902 | 3913 | pr-url: https://github.com/nodejs/node/pull/35093 | |
| 3903 | 3914 | description: The data, key, and signature arguments can also be ArrayBuffer. | |
@@ -3913,7 +3924,12 @@ changes: | |||
| 3913 | 3924 | * `data` {ArrayBuffer| Buffer|TypedArray|DataView} | |
| 3914 | 3925 | * `key` {Object|string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject|CryptoKey} | |
| 3915 | 3926 | * `signature` {ArrayBuffer|Buffer|TypedArray|DataView} | |
| 3916 | - * Returns: {boolean} | ||
| 3927 | + * `callback` {Function} | ||
| 3928 | + * `err` {Error} | ||
| 3929 | + * `result` {boolean} | ||
| 3930 | + * Returns: {boolean} `true` or `false` depending on the validity of the | ||
| 3931 | + signature for the data and public key if the `callback` function is not | ||
| 3932 | + provided. | ||
| 3917 | 3933 | <!--lint enable maximum-line-length remark-lint--> | |
| 3918 | 3934 | ||
| 3919 | 3935 | Verifies the given signature for `data` using the given key and algorithm. If | |
@@ -3945,6 +3961,8 @@ The `signature` argument is the previously calculated signature for the `data`. | |||
| 3945 | 3961 | Because public keys can be derived from private keys, a private key or a public | |
| 3946 | 3962 | key may be passed for `key`. | |
| 3947 | 3963 | ||
| 3964 | + If the `callback` function is provided this function uses libuv's threadpool. | ||
| 3965 | + | ||
| 3948 | 3966 | ### `crypto.webcrypto` | |
| 3949 | 3967 | <!-- YAML | |
| 3950 | 3968 | added: v15.0.0 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,6 +10,7 @@ const { | |||
| 10 | 10 | KeyObjectHandle, | |
| 11 | 11 | SignJob, | |
| 12 | 12 | kCryptoJobAsync, | |
| 13 | + kSigEncDER, | ||
| 13 | 14 | kKeyTypePrivate, | |
| 14 | 15 | kSignJobModeSign, | |
| 15 | 16 | kSignJobModeVerify, | |
@@ -254,7 +255,8 @@ function dsaSignVerify(key, data, algorithm, signature) { | |||
| 254 | 255 | normalizeHashName(key.algorithm.hash.name), | |
| 255 | 256 | undefined, // Salt-length is not used in DSA | |
| 256 | 257 | undefined, // Padding is not used in DSA | |
| 257 | - signature)); | ||
| 258 | + signature, | ||
| 259 | + kSigEncDER)); | ||
| 258 | 260 | } | |
| 259 | 261 | ||
| 260 | 262 | module.exports = { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,6 +17,7 @@ const { | |||
| 17 | 17 | kKeyTypePublic, | |
| 18 | 18 | kSignJobModeSign, | |
| 19 | 19 | kSignJobModeVerify, | |
| 20 | + kSigEncP1363, | ||
| 20 | 21 | } = internalBinding('crypto'); | |
| 21 | 22 | ||
| 22 | 23 | const { | |
@@ -470,7 +471,8 @@ function ecdsaSignVerify(key, data, { name, hash }, signature) { | |||
| 470 | 471 | hashname, | |
| 471 | 472 | undefined, // Salt length, not used with ECDSA | |
| 472 | 473 | undefined, // PSS Padding, not used with ECDSA | |
| 473 | - signature)); | ||
| 474 | + signature, | ||
| 475 | + kSigEncP1363)); | ||
| 474 | 476 | } | |
| 475 | 477 | ||
| 476 | 478 | module.exports = { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -30,6 +30,7 @@ const { | |||
| 30 | 30 | } = require('internal/errors'); | |
| 31 | 31 | ||
| 32 | 32 | const { | |
| 33 | + validateInt32, | ||
| 33 | 34 | validateUint32, | |
| 34 | 35 | } = require('internal/validators'); | |
| 35 | 36 | ||
@@ -342,7 +343,7 @@ function rsaSignVerify(key, data, { saltLength }, signature) { | |||
| 342 | 343 | // TODO(@jasnell): Validate maximum size of saltLength | |
| 343 | 344 | // based on the key size: | |
| 344 | 345 | // Math.ceil((keySizeInBits - 1)/8) - digestSizeInBytes - 2 | |
| 345 | - validateUint32(saltLength, 'algorithm.saltLength'); | ||
| 346 | + validateInt32(saltLength, 'algorithm.saltLength', -2); | ||
| 346 | 347 | } | |
| 347 | 348 | ||
| 348 | 349 | const mode = signature === undefined ? kSignJobModeSign : kSignJobModeVerify; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,6 +1,7 @@ | |||
| 1 | 1 | 'use strict'; | |
| 2 | 2 | ||
| 3 | 3 | const { | |
| 4 | + FunctionPrototypeCall, | ||
| 4 | 5 | ObjectSetPrototypeOf, | |
| 5 | 6 | ReflectApply, | |
| 6 | 7 | } = primordials; | |
@@ -14,17 +15,22 @@ const { | |||
| 14 | 15 | } = require('internal/errors'); | |
| 15 | 16 | ||
| 16 | 17 | const { | |
| 18 | + validateCallback, | ||
| 17 | 19 | validateEncoding, | |
| 18 | 20 | validateString, | |
| 19 | 21 | } = require('internal/validators'); | |
| 20 | 22 | ||
| 21 | 23 | const { | |
| 22 | 24 | Sign: _Sign, | |
| 25 | + SignJob, | ||
| 23 | 26 | Verify: _Verify, | |
| 24 | 27 | signOneShot: _signOneShot, | |
| 25 | 28 | verifyOneShot: _verifyOneShot, | |
| 29 | + kCryptoJobAsync, | ||
| 26 | 30 | kSigEncDER, | |
| 27 | 31 | kSigEncP1363, | |
| 32 | + kSignJobModeSign, | ||
| 33 | + kSignJobModeVerify, | ||
| 28 | 34 | } = internalBinding('crypto'); | |
| 29 | 35 | ||
| 30 | 36 | const { | |
@@ -34,12 +40,18 @@ const { | |||
| 34 | 40 | } = require('internal/crypto/util'); | |
| 35 | 41 | ||
| 36 | 42 | const { | |
| 37 | - preparePublicOrPrivateKey, | ||
| 43 | + createPrivateKey, | ||
| 44 | + createPublicKey, | ||
| 45 | + isCryptoKey, | ||
| 46 | + isKeyObject, | ||
| 38 | 47 | preparePrivateKey, | |
| 48 | + preparePublicOrPrivateKey, | ||
| 39 | 49 | } = require('internal/crypto/keys'); | |
| 40 | 50 | ||
| 41 | 51 | const { Writable } = require('stream'); | |
| 42 | 52 | ||
| 53 | + const { Buffer } = require('buffer'); | ||
| 54 | + | ||
| 43 | 55 | const { | |
| 44 | 56 | isArrayBufferView, | |
| 45 | 57 | } = require('internal/util/types'); | |
@@ -131,31 +143,62 @@ Sign.prototype.sign = function sign(options, encoding) { | |||
| 131 | 143 | return ret; | |
| 132 | 144 | }; | |
| 133 | 145 | ||
| 134 | - function signOneShot(algorithm, data, key) { | ||
| 146 | + function signOneShot(algorithm, data, key, callback) { | ||
| 135 | 147 | if (algorithm != null) | |
| 136 | 148 | validateString(algorithm, 'algorithm'); | |
| 137 | 149 | ||
| 150 | + if (callback !== undefined) | ||
| 151 | + validateCallback(callback); | ||
| 152 | + | ||
| 138 | 153 | data = getArrayBufferOrView(data, 'data'); | |
| 139 | 154 | ||
| 140 | 155 | if (!key) | |
| 141 | 156 | throw new ERR_CRYPTO_SIGN_KEY_REQUIRED(); | |
| 142 | 157 | ||
| 143 | - const { | ||
| 144 | - data: keyData, | ||
| 145 | - format: keyFormat, | ||
| 146 | - type: keyType, | ||
| 147 | - passphrase: keyPassphrase | ||
| 148 | - } = preparePrivateKey(key); | ||
| 149 | - | ||
| 150 | 158 | // Options specific to RSA | |
| 151 | 159 | const rsaPadding = getPadding(key); | |
| 152 | 160 | const pssSaltLength = getSaltLength(key); | |
| 153 | 161 | ||
| 154 | 162 | // Options specific to (EC)DSA | |
| 155 | 163 | const dsaSigEnc = getDSASignatureEncoding(key); | |
| 156 | 164 | ||
| 157 | - return _signOneShot(keyData, keyFormat, keyType, keyPassphrase, data, | ||
| 158 | - algorithm, rsaPadding, pssSaltLength, dsaSigEnc); | ||
| 165 | + if (!callback) { | ||
| 166 | + const { | ||
| 167 | + data: keyData, | ||
| 168 | + format: keyFormat, | ||
| 169 | + type: keyType, | ||
| 170 | + passphrase: keyPassphrase | ||
| 171 | + } = preparePrivateKey(key); | ||
| 172 | + | ||
| 173 | + return _signOneShot(keyData, keyFormat, keyType, keyPassphrase, data, | ||
| 174 | + algorithm, rsaPadding, pssSaltLength, dsaSigEnc); | ||
| 175 | + } | ||
| 176 | + | ||
| 177 | + let keyData; | ||
| 178 | + if (isKeyObject(key) || isCryptoKey(key)) { | ||
| 179 | + ({ data: keyData } = preparePrivateKey(key)); | ||
| 180 | + } else if (key != null && (isKeyObject(key.key) || isCryptoKey(key.key))) { | ||
| 181 | + ({ data: keyData } = preparePrivateKey(key.key)); | ||
| 182 | + } else { | ||
| 183 | + keyData = createPrivateKey(key)[kHandle]; | ||
| 184 | + } | ||
| 185 | + | ||
| 186 | + const job = new SignJob( | ||
| 187 | + kCryptoJobAsync, | ||
| 188 | + kSignJobModeSign, | ||
| 189 | + keyData, | ||
| 190 | + data, | ||
| 191 | + algorithm, | ||
| 192 | + pssSaltLength, | ||
| 193 | + rsaPadding, | ||
| 194 | + undefined, | ||
| 195 | + dsaSigEnc); | ||
| 196 | + | ||
| 197 | + job.ondone = (error, signature) => { | ||
| 198 | + if (error) return FunctionPrototypeCall(callback, job, error); | ||
| 199 | + FunctionPrototypeCall(callback, job, null, Buffer.from(signature)); | ||
| 200 | + }; | ||
| 201 | + job.run(); | ||
| 159 | 202 | } | |
| 160 | 203 | ||
| 161 | 204 | function Verify(algorithm, options) { | |
@@ -197,10 +240,13 @@ Verify.prototype.verify = function verify(options, signature, sigEncoding) { | |||
| 197 | 240 | rsaPadding, pssSaltLength, dsaSigEnc); | |
| 198 | 241 | }; | |
| 199 | 242 | ||
| 200 | - function verifyOneShot(algorithm, data, key, signature) { | ||
| 243 | + function verifyOneShot(algorithm, data, key, signature, callback) { | ||
| 201 | 244 | if (algorithm != null) | |
| 202 | 245 | validateString(algorithm, 'algorithm'); | |
| 203 | 246 | ||
| 247 | + if (callback !== undefined) | ||
| 248 | + validateCallback(callback); | ||
| 249 | + | ||
| 204 | 250 | data = getArrayBufferOrView(data, 'data'); | |
| 205 | 251 | ||
| 206 | 252 | if (!isArrayBufferView(data)) { | |
@@ -211,13 +257,6 @@ function verifyOneShot(algorithm, data, key, signature) { | |||
| 211 | 257 | ); | |
| 212 | 258 | } | |
| 213 | 259 | ||
| 214 | - const { | ||
| 215 | - data: keyData, | ||
| 216 | - format: keyFormat, | ||
| 217 | - type: keyType, | ||
| 218 | - passphrase: keyPassphrase | ||
| 219 | - } = preparePublicOrPrivateKey(key); | ||
| 220 | - | ||
| 221 | 260 | // Options specific to RSA | |
| 222 | 261 | const rsaPadding = getPadding(key); | |
| 223 | 262 | const pssSaltLength = getSaltLength(key); | |
@@ -233,8 +272,44 @@ function verifyOneShot(algorithm, data, key, signature) { | |||
| 233 | 272 | ); | |
| 234 | 273 | } | |
| 235 | 274 | ||
| 236 | - return _verifyOneShot(keyData, keyFormat, keyType, keyPassphrase, signature, | ||
| 237 | - data, algorithm, rsaPadding, pssSaltLength, dsaSigEnc); | ||
| 275 | + if (!callback) { | ||
| 276 | + const { | ||
| 277 | + data: keyData, | ||
| 278 | + format: keyFormat, | ||
| 279 | + type: keyType, | ||
| 280 | + passphrase: keyPassphrase | ||
| 281 | + } = preparePublicOrPrivateKey(key); | ||
| 282 | + | ||
| 283 | + return _verifyOneShot(keyData, keyFormat, keyType, keyPassphrase, | ||
| 284 | + signature, data, algorithm, rsaPadding, | ||
| 285 | + pssSaltLength, dsaSigEnc); | ||
| 286 | + } | ||
| 287 | + | ||
| 288 | + let keyData; | ||
| 289 | + if (isKeyObject(key) || isCryptoKey(key)) { | ||
| 290 | + ({ data: keyData } = preparePublicOrPrivateKey(key)); | ||
| 291 | + } else if (key != null && (isKeyObject(key.key) || isCryptoKey(key.key))) { | ||
| 292 | + ({ data: keyData } = preparePublicOrPrivateKey(key.key)); | ||
| 293 | + } else { | ||
| 294 | + keyData = createPublicKey(key)[kHandle]; | ||
| 295 | + } | ||
| 296 | + | ||
| 297 | + const job = new SignJob( | ||
| 298 | + kCryptoJobAsync, | ||
| 299 | + kSignJobModeVerify, | ||
| 300 | + keyData, | ||
| 301 | + data, | ||
| 302 | + algorithm, | ||
| 303 | + pssSaltLength, | ||
| 304 | + rsaPadding, | ||
| 305 | + signature, | ||
| 306 | + dsaSigEnc); | ||
| 307 | + | ||
| 308 | + job.ondone = (error, result) => { | ||
| 309 | + if (error) return FunctionPrototypeCall(callback, job, error); | ||
| 310 | + FunctionPrototypeCall(callback, job, null, result); | ||
| 311 | + }; | ||
| 312 | + job.run(); | ||
| 238 | 313 | } | |
| 239 | 314 | ||
| 240 | 315 | module.exports = { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments