44//! through an extension trait on `sigstore_types::Checkpoint`.
55
66use crate :: { Error , Result } ;
7+ use sigstore_types:: { DerPublicKey , KeyHint , SignatureBytes } ;
78
89// Re-export checkpoint types from sigstore-types
910pub use sigstore_types:: { Checkpoint , CheckpointSignature } ;
1011
1112/// Compute the key hint (4-byte key ID) from a public key.
1213///
1314/// The key hint is the first 4 bytes of SHA-256(public key).
14- pub fn compute_key_hint ( public_key_der : & [ u8 ] ) -> [ u8 ; 4 ] {
15- let hash = crate :: hash:: sha256 ( public_key_der ) ;
15+ pub fn compute_key_hint ( public_key : & DerPublicKey ) -> KeyHint {
16+ let hash = crate :: hash:: sha256 ( public_key . as_bytes ( ) ) ;
1617 let bytes = hash. as_bytes ( ) ;
17- [ bytes[ 0 ] , bytes[ 1 ] , bytes[ 2 ] , bytes[ 3 ] ]
18+ KeyHint :: new ( [ bytes[ 0 ] , bytes[ 1 ] , bytes[ 2 ] , bytes[ 3 ] ] )
1819}
1920
2021// OID constants for key type identification
@@ -38,10 +39,10 @@ pub enum KeyType {
3839/// Detect the key type from SPKI-encoded public key bytes.
3940///
4041/// This parses the SubjectPublicKeyInfo structure to determine the algorithm.
41- pub fn detect_key_type ( public_key_der : & [ u8 ] ) -> KeyType {
42+ pub fn detect_key_type ( public_key : & DerPublicKey ) -> KeyType {
4243 use spki:: SubjectPublicKeyInfoRef ;
4344
44- match SubjectPublicKeyInfoRef :: try_from ( public_key_der ) {
45+ match SubjectPublicKeyInfoRef :: try_from ( public_key . as_bytes ( ) ) {
4546 Ok ( spki) => {
4647 if spki. algorithm . oid == ID_ED25519 {
4748 KeyType :: Ed25519
@@ -55,7 +56,7 @@ pub fn detect_key_type(public_key_der: &[u8]) -> KeyType {
5556 Err ( _) => {
5657 // If we can't parse as SPKI, might be raw key bytes
5758 // Check if it looks like a raw Ed25519 key (32 bytes)
58- if public_key_der . len ( ) == 32 {
59+ if public_key . as_bytes ( ) . len ( ) == 32 {
5960 KeyType :: Ed25519
6061 } else {
6162 KeyType :: Unknown
@@ -68,48 +69,53 @@ pub fn detect_key_type(public_key_der: &[u8]) -> KeyType {
6869///
6970/// For Ed25519, this extracts the 32-byte raw key from the SPKI wrapper.
7071/// For ECDSA, the full SPKI is typically used by aws-lc-rs.
71- pub fn extract_raw_key ( public_key_der : & [ u8 ] ) -> Result < Vec < u8 > > {
72+ pub fn extract_raw_key ( public_key : & DerPublicKey ) -> Result < Vec < u8 > > {
7273 use spki:: SubjectPublicKeyInfoRef ;
7374
74- match SubjectPublicKeyInfoRef :: try_from ( public_key_der ) {
75+ match SubjectPublicKeyInfoRef :: try_from ( public_key . as_bytes ( ) ) {
7576 Ok ( spki) => {
7677 let raw_bytes = spki. subject_public_key . raw_bytes ( ) ;
7778 Ok ( raw_bytes. to_vec ( ) )
7879 }
7980 Err ( _) => {
8081 // Already raw bytes
81- Ok ( public_key_der . to_vec ( ) )
82+ Ok ( public_key . as_bytes ( ) . to_vec ( ) )
8283 }
8384 }
8485}
8586
8687/// Verify an Ed25519 signature.
8788///
8889/// Accepts either SPKI-encoded or raw 32-byte public keys.
89- pub fn verify_ed25519 ( public_key_der : & [ u8 ] , signature : & [ u8 ] , message : & [ u8 ] ) -> Result < ( ) > {
90- use aws_lc_rs:: signature;
90+ pub fn verify_ed25519 (
91+ public_key : & DerPublicKey ,
92+ signature : & SignatureBytes ,
93+ message : & [ u8 ] ,
94+ ) -> Result < ( ) > {
95+ use aws_lc_rs:: signature as sig;
9196
9297 // Extract raw key bytes from SPKI if needed
93- let raw_key = extract_raw_key ( public_key_der ) ?;
98+ let raw_key = extract_raw_key ( public_key ) ?;
9499
95- let public_key = signature:: UnparsedPublicKey :: new ( & signature:: ED25519 , & raw_key) ;
96- public_key
97- . verify ( message, signature)
100+ let pk = sig:: UnparsedPublicKey :: new ( & sig:: ED25519 , & raw_key) ;
101+ pk. verify ( message, signature. as_bytes ( ) )
98102 . map_err ( |_| Error :: Verification ( "Ed25519 verification failed" . to_string ( ) ) )
99103}
100104
101105/// Verify an ECDSA P-256 signature.
102106///
103107/// Expects SPKI-encoded public key (as produced by x509 certificates).
104- pub fn verify_ecdsa_p256 ( public_key_der : & [ u8 ] , signature : & [ u8 ] , message : & [ u8 ] ) -> Result < ( ) > {
105- use aws_lc_rs:: signature;
108+ pub fn verify_ecdsa_p256 (
109+ public_key : & DerPublicKey ,
110+ signature : & SignatureBytes ,
111+ message : & [ u8 ] ,
112+ ) -> Result < ( ) > {
113+ use aws_lc_rs:: signature as sig;
106114
107115 // aws-lc-rs expects the full SPKI for ECDSA, or raw uncompressed point
108- let public_key =
109- signature:: UnparsedPublicKey :: new ( & signature:: ECDSA_P256_SHA256_ASN1 , public_key_der) ;
116+ let pk = sig:: UnparsedPublicKey :: new ( & sig:: ECDSA_P256_SHA256_ASN1 , public_key. as_bytes ( ) ) ;
110117
111- public_key
112- . verify ( message, signature)
118+ pk. verify ( message, signature. as_bytes ( ) )
113119 . map_err ( |_| Error :: Verification ( "ECDSA P-256 verification failed" . to_string ( ) ) )
114120}
115121
@@ -118,20 +124,20 @@ pub fn verify_ecdsa_p256(public_key_der: &[u8], signature: &[u8], message: &[u8]
118124/// This function detects the key type from the SPKI structure and calls
119125/// the appropriate verification function.
120126pub fn verify_signature_auto (
121- public_key_der : & [ u8 ] ,
122- signature : & [ u8 ] ,
127+ public_key : & DerPublicKey ,
128+ signature : & SignatureBytes ,
123129 message : & [ u8 ] ,
124130) -> Result < ( ) > {
125- match detect_key_type ( public_key_der ) {
126- KeyType :: Ed25519 => verify_ed25519 ( public_key_der , signature, message) ,
127- KeyType :: EcdsaP256 => verify_ecdsa_p256 ( public_key_der , signature, message) ,
131+ match detect_key_type ( public_key ) {
132+ KeyType :: Ed25519 => verify_ed25519 ( public_key , signature, message) ,
133+ KeyType :: EcdsaP256 => verify_ecdsa_p256 ( public_key , signature, message) ,
128134 KeyType :: Unknown => {
129135 // Fallback: try both (maintains backwards compatibility)
130136 tracing:: debug!( "Unknown key type, trying Ed25519 then ECDSA P-256" ) ;
131- if verify_ed25519 ( public_key_der , signature, message) . is_ok ( ) {
137+ if verify_ed25519 ( public_key , signature, message) . is_ok ( ) {
132138 return Ok ( ( ) ) ;
133139 }
134- verify_ecdsa_p256 ( public_key_der , signature, message)
140+ verify_ecdsa_p256 ( public_key , signature, message)
135141 }
136142 }
137143}
@@ -148,13 +154,13 @@ pub trait CheckpointVerifyExt {
148154 /// The key type is automatically detected from the SPKI structure.
149155 ///
150156 /// Returns Ok(()) if verification succeeds, or an error if it fails.
151- fn verify_signature ( & self , public_key_der : & [ u8 ] ) -> Result < ( ) > ;
157+ fn verify_signature ( & self , public_key : & DerPublicKey ) -> Result < ( ) > ;
152158}
153159
154160impl CheckpointVerifyExt for Checkpoint {
155- fn verify_signature ( & self , public_key_der : & [ u8 ] ) -> Result < ( ) > {
161+ fn verify_signature ( & self , public_key : & DerPublicKey ) -> Result < ( ) > {
156162 // Compute key hint from public key
157- let key_hint = compute_key_hint ( public_key_der ) ;
163+ let key_hint = compute_key_hint ( public_key ) ;
158164
159165 // Find signature with matching key hint
160166 let signature = self
@@ -165,7 +171,7 @@ impl CheckpointVerifyExt for Checkpoint {
165171 let signed_data = self . signed_data ( ) ;
166172
167173 // Use automatic key type detection
168- verify_signature_auto ( public_key_der , & signature. signature , signed_data)
174+ verify_signature_auto ( public_key , & signature. signature , signed_data)
169175 . map_err ( |e| Error :: Checkpoint ( format ! ( "Signature verification failed: {}" , e) ) )
170176 }
171177}
@@ -199,6 +205,6 @@ mod tests {
199205 assert_eq ! ( checkpoint. signatures. len( ) , 1 ) ;
200206 assert_eq ! ( checkpoint. signatures[ 0 ] . name, "rekor.sigstore.dev" ) ;
201207 // Key hint is first 4 bytes of base64-decoded signature
202- assert_eq ! ( checkpoint. signatures[ 0 ] . key_id. len( ) , 4 ) ;
208+ assert_eq ! ( checkpoint. signatures[ 0 ] . key_id. as_bytes ( ) . len( ) , 4 ) ;
203209 }
204210}
0 commit comments