@@ -89,61 +89,136 @@ define_ecdsa_signer!(Es384Signer, Algorithm::ES384, SigningKey384);
8989define_ecdsa_verifier ! ( Es256Verifier , Algorithm :: ES256 , VerifyingKey256 , Signature256 ) ;
9090define_ecdsa_verifier ! ( Es384Verifier , Algorithm :: ES384 , VerifyingKey384 , Signature384 ) ;
9191
92- // P521 (ES512) uses a different API - no sign_recoverable
93- pub struct Es512Signer ( SigningKey521 ) ;
92+ // P521 (ES512) signer - uses different API (no sign_recoverable, different PKCS8 extraction)
93+ macro_rules! define_p521_signer {
94+ ( $name: ident, $alg: expr) => {
95+ pub struct $name( SigningKey521 ) ;
9496
95- impl Es512Signer {
96- pub ( crate ) fn new ( encoding_key : & EncodingKey ) -> Result < Self > {
97- if encoding_key. family != AlgorithmFamily :: Ec {
98- return Err ( new_error ( ErrorKind :: InvalidKeyFormat ) ) ;
97+ impl $name {
98+ pub ( crate ) fn new( encoding_key: & EncodingKey ) -> Result <Self > {
99+ if encoding_key. family != AlgorithmFamily :: Ec {
100+ return Err ( new_error( ErrorKind :: InvalidKeyFormat ) ) ;
101+ }
102+
103+ // Extract the raw 66-byte key from PKCS8 DER format
104+ let pkcs8_der = encoding_key. inner( ) ;
105+ let key_bytes = extract_p521_key_from_pkcs8( pkcs8_der) ?;
106+
107+ // Verify correct length and convert to fixed-size array safely
108+ if key_bytes. len( ) != 66 {
109+ return Err ( new_error( ErrorKind :: InvalidEcdsaKey ) ) ;
110+ }
111+
112+ // Safe conversion using slice_as_array pattern
113+ let mut key_array = [ 0u8 ; 66 ] ;
114+ key_array. copy_from_slice( & key_bytes) ;
115+
116+ // Convert array to GenericArray reference using From trait
117+ let field_bytes: & p521:: FieldBytes = key_array. as_slice( ) . try_into( )
118+ . map_err( |_| ErrorKind :: InvalidEcdsaKey ) ?;
119+
120+ Ok ( Self (
121+ SigningKey521 :: from_bytes( field_bytes)
122+ . map_err( |_| ErrorKind :: InvalidEcdsaKey ) ?,
123+ ) )
124+ }
99125 }
100126
101- Ok ( Self (
102- SigningKey521 :: from_bytes ( encoding_key . inner ( ) . into ( ) )
103- . map_err ( |_| ErrorKind :: InvalidEcdsaKey ) ? ,
104- ) )
105- }
106- }
127+ impl Signer < Vec < u8 >> for $name {
128+ fn try_sign ( & self , msg : & [ u8 ] ) -> std :: result :: Result < Vec < u8 > , Error > {
129+ let signature : Signature521 = self . 0 . sign ( msg ) ;
130+ Ok ( signature . to_vec ( ) )
131+ }
132+ }
107133
108- impl Signer < Vec < u8 > > for Es512Signer {
109- fn try_sign ( & self , msg : & [ u8 ] ) -> std:: result:: Result < Vec < u8 > , Error > {
110- let signature: Signature521 = self . 0 . sign ( msg) ;
111- Ok ( signature. to_vec ( ) )
112- }
134+ impl JwtSigner for $name {
135+ fn algorithm( & self ) -> Algorithm {
136+ $alg
137+ }
138+ }
139+ } ;
113140}
114141
115- impl JwtSigner for Es512Signer {
116- fn algorithm ( & self ) -> Algorithm {
117- Algorithm :: ES512
118- }
119- }
142+ // P521 (ES512) verifier
143+ macro_rules! define_p521_verifier {
144+ ( $name: ident, $alg: expr) => {
145+ pub struct $name( VerifyingKey521 ) ;
120146
121- pub struct Es512Verifier ( VerifyingKey521 ) ;
147+ impl $name {
148+ pub ( crate ) fn new( decoding_key: & DecodingKey ) -> Result <Self > {
149+ if decoding_key. family != AlgorithmFamily :: Ec {
150+ return Err ( new_error( ErrorKind :: InvalidKeyFormat ) ) ;
151+ }
122152
123- impl Es512Verifier {
124- pub ( crate ) fn new ( decoding_key : & DecodingKey ) -> Result < Self > {
125- if decoding_key. family != AlgorithmFamily :: Ec {
126- return Err ( new_error ( ErrorKind :: InvalidKeyFormat ) ) ;
153+ Ok ( Self (
154+ VerifyingKey521 :: from_sec1_bytes( decoding_key. as_bytes( ) )
155+ . map_err( |_| ErrorKind :: InvalidEcdsaKey ) ?,
156+ ) )
157+ }
127158 }
128159
129- Ok ( Self (
130- VerifyingKey521 :: from_sec1_bytes ( decoding_key. as_bytes ( ) )
131- . map_err ( |_| ErrorKind :: InvalidEcdsaKey ) ?,
132- ) )
133- }
134- }
160+ impl Verifier <Vec <u8 >> for $name {
161+ fn verify( & self , msg: & [ u8 ] , signature: & Vec <u8 >) -> std:: result:: Result <( ) , Error > {
162+ self . 0
163+ . verify( msg, & Signature521 :: from_slice( signature) . map_err( Error :: from_source) ?)
164+ . map_err( Error :: from_source) ?;
165+ Ok ( ( ) )
166+ }
167+ }
135168
136- impl Verifier < Vec < u8 > > for Es512Verifier {
137- fn verify ( & self , msg : & [ u8 ] , signature : & Vec < u8 > ) -> std:: result:: Result < ( ) , Error > {
138- self . 0
139- . verify ( msg, & Signature521 :: from_slice ( signature) . map_err ( Error :: from_source) ?)
140- . map_err ( Error :: from_source) ?;
141- Ok ( ( ) )
142- }
169+ impl JwtVerifier for $name {
170+ fn algorithm( & self ) -> Algorithm {
171+ $alg
172+ }
173+ }
174+ } ;
143175}
144176
145- impl JwtVerifier for Es512Verifier {
146- fn algorithm ( & self ) -> Algorithm {
147- Algorithm :: ES512
177+ define_p521_signer ! ( Es512Signer , Algorithm :: ES512 ) ;
178+ define_p521_verifier ! ( Es512Verifier , Algorithm :: ES512 ) ;
179+
180+ /// Extract the 66-byte P-521 private key from PKCS8 DER format
181+ ///
182+ /// P-521 keys in PKCS8 format have a different structure than the standard P256/P384:
183+ /// PKCS8 ::= SEQUENCE {
184+ /// version INTEGER,
185+ /// algorithm AlgorithmIdentifier,
186+ /// PrivateKey OCTET STRING
187+ /// }
188+ /// The PrivateKey octet string contains a DER-encoded ECPrivateKey SEQUENCE:
189+ /// ECPrivateKey ::= SEQUENCE {
190+ /// version INTEGER,
191+ /// privateKey OCTET STRING (66 bytes for P-521)
192+ /// }
193+ fn extract_p521_key_from_pkcs8 ( pkcs8_der : & [ u8 ] ) -> Result < Vec < u8 > > {
194+ let asn1_blocks = simple_asn1:: from_der ( pkcs8_der)
195+ . map_err ( |_| ErrorKind :: InvalidKeyFormat ) ?;
196+
197+ for block in asn1_blocks {
198+ if let simple_asn1:: ASN1Block :: Sequence ( _, entries) = block {
199+ // The third element (index 2) should be the privateKey OCTET STRING
200+ if entries. len ( ) >= 3 {
201+ if let simple_asn1:: ASN1Block :: OctetString ( _, value) = & entries[ 2 ] {
202+ // The value is DER-encoded and contains a SEQUENCE with the actual key
203+ if let Ok ( inner_blocks) = simple_asn1:: from_der ( value) {
204+ for inner_block in inner_blocks {
205+ if let simple_asn1:: ASN1Block :: Sequence ( _, inner_entries) = inner_block {
206+ // Look for the OCTET STRING within this sequence
207+ for inner_entry in inner_entries {
208+ if let simple_asn1:: ASN1Block :: OctetString ( _, key_value) = inner_entry {
209+ // This should be our 66-byte key
210+ if key_value. len ( ) == 66 {
211+ return Ok ( key_value. to_vec ( ) ) ;
212+ }
213+ }
214+ }
215+ }
216+ }
217+ }
218+ }
219+ }
220+ }
148221 }
222+
223+ Err ( new_error ( ErrorKind :: InvalidKeyFormat ) )
149224}
0 commit comments