@@ -22,6 +22,11 @@ const {
22
22
kKeyEncodingSEC1,
23
23
} = internalBinding ( 'crypto' ) ;
24
24
25
+ const {
26
+ validateObject,
27
+ validateOneOf,
28
+ } = require ( 'internal/validators' ) ;
29
+
25
30
const {
26
31
codes : {
27
32
ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS ,
@@ -30,6 +35,8 @@ const {
30
35
ERR_INVALID_ARG_VALUE ,
31
36
ERR_OUT_OF_RANGE ,
32
37
ERR_OPERATION_FAILED ,
38
+ ERR_CRYPTO_JWK_UNSUPPORTED_CURVE ,
39
+ ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE ,
33
40
}
34
41
} = require ( 'internal/errors' ) ;
35
42
@@ -124,13 +131,22 @@ const [
124
131
return this [ kHandle ] . getSymmetricKeySize ( ) ;
125
132
}
126
133
127
- export ( ) {
134
+ export ( options ) {
135
+ if ( options !== undefined ) {
136
+ validateObject ( options , 'options' ) ;
137
+ validateOneOf (
138
+ options . format , 'options.format' , [ undefined , 'buffer' , 'jwk' ] ) ;
139
+ if ( options . format === 'jwk' ) {
140
+ return this [ kHandle ] . exportJwk ( { } ) ;
141
+ }
142
+ }
128
143
return this [ kHandle ] . export ( ) ;
129
144
}
130
145
}
131
146
132
147
const kAsymmetricKeyType = Symbol ( 'kAsymmetricKeyType' ) ;
133
148
const kAsymmetricKeyDetails = Symbol ( 'kAsymmetricKeyDetails' ) ;
149
+ const kAsymmetricKeyJWKProperties = Symbol ( 'kAsymmetricKeyJWKProperties' ) ;
134
150
135
151
function normalizeKeyDetails ( details = { } ) {
136
152
if ( details . publicExponent !== undefined ) {
@@ -163,18 +179,44 @@ const [
163
179
return { } ;
164
180
}
165
181
}
182
+
183
+ [ kAsymmetricKeyJWKProperties ] ( ) {
184
+ switch ( this . asymmetricKeyType ) {
185
+ case 'rsa' : return { } ;
186
+ case 'ec' :
187
+ switch ( this . asymmetricKeyDetails . namedCurve ) {
188
+ case 'prime256v1' : return { crv : 'P-256' } ;
189
+ case 'secp256k1' : return { crv : 'secp256k1' } ;
190
+ case 'secp384r1' : return { crv : 'P-384' } ;
191
+ case 'secp521r1' : return { crv : 'P-521' } ;
192
+ default :
193
+ throw new ERR_CRYPTO_JWK_UNSUPPORTED_CURVE (
194
+ this . asymmetricKeyDetails . namedCurve ) ;
195
+ }
196
+ case 'ed25519' : return { crv : 'Ed25519' } ;
197
+ case 'ed448' : return { crv : 'Ed448' } ;
198
+ case 'x25519' : return { crv : 'X25519' } ;
199
+ case 'x448' : return { crv : 'X448' } ;
200
+ default :
201
+ throw new ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE ( ) ;
202
+ }
203
+ }
166
204
}
167
205
168
206
class PublicKeyObject extends AsymmetricKeyObject {
169
207
constructor ( handle ) {
170
208
super ( 'public' , handle ) ;
171
209
}
172
210
173
- export ( encoding ) {
211
+ export ( options ) {
212
+ if ( options && options . format === 'jwk' ) {
213
+ const properties = this [ kAsymmetricKeyJWKProperties ] ( ) ;
214
+ return this [ kHandle ] . exportJwk ( properties ) ;
215
+ }
174
216
const {
175
217
format,
176
218
type
177
- } = parsePublicKeyEncoding ( encoding , this . asymmetricKeyType ) ;
219
+ } = parsePublicKeyEncoding ( options , this . asymmetricKeyType ) ;
178
220
return this [ kHandle ] . export ( format , type ) ;
179
221
}
180
222
}
@@ -184,13 +226,21 @@ const [
184
226
super ( 'private' , handle ) ;
185
227
}
186
228
187
- export ( encoding ) {
229
+ export ( options ) {
230
+ if ( options && options . format === 'jwk' ) {
231
+ if ( options . passphrase !== undefined ) {
232
+ throw new ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS (
233
+ 'jwk' , 'does not support encryption' ) ;
234
+ }
235
+ const properties = this [ kAsymmetricKeyJWKProperties ] ( ) ;
236
+ return this [ kHandle ] . exportJwk ( properties ) ;
237
+ }
188
238
const {
189
239
format,
190
240
type,
191
241
cipher,
192
242
passphrase
193
- } = parsePrivateKeyEncoding ( encoding , this . asymmetricKeyType ) ;
243
+ } = parsePrivateKeyEncoding ( options , this . asymmetricKeyType ) ;
194
244
return this [ kHandle ] . export ( format , type , cipher , passphrase ) ;
195
245
}
196
246
}
0 commit comments