diff --git a/src/ctap/credential_management.rs b/src/ctap/credential_management.rs index 27fc5a7..caf4aa8 100644 --- a/src/ctap/credential_management.rs +++ b/src/ctap/credential_management.rs @@ -93,9 +93,7 @@ fn enumerate_credentials_response( key_id: credential_id, transports: None, // You can set USB as a hint here. }; - let public_key = private_key - .get_pub_key(env) - .ok_or(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?; + let public_key = private_key.get_pub_key(env)?; Ok(AuthenticatorCredentialManagementResponse { user: Some(user), credential_id: Some(credential_id), diff --git a/src/ctap/crypto_wrapper.rs b/src/ctap/crypto_wrapper.rs index 6a35bd1..881b075 100644 --- a/src/ctap/crypto_wrapper.rs +++ b/src/ctap/crypto_wrapper.rs @@ -153,17 +153,17 @@ impl PrivateKey { } /// Returns the ECDSA private key. - pub fn ecdsa_key(&self, env: &mut impl Env) -> Option { + pub fn ecdsa_key(&self, env: &mut impl Env) -> Result { match self { PrivateKey::Ecdsa(seed) => ecdsa_key_from_seed(env, seed), #[allow(unreachable_patterns)] - _ => None, + _ => Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR), } } /// Returns the corresponding public key. - pub fn get_pub_key(&self, env: &mut impl Env) -> Option { - Some(match self { + pub fn get_pub_key(&self, env: &mut impl Env) -> Result { + Ok(match self { PrivateKey::Ecdsa(ecdsa_seed) => { CoseKey::from(ecdsa_key_from_seed(env, ecdsa_seed)?.genpk()) } @@ -173,8 +173,12 @@ impl PrivateKey { } /// Returns the encoded signature for a given message. - pub fn sign_and_encode(&self, env: &mut impl Env, message: &[u8]) -> Option> { - Some(match self { + pub fn sign_and_encode( + &self, + env: &mut impl Env, + message: &[u8], + ) -> Result, Ctap2StatusCode> { + Ok(match self { PrivateKey::Ecdsa(ecdsa_seed) => ecdsa_key_from_seed(env, ecdsa_seed)? .sign_rfc6979::(message) .to_asn1_der(), @@ -202,9 +206,12 @@ impl PrivateKey { } } -fn ecdsa_key_from_seed(env: &mut impl Env, seed: &[u8; 32]) -> Option { - let ecdsa_bytes = env.key_store().derive_ecdsa(seed).ok()?; - ecdsa::SecKey::from_bytes(&ecdsa_bytes) +fn ecdsa_key_from_seed( + env: &mut impl Env, + seed: &[u8; 32], +) -> Result { + let ecdsa_bytes = env.key_store().derive_ecdsa(seed)?; + Ok(ecdsa::SecKey::from_bytes(&ecdsa_bytes).unwrap()) } impl From for cbor::Value { @@ -481,7 +488,7 @@ mod test { let public_key = ecdsa_key.genpk(); assert_eq!( private_key.get_pub_key(&mut env), - Some(CoseKey::from(public_key)) + Ok(CoseKey::from(public_key)) ); } @@ -494,7 +501,7 @@ mod test { let signature = ecdsa_key.sign_rfc6979::(&message).to_asn1_der(); assert_eq!( private_key.sign_and_encode(&mut env, &message), - Some(signature) + Ok(signature) ); } diff --git a/src/ctap/ctap1.rs b/src/ctap/ctap1.rs index 5a72f77..00def87 100644 --- a/src/ctap/ctap1.rs +++ b/src/ctap/ctap1.rs @@ -248,7 +248,7 @@ impl Ctap1Command { let private_key = PrivateKey::new_ecdsa(env); let sk = private_key .ecdsa_key(env) - .ok_or(Ctap1StatusCode::SW_INTERNAL_EXCEPTION)?; + .map_err(|_| Ctap1StatusCode::SW_INTERNAL_EXCEPTION)?; let pk = sk.genpk(); let key_handle = encrypt_key_handle(env, &private_key, &application) .map_err(|_| Ctap1StatusCode::SW_INTERNAL_EXCEPTION)?; @@ -315,7 +315,7 @@ impl Ctap1Command { let ecdsa_key = credential_source .private_key .ecdsa_key(env) - .ok_or(Ctap1StatusCode::SW_WRONG_DATA)?; + .map_err(|_| Ctap1StatusCode::SW_WRONG_DATA)?; if flags == Ctap1Flags::CheckOnly { return Err(Ctap1StatusCode::SW_COND_USE_NOT_SATISFIED); } diff --git a/src/ctap/mod.rs b/src/ctap/mod.rs index 678cc29..52a410f 100644 --- a/src/ctap/mod.rs +++ b/src/ctap/mod.rs @@ -892,9 +892,7 @@ impl CtapState { } auth_data.extend(vec![0x00, credential_id.len() as u8]); auth_data.extend(&credential_id); - let public_cose_key = private_key - .get_pub_key(env) - .ok_or(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?; + let public_cose_key = private_key.get_pub_key(env)?; cbor_write(cbor::Value::from(public_cose_key), &mut auth_data)?; if has_extension_output { let hmac_secret_output = if extensions.hmac_secret { @@ -934,12 +932,7 @@ impl CtapState { Some(vec![attestation_certificate]), ) } else { - ( - private_key - .sign_and_encode(env, &signature_data) - .ok_or(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?, - None, - ) + (private_key.sign_and_encode(env, &signature_data)?, None) }; let attestation_statement = PackedAttestationStatement { alg: SignatureAlgorithm::ES256 as i64, @@ -1023,8 +1016,7 @@ impl CtapState { signature_data.extend(client_data_hash); let signature = credential .private_key - .sign_and_encode(env, &signature_data) - .ok_or(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?; + .sign_and_encode(env, &signature_data)?; let cred_desc = PublicKeyCredentialDescriptor { key_type: PublicKeyCredentialType::PublicKey,