@@ -22,6 +22,11 @@ const {
2222 kKeyEncodingSEC1,
2323} = internalBinding ( 'crypto' ) ;
2424
25+ const {
26+ validateObject,
27+ validateOneOf,
28+ } = require ( 'internal/validators' ) ;
29+
2530const {
2631 codes : {
2732 ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS ,
@@ -30,6 +35,8 @@ const {
3035 ERR_INVALID_ARG_VALUE ,
3136 ERR_OUT_OF_RANGE ,
3237 ERR_OPERATION_FAILED ,
38+ ERR_CRYPTO_JWK_UNSUPPORTED_CURVE ,
39+ ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE ,
3340 }
3441} = require ( 'internal/errors' ) ;
3542
@@ -124,13 +131,22 @@ const [
124131 return this [ kHandle ] . getSymmetricKeySize ( ) ;
125132 }
126133
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+ }
128143 return this [ kHandle ] . export ( ) ;
129144 }
130145 }
131146
132147 const kAsymmetricKeyType = Symbol ( 'kAsymmetricKeyType' ) ;
133148 const kAsymmetricKeyDetails = Symbol ( 'kAsymmetricKeyDetails' ) ;
149+ const kAsymmetricKeyJWKProperties = Symbol ( 'kAsymmetricKeyJWKProperties' ) ;
134150
135151 function normalizeKeyDetails ( details = { } ) {
136152 if ( details . publicExponent !== undefined ) {
@@ -163,18 +179,44 @@ const [
163179 return { } ;
164180 }
165181 }
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+ }
166204 }
167205
168206 class PublicKeyObject extends AsymmetricKeyObject {
169207 constructor ( handle ) {
170208 super ( 'public' , handle ) ;
171209 }
172210
173- export ( encoding ) {
211+ export ( options ) {
212+ if ( options && options . format === 'jwk' ) {
213+ const properties = this [ kAsymmetricKeyJWKProperties ] ( ) ;
214+ return this [ kHandle ] . exportJwk ( properties ) ;
215+ }
174216 const {
175217 format,
176218 type
177- } = parsePublicKeyEncoding ( encoding , this . asymmetricKeyType ) ;
219+ } = parsePublicKeyEncoding ( options , this . asymmetricKeyType ) ;
178220 return this [ kHandle ] . export ( format , type ) ;
179221 }
180222 }
@@ -184,13 +226,21 @@ const [
184226 super ( 'private' , handle ) ;
185227 }
186228
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+ }
188238 const {
189239 format,
190240 type,
191241 cipher,
192242 passphrase
193- } = parsePrivateKeyEncoding ( encoding , this . asymmetricKeyType ) ;
243+ } = parsePrivateKeyEncoding ( options , this . asymmetricKeyType ) ;
194244 return this [ kHandle ] . export ( format , type , cipher , passphrase ) ;
195245 }
196246 }
0 commit comments