@@ -220,14 +220,14 @@ impl KeyInner {
220220 }
221221}
222222
223- unsafe impl Send for PrivateKey { }
224-
225- // https://github.com/awslabs/aws-lc/blob/main/include/openssl/ec_key.h#L88
226- // An |EC_KEY| object represents a public or private EC key. A given object may
223+ // See EVP_PKEY documentation here:
224+ // https://github.com/aws/aws-lc/blob/125af14c57451565b875fbf1282a38a6ecf83782/include/openssl/evp.h#L83-L89
225+ // An |EVP_PKEY| object represents a public or private key. A given object may
227226// be used concurrently on multiple threads by non-mutating functions, provided
228227// no other thread is concurrently calling a mutating function. Unless otherwise
229228// documented, functions which take a |const| pointer are non-mutating and
230229// functions which take a non-|const| pointer are mutating.
230+ unsafe impl Send for PrivateKey { }
231231unsafe impl Sync for PrivateKey { }
232232
233233impl Debug for PrivateKey {
@@ -536,6 +536,13 @@ impl PublicKey {
536536 }
537537}
538538
539+ // See EVP_PKEY documentation here:
540+ // https://github.com/aws/aws-lc/blob/125af14c57451565b875fbf1282a38a6ecf83782/include/openssl/evp.h#L83-L89
541+ // An |EVP_PKEY| object represents a public or private key. A given object may
542+ // be used concurrently on multiple threads by non-mutating functions, provided
543+ // no other thread is concurrently calling a mutating function. Unless otherwise
544+ // documented, functions which take a |const| pointer are non-mutating and
545+ // functions which take a non-|const| pointer are mutating.
539546unsafe impl Send for PublicKey { }
540547unsafe impl Sync for PublicKey { }
541548
@@ -666,13 +673,21 @@ impl<B: AsRef<[u8]>> UnparsedPublicKey<B> {
666673/// This represents a public key that has been successfully parsed and validated
667674/// from its encoded form. The key can be used with the `agree` function to
668675/// perform key agreement operations.
669- #[ derive( Debug ) ]
676+ #[ derive( Debug , Clone ) ]
670677pub struct ParsedPublicKey {
671678 format : ParsedPublicKeyFormat ,
672679 nid : i32 ,
673680 key : LcPtr < EVP_PKEY > ,
681+ bytes : Box < [ u8 ] > ,
674682}
675683
684+ // See EVP_PKEY documentation here:
685+ // https://github.com/aws/aws-lc/blob/125af14c57451565b875fbf1282a38a6ecf83782/include/openssl/evp.h#L83-L89
686+ // An |EVP_PKEY| object represents a public or private key. A given object may
687+ // be used concurrently on multiple threads by non-mutating functions, provided
688+ // no other thread is concurrently calling a mutating function. Unless otherwise
689+ // documented, functions which take a |const| pointer are non-mutating and
690+ // functions which take a non-|const| pointer are mutating.
676691unsafe impl Send for ParsedPublicKey { }
677692unsafe impl Sync for ParsedPublicKey { }
678693
@@ -730,35 +745,40 @@ impl ParsedPublicKey {
730745impl ParsedPublicKey {
731746 #[ allow( non_upper_case_globals) ]
732747 pub ( crate ) fn new ( bytes : impl AsRef < [ u8 ] > , nid : i32 ) -> Result < Self , KeyRejected > {
733- let key_bytes = bytes. as_ref ( ) ;
734- if key_bytes . is_empty ( ) {
748+ let bytes = bytes. as_ref ( ) . to_vec ( ) . into_boxed_slice ( ) ;
749+ if bytes . is_empty ( ) {
735750 return Err ( KeyRejected :: unspecified ( ) ) ;
736751 }
737752 match nid {
738753 NID_X25519 => {
739754 let format: ParsedPublicKeyFormat ;
740755 let key = if let Ok ( evp_pkey) =
741- LcPtr :: < EVP_PKEY > :: parse_rfc5280_public_key ( key_bytes , EVP_PKEY_X25519 )
756+ LcPtr :: < EVP_PKEY > :: parse_rfc5280_public_key ( & bytes , EVP_PKEY_X25519 )
742757 {
743758 format = ParsedPublicKeyFormat :: X509 ;
744759 evp_pkey
745760 } else {
746761 format = ParsedPublicKeyFormat :: Raw ;
747- try_parse_x25519_public_key_raw_bytes ( key_bytes ) ?
762+ try_parse_x25519_public_key_raw_bytes ( & bytes ) ?
748763 } ;
749764
750- Ok ( ParsedPublicKey { format, nid, key } )
765+ Ok ( ParsedPublicKey {
766+ format,
767+ nid,
768+ key,
769+ bytes,
770+ } )
751771 }
752772 NID_X9_62_prime256v1 | NID_secp384r1 | NID_secp521r1 => {
753773 let format: ParsedPublicKeyFormat ;
754774 let key = if let Ok ( evp_pkey) =
755- LcPtr :: < EVP_PKEY > :: parse_rfc5280_public_key ( key_bytes , EVP_PKEY_EC )
775+ LcPtr :: < EVP_PKEY > :: parse_rfc5280_public_key ( & bytes , EVP_PKEY_EC )
756776 {
757777 validate_ec_evp_key ( & evp_pkey. as_const ( ) , nid) ?;
758778 format = ParsedPublicKeyFormat :: X509 ;
759779 evp_pkey
760- } else if let Ok ( evp_pkey) = parse_sec1_public_point ( key_bytes , nid) {
761- format = match key_bytes [ 0 ] {
780+ } else if let Ok ( evp_pkey) = parse_sec1_public_point ( & bytes , nid) {
781+ format = match bytes [ 0 ] {
762782 0x02 | 0x03 => ParsedPublicKeyFormat :: Compressed ,
763783 0x04 => ParsedPublicKeyFormat :: Uncompressed ,
764784 0x06 | 0x07 => ParsedPublicKeyFormat :: Hybrid ,
@@ -769,13 +789,25 @@ impl ParsedPublicKey {
769789 return Err ( KeyRejected :: invalid_encoding ( ) ) ;
770790 } ;
771791
772- Ok ( ParsedPublicKey { format, nid, key } )
792+ Ok ( ParsedPublicKey {
793+ format,
794+ nid,
795+ key,
796+ bytes,
797+ } )
773798 }
774799 _ => Err ( KeyRejected :: unspecified ( ) ) ,
775800 }
776801 }
777802}
778803
804+ impl AsRef < [ u8 ] > for ParsedPublicKey {
805+ /// Returns the original bytes from which this key was parsed.
806+ fn as_ref ( & self ) -> & [ u8 ] {
807+ & self . bytes
808+ }
809+ }
810+
779811impl < B : AsRef < [ u8 ] > > UnparsedPublicKey < B > {
780812 #[ allow( dead_code) ]
781813 fn parse ( & self ) -> Result < ParsedPublicKey , KeyRejected > {
0 commit comments