@@ -11,6 +11,9 @@ use p256::ecdsa::{
1111use p384:: ecdsa:: {
1212 Signature as Signature384 , SigningKey as SigningKey384 , VerifyingKey as VerifyingKey384 ,
1313} ;
14+ use p521:: ecdsa:: {
15+ Signature as Signature521 , SigningKey as SigningKey521 , VerifyingKey as VerifyingKey521 ,
16+ } ;
1417use rsa:: pkcs8:: DecodePrivateKey ;
1518use signature:: { Error , Signer , Verifier } ;
1619
@@ -85,3 +88,127 @@ define_ecdsa_signer!(Es384Signer, Algorithm::ES384, SigningKey384);
8588
8689define_ecdsa_verifier ! ( Es256Verifier , Algorithm :: ES256 , VerifyingKey256 , Signature256 ) ;
8790define_ecdsa_verifier ! ( Es384Verifier , Algorithm :: ES384 , VerifyingKey384 , Signature384 ) ;
91+
92+ // P521 (ES512) requires custom macros instead of the generic ones because:
93+ // 1. SigningKey521 doesn't implement DecodePrivateKey (no from_pkcs8_der), so we manually extract the key
94+ // 2. SigningKey521 doesn't have sign_recoverable(), only the regular sign() method
95+ // These API differences in the p521 crate necessitate separate implementations.
96+ // P521 (ES512) signer - requires PKCS8 extraction
97+ macro_rules! define_p521_signer {
98+ ( $name: ident, $alg: expr) => {
99+ pub struct $name( SigningKey521 ) ;
100+
101+ impl $name {
102+ pub ( crate ) fn new( encoding_key: & EncodingKey ) -> Result <Self > {
103+ if encoding_key. family( ) != AlgorithmFamily :: Ec {
104+ return Err ( new_error( ErrorKind :: InvalidKeyFormat ) ) ;
105+ }
106+
107+ // For P521, we need to extract the 66-byte key from PKCS8 DER format
108+ let pkcs8_der = encoding_key. inner( ) ;
109+ let key_bytes = extract_p521_key_from_pkcs8( pkcs8_der) ?;
110+
111+ // Convert to FieldBytes and create SigningKey
112+ let field_bytes: & p521:: FieldBytes = key_bytes
113+ . as_slice( )
114+ . try_into( )
115+ . map_err( |_| ErrorKind :: InvalidEcdsaKey ) ?;
116+
117+ Ok ( Self (
118+ SigningKey521 :: from_bytes( field_bytes)
119+ . map_err( |_| ErrorKind :: InvalidEcdsaKey ) ?,
120+ ) )
121+ }
122+ }
123+
124+ impl Signer <Vec <u8 >> for $name {
125+ fn try_sign( & self , msg: & [ u8 ] ) -> std:: result:: Result <Vec <u8 >, Error > {
126+ let signature: Signature521 = self . 0 . sign( msg) ;
127+ Ok ( signature. to_vec( ) )
128+ }
129+ }
130+
131+ impl JwtSigner for $name {
132+ fn algorithm( & self ) -> Algorithm {
133+ $alg
134+ }
135+ }
136+ } ;
137+ }
138+
139+ // P521 (ES512) verifier
140+ macro_rules! define_p521_verifier {
141+ ( $name: ident, $alg: expr) => {
142+ pub struct $name( VerifyingKey521 ) ;
143+
144+ impl $name {
145+ pub ( crate ) fn new( decoding_key: & DecodingKey ) -> Result <Self > {
146+ if decoding_key. family( ) != AlgorithmFamily :: Ec {
147+ return Err ( new_error( ErrorKind :: InvalidKeyFormat ) ) ;
148+ }
149+
150+ Ok ( Self (
151+ VerifyingKey521 :: from_sec1_bytes( decoding_key. as_bytes( ) )
152+ . map_err( |_| ErrorKind :: InvalidEcdsaKey ) ?,
153+ ) )
154+ }
155+ }
156+
157+ impl Verifier <Vec <u8 >> for $name {
158+ fn verify( & self , msg: & [ u8 ] , signature: & Vec <u8 >) -> std:: result:: Result <( ) , Error > {
159+ self . 0
160+ . verify( msg, & Signature521 :: from_slice( signature) . map_err( Error :: from_source) ?)
161+ . map_err( Error :: from_source) ?;
162+ Ok ( ( ) )
163+ }
164+ }
165+
166+ impl JwtVerifier for $name {
167+ fn algorithm( & self ) -> Algorithm {
168+ $alg
169+ }
170+ }
171+ } ;
172+ }
173+
174+ define_p521_signer ! ( Es512Signer , Algorithm :: ES512 ) ;
175+ define_p521_verifier ! ( Es512Verifier , Algorithm :: ES512 ) ;
176+
177+ /// Extract the 66-byte P-521 private key from PKCS8 DER format
178+ fn extract_p521_key_from_pkcs8 ( pkcs8_der : & [ u8 ] ) -> Result < Vec < u8 > > {
179+ use rsa:: pkcs8:: PrivateKeyInfo ;
180+
181+ // Decode as PKCS8 structure
182+ let private_key_info = PrivateKeyInfo :: try_from ( pkcs8_der)
183+ . map_err ( |_| ErrorKind :: InvalidKeyFormat ) ?;
184+
185+ // The private key bytes should be in the private_key field
186+ // For P-521 in PKCS8, this is a DER-encoded ECPrivateKey which contains the 66-byte key
187+ let private_key_bytes = private_key_info. private_key ;
188+
189+ // Parse the ECPrivateKey structure (which is a SEQUENCE with the key as an OCTET STRING)
190+ use simple_asn1:: ASN1Block ;
191+ let asn1_blocks = simple_asn1:: from_der ( private_key_bytes)
192+ . map_err ( |_| ErrorKind :: InvalidKeyFormat ) ?;
193+
194+ for block in asn1_blocks {
195+ if let ASN1Block :: Sequence ( _, entries) = block {
196+ // ECPrivateKey ::= SEQUENCE {
197+ // version INTEGER { ecPrivkeyVer1(0) }
198+ // privateKey OCTET STRING,
199+ // parameters [0] ECParameters OPTIONAL,
200+ // publicKey [1] BIT STRING OPTIONAL
201+ // }
202+ if entries. len ( ) >= 2 {
203+ // The second element (index 1) should be the privateKey OCTET STRING
204+ if let ASN1Block :: OctetString ( _, key_bytes) = & entries[ 1 ] {
205+ if key_bytes. len ( ) == 66 {
206+ return Ok ( key_bytes. clone ( ) ) ;
207+ }
208+ }
209+ }
210+ }
211+ }
212+
213+ Err ( new_error ( ErrorKind :: InvalidKeyFormat ) )
214+ }
0 commit comments