@@ -10,7 +10,8 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
1010
1111use crate :: serialization:: b64_encode;
1212use crate :: {
13- Algorithm , EncodingKey ,
13+ Algorithm , EncodingKey , DecodingKey ,
14+ decoding:: DecodingKeyKind ,
1415 errors:: { self , Error , ErrorKind } ,
1516} ;
1617
@@ -19,12 +20,6 @@ use aws_lc_rs::{digest, signature as aws_sig};
1920#[ cfg( feature = "aws_lc_rs" ) ]
2021use aws_sig:: KeyPair ;
2122#[ cfg( feature = "rust_crypto" ) ]
22- use p256:: { ecdsa:: SigningKey as P256SigningKey , pkcs8:: DecodePrivateKey } ;
23- #[ cfg( feature = "rust_crypto" ) ]
24- use p384:: ecdsa:: SigningKey as P384SigningKey ;
25- #[ cfg( feature = "rust_crypto" ) ]
26- use rsa:: { RsaPrivateKey , pkcs1:: DecodeRsaPrivateKey , traits:: PublicKeyParts } ;
27- #[ cfg( feature = "rust_crypto" ) ]
2823use sha2:: { Digest , Sha256 , Sha384 , Sha512 } ;
2924
3025/// The intended usage of the public `KeyType`. This enum is serialized `untagged`
@@ -234,6 +229,25 @@ impl FromStr for KeyAlgorithm {
234229 }
235230}
236231
232+ impl From < Algorithm > for KeyAlgorithm {
233+ fn from ( algorithm : Algorithm ) -> Self {
234+ match algorithm {
235+ Algorithm :: HS256 => KeyAlgorithm :: HS256 ,
236+ Algorithm :: HS384 => KeyAlgorithm :: HS384 ,
237+ Algorithm :: HS512 => KeyAlgorithm :: HS512 ,
238+ Algorithm :: ES256 => KeyAlgorithm :: ES256 ,
239+ Algorithm :: ES384 => KeyAlgorithm :: ES384 ,
240+ Algorithm :: RS256 => KeyAlgorithm :: RS256 ,
241+ Algorithm :: RS384 => KeyAlgorithm :: RS384 ,
242+ Algorithm :: RS512 => KeyAlgorithm :: RS512 ,
243+ Algorithm :: PS256 => KeyAlgorithm :: PS256 ,
244+ Algorithm :: PS384 => KeyAlgorithm :: PS384 ,
245+ Algorithm :: PS512 => KeyAlgorithm :: PS512 ,
246+ Algorithm :: EdDSA => KeyAlgorithm :: EdDSA ,
247+ }
248+ }
249+ }
250+
237251impl fmt:: Display for KeyAlgorithm {
238252 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
239253 write ! ( f, "{:?}" , self )
@@ -440,80 +454,141 @@ pub struct Jwk {
440454}
441455
442456#[ cfg( feature = "aws_lc_rs" ) ]
443- fn extract_rsa_public_key_components ( key_content : & [ u8 ] ) -> errors:: Result < ( Vec < u8 > , Vec < u8 > ) > {
444- let key_pair = aws_sig:: RsaKeyPair :: from_der ( key_content)
445- . map_err ( |e| ErrorKind :: InvalidRsaKey ( e. to_string ( ) ) ) ?;
446- let public = key_pair. public_key ( ) ;
447- let components = aws_sig:: RsaPublicKeyComponents :: < Vec < u8 > > :: from ( public) ;
448- Ok ( ( components. n , components. e ) )
457+ mod rsa_pubkey_components {
458+ use super :: * ;
459+
460+ pub fn from_private_key ( key_content : & [ u8 ] ) -> errors:: Result < ( Vec < u8 > , Vec < u8 > ) > {
461+ let key_pair = aws_sig:: RsaKeyPair :: from_der ( key_content)
462+ . map_err ( |e| ErrorKind :: InvalidRsaKey ( e. to_string ( ) ) ) ?;
463+ let public = key_pair. public_key ( ) ;
464+ let components = aws_sig:: RsaPublicKeyComponents :: < Vec < u8 > > :: from ( public) ;
465+ Ok ( ( components. n , components. e ) )
466+ }
467+
468+ pub fn from_public_key ( key_content : & [ u8 ] ) -> errors:: Result < ( Vec < u8 > , Vec < u8 > ) > {
469+ let public = aws_lc_rs:: rsa:: PublicKey :: from_der ( key_content)
470+ . map_err ( |e| ErrorKind :: InvalidRsaKey ( e. to_string ( ) ) ) ?;
471+
472+ let components = aws_sig:: RsaPublicKeyComponents :: < Vec < u8 > > :: from ( & public) ;
473+ Ok ( ( components. n , components. e ) )
474+ }
449475}
450476
451477#[ cfg( feature = "rust_crypto" ) ]
452- fn extract_rsa_public_key_components ( key_content : & [ u8 ] ) -> errors:: Result < ( Vec < u8 > , Vec < u8 > ) > {
453- let private_key = RsaPrivateKey :: from_pkcs1_der ( key_content)
454- . map_err ( |e| ErrorKind :: InvalidRsaKey ( e. to_string ( ) ) ) ?;
455- let public_key = private_key. to_public_key ( ) ;
456- Ok ( ( public_key. n ( ) . to_bytes_be ( ) , public_key. e ( ) . to_bytes_be ( ) ) )
478+ mod rsa_pubkey_components {
479+ use super :: * ;
480+ use rsa:: { RsaPrivateKey , RsaPublicKey , pkcs1:: DecodeRsaPrivateKey , traits:: PublicKeyParts } ;
481+
482+ pub fn from_private_key ( key_content : & [ u8 ] ) -> errors:: Result < ( Vec < u8 > , Vec < u8 > ) > {
483+ let private_key = RsaPrivateKey :: from_pkcs1_der ( key_content)
484+ . map_err ( |e| ErrorKind :: InvalidRsaKey ( e. to_string ( ) ) ) ?;
485+ let public_key = private_key. to_public_key ( ) ;
486+ Ok ( ( public_key. n ( ) . to_bytes_be ( ) , public_key. e ( ) . to_bytes_be ( ) ) )
487+ }
488+
489+ pub fn from_public_key ( key_content : & [ u8 ] ) -> errors:: Result < ( Vec < u8 > , Vec < u8 > ) > {
490+ use rsa:: pkcs1:: DecodeRsaPublicKey ;
491+
492+ let public_key = RsaPublicKey :: from_pkcs1_der ( key_content)
493+ . map_err ( |e| ErrorKind :: InvalidRsaKey ( e. to_string ( ) ) ) ?;
494+ Ok ( ( public_key. n ( ) . to_bytes_be ( ) , public_key. e ( ) . to_bytes_be ( ) ) )
495+ }
457496}
458497
459- #[ cfg( feature = "aws_lc_rs" ) ]
460- fn extract_ec_public_key_coordinates (
461- key_content : & [ u8 ] ,
462- alg : Algorithm ,
498+ fn ec_components_from_public_key (
499+ pub_bytes : & [ u8 ] ,
463500) -> errors:: Result < ( EllipticCurve , Vec < u8 > , Vec < u8 > ) > {
464- use aws_lc_rs:: signature:: {
465- ECDSA_P256_SHA256_FIXED_SIGNING , ECDSA_P384_SHA384_FIXED_SIGNING , EcdsaKeyPair ,
466- } ;
467-
468- let ( signing_alg, curve, pub_elem_bytes) = match alg {
469- Algorithm :: ES256 => ( & ECDSA_P256_SHA256_FIXED_SIGNING , EllipticCurve :: P256 , 32 ) ,
470- Algorithm :: ES384 => ( & ECDSA_P384_SHA384_FIXED_SIGNING , EllipticCurve :: P384 , 48 ) ,
501+ let ( curve, pub_elem_bytes) = match pub_bytes. len ( ) {
502+ 65 => ( EllipticCurve :: P256 , 32 ) ,
503+ 97 => ( EllipticCurve :: P384 , 48 ) ,
471504 _ => return Err ( ErrorKind :: InvalidEcdsaKey . into ( ) ) ,
472505 } ;
473506
474- let key_pair = EcdsaKeyPair :: from_pkcs8 ( signing_alg, key_content)
475- . map_err ( |_| ErrorKind :: InvalidEcdsaKey ) ?;
476-
477- let pub_bytes = key_pair. public_key ( ) . as_ref ( ) ;
478507 if pub_bytes[ 0 ] != 4 {
479508 return Err ( ErrorKind :: InvalidEcdsaKey . into ( ) ) ;
480509 }
481510
482511 let ( x, y) = pub_bytes[ 1 ..] . split_at ( pub_elem_bytes) ;
483512 Ok ( ( curve, x. to_vec ( ) , y. to_vec ( ) ) )
484513}
514+ #[ cfg( feature = "aws_lc_rs" ) ]
515+ mod ec_pubkey_components {
516+ use super :: * ;
517+
518+ pub fn from_private_key (
519+ key_content : & [ u8 ] ,
520+ alg : Algorithm ,
521+ ) -> errors:: Result < ( EllipticCurve , Vec < u8 > , Vec < u8 > ) > {
522+ use aws_lc_rs:: signature:: {
523+ ECDSA_P256_SHA256_FIXED_SIGNING , ECDSA_P384_SHA384_FIXED_SIGNING , EcdsaKeyPair ,
524+ } ;
525+
526+ let ( signing_alg, curve, pub_elem_bytes) = match alg {
527+ Algorithm :: ES256 => ( & ECDSA_P256_SHA256_FIXED_SIGNING , EllipticCurve :: P256 , 32 ) ,
528+ Algorithm :: ES384 => ( & ECDSA_P384_SHA384_FIXED_SIGNING , EllipticCurve :: P384 , 48 ) ,
529+ _ => return Err ( ErrorKind :: InvalidEcdsaKey . into ( ) ) ,
530+ } ;
531+
532+ let key_pair = EcdsaKeyPair :: from_pkcs8 ( signing_alg, key_content)
533+ . map_err ( |_| ErrorKind :: InvalidEcdsaKey ) ?;
534+
535+ let pub_bytes = key_pair. public_key ( ) . as_ref ( ) ;
536+ if pub_bytes[ 0 ] != 4 {
537+ return Err ( ErrorKind :: InvalidEcdsaKey . into ( ) ) ;
538+ }
539+
540+ let ( x, y) = pub_bytes[ 1 ..] . split_at ( pub_elem_bytes) ;
541+ Ok ( ( curve, x. to_vec ( ) , y. to_vec ( ) ) )
542+ }
543+
544+ pub fn from_public_key (
545+ pub_bytes : & [ u8 ] ,
546+ ) -> errors:: Result < ( EllipticCurve , Vec < u8 > , Vec < u8 > ) > {
547+ ec_components_from_public_key ( pub_bytes)
548+ }
549+ }
485550
486551#[ cfg( feature = "rust_crypto" ) ]
487- fn extract_ec_public_key_coordinates (
488- key_content : & [ u8 ] ,
489- alg : Algorithm ,
490- ) -> errors:: Result < ( EllipticCurve , Vec < u8 > , Vec < u8 > ) > {
491- match alg {
492- Algorithm :: ES256 => {
493- let signing_key = P256SigningKey :: from_pkcs8_der ( key_content)
494- . map_err ( |_| ErrorKind :: InvalidEcdsaKey ) ?;
495- let public_key = signing_key. verifying_key ( ) ;
496- let encoded = public_key. to_encoded_point ( false ) ;
497- match encoded. coordinates ( ) {
498- p256:: elliptic_curve:: sec1:: Coordinates :: Uncompressed { x, y } => {
499- Ok ( ( EllipticCurve :: P256 , x. to_vec ( ) , y. to_vec ( ) ) )
552+ mod ec_pubkey_components {
553+ use super :: * ;
554+ use p256:: { ecdsa:: SigningKey as P256SigningKey , pkcs8:: DecodePrivateKey } ;
555+ use p384:: ecdsa:: SigningKey as P384SigningKey ;
556+
557+ pub fn from_private_key (
558+ key_content : & [ u8 ] ,
559+ alg : Algorithm ,
560+ ) -> errors:: Result < ( EllipticCurve , Vec < u8 > , Vec < u8 > ) > {
561+ match alg {
562+ Algorithm :: ES256 => {
563+ let signing_key = P256SigningKey :: from_pkcs8_der ( key_content)
564+ . map_err ( |_| ErrorKind :: InvalidEcdsaKey ) ?;
565+ let public_key = signing_key. verifying_key ( ) ;
566+ let encoded = public_key. to_encoded_point ( false ) ;
567+ match encoded. coordinates ( ) {
568+ p256:: elliptic_curve:: sec1:: Coordinates :: Uncompressed { x, y } => {
569+ Ok ( ( EllipticCurve :: P256 , x. to_vec ( ) , y. to_vec ( ) ) )
570+ }
571+ _ => Err ( ErrorKind :: InvalidEcdsaKey . into ( ) ) ,
500572 }
501- _ => Err ( ErrorKind :: InvalidEcdsaKey . into ( ) ) ,
502573 }
503- }
504- Algorithm :: ES384 => {
505- let signing_key = P384SigningKey :: from_pkcs8_der ( key_content)
506- . map_err ( |_| ErrorKind :: InvalidEcdsaKey ) ?;
507- let public_key = signing_key. verifying_key ( ) ;
508- let encoded = public_key. to_encoded_point ( false ) ;
509- match encoded. coordinates ( ) {
510- p384:: elliptic_curve:: sec1:: Coordinates :: Uncompressed { x, y } => {
511- Ok ( ( EllipticCurve :: P384 , x. to_vec ( ) , y. to_vec ( ) ) )
574+ Algorithm :: ES384 => {
575+ let signing_key = P384SigningKey :: from_pkcs8_der ( key_content)
576+ . map_err ( |_| ErrorKind :: InvalidEcdsaKey ) ?;
577+ let public_key = signing_key. verifying_key ( ) ;
578+ let encoded = public_key. to_encoded_point ( false ) ;
579+ match encoded. coordinates ( ) {
580+ p384:: elliptic_curve:: sec1:: Coordinates :: Uncompressed { x, y } => {
581+ Ok ( ( EllipticCurve :: P384 , x. to_vec ( ) , y. to_vec ( ) ) )
582+ }
583+ _ => Err ( ErrorKind :: InvalidEcdsaKey . into ( ) ) ,
512584 }
513- _ => Err ( ErrorKind :: InvalidEcdsaKey . into ( ) ) ,
514585 }
586+ _ => Err ( ErrorKind :: InvalidEcdsaKey . into ( ) ) ,
515587 }
516- _ => Err ( ErrorKind :: InvalidEcdsaKey . into ( ) ) ,
588+ }
589+
590+ pub fn from_public_key ( pub_bytes : & [ u8 ] ) -> errors:: Result < ( EllipticCurve , Vec < u8 > , Vec < u8 > ) > {
591+ ec_components_from_public_key ( pub_bytes)
517592 }
518593}
519594
@@ -547,20 +622,7 @@ impl Jwk {
547622 pub fn from_encoding_key ( key : & EncodingKey , alg : Algorithm ) -> crate :: errors:: Result < Self > {
548623 Ok ( Self {
549624 common : CommonParameters {
550- key_algorithm : Some ( match alg {
551- Algorithm :: HS256 => KeyAlgorithm :: HS256 ,
552- Algorithm :: HS384 => KeyAlgorithm :: HS384 ,
553- Algorithm :: HS512 => KeyAlgorithm :: HS512 ,
554- Algorithm :: ES256 => KeyAlgorithm :: ES256 ,
555- Algorithm :: ES384 => KeyAlgorithm :: ES384 ,
556- Algorithm :: RS256 => KeyAlgorithm :: RS256 ,
557- Algorithm :: RS384 => KeyAlgorithm :: RS384 ,
558- Algorithm :: RS512 => KeyAlgorithm :: RS512 ,
559- Algorithm :: PS256 => KeyAlgorithm :: PS256 ,
560- Algorithm :: PS384 => KeyAlgorithm :: PS384 ,
561- Algorithm :: PS512 => KeyAlgorithm :: PS512 ,
562- Algorithm :: EdDSA => KeyAlgorithm :: EdDSA ,
563- } ) ,
625+ key_algorithm : Some ( alg. into ( ) ) ,
564626 ..Default :: default ( )
565627 } ,
566628 algorithm : match key. family {
@@ -571,15 +633,15 @@ impl Jwk {
571633 } )
572634 }
573635 crate :: algorithms:: AlgorithmFamily :: Rsa => {
574- let ( n, e) = extract_rsa_public_key_components ( & key. content ) ?;
636+ let ( n, e) = rsa_pubkey_components :: from_private_key ( & key. content ) ?;
575637 AlgorithmParameters :: RSA ( RSAKeyParameters {
576638 key_type : RSAKeyType :: RSA ,
577639 n : b64_encode ( n) ,
578640 e : b64_encode ( e) ,
579641 } )
580642 }
581643 crate :: algorithms:: AlgorithmFamily :: Ec => {
582- let ( curve, x, y) = extract_ec_public_key_coordinates ( & key. content , alg) ?;
644+ let ( curve, x, y) = ec_pubkey_components :: from_private_key ( & key. content , alg) ?;
583645 AlgorithmParameters :: EllipticCurve ( EllipticCurveKeyParameters {
584646 key_type : EllipticCurveKeyType :: EC ,
585647 curve,
@@ -592,6 +654,62 @@ impl Jwk {
592654 }
593655 } ,
594656 } )
657+
658+ }
659+
660+ pub fn from_decoding_key ( key : & DecodingKey , alg : Option < Algorithm > ) -> crate :: errors:: Result < Self > {
661+ Ok ( Self {
662+ common : CommonParameters {
663+ key_algorithm : alg. map ( |a| a. into ( ) ) ,
664+ ..Default :: default ( )
665+ } ,
666+ algorithm : match key. family {
667+ crate :: algorithms:: AlgorithmFamily :: Hmac => {
668+ let secret = match & key. kind {
669+ DecodingKeyKind :: SecretOrDer ( secret) => secret,
670+ _ => return Err ( ErrorKind :: InvalidKeyFormat . into ( ) ) ,
671+ } ;
672+
673+ AlgorithmParameters :: OctetKey ( OctetKeyParameters {
674+ key_type : OctetKeyType :: Octet ,
675+ value : b64_encode ( secret) ,
676+ } )
677+ }
678+ crate :: algorithms:: AlgorithmFamily :: Rsa => {
679+ let ( n, e) = match & key. kind {
680+ DecodingKeyKind :: RsaModulusExponent { n, e } => ( b64_encode ( n) , b64_encode ( e) ) ,
681+ DecodingKeyKind :: SecretOrDer ( der) => {
682+ let ( n, e) = rsa_pubkey_components:: from_public_key ( der) ?;
683+ ( b64_encode ( n) , b64_encode ( e) )
684+ }
685+ } ;
686+
687+ AlgorithmParameters :: RSA ( RSAKeyParameters {
688+ key_type : RSAKeyType :: RSA ,
689+ n,
690+ e,
691+ } )
692+ }
693+ crate :: algorithms:: AlgorithmFamily :: Ec => {
694+ let ( curve, x, y) = match & key. kind {
695+ DecodingKeyKind :: SecretOrDer ( pub_bytes) => {
696+ ec_pubkey_components:: from_public_key ( pub_bytes) ?
697+ }
698+ _ => return Err ( ErrorKind :: InvalidKeyFormat . into ( ) ) ,
699+ } ;
700+
701+ AlgorithmParameters :: EllipticCurve ( EllipticCurveKeyParameters {
702+ key_type : EllipticCurveKeyType :: EC ,
703+ curve,
704+ x : b64_encode ( x) ,
705+ y : b64_encode ( y) ,
706+ } )
707+ } ,
708+ crate :: algorithms:: AlgorithmFamily :: Ed => {
709+ unimplemented ! ( ) ;
710+ }
711+ } ,
712+ } )
595713 }
596714
597715 /// Compute the thumbprint of the JWK.
@@ -669,6 +787,7 @@ mod tests {
669787 AlgorithmParameters , Jwk , JwkSet , KeyAlgorithm , OctetKeyType , RSAKeyParameters ,
670788 ThumbprintHash ,
671789 } ;
790+ use crate :: { EncodingKey , DecodingKey } ;
672791 use crate :: serialization:: b64_encode;
673792
674793 #[ test]
@@ -724,4 +843,22 @@ mod tests {
724843 . thumbprint ( ThumbprintHash :: SHA256 ) ;
725844 assert_eq ! ( tp. as_str( ) , "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs" ) ;
726845 }
846+
847+ #[ test]
848+ fn check_jwk_from_decoding_key_rsa ( ) {
849+ let enc_key = EncodingKey :: from_rsa_pem ( include_bytes ! ( "../tests/rsa/private_rsa_key_pkcs8.pem" ) ) . unwrap ( ) ;
850+ let dec_key = DecodingKey :: from_rsa_pem ( include_bytes ! ( "../tests/rsa/public_rsa_key_pkcs8.pem" ) ) . unwrap ( ) ;
851+ let expected_jwk = Jwk :: from_encoding_key ( & enc_key, Algorithm :: RS256 ) . unwrap ( ) ;
852+ let jwk = Jwk :: from_decoding_key ( & dec_key, Some ( Algorithm :: RS256 ) ) . unwrap ( ) ;
853+ assert_eq ! ( jwk, expected_jwk) ;
854+ }
855+
856+ #[ test]
857+ fn check_jwk_from_decoding_key_ec ( ) {
858+ let enc_key = EncodingKey :: from_ec_pem ( include_bytes ! ( "../tests/ecdsa/private_ecdsa_key.pem" ) ) . unwrap ( ) ;
859+ let dec_key = DecodingKey :: from_ec_pem ( include_bytes ! ( "../tests/ecdsa/public_ecdsa_key.pem" ) ) . unwrap ( ) ;
860+ let expected_jwk = Jwk :: from_encoding_key ( & enc_key, Algorithm :: ES256 ) . unwrap ( ) ;
861+ let jwk = Jwk :: from_decoding_key ( & dec_key, Some ( Algorithm :: ES256 ) ) . unwrap ( ) ;
862+ assert_eq ! ( jwk, expected_jwk) ;
863+ }
727864}
0 commit comments