@@ -6,24 +6,32 @@ const {
66 generateKeyPairDSA,
77 generateKeyPairEC,
88 OPENSSL_EC_NAMED_CURVE ,
9- OPENSSL_EC_EXPLICIT_CURVE ,
10- PK_ENCODING_PKCS1 ,
11- PK_ENCODING_PKCS8 ,
12- PK_ENCODING_SPKI ,
13- PK_ENCODING_SEC1 ,
14- PK_FORMAT_DER ,
15- PK_FORMAT_PEM
9+ OPENSSL_EC_EXPLICIT_CURVE
1610} = internalBinding ( 'crypto' ) ;
11+ const {
12+ parsePublicKeyEncoding,
13+ parsePrivateKeyEncoding,
14+
15+ PublicKeyObject,
16+ PrivateKeyObject
17+ } = require ( 'internal/crypto/keys' ) ;
1718const { customPromisifyArgs } = require ( 'internal/util' ) ;
1819const { isUint32, validateString } = require ( 'internal/validators' ) ;
1920const {
20- ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS ,
2121 ERR_INVALID_ARG_TYPE ,
2222 ERR_INVALID_ARG_VALUE ,
2323 ERR_INVALID_CALLBACK ,
2424 ERR_INVALID_OPT_VALUE
2525} = require ( 'internal/errors' ) . codes ;
2626
27+ const { isArrayBufferView } = require ( 'internal/util/types' ) ;
28+
29+ function wrapKey ( key , ctor ) {
30+ if ( typeof key === 'string' || isArrayBufferView ( key ) )
31+ return key ;
32+ return new ctor ( key ) ;
33+ }
34+
2735function generateKeyPair ( type , options , callback ) {
2836 if ( typeof options === 'function' ) {
2937 callback = options ;
@@ -38,6 +46,9 @@ function generateKeyPair(type, options, callback) {
3846 const wrap = new AsyncWrap ( Providers . KEYPAIRGENREQUEST ) ;
3947 wrap . ondone = ( ex , pubkey , privkey ) => {
4048 if ( ex ) return callback . call ( wrap , ex ) ;
49+ // If no encoding was chosen, return key objects instead.
50+ pubkey = wrapKey ( pubkey , PublicKeyObject ) ;
51+ privkey = wrapKey ( privkey , PrivateKeyObject ) ;
4152 callback . call ( wrap , null , pubkey , privkey ) ;
4253 } ;
4354
@@ -69,86 +80,32 @@ function handleError(impl, wrap) {
6980function parseKeyEncoding ( keyType , options ) {
7081 const { publicKeyEncoding, privateKeyEncoding } = options ;
7182
72- if ( publicKeyEncoding == null || typeof publicKeyEncoding !== 'object' )
73- throw new ERR_INVALID_OPT_VALUE ( 'publicKeyEncoding' , publicKeyEncoding ) ;
74-
75- const { format : strPublicFormat , type : strPublicType } = publicKeyEncoding ;
76-
77- let publicType ;
78- if ( strPublicType === 'pkcs1' ) {
79- if ( keyType !== 'rsa' ) {
80- throw new ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS (
81- strPublicType , 'can only be used for RSA keys' ) ;
82- }
83- publicType = PK_ENCODING_PKCS1 ;
84- } else if ( strPublicType === 'spki' ) {
85- publicType = PK_ENCODING_SPKI ;
83+ let publicFormat , publicType ;
84+ if ( publicKeyEncoding == null ) {
85+ publicFormat = publicType = undefined ;
86+ } else if ( typeof publicKeyEncoding === 'object' ) {
87+ ( {
88+ format : publicFormat ,
89+ type : publicType
90+ } = parsePublicKeyEncoding ( publicKeyEncoding , keyType ,
91+ 'publicKeyEncoding' ) ) ;
8692 } else {
87- throw new ERR_INVALID_OPT_VALUE ( 'publicKeyEncoding.type ' , strPublicType ) ;
93+ throw new ERR_INVALID_OPT_VALUE ( 'publicKeyEncoding' , publicKeyEncoding ) ;
8894 }
8995
90- let publicFormat ;
91- if ( strPublicFormat === 'der' ) {
92- publicFormat = PK_FORMAT_DER ;
93- } else if ( strPublicFormat === 'pem' ) {
94- publicFormat = PK_FORMAT_PEM ;
96+ let privateFormat , privateType , cipher , passphrase ;
97+ if ( privateKeyEncoding == null ) {
98+ privateFormat = privateType = undefined ;
99+ } else if ( typeof privateKeyEncoding === 'object' ) {
100+ ( {
101+ format : privateFormat ,
102+ type : privateType ,
103+ cipher,
104+ passphrase
105+ } = parsePrivateKeyEncoding ( privateKeyEncoding , keyType ,
106+ 'privateKeyEncoding' ) ) ;
95107 } else {
96- throw new ERR_INVALID_OPT_VALUE ( 'publicKeyEncoding.format' ,
97- strPublicFormat ) ;
98- }
99-
100- if ( privateKeyEncoding == null || typeof privateKeyEncoding !== 'object' )
101108 throw new ERR_INVALID_OPT_VALUE ( 'privateKeyEncoding' , privateKeyEncoding ) ;
102-
103- const {
104- cipher,
105- passphrase,
106- format : strPrivateFormat ,
107- type : strPrivateType
108- } = privateKeyEncoding ;
109-
110- let privateType ;
111- if ( strPrivateType === 'pkcs1' ) {
112- if ( keyType !== 'rsa' ) {
113- throw new ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS (
114- strPrivateType , 'can only be used for RSA keys' ) ;
115- }
116- privateType = PK_ENCODING_PKCS1 ;
117- } else if ( strPrivateType === 'pkcs8' ) {
118- privateType = PK_ENCODING_PKCS8 ;
119- } else if ( strPrivateType === 'sec1' ) {
120- if ( keyType !== 'ec' ) {
121- throw new ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS (
122- strPrivateType , 'can only be used for EC keys' ) ;
123- }
124- privateType = PK_ENCODING_SEC1 ;
125- } else {
126- throw new ERR_INVALID_OPT_VALUE ( 'privateKeyEncoding.type' , strPrivateType ) ;
127- }
128-
129- let privateFormat ;
130- if ( strPrivateFormat === 'der' ) {
131- privateFormat = PK_FORMAT_DER ;
132- } else if ( strPrivateFormat === 'pem' ) {
133- privateFormat = PK_FORMAT_PEM ;
134- } else {
135- throw new ERR_INVALID_OPT_VALUE ( 'privateKeyEncoding.format' ,
136- strPrivateFormat ) ;
137- }
138-
139- if ( cipher != null ) {
140- if ( typeof cipher !== 'string' )
141- throw new ERR_INVALID_OPT_VALUE ( 'privateKeyEncoding.cipher' , cipher ) ;
142- if ( privateFormat === PK_FORMAT_DER &&
143- ( privateType === PK_ENCODING_PKCS1 ||
144- privateType === PK_ENCODING_SEC1 ) ) {
145- throw new ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS (
146- strPrivateType , 'does not support encryption' ) ;
147- }
148- if ( typeof passphrase !== 'string' ) {
149- throw new ERR_INVALID_OPT_VALUE ( 'privateKeyEncoding.passphrase' ,
150- passphrase ) ;
151- }
152109 }
153110
154111 return {
@@ -181,8 +138,8 @@ function check(type, options, callback) {
181138 }
182139
183140 impl = ( wrap ) => generateKeyPairRSA ( modulusLength , publicExponent ,
184- publicType , publicFormat ,
185- privateType , privateFormat ,
141+ publicFormat , publicType ,
142+ privateFormat , privateType ,
186143 cipher , passphrase , wrap ) ;
187144 }
188145 break ;
@@ -200,8 +157,8 @@ function check(type, options, callback) {
200157 }
201158
202159 impl = ( wrap ) => generateKeyPairDSA ( modulusLength , divisorLength ,
203- publicType , publicFormat ,
204- privateType , privateFormat ,
160+ publicFormat , publicType ,
161+ privateFormat , privateType ,
205162 cipher , passphrase , wrap ) ;
206163 }
207164 break ;
@@ -219,8 +176,8 @@ function check(type, options, callback) {
219176 throw new ERR_INVALID_OPT_VALUE ( 'paramEncoding' , paramEncoding ) ;
220177
221178 impl = ( wrap ) => generateKeyPairEC ( namedCurve , paramEncoding ,
222- publicType , publicFormat ,
223- privateType , privateFormat ,
179+ publicFormat , publicType ,
180+ privateFormat , privateType ,
224181 cipher , passphrase , wrap ) ;
225182 }
226183 break ;
0 commit comments