11'use strict';
22
33const {
4+ FunctionPrototypeCall,
45 ObjectSetPrototypeOf,
56 ReflectApply,
67} = primordials;
@@ -14,17 +15,22 @@ const {
1415} = require('internal/errors');
1516
1617const {
18+ validateCallback,
1719 validateEncoding,
1820 validateString,
1921} = require('internal/validators');
2022
2123const {
2224 Sign: _Sign,
25+ SignJob,
2326 Verify: _Verify,
2427 signOneShot: _signOneShot,
2528 verifyOneShot: _verifyOneShot,
29+ kCryptoJobAsync,
2630 kSigEncDER,
2731 kSigEncP1363,
32+ kSignJobModeSign,
33+ kSignJobModeVerify,
2834} = internalBinding('crypto');
2935
3036const {
@@ -34,12 +40,18 @@ const {
3440} = require('internal/crypto/util');
3541
3642const {
37- preparePublicOrPrivateKey,
43+ createPrivateKey,
44+ createPublicKey,
45+ isCryptoKey,
46+ isKeyObject,
3847 preparePrivateKey,
48+ preparePublicOrPrivateKey,
3949} = require('internal/crypto/keys');
4050
4151const { Writable } = require('stream');
4252
53+ const { Buffer } = require('buffer');
54+
4355const {
4456 isArrayBufferView,
4557} = require('internal/util/types');
@@ -131,31 +143,62 @@ Sign.prototype.sign = function sign(options, encoding) {
131143 return ret;
132144};
133145
134- function signOneShot(algorithm, data, key) {
146+ function signOneShot(algorithm, data, key, callback ) {
135147 if (algorithm != null)
136148 validateString(algorithm, 'algorithm');
137149
150+ if (callback !== undefined)
151+ validateCallback(callback);
152+
138153 data = getArrayBufferOrView(data, 'data');
139154
140155 if (!key)
141156 throw new ERR_CRYPTO_SIGN_KEY_REQUIRED();
142157
143- const {
144- data: keyData,
145- format: keyFormat,
146- type: keyType,
147- passphrase: keyPassphrase
148- } = preparePrivateKey(key);
149-
150158 // Options specific to RSA
151159 const rsaPadding = getPadding(key);
152160 const pssSaltLength = getSaltLength(key);
153161
154162 // Options specific to (EC)DSA
155163 const dsaSigEnc = getDSASignatureEncoding(key);
156164
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();
159202}
160203
161204function Verify(algorithm, options) {
@@ -197,10 +240,13 @@ Verify.prototype.verify = function verify(options, signature, sigEncoding) {
197240 rsaPadding, pssSaltLength, dsaSigEnc);
198241};
199242
200- function verifyOneShot(algorithm, data, key, signature) {
243+ function verifyOneShot(algorithm, data, key, signature, callback ) {
201244 if (algorithm != null)
202245 validateString(algorithm, 'algorithm');
203246
247+ if (callback !== undefined)
248+ validateCallback(callback);
249+
204250 data = getArrayBufferOrView(data, 'data');
205251
206252 if (!isArrayBufferView(data)) {
@@ -211,13 +257,6 @@ function verifyOneShot(algorithm, data, key, signature) {
211257 );
212258 }
213259
214- const {
215- data: keyData,
216- format: keyFormat,
217- type: keyType,
218- passphrase: keyPassphrase
219- } = preparePublicOrPrivateKey(key);
220-
221260 // Options specific to RSA
222261 const rsaPadding = getPadding(key);
223262 const pssSaltLength = getSaltLength(key);
@@ -233,8 +272,44 @@ function verifyOneShot(algorithm, data, key, signature) {
233272 );
234273 }
235274
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();
238313}
239314
240315module.exports = {
0 commit comments