Return Result instead of Option
This commit is contained in:
@@ -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),
|
||||||
|
|||||||
@@ -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)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user