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 = {
0 commit comments