@@ -165,36 +165,38 @@ fn effective_trust_policy(cmd: &VerifyCommand) -> TrustPolicy {
165165 }
166166}
167167
168+ /// Wrap raw pubkey bytes from a trust store (pin or roots.json) into a curve-tagged
169+ /// `DevicePublicKey`. Infers the curve from length via `CurveType::from_public_key_len`.
170+ fn bytes_to_device_public_key (
171+ bytes : & [ u8 ] ,
172+ source : & str ,
173+ ) -> Result < auths_verifier:: DevicePublicKey > {
174+ let curve = auths_crypto:: CurveType :: from_public_key_len ( bytes. len ( ) )
175+ . ok_or_else ( || anyhow ! ( "Invalid {} public key length: {}" , source, bytes. len( ) ) ) ?;
176+ auths_verifier:: DevicePublicKey :: try_new ( curve, bytes)
177+ . map_err ( |e| anyhow ! ( "Invalid {} public key: {e}" , source) )
178+ }
179+
168180/// Resolve the issuer public key from various sources.
169181///
170182/// Resolution precedence:
171- /// 1. --issuer-pk (direct key, bypasses trust)
183+ /// 1. ` --issuer-pk` (direct key, bypasses trust)
172184/// 2. Pinned identity store
173- /// 3. roots.json file
185+ /// 3. ` roots.json` file
174186/// 4. Trust policy (TOFU prompt or explicit rejection)
175187fn resolve_issuer_key (
176188 now : chrono:: DateTime < Utc > ,
177189 cmd : & VerifyCommand ,
178190 att : & Attestation ,
179- ) -> Result < Vec < u8 > > {
191+ ) -> Result < auths_verifier :: DevicePublicKey > {
180192 // 1. Direct key takes precedence
181193 if let Some ( ref pk_hex) = cmd. issuer_pk {
182194 let pk_bytes =
183195 hex:: decode ( pk_hex) . context ( "Invalid hex string provided for issuer public key" ) ?;
184- let curve = match pk_bytes. len ( ) {
185- 32 => auths_crypto:: CurveType :: Ed25519 ,
186- 33 | 65 => auths_crypto:: CurveType :: P256 ,
187- _ => {
188- return Err ( anyhow ! (
189- "Invalid issuer public key length: {}" ,
190- pk_bytes. len( )
191- ) ) ;
192- }
193- } ;
194- // Validate via DevicePublicKey type system
195- auths_verifier:: DevicePublicKey :: try_new ( curve, & pk_bytes)
196- . map_err ( |e| anyhow ! ( "Invalid issuer public key: {e}" ) ) ?;
197- return Ok ( pk_bytes) ;
196+ let curve = auths_crypto:: CurveType :: from_public_key_len ( pk_bytes. len ( ) )
197+ . ok_or_else ( || anyhow ! ( "Invalid issuer public key length: {}" , pk_bytes. len( ) ) ) ?;
198+ return auths_verifier:: DevicePublicKey :: try_new ( curve, & pk_bytes)
199+ . map_err ( |e| anyhow ! ( "Invalid issuer public key: {e}" ) ) ;
198200 }
199201
200202 // Determine the DID to look up
@@ -209,7 +211,7 @@ fn resolve_issuer_key(
209211 if !is_json_mode ( ) {
210212 println ! ( "Using pinned identity: {}" , did) ;
211213 }
212- return Ok ( pin. public_key_bytes ( ) ?) ;
214+ return bytes_to_device_public_key ( & pin. public_key_bytes ( ) ?, "pinned identity" ) ;
213215 }
214216
215217 // 3. Check roots.json file
@@ -240,7 +242,7 @@ fn resolve_issuer_key(
240242 trust_level : TrustLevel :: OrgPolicy ,
241243 } ;
242244 store. pin ( pin) ?;
243- return Ok ( root. public_key_bytes ( ) ?) ;
245+ return bytes_to_device_public_key ( & root. public_key_bytes ( ) ?, "roots.json" ) ;
244246 }
245247 }
246248
@@ -297,7 +299,7 @@ async fn run_verify(now: chrono::DateTime<Utc>, cmd: &VerifyCommand) -> Result<V
297299 }
298300
299301 // 3. Resolve issuer public key
300- let issuer_pk_bytes = resolve_issuer_key ( now, cmd, & att) ?;
302+ let issuer_pk = resolve_issuer_key ( now, cmd, & att) ?;
301303
302304 let required_capability: Option < Capability > = cmd. require_capability . as_ref ( ) . map ( |cap| {
303305 cap. parse :: < Capability > ( ) . unwrap_or_else ( |e| {
@@ -308,9 +310,9 @@ async fn run_verify(now: chrono::DateTime<Utc>, cmd: &VerifyCommand) -> Result<V
308310
309311 // 5. Verify the attestation (with or without capability check)
310312 let verify_result = if let Some ( ref cap) = required_capability {
311- verify_with_capability ( & att, cap, & issuer_pk_bytes ) . await
313+ verify_with_capability ( & att, cap, & issuer_pk ) . await
312314 } else {
313- verify_with_keys ( & att, & issuer_pk_bytes ) . await
315+ verify_with_keys ( & att, & issuer_pk ) . await
314316 } ;
315317
316318 match verify_result {
@@ -330,13 +332,10 @@ async fn run_verify(now: chrono::DateTime<Utc>, cmd: &VerifyCommand) -> Result<V
330332 threshold : cmd. witness_threshold ,
331333 } ;
332334
333- let report = verify_chain_with_witnesses (
334- std:: slice:: from_ref ( & att) ,
335- & issuer_pk_bytes,
336- & config,
337- )
338- . await
339- . context ( "Witness chain verification failed" ) ?;
335+ let report =
336+ verify_chain_with_witnesses ( std:: slice:: from_ref ( & att) , & issuer_pk, & config)
337+ . await
338+ . context ( "Witness chain verification failed" ) ?;
340339
341340 if !report. is_valid ( ) {
342341 if !is_json_mode ( )
@@ -447,21 +446,9 @@ pub async fn handle_verify_attestation(
447446
448447 let issuer_pk_bytes = hex:: decode ( issuer_pubkey_hex)
449448 . context ( "Invalid hex string provided for issuer public key" ) ?;
449+ let issuer_pk = bytes_to_device_public_key ( & issuer_pk_bytes, "issuer" ) ?;
450450
451- let curve = match issuer_pk_bytes. len ( ) {
452- 32 => auths_crypto:: CurveType :: Ed25519 ,
453- 33 | 65 => auths_crypto:: CurveType :: P256 ,
454- _ => {
455- return Err ( anyhow ! (
456- "Invalid issuer public key length: {}" ,
457- issuer_pk_bytes. len( )
458- ) ) ;
459- }
460- } ;
461- auths_verifier:: DevicePublicKey :: try_new ( curve, & issuer_pk_bytes)
462- . map_err ( |e| anyhow ! ( "Invalid issuer public key: {e}" ) ) ?;
463-
464- match verify_with_keys ( & att, & issuer_pk_bytes) . await {
451+ match verify_with_keys ( & att, & issuer_pk) . await {
465452 Ok ( _) => {
466453 println ! ( "Attestation verified successfully." ) ;
467454 Ok ( ( ) )
0 commit comments