@@ -26,6 +26,12 @@ const { isArrayBufferView } = require('internal/util/types');
26
26
27
27
const kKeyType = Symbol ( 'kKeyType' ) ;
28
28
29
+ // Key input contexts.
30
+ const kConsumePublic = 0 ;
31
+ const kConsumePrivate = 1 ;
32
+ const kCreatePublic = 2 ;
33
+ const kCreatePrivate = 3 ;
34
+
29
35
const encodingNames = [ ] ;
30
36
for ( const m of [ [ kKeyEncodingPKCS1 , 'pkcs1' ] , [ kKeyEncodingPKCS8 , 'pkcs8' ] ,
31
37
[ kKeyEncodingSPKI , 'spki' ] , [ kKeyEncodingSEC1 , 'sec1' ] ] )
@@ -203,7 +209,7 @@ function parseKeyEncoding(enc, keyType, isPublic, objName) {
203
209
// when this is used to parse an input encoding and must be a valid key type if
204
210
// used to parse an output encoding.
205
211
function parsePublicKeyEncoding ( enc , keyType , objName ) {
206
- return parseKeyFormatAndType ( enc , keyType , true , objName ) ;
212
+ return parseKeyEncoding ( enc , keyType , keyType ? true : undefined , objName ) ;
207
213
}
208
214
209
215
// Parses the private key encoding based on an object. keyType must be undefined
@@ -213,26 +219,31 @@ function parsePrivateKeyEncoding(enc, keyType, objName) {
213
219
return parseKeyEncoding ( enc , keyType , false , objName ) ;
214
220
}
215
221
216
- function getKeyObjectHandle ( key , isPublic , allowKeyObject ) {
217
- if ( ! allowKeyObject ) {
222
+ function getKeyObjectHandle ( key , ctx ) {
223
+ if ( ctx === kCreatePrivate ) {
218
224
throw new ERR_INVALID_ARG_TYPE (
219
225
'key' ,
220
226
[ 'string' , 'Buffer' , 'TypedArray' , 'DataView' ] ,
221
227
key
222
228
) ;
223
229
}
224
- if ( isPublic != null ) {
225
- const expectedType = isPublic ? 'public' : 'private' ;
226
- if ( key . type !== expectedType )
227
- throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE ( key . type , expectedType ) ;
230
+
231
+ if ( key . type !== 'private' ) {
232
+ if ( ctx === kConsumePrivate || ctx === kCreatePublic )
233
+ throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE ( key . type , 'private' ) ;
234
+ if ( key . type !== 'public' ) {
235
+ throw new ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE ( key . type ,
236
+ 'private or public' ) ;
237
+ }
228
238
}
239
+
229
240
return key [ kHandle ] ;
230
241
}
231
242
232
- function prepareAsymmetricKey ( key , isPublic , allowKeyObject = true ) {
243
+ function prepareAsymmetricKey ( key , ctx ) {
233
244
if ( isKeyObject ( key ) ) {
234
245
// Best case: A key object, as simple as that.
235
- return { data : getKeyObjectHandle ( key , isPublic , allowKeyObject ) } ;
246
+ return { data : getKeyObjectHandle ( key , ctx ) } ;
236
247
} else if ( typeof key === 'string' || isArrayBufferView ( key ) ) {
237
248
// Expect PEM by default, mostly for backward compatibility.
238
249
return { format : kKeyFormatPEM , data : key } ;
@@ -241,32 +252,32 @@ function prepareAsymmetricKey(key, isPublic, allowKeyObject = true) {
241
252
// The 'key' property can be a KeyObject as well to allow specifying
242
253
// additional options such as padding along with the key.
243
254
if ( isKeyObject ( data ) )
244
- return { data : getKeyObjectHandle ( data , isPublic , allowKeyObject ) } ;
255
+ return { data : getKeyObjectHandle ( data , ctx ) } ;
245
256
// Either PEM or DER using PKCS#1 or SPKI.
246
257
if ( ! isStringOrBuffer ( data ) ) {
247
258
throw new ERR_INVALID_ARG_TYPE (
248
259
'key' ,
249
260
[ 'string' , 'Buffer' , 'TypedArray' , 'DataView' ,
250
- ...( allowKeyObject ? [ 'KeyObject' ] : [ ] ) ] ,
261
+ ...( ctx !== kCreatePrivate ? [ 'KeyObject' ] : [ ] ) ] ,
251
262
key ) ;
252
263
}
253
- return { data, ...parseKeyEncoding ( key , undefined , isPublic ) } ;
264
+ return { data, ...parseKeyEncoding ( key , undefined ) } ;
254
265
} else {
255
266
throw new ERR_INVALID_ARG_TYPE (
256
267
'key' ,
257
268
[ 'string' , 'Buffer' , 'TypedArray' , 'DataView' ,
258
- ...( allowKeyObject ? [ 'KeyObject' ] : [ ] ) ] ,
269
+ ...( ctx !== kCreatePrivate ? [ 'KeyObject' ] : [ ] ) ] ,
259
270
key
260
271
) ;
261
272
}
262
273
}
263
274
264
- function preparePrivateKey ( key , allowKeyObject ) {
265
- return prepareAsymmetricKey ( key , false , allowKeyObject ) ;
275
+ function preparePrivateKey ( key ) {
276
+ return prepareAsymmetricKey ( key , kConsumePrivate ) ;
266
277
}
267
278
268
- function preparePublicOrPrivateKey ( key , allowKeyObject ) {
269
- return prepareAsymmetricKey ( key , undefined , allowKeyObject ) ;
279
+ function preparePublicOrPrivateKey ( key ) {
280
+ return prepareAsymmetricKey ( key , kConsumePublic ) ;
270
281
}
271
282
272
283
function prepareSecretKey ( key , bufferOnly = false ) {
@@ -296,14 +307,15 @@ function createSecretKey(key) {
296
307
}
297
308
298
309
function createPublicKey ( key ) {
299
- const { format, type, data } = preparePublicOrPrivateKey ( key , false ) ;
310
+ const { format, type, data } = prepareAsymmetricKey ( key , kCreatePublic ) ;
300
311
const handle = new KeyObjectHandle ( kKeyTypePublic ) ;
301
312
handle . init ( data , format , type ) ;
302
313
return new PublicKeyObject ( handle ) ;
303
314
}
304
315
305
316
function createPrivateKey ( key ) {
306
- const { format, type, data, passphrase } = preparePrivateKey ( key , false ) ;
317
+ const { format, type, data, passphrase } =
318
+ prepareAsymmetricKey ( key , kCreatePrivate ) ;
307
319
const handle = new KeyObjectHandle ( kKeyTypePrivate ) ;
308
320
handle . init ( data , format , type , passphrase ) ;
309
321
return new PrivateKeyObject ( handle ) ;
0 commit comments