@@ -10,9 +10,11 @@ use pkcs8::DecodePrivateKey;
1010use spki:: ObjectIdentifier ;
1111use x509_cert:: Certificate as X509Certificate ;
1212
13+ use super :: super :: check_verify_scheme;
1314use super :: super :: { KeyProvider , SignatureVerifier , SigningKey as SigningKeyTrait } ;
15+ use super :: super :: { OID_P256 , OID_P384 } ;
1416use crate :: buffer:: Buf ;
15- use crate :: types:: { HashAlgorithm , SignatureAlgorithm } ;
17+ use crate :: types:: { HashAlgorithm , NamedGroup , SignatureAlgorithm } ;
1618
1719/// ECDSA signing key implementation.
1820enum EcdsaSigningKey {
@@ -201,47 +203,60 @@ impl SignatureVerifier for RustCryptoSignatureVerifier {
201203 . as_bytes ( )
202204 . ok_or_else ( || "Invalid EC subject_public_key bitstring" . to_string ( ) ) ?;
203205
204- match hash_alg {
205- HashAlgorithm :: SHA256 => {
206- use ecdsa:: signature:: hazmat:: PrehashVerifier ;
207- use sha2:: { Digest , Sha256 } ;
208-
206+ let curve_oid: ObjectIdentifier = spki
207+ . algorithm
208+ . parameters
209+ . as_ref ( )
210+ . ok_or ( "Missing EC curve parameter in certificate" ) ?
211+ . decode_as ( )
212+ . map_err ( |_| "Invalid EC curve parameter in certificate" . to_string ( ) ) ?;
213+
214+ let group = match curve_oid {
215+ OID_P256 => NamedGroup :: Secp256r1 ,
216+ OID_P384 => NamedGroup :: Secp384r1 ,
217+ _ => return Err ( format ! ( "Unsupported EC curve: {}" , curve_oid) ) ,
218+ } ;
219+
220+ check_verify_scheme ( sig_alg, hash_alg, group) ?;
221+
222+ use ecdsa:: signature:: hazmat:: PrehashVerifier ;
223+ use sha2:: Digest ;
224+
225+ // Hash the data before verification (PrehashVerifier expects a hash digest)
226+ let hash: Box < [ u8 ] > = match hash_alg {
227+ HashAlgorithm :: SHA256 => Box :: from ( sha2:: Sha256 :: digest ( data) . as_slice ( ) ) ,
228+ HashAlgorithm :: SHA384 => Box :: from ( sha2:: Sha384 :: digest ( data) . as_slice ( ) ) ,
229+ // unreachable: check_verify_scheme already validated
230+ _ => unreachable ! ( ) ,
231+ } ;
232+
233+ match group {
234+ NamedGroup :: Secp256r1 => {
209235 let verifying_key = VerifyingKey :: < NistP256 > :: from_sec1_bytes ( pubkey_bytes)
210236 . map_err ( |_| "Invalid P-256 public key" . to_string ( ) ) ?;
211- let signature = Signature :: < NistP256 > :: from_der ( signature)
237+ let sig = Signature :: < NistP256 > :: from_der ( signature)
212238 . map_err ( |_| "Invalid signature format" . to_string ( ) ) ?;
213-
214- // Hash the data before verification (PrehashVerifier expects a hash digest)
215- let mut hasher = Sha256 :: new ( ) ;
216- hasher. update ( data) ;
217- let hash = hasher. finalize ( ) ;
218-
219- verifying_key
220- . verify_prehash ( & hash, & signature)
221- . map_err ( |_| format ! ( "ECDSA signature verification failed for {:?}" , hash_alg) )
239+ verifying_key. verify_prehash ( & hash, & sig) . map_err ( |_| {
240+ format ! (
241+ "ECDSA signature verification failed for {:?} {:?}" ,
242+ hash_alg, group
243+ )
244+ } )
222245 }
223- HashAlgorithm :: SHA384 => {
224- use ecdsa:: signature:: hazmat:: PrehashVerifier ;
225- use sha2:: { Digest , Sha384 } ;
226-
246+ NamedGroup :: Secp384r1 => {
227247 let verifying_key = VerifyingKey :: < NistP384 > :: from_sec1_bytes ( pubkey_bytes)
228248 . map_err ( |_| "Invalid P-384 public key" . to_string ( ) ) ?;
229- let signature = Signature :: < NistP384 > :: from_der ( signature)
249+ let sig = Signature :: < NistP384 > :: from_der ( signature)
230250 . map_err ( |_| "Invalid signature format" . to_string ( ) ) ?;
231-
232- // Hash the data before verification (PrehashVerifier expects a hash digest)
233- let mut hasher = Sha384 :: new ( ) ;
234- hasher. update ( data) ;
235- let hash = hasher. finalize ( ) ;
236-
237- verifying_key
238- . verify_prehash ( & hash, & signature)
239- . map_err ( |_| format ! ( "ECDSA signature verification failed for {:?}" , hash_alg) )
251+ verifying_key. verify_prehash ( & hash, & sig) . map_err ( |_| {
252+ format ! (
253+ "ECDSA signature verification failed for {:?} {:?}" ,
254+ hash_alg, group
255+ )
256+ } )
240257 }
241- _ => Err ( format ! (
242- "Unsupported hash algorithm for ECDSA: {:?}" ,
243- hash_alg
244- ) ) ,
258+ // unreachable: OID match above only produces Secp256r1/Secp384r1
259+ _ => unreachable ! ( ) ,
245260 }
246261 }
247262}
0 commit comments