Return Result instead of Option

This commit is contained in:
Julien Cretin
2022-07-01 13:26:35 +02:00
parent 30a3205fa7
commit ecb98b0f58
4 changed files with 24 additions and 27 deletions

View File

@@ -93,9 +93,7 @@ fn enumerate_credentials_response(
key_id: credential_id, key_id: credential_id,
transports: None, // You can set USB as a hint here. transports: None, // You can set USB as a hint here.
}; };
let public_key = private_key let public_key = private_key.get_pub_key(env)?;
.get_pub_key(env)
.ok_or(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?;
Ok(AuthenticatorCredentialManagementResponse { Ok(AuthenticatorCredentialManagementResponse {
user: Some(user), user: Some(user),
credential_id: Some(credential_id), credential_id: Some(credential_id),

View File

@@ -153,17 +153,17 @@ impl PrivateKey {
} }
/// Returns the ECDSA private key. /// Returns the ECDSA private key.
pub fn ecdsa_key(&self, env: &mut impl Env) -> Option<ecdsa::SecKey> { pub fn ecdsa_key(&self, env: &mut impl Env) -> Result<ecdsa::SecKey, Ctap2StatusCode> {
match self { match self {
PrivateKey::Ecdsa(seed) => ecdsa_key_from_seed(env, seed), PrivateKey::Ecdsa(seed) => ecdsa_key_from_seed(env, seed),
#[allow(unreachable_patterns)] #[allow(unreachable_patterns)]
_ => None, _ => Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR),
} }
} }
/// Returns the corresponding public key. /// Returns the corresponding public key.
pub fn get_pub_key(&self, env: &mut impl Env) -> Option<CoseKey> { pub fn get_pub_key(&self, env: &mut impl Env) -> Result<CoseKey, Ctap2StatusCode> {
Some(match self { Ok(match self {
PrivateKey::Ecdsa(ecdsa_seed) => { PrivateKey::Ecdsa(ecdsa_seed) => {
CoseKey::from(ecdsa_key_from_seed(env, ecdsa_seed)?.genpk()) CoseKey::from(ecdsa_key_from_seed(env, ecdsa_seed)?.genpk())
} }
@@ -173,8 +173,12 @@ impl PrivateKey {
} }
/// Returns the encoded signature for a given message. /// Returns the encoded signature for a given message.
pub fn sign_and_encode(&self, env: &mut impl Env, message: &[u8]) -> Option<Vec<u8>> { pub fn sign_and_encode(
Some(match self { &self,
env: &mut impl Env,
message: &[u8],
) -> Result<Vec<u8>, Ctap2StatusCode> {
Ok(match self {
PrivateKey::Ecdsa(ecdsa_seed) => ecdsa_key_from_seed(env, ecdsa_seed)? PrivateKey::Ecdsa(ecdsa_seed) => ecdsa_key_from_seed(env, ecdsa_seed)?
.sign_rfc6979::<Sha256>(message) .sign_rfc6979::<Sha256>(message)
.to_asn1_der(), .to_asn1_der(),
@@ -202,9 +206,12 @@ impl PrivateKey {
} }
} }
fn ecdsa_key_from_seed(env: &mut impl Env, seed: &[u8; 32]) -> Option<ecdsa::SecKey> { fn ecdsa_key_from_seed(
let ecdsa_bytes = env.key_store().derive_ecdsa(seed).ok()?; env: &mut impl Env,
ecdsa::SecKey::from_bytes(&ecdsa_bytes) seed: &[u8; 32],
) -> Result<ecdsa::SecKey, Ctap2StatusCode> {
let ecdsa_bytes = env.key_store().derive_ecdsa(seed)?;
Ok(ecdsa::SecKey::from_bytes(&ecdsa_bytes).unwrap())
} }
impl From<PrivateKey> for cbor::Value { impl From<PrivateKey> for cbor::Value {
@@ -481,7 +488,7 @@ mod test {
let public_key = ecdsa_key.genpk(); let public_key = ecdsa_key.genpk();
assert_eq!( assert_eq!(
private_key.get_pub_key(&mut env), 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::<Sha256>(&message).to_asn1_der(); let signature = ecdsa_key.sign_rfc6979::<Sha256>(&message).to_asn1_der();
assert_eq!( assert_eq!(
private_key.sign_and_encode(&mut env, &message), private_key.sign_and_encode(&mut env, &message),
Some(signature) Ok(signature)
); );
} }

View File

@@ -248,7 +248,7 @@ impl Ctap1Command {
let private_key = PrivateKey::new_ecdsa(env); let private_key = PrivateKey::new_ecdsa(env);
let sk = private_key let sk = private_key
.ecdsa_key(env) .ecdsa_key(env)
.ok_or(Ctap1StatusCode::SW_INTERNAL_EXCEPTION)?; .map_err(|_| Ctap1StatusCode::SW_INTERNAL_EXCEPTION)?;
let pk = sk.genpk(); let pk = sk.genpk();
let key_handle = encrypt_key_handle(env, &private_key, &application) let key_handle = encrypt_key_handle(env, &private_key, &application)
.map_err(|_| Ctap1StatusCode::SW_INTERNAL_EXCEPTION)?; .map_err(|_| Ctap1StatusCode::SW_INTERNAL_EXCEPTION)?;
@@ -315,7 +315,7 @@ impl Ctap1Command {
let ecdsa_key = credential_source let ecdsa_key = credential_source
.private_key .private_key
.ecdsa_key(env) .ecdsa_key(env)
.ok_or(Ctap1StatusCode::SW_WRONG_DATA)?; .map_err(|_| Ctap1StatusCode::SW_WRONG_DATA)?;
if flags == Ctap1Flags::CheckOnly { if flags == Ctap1Flags::CheckOnly {
return Err(Ctap1StatusCode::SW_COND_USE_NOT_SATISFIED); return Err(Ctap1StatusCode::SW_COND_USE_NOT_SATISFIED);
} }

View File

@@ -892,9 +892,7 @@ impl CtapState {
} }
auth_data.extend(vec![0x00, credential_id.len() as u8]); auth_data.extend(vec![0x00, credential_id.len() as u8]);
auth_data.extend(&credential_id); auth_data.extend(&credential_id);
let public_cose_key = private_key let public_cose_key = private_key.get_pub_key(env)?;
.get_pub_key(env)
.ok_or(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?;
cbor_write(cbor::Value::from(public_cose_key), &mut auth_data)?; cbor_write(cbor::Value::from(public_cose_key), &mut auth_data)?;
if has_extension_output { if has_extension_output {
let hmac_secret_output = if extensions.hmac_secret { let hmac_secret_output = if extensions.hmac_secret {
@@ -934,12 +932,7 @@ impl CtapState {
Some(vec![attestation_certificate]), Some(vec![attestation_certificate]),
) )
} else { } else {
( (private_key.sign_and_encode(env, &signature_data)?, None)
private_key
.sign_and_encode(env, &signature_data)
.ok_or(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?,
None,
)
}; };
let attestation_statement = PackedAttestationStatement { let attestation_statement = PackedAttestationStatement {
alg: SignatureAlgorithm::ES256 as i64, alg: SignatureAlgorithm::ES256 as i64,
@@ -1023,8 +1016,7 @@ impl CtapState {
signature_data.extend(client_data_hash); signature_data.extend(client_data_hash);
let signature = credential let signature = credential
.private_key .private_key
.sign_and_encode(env, &signature_data) .sign_and_encode(env, &signature_data)?;
.ok_or(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?;
let cred_desc = PublicKeyCredentialDescriptor { let cred_desc = PublicKeyCredentialDescriptor {
key_type: PublicKeyCredentialType::PublicKey, key_type: PublicKeyCredentialType::PublicKey,