renames PIN protocol related variables to prepare PIN protocol v2 (#291)

This commit is contained in:
kaczmarczyck
2021-03-04 10:37:19 +01:00
committed by GitHub
parent 5e9c32dff5
commit 351e6c12c6
7 changed files with 246 additions and 320 deletions

View File

@@ -166,7 +166,7 @@ pub enum PinPermission {
AuthenticatorConfiguration = 0x20,
}
pub struct PinProtocolV1 {
pub struct ClientPin {
key_agreement_key: crypto::ecdh::SecKey,
pin_uv_auth_token: [u8; PIN_TOKEN_LENGTH],
consecutive_pin_mismatches: u8,
@@ -174,11 +174,11 @@ pub struct PinProtocolV1 {
permissions_rp_id: Option<String>,
}
impl PinProtocolV1 {
pub fn new(rng: &mut impl Rng256) -> PinProtocolV1 {
impl ClientPin {
pub fn new(rng: &mut impl Rng256) -> ClientPin {
let key_agreement_key = crypto::ecdh::SecKey::gensk(rng);
let pin_uv_auth_token = rng.gen_uniform_u8x32();
PinProtocolV1 {
ClientPin {
key_agreement_key,
pin_uv_auth_token,
consecutive_pin_mismatches: 0,
@@ -395,14 +395,14 @@ impl PinProtocolV1 {
Ok(response)
}
pub fn process_subcommand(
pub fn process_command(
&mut self,
rng: &mut impl Rng256,
persistent_store: &mut PersistentStore,
client_pin_params: AuthenticatorClientPinParameters,
) -> Result<ResponseData, Ctap2StatusCode> {
let AuthenticatorClientPinParameters {
pin_protocol,
pin_uv_auth_protocol,
sub_command,
key_agreement,
pin_auth,
@@ -412,7 +412,7 @@ impl PinProtocolV1 {
permissions_rp_id,
} = client_pin_params;
if pin_protocol != 1 {
if pin_uv_auth_protocol != 1 {
return Err(Ctap2StatusCode::CTAP1_ERR_INVALID_PARAMETER);
}
@@ -558,8 +558,8 @@ impl PinProtocolV1 {
pub fn new_test(
key_agreement_key: crypto::ecdh::SecKey,
pin_uv_auth_token: [u8; PIN_TOKEN_LENGTH],
) -> PinProtocolV1 {
PinProtocolV1 {
) -> ClientPin {
ClientPin {
key_agreement_key,
pin_uv_auth_token,
consecutive_pin_mismatches: 0,
@@ -647,13 +647,13 @@ mod test {
let aes_enc_key = crypto::aes256::EncryptionKey::new(&shared_secret);
let aes_dec_key = crypto::aes256::DecryptionKey::new(&aes_enc_key);
let mut pin_protocol_v1 = PinProtocolV1::new(&mut rng);
let mut client_pin = ClientPin::new(&mut rng);
let pin_hash_enc = vec![
0x8D, 0x7A, 0xA3, 0x9F, 0x7F, 0xC6, 0x08, 0x13, 0x9A, 0xC8, 0x56, 0x97, 0x70, 0x74,
0x99, 0x66,
];
assert_eq!(
pin_protocol_v1.verify_pin_hash_enc(
client_pin.verify_pin_hash_enc(
&mut rng,
&mut persistent_store,
&aes_dec_key,
@@ -664,7 +664,7 @@ mod test {
let pin_hash_enc = vec![0xEE; 16];
assert_eq!(
pin_protocol_v1.verify_pin_hash_enc(
client_pin.verify_pin_hash_enc(
&mut rng,
&mut persistent_store,
&aes_dec_key,
@@ -677,9 +677,9 @@ mod test {
0x8D, 0x7A, 0xA3, 0x9F, 0x7F, 0xC6, 0x08, 0x13, 0x9A, 0xC8, 0x56, 0x97, 0x70, 0x74,
0x99, 0x66,
];
pin_protocol_v1.consecutive_pin_mismatches = 3;
client_pin.consecutive_pin_mismatches = 3;
assert_eq!(
pin_protocol_v1.verify_pin_hash_enc(
client_pin.verify_pin_hash_enc(
&mut rng,
&mut persistent_store,
&aes_dec_key,
@@ -687,11 +687,11 @@ mod test {
),
Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_BLOCKED)
);
pin_protocol_v1.consecutive_pin_mismatches = 0;
client_pin.consecutive_pin_mismatches = 0;
let pin_hash_enc = vec![0x77; PIN_AUTH_LENGTH - 1];
assert_eq!(
pin_protocol_v1.verify_pin_hash_enc(
client_pin.verify_pin_hash_enc(
&mut rng,
&mut persistent_store,
&aes_dec_key,
@@ -702,7 +702,7 @@ mod test {
let pin_hash_enc = vec![0x77; PIN_AUTH_LENGTH + 1];
assert_eq!(
pin_protocol_v1.verify_pin_hash_enc(
client_pin.verify_pin_hash_enc(
&mut rng,
&mut persistent_store,
&aes_dec_key,
@@ -716,14 +716,14 @@ mod test {
fn test_process_get_pin_retries() {
let mut rng = ThreadRng256 {};
let persistent_store = PersistentStore::new(&mut rng);
let pin_protocol_v1 = PinProtocolV1::new(&mut rng);
let client_pin = ClientPin::new(&mut rng);
let expected_response = Ok(AuthenticatorClientPinResponse {
key_agreement: None,
pin_token: None,
retries: Some(persistent_store.pin_retries().unwrap() as u64),
});
assert_eq!(
pin_protocol_v1.process_get_pin_retries(&persistent_store),
client_pin.process_get_pin_retries(&persistent_store),
expected_response
);
}
@@ -731,36 +731,28 @@ mod test {
#[test]
fn test_process_get_key_agreement() {
let mut rng = ThreadRng256 {};
let pin_protocol_v1 = PinProtocolV1::new(&mut rng);
let pk = pin_protocol_v1.key_agreement_key.genpk();
let client_pin = ClientPin::new(&mut rng);
let pk = client_pin.key_agreement_key.genpk();
let expected_response = Ok(AuthenticatorClientPinResponse {
key_agreement: Some(CoseKey::from(pk)),
pin_token: None,
retries: None,
});
assert_eq!(
pin_protocol_v1.process_get_key_agreement(),
expected_response
);
assert_eq!(client_pin.process_get_key_agreement(), expected_response);
}
#[test]
fn test_process_set_pin() {
let mut rng = ThreadRng256 {};
let mut persistent_store = PersistentStore::new(&mut rng);
let mut pin_protocol_v1 = PinProtocolV1::new(&mut rng);
let pk = pin_protocol_v1.key_agreement_key.genpk();
let shared_secret = pin_protocol_v1.key_agreement_key.exchange_x_sha256(&pk);
let mut client_pin = ClientPin::new(&mut rng);
let pk = client_pin.key_agreement_key.genpk();
let shared_secret = client_pin.key_agreement_key.exchange_x_sha256(&pk);
let key_agreement = CoseKey::from(pk);
let new_pin_enc = encrypt_standard_pin(&shared_secret);
let pin_auth = hmac_256::<Sha256>(&shared_secret, &new_pin_enc[..])[..16].to_vec();
assert_eq!(
pin_protocol_v1.process_set_pin(
&mut persistent_store,
key_agreement,
pin_auth,
new_pin_enc
),
client_pin.process_set_pin(&mut persistent_store, key_agreement, pin_auth, new_pin_enc),
Ok(())
);
}
@@ -770,9 +762,9 @@ mod test {
let mut rng = ThreadRng256 {};
let mut persistent_store = PersistentStore::new(&mut rng);
set_standard_pin(&mut persistent_store);
let mut pin_protocol_v1 = PinProtocolV1::new(&mut rng);
let pk = pin_protocol_v1.key_agreement_key.genpk();
let shared_secret = pin_protocol_v1.key_agreement_key.exchange_x_sha256(&pk);
let mut client_pin = ClientPin::new(&mut rng);
let pk = client_pin.key_agreement_key.genpk();
let shared_secret = client_pin.key_agreement_key.exchange_x_sha256(&pk);
let key_agreement = CoseKey::from(pk);
let new_pin_enc = encrypt_standard_pin(&shared_secret);
let pin_hash_enc = encrypt_standard_pin_hash(&shared_secret);
@@ -780,7 +772,7 @@ mod test {
auth_param_data.extend(&pin_hash_enc);
let pin_auth = hmac_256::<Sha256>(&shared_secret, &auth_param_data[..])[..16].to_vec();
assert_eq!(
pin_protocol_v1.process_change_pin(
client_pin.process_change_pin(
&mut rng,
&mut persistent_store,
key_agreement.clone(),
@@ -793,7 +785,7 @@ mod test {
let bad_pin_hash_enc = vec![0xEE; 16];
assert_eq!(
pin_protocol_v1.process_change_pin(
client_pin.process_change_pin(
&mut rng,
&mut persistent_store,
key_agreement.clone(),
@@ -808,7 +800,7 @@ mod test {
persistent_store.decr_pin_retries().unwrap();
}
assert_eq!(
pin_protocol_v1.process_change_pin(
client_pin.process_change_pin(
&mut rng,
&mut persistent_store,
key_agreement,
@@ -825,12 +817,12 @@ mod test {
let mut rng = ThreadRng256 {};
let mut persistent_store = PersistentStore::new(&mut rng);
set_standard_pin(&mut persistent_store);
let mut pin_protocol_v1 = PinProtocolV1::new(&mut rng);
let pk = pin_protocol_v1.key_agreement_key.genpk();
let shared_secret = pin_protocol_v1.key_agreement_key.exchange_x_sha256(&pk);
let mut client_pin = ClientPin::new(&mut rng);
let pk = client_pin.key_agreement_key.genpk();
let shared_secret = client_pin.key_agreement_key.exchange_x_sha256(&pk);
let key_agreement = CoseKey::from(pk);
let pin_hash_enc = encrypt_standard_pin_hash(&shared_secret);
assert!(pin_protocol_v1
assert!(client_pin
.process_get_pin_token(
&mut rng,
&mut persistent_store,
@@ -841,7 +833,7 @@ mod test {
let pin_hash_enc = vec![0xEE; 16];
assert_eq!(
pin_protocol_v1.process_get_pin_token(
client_pin.process_get_pin_token(
&mut rng,
&mut persistent_store,
key_agreement,
@@ -857,13 +849,13 @@ mod test {
let mut persistent_store = PersistentStore::new(&mut rng);
set_standard_pin(&mut persistent_store);
assert_eq!(persistent_store.force_pin_change(), Ok(()));
let mut pin_protocol_v1 = PinProtocolV1::new(&mut rng);
let pk = pin_protocol_v1.key_agreement_key.genpk();
let shared_secret = pin_protocol_v1.key_agreement_key.exchange_x_sha256(&pk);
let mut client_pin = ClientPin::new(&mut rng);
let pk = client_pin.key_agreement_key.genpk();
let shared_secret = client_pin.key_agreement_key.exchange_x_sha256(&pk);
let key_agreement = CoseKey::from(pk);
let pin_hash_enc = encrypt_standard_pin_hash(&shared_secret);
assert_eq!(
pin_protocol_v1.process_get_pin_token(
client_pin.process_get_pin_token(
&mut rng,
&mut persistent_store,
key_agreement,
@@ -878,12 +870,12 @@ mod test {
let mut rng = ThreadRng256 {};
let mut persistent_store = PersistentStore::new(&mut rng);
set_standard_pin(&mut persistent_store);
let mut pin_protocol_v1 = PinProtocolV1::new(&mut rng);
let pk = pin_protocol_v1.key_agreement_key.genpk();
let shared_secret = pin_protocol_v1.key_agreement_key.exchange_x_sha256(&pk);
let mut client_pin = ClientPin::new(&mut rng);
let pk = client_pin.key_agreement_key.genpk();
let shared_secret = client_pin.key_agreement_key.exchange_x_sha256(&pk);
let key_agreement = CoseKey::from(pk);
let pin_hash_enc = encrypt_standard_pin_hash(&shared_secret);
assert!(pin_protocol_v1
assert!(client_pin
.process_get_pin_uv_auth_token_using_pin_with_permissions(
&mut rng,
&mut persistent_store,
@@ -893,14 +885,14 @@ mod test {
Some(String::from("example.com")),
)
.is_ok());
assert_eq!(pin_protocol_v1.permissions, 0x03);
assert_eq!(client_pin.permissions, 0x03);
assert_eq!(
pin_protocol_v1.permissions_rp_id,
client_pin.permissions_rp_id,
Some(String::from("example.com"))
);
assert_eq!(
pin_protocol_v1.process_get_pin_uv_auth_token_using_pin_with_permissions(
client_pin.process_get_pin_uv_auth_token_using_pin_with_permissions(
&mut rng,
&mut persistent_store,
key_agreement.clone(),
@@ -912,7 +904,7 @@ mod test {
);
assert_eq!(
pin_protocol_v1.process_get_pin_uv_auth_token_using_pin_with_permissions(
client_pin.process_get_pin_uv_auth_token_using_pin_with_permissions(
&mut rng,
&mut persistent_store,
key_agreement.clone(),
@@ -925,7 +917,7 @@ mod test {
let pin_hash_enc = vec![0xEE; 16];
assert_eq!(
pin_protocol_v1.process_get_pin_uv_auth_token_using_pin_with_permissions(
client_pin.process_get_pin_uv_auth_token_using_pin_with_permissions(
&mut rng,
&mut persistent_store,
key_agreement,
@@ -943,13 +935,13 @@ mod test {
let mut persistent_store = PersistentStore::new(&mut rng);
set_standard_pin(&mut persistent_store);
assert_eq!(persistent_store.force_pin_change(), Ok(()));
let mut pin_protocol_v1 = PinProtocolV1::new(&mut rng);
let pk = pin_protocol_v1.key_agreement_key.genpk();
let shared_secret = pin_protocol_v1.key_agreement_key.exchange_x_sha256(&pk);
let mut client_pin = ClientPin::new(&mut rng);
let pk = client_pin.key_agreement_key.genpk();
let shared_secret = client_pin.key_agreement_key.exchange_x_sha256(&pk);
let key_agreement = CoseKey::from(pk);
let pin_hash_enc = encrypt_standard_pin_hash(&shared_secret);
assert_eq!(
pin_protocol_v1.process_get_pin_uv_auth_token_using_pin_with_permissions(
client_pin.process_get_pin_uv_auth_token_using_pin_with_permissions(
&mut rng,
&mut persistent_store,
key_agreement,
@@ -965,9 +957,9 @@ mod test {
fn test_process() {
let mut rng = ThreadRng256 {};
let mut persistent_store = PersistentStore::new(&mut rng);
let mut pin_protocol_v1 = PinProtocolV1::new(&mut rng);
let mut client_pin = ClientPin::new(&mut rng);
let client_pin_params = AuthenticatorClientPinParameters {
pin_protocol: 1,
pin_uv_auth_protocol: 1,
sub_command: ClientPinSubCommand::GetPinRetries,
key_agreement: None,
pin_auth: None,
@@ -976,12 +968,12 @@ mod test {
permissions: None,
permissions_rp_id: None,
};
assert!(pin_protocol_v1
.process_subcommand(&mut rng, &mut persistent_store, client_pin_params)
assert!(client_pin
.process_command(&mut rng, &mut persistent_store, client_pin_params)
.is_ok());
let client_pin_params = AuthenticatorClientPinParameters {
pin_protocol: 2,
pin_uv_auth_protocol: 2,
sub_command: ClientPinSubCommand::GetPinRetries,
key_agreement: None,
pin_auth: None,
@@ -992,7 +984,7 @@ mod test {
};
let error_code = Ctap2StatusCode::CTAP1_ERR_INVALID_PARAMETER;
assert_eq!(
pin_protocol_v1.process_subcommand(&mut rng, &mut persistent_store, client_pin_params),
client_pin.process_command(&mut rng, &mut persistent_store, client_pin_params),
Err(error_code)
);
}
@@ -1161,15 +1153,15 @@ mod test {
#[test]
fn test_has_permission() {
let mut rng = ThreadRng256 {};
let mut pin_protocol_v1 = PinProtocolV1::new(&mut rng);
pin_protocol_v1.permissions = 0x7F;
let mut client_pin = ClientPin::new(&mut rng);
client_pin.permissions = 0x7F;
for permission in PinPermission::into_enum_iter() {
assert_eq!(pin_protocol_v1.has_permission(permission), Ok(()));
assert_eq!(client_pin.has_permission(permission), Ok(()));
}
pin_protocol_v1.permissions = 0x00;
client_pin.permissions = 0x00;
for permission in PinPermission::into_enum_iter() {
assert_eq!(
pin_protocol_v1.has_permission(permission),
client_pin.has_permission(permission),
Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID)
);
}
@@ -1178,12 +1170,12 @@ mod test {
#[test]
fn test_has_no_rp_id_permission() {
let mut rng = ThreadRng256 {};
let mut pin_protocol_v1 = PinProtocolV1::new(&mut rng);
assert_eq!(pin_protocol_v1.has_no_rp_id_permission(), Ok(()));
assert_eq!(pin_protocol_v1.permissions_rp_id, None);
pin_protocol_v1.permissions_rp_id = Some("example.com".to_string());
let mut client_pin = ClientPin::new(&mut rng);
assert_eq!(client_pin.has_no_rp_id_permission(), Ok(()));
assert_eq!(client_pin.permissions_rp_id, None);
client_pin.permissions_rp_id = Some("example.com".to_string());
assert_eq!(
pin_protocol_v1.has_no_rp_id_permission(),
client_pin.has_no_rp_id_permission(),
Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID)
);
}
@@ -1191,19 +1183,13 @@ mod test {
#[test]
fn test_has_no_or_rp_id_permission() {
let mut rng = ThreadRng256 {};
let mut pin_protocol_v1 = PinProtocolV1::new(&mut rng);
let mut client_pin = ClientPin::new(&mut rng);
assert_eq!(client_pin.has_no_or_rp_id_permission("example.com"), Ok(()));
assert_eq!(client_pin.permissions_rp_id, None);
client_pin.permissions_rp_id = Some("example.com".to_string());
assert_eq!(client_pin.has_no_or_rp_id_permission("example.com"), Ok(()));
assert_eq!(
pin_protocol_v1.has_no_or_rp_id_permission("example.com"),
Ok(())
);
assert_eq!(pin_protocol_v1.permissions_rp_id, None);
pin_protocol_v1.permissions_rp_id = Some("example.com".to_string());
assert_eq!(
pin_protocol_v1.has_no_or_rp_id_permission("example.com"),
Ok(())
);
assert_eq!(
pin_protocol_v1.has_no_or_rp_id_permission("another.example.com"),
client_pin.has_no_or_rp_id_permission("another.example.com"),
Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID)
);
}
@@ -1211,20 +1197,20 @@ mod test {
#[test]
fn test_has_no_or_rp_id_hash_permission() {
let mut rng = ThreadRng256 {};
let mut pin_protocol_v1 = PinProtocolV1::new(&mut rng);
let mut client_pin = ClientPin::new(&mut rng);
let rp_id_hash = Sha256::hash(b"example.com");
assert_eq!(
pin_protocol_v1.has_no_or_rp_id_hash_permission(&rp_id_hash),
client_pin.has_no_or_rp_id_hash_permission(&rp_id_hash),
Ok(())
);
assert_eq!(pin_protocol_v1.permissions_rp_id, None);
pin_protocol_v1.permissions_rp_id = Some("example.com".to_string());
assert_eq!(client_pin.permissions_rp_id, None);
client_pin.permissions_rp_id = Some("example.com".to_string());
assert_eq!(
pin_protocol_v1.has_no_or_rp_id_hash_permission(&rp_id_hash),
client_pin.has_no_or_rp_id_hash_permission(&rp_id_hash),
Ok(())
);
assert_eq!(
pin_protocol_v1.has_no_or_rp_id_hash_permission(&[0x4A; 32]),
client_pin.has_no_or_rp_id_hash_permission(&[0x4A; 32]),
Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID)
);
}
@@ -1232,21 +1218,15 @@ mod test {
#[test]
fn test_ensure_rp_id_permission() {
let mut rng = ThreadRng256 {};
let mut pin_protocol_v1 = PinProtocolV1::new(&mut rng);
let mut client_pin = ClientPin::new(&mut rng);
assert_eq!(client_pin.ensure_rp_id_permission("example.com"), Ok(()));
assert_eq!(
pin_protocol_v1.ensure_rp_id_permission("example.com"),
Ok(())
);
assert_eq!(
pin_protocol_v1.permissions_rp_id,
client_pin.permissions_rp_id,
Some(String::from("example.com"))
);
assert_eq!(client_pin.ensure_rp_id_permission("example.com"), Ok(()));
assert_eq!(
pin_protocol_v1.ensure_rp_id_permission("example.com"),
Ok(())
);
assert_eq!(
pin_protocol_v1.ensure_rp_id_permission("counter-example.com"),
client_pin.ensure_rp_id_permission("counter-example.com"),
Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID)
);
}

View File

@@ -304,7 +304,7 @@ impl TryFrom<cbor::Value> for AuthenticatorGetAssertionParameters {
#[derive(Debug, PartialEq)]
pub struct AuthenticatorClientPinParameters {
pub pin_protocol: u64,
pub pin_uv_auth_protocol: u64,
pub sub_command: ClientPinSubCommand,
pub key_agreement: Option<CoseKey>,
pub pin_auth: Option<Vec<u8>>,
@@ -320,7 +320,7 @@ impl TryFrom<cbor::Value> for AuthenticatorClientPinParameters {
fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
destructure_cbor_map! {
let {
0x01 => pin_protocol,
0x01 => pin_uv_auth_protocol,
0x02 => sub_command,
0x03 => key_agreement,
0x04 => pin_auth,
@@ -331,7 +331,7 @@ impl TryFrom<cbor::Value> for AuthenticatorClientPinParameters {
} = extract_map(cbor_value)?;
}
let pin_protocol = extract_unsigned(ok_or_missing(pin_protocol)?)?;
let pin_uv_auth_protocol = extract_unsigned(ok_or_missing(pin_uv_auth_protocol)?)?;
let sub_command = ClientPinSubCommand::try_from(ok_or_missing(sub_command)?)?;
let key_agreement = key_agreement.map(CoseKey::try_from).transpose()?;
let pin_auth = pin_auth.map(extract_byte_string).transpose()?;
@@ -346,7 +346,7 @@ impl TryFrom<cbor::Value> for AuthenticatorClientPinParameters {
let permissions_rp_id = permissions_rp_id.map(extract_text_string).transpose()?;
Ok(AuthenticatorClientPinParameters {
pin_protocol,
pin_uv_auth_protocol,
sub_command,
key_agreement,
pin_auth,
@@ -506,7 +506,7 @@ impl TryFrom<cbor::Value> for AuthenticatorAttestationMaterial {
pub struct AuthenticatorCredentialManagementParameters {
pub sub_command: CredentialManagementSubCommand,
pub sub_command_params: Option<CredentialManagementSubCommandParameters>,
pub pin_protocol: Option<u64>,
pub pin_uv_auth_protocol: Option<u64>,
pub pin_auth: Option<Vec<u8>>,
}
@@ -518,7 +518,7 @@ impl TryFrom<cbor::Value> for AuthenticatorCredentialManagementParameters {
let {
0x01 => sub_command,
0x02 => sub_command_params,
0x03 => pin_protocol,
0x03 => pin_uv_auth_protocol,
0x04 => pin_auth,
} = extract_map(cbor_value)?;
}
@@ -527,13 +527,13 @@ impl TryFrom<cbor::Value> for AuthenticatorCredentialManagementParameters {
let sub_command_params = sub_command_params
.map(CredentialManagementSubCommandParameters::try_from)
.transpose()?;
let pin_protocol = pin_protocol.map(extract_unsigned).transpose()?;
let pin_uv_auth_protocol = pin_uv_auth_protocol.map(extract_unsigned).transpose()?;
let pin_auth = pin_auth.map(extract_byte_string).transpose()?;
Ok(AuthenticatorCredentialManagementParameters {
sub_command,
sub_command_params,
pin_protocol,
pin_uv_auth_protocol,
pin_auth,
})
}
@@ -706,7 +706,7 @@ mod test {
AuthenticatorClientPinParameters::try_from(cbor_value).unwrap();
let expected_client_pin_parameters = AuthenticatorClientPinParameters {
pin_protocol: 1,
pin_uv_auth_protocol: 1,
sub_command: ClientPinSubCommand::GetPinRetries,
key_agreement: Some(cose_key),
pin_auth: Some(vec![0xBB]),
@@ -765,7 +765,7 @@ mod test {
let expected_cred_management_parameters = AuthenticatorCredentialManagementParameters {
sub_command: CredentialManagementSubCommand::EnumerateCredentialsBegin,
sub_command_params: Some(params),
pin_protocol: Some(1),
pin_uv_auth_protocol: Some(1),
pin_auth: Some(vec![0x9A; 16]),
};

View File

@@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use super::client_pin::ClientPin;
use super::command::AuthenticatorConfigParameters;
use super::data_formats::{ConfigSubCommand, ConfigSubCommandParams, SetMinPinLengthParams};
use super::pin_protocol_v1::PinProtocolV1;
use super::response::ResponseData;
use super::status_code::Ctap2StatusCode;
use super::storage::PersistentStore;
@@ -76,7 +76,7 @@ fn process_set_min_pin_length(
/// Processes the AuthenticatorConfig command.
pub fn process_config(
persistent_store: &mut PersistentStore,
pin_protocol_v1: &mut PinProtocolV1,
client_pin: &mut ClientPin,
params: AuthenticatorConfigParameters,
) -> Result<ResponseData, Ctap2StatusCode> {
let AuthenticatorConfigParameters {
@@ -103,7 +103,7 @@ pub fn process_config(
return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR);
}
}
if !pin_protocol_v1.verify_pin_auth_token(&config_data, &auth_param) {
if !client_pin.verify_pin_auth_token(&config_data, &auth_param) {
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID);
}
}
@@ -136,7 +136,7 @@ mod test {
let mut persistent_store = PersistentStore::new(&mut rng);
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let mut pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let mut client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let config_params = AuthenticatorConfigParameters {
sub_command: ConfigSubCommand::EnableEnterpriseAttestation,
@@ -144,8 +144,7 @@ mod test {
pin_uv_auth_param: None,
pin_uv_auth_protocol: None,
};
let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
let config_response = process_config(&mut persistent_store, &mut client_pin, config_params);
if ENTERPRISE_ATTESTATION_MODE.is_some() {
assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig));
@@ -164,7 +163,7 @@ mod test {
let mut persistent_store = PersistentStore::new(&mut rng);
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let mut pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let mut client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let config_params = AuthenticatorConfigParameters {
sub_command: ConfigSubCommand::ToggleAlwaysUv,
@@ -172,8 +171,7 @@ mod test {
pin_uv_auth_param: None,
pin_uv_auth_protocol: None,
};
let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
let config_response = process_config(&mut persistent_store, &mut client_pin, config_params);
assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig));
assert!(persistent_store.has_always_uv().unwrap());
@@ -183,8 +181,7 @@ mod test {
pin_uv_auth_param: None,
pin_uv_auth_protocol: None,
};
let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
let config_response = process_config(&mut persistent_store, &mut client_pin, config_params);
if ENFORCE_ALWAYS_UV {
assert_eq!(
config_response,
@@ -202,7 +199,7 @@ mod test {
let mut persistent_store = PersistentStore::new(&mut rng);
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let mut pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let mut client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
persistent_store.set_pin(&[0x88; 16], 4).unwrap();
let pin_uv_auth_param = Some(vec![
@@ -215,8 +212,7 @@ mod test {
pin_uv_auth_param: pin_uv_auth_param.clone(),
pin_uv_auth_protocol: Some(1),
};
let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
let config_response = process_config(&mut persistent_store, &mut client_pin, config_params);
if ENFORCE_ALWAYS_UV {
assert_eq!(
config_response,
@@ -233,8 +229,7 @@ mod test {
pin_uv_auth_param,
pin_uv_auth_protocol: Some(1),
};
let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
let config_response = process_config(&mut persistent_store, &mut client_pin, config_params);
assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig));
assert!(!persistent_store.has_always_uv().unwrap());
}
@@ -264,13 +259,12 @@ mod test {
let mut persistent_store = PersistentStore::new(&mut rng);
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let mut pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let mut client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
// First, increase minimum PIN length from 4 to 6 without PIN auth.
let min_pin_length = 6;
let config_params = create_min_pin_config_params(min_pin_length, None);
let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
let config_response = process_config(&mut persistent_store, &mut client_pin, config_params);
assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig));
assert_eq!(persistent_store.min_pin_length(), Ok(min_pin_length));
@@ -284,8 +278,7 @@ mod test {
0xB2, 0xDE,
];
config_params.pin_uv_auth_param = Some(pin_auth);
let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
let config_response = process_config(&mut persistent_store, &mut client_pin, config_params);
assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig));
assert_eq!(persistent_store.min_pin_length(), Ok(min_pin_length));
@@ -296,8 +289,7 @@ mod test {
0xA7, 0x71,
];
config_params.pin_uv_auth_param = Some(pin_auth);
let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
let config_response = process_config(&mut persistent_store, &mut client_pin, config_params);
assert_eq!(
config_response,
Err(Ctap2StatusCode::CTAP2_ERR_PIN_POLICY_VIOLATION)
@@ -311,15 +303,14 @@ mod test {
let mut persistent_store = PersistentStore::new(&mut rng);
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let mut pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let mut client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
// First, set RP IDs without PIN auth.
let min_pin_length = 6;
let min_pin_length_rp_ids = vec!["example.com".to_string()];
let config_params =
create_min_pin_config_params(min_pin_length, Some(min_pin_length_rp_ids.clone()));
let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
let config_response = process_config(&mut persistent_store, &mut client_pin, config_params);
assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig));
assert_eq!(persistent_store.min_pin_length(), Ok(min_pin_length));
assert_eq!(
@@ -339,8 +330,7 @@ mod test {
0xD6, 0xDA,
];
config_params.pin_uv_auth_param = Some(pin_auth.clone());
let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
let config_response = process_config(&mut persistent_store, &mut client_pin, config_params);
assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig));
assert_eq!(persistent_store.min_pin_length(), Ok(min_pin_length));
assert_eq!(
@@ -353,8 +343,7 @@ mod test {
let mut config_params =
create_min_pin_config_params(9, Some(min_pin_length_rp_ids.clone()));
config_params.pin_uv_auth_param = Some(pin_auth.clone());
let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
let config_response = process_config(&mut persistent_store, &mut client_pin, config_params);
assert_eq!(
config_response,
Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID)
@@ -372,8 +361,7 @@ mod test {
Some(vec!["counter.example.com".to_string()]),
);
config_params.pin_uv_auth_param = Some(pin_auth);
let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
let config_response = process_config(&mut persistent_store, &mut client_pin, config_params);
assert_eq!(
config_response,
Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID)
@@ -391,7 +379,7 @@ mod test {
let mut persistent_store = PersistentStore::new(&mut rng);
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let mut pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let mut client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
persistent_store.set_pin(&[0x88; 16], 4).unwrap();
// Increase min PIN, force PIN change.
@@ -402,8 +390,7 @@ mod test {
0xA8, 0xC8,
]);
config_params.pin_uv_auth_param = pin_uv_auth_param;
let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
let config_response = process_config(&mut persistent_store, &mut client_pin, config_params);
assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig));
assert_eq!(persistent_store.min_pin_length(), Ok(min_pin_length));
assert_eq!(persistent_store.has_force_pin_change(), Ok(true));
@@ -415,7 +402,7 @@ mod test {
let mut persistent_store = PersistentStore::new(&mut rng);
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let mut pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let mut client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
persistent_store.set_pin(&[0x88; 16], 4).unwrap();
let pin_uv_auth_param = Some(vec![
@@ -435,8 +422,7 @@ mod test {
pin_uv_auth_param,
pin_uv_auth_protocol: Some(1),
};
let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
let config_response = process_config(&mut persistent_store, &mut client_pin, config_params);
assert_eq!(config_response, Ok(ResponseData::AuthenticatorConfig));
assert_eq!(persistent_store.has_force_pin_change(), Ok(true));
}
@@ -447,7 +433,7 @@ mod test {
let mut persistent_store = PersistentStore::new(&mut rng);
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let mut pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let mut client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let config_params = AuthenticatorConfigParameters {
sub_command: ConfigSubCommand::VendorPrototype,
@@ -455,8 +441,7 @@ mod test {
pin_uv_auth_param: None,
pin_uv_auth_protocol: None,
};
let config_response =
process_config(&mut persistent_store, &mut pin_protocol_v1, config_params);
let config_response = process_config(&mut persistent_store, &mut client_pin, config_params);
assert_eq!(
config_response,
Err(Ctap2StatusCode::CTAP1_ERR_INVALID_PARAMETER)

View File

@@ -12,13 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use super::client_pin::{ClientPin, PinPermission};
use super::command::AuthenticatorCredentialManagementParameters;
use super::data_formats::{
CoseKey, CredentialManagementSubCommand, CredentialManagementSubCommandParameters,
PublicKeyCredentialDescriptor, PublicKeyCredentialRpEntity, PublicKeyCredentialSource,
PublicKeyCredentialUserEntity,
};
use super::pin_protocol_v1::{PinPermission, PinProtocolV1};
use super::response::{AuthenticatorCredentialManagementResponse, ResponseData};
use super::status_code::Ctap2StatusCode;
use super::storage::PersistentStore;
@@ -110,15 +110,15 @@ fn enumerate_credentials_response(
/// Either no RP ID is associated, or the RP ID matches the stored credential.
fn check_rp_id_permissions(
persistent_store: &mut PersistentStore,
pin_protocol_v1: &mut PinProtocolV1,
client_pin: &mut ClientPin,
credential_id: &[u8],
) -> Result<(), Ctap2StatusCode> {
// Pre-check a sufficient condition before calling the store.
if pin_protocol_v1.has_no_rp_id_permission().is_ok() {
if client_pin.has_no_rp_id_permission().is_ok() {
return Ok(());
}
let (_, credential) = persistent_store.find_credential_item(credential_id)?;
pin_protocol_v1.has_no_or_rp_id_permission(&credential.rp_id)
client_pin.has_no_or_rp_id_permission(&credential.rp_id)
}
/// Processes the subcommand getCredsMetadata for CredentialManagement.
@@ -173,14 +173,14 @@ fn process_enumerate_rps_get_next_rp(
fn process_enumerate_credentials_begin(
persistent_store: &PersistentStore,
stateful_command_permission: &mut StatefulPermission,
pin_protocol_v1: &mut PinProtocolV1,
client_pin: &mut ClientPin,
sub_command_params: CredentialManagementSubCommandParameters,
now: ClockValue,
) -> Result<AuthenticatorCredentialManagementResponse, Ctap2StatusCode> {
let rp_id_hash = sub_command_params
.rp_id_hash
.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?;
pin_protocol_v1.has_no_or_rp_id_hash_permission(&rp_id_hash[..])?;
client_pin.has_no_or_rp_id_hash_permission(&rp_id_hash[..])?;
let mut iter_result = Ok(());
let iter = persistent_store.iter_credentials(&mut iter_result)?;
let mut rp_credentials: Vec<usize> = iter
@@ -219,21 +219,21 @@ fn process_enumerate_credentials_get_next_credential(
/// Processes the subcommand deleteCredential for CredentialManagement.
fn process_delete_credential(
persistent_store: &mut PersistentStore,
pin_protocol_v1: &mut PinProtocolV1,
client_pin: &mut ClientPin,
sub_command_params: CredentialManagementSubCommandParameters,
) -> Result<(), Ctap2StatusCode> {
let credential_id = sub_command_params
.credential_id
.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?
.key_id;
check_rp_id_permissions(persistent_store, pin_protocol_v1, &credential_id)?;
check_rp_id_permissions(persistent_store, client_pin, &credential_id)?;
persistent_store.delete_credential(&credential_id)
}
/// Processes the subcommand updateUserInformation for CredentialManagement.
fn process_update_user_information(
persistent_store: &mut PersistentStore,
pin_protocol_v1: &mut PinProtocolV1,
client_pin: &mut ClientPin,
sub_command_params: CredentialManagementSubCommandParameters,
) -> Result<(), Ctap2StatusCode> {
let credential_id = sub_command_params
@@ -243,7 +243,7 @@ fn process_update_user_information(
let user = sub_command_params
.user
.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?;
check_rp_id_permissions(persistent_store, pin_protocol_v1, &credential_id)?;
check_rp_id_permissions(persistent_store, client_pin, &credential_id)?;
persistent_store.update_credential(&credential_id, user)
}
@@ -251,14 +251,14 @@ fn process_update_user_information(
pub fn process_credential_management(
persistent_store: &mut PersistentStore,
stateful_command_permission: &mut StatefulPermission,
pin_protocol_v1: &mut PinProtocolV1,
client_pin: &mut ClientPin,
cred_management_params: AuthenticatorCredentialManagementParameters,
now: ClockValue,
) -> Result<ResponseData, Ctap2StatusCode> {
let AuthenticatorCredentialManagementParameters {
sub_command,
sub_command_params,
pin_protocol,
pin_uv_auth_protocol,
pin_auth,
} = cred_management_params;
@@ -282,7 +282,7 @@ pub fn process_credential_management(
| CredentialManagementSubCommand::EnumerateCredentialsBegin
| CredentialManagementSubCommand::DeleteCredential
| CredentialManagementSubCommand::UpdateUserInformation => {
check_pin_uv_auth_protocol(pin_protocol)?;
check_pin_uv_auth_protocol(pin_uv_auth_protocol)?;
let pin_auth = pin_auth.ok_or(Ctap2StatusCode::CTAP2_ERR_PUAT_REQUIRED)?;
let mut management_data = vec![sub_command as u8];
if let Some(sub_command_params) = sub_command_params.clone() {
@@ -290,11 +290,11 @@ pub fn process_credential_management(
return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR);
}
}
if !pin_protocol_v1.verify_pin_auth_token(&management_data, &pin_auth) {
if !client_pin.verify_pin_auth_token(&management_data, &pin_auth) {
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID);
}
// The RP ID permission is handled differently per subcommand below.
pin_protocol_v1.has_permission(PinPermission::CredentialManagement)?;
client_pin.has_permission(PinPermission::CredentialManagement)?;
}
CredentialManagementSubCommand::EnumerateRpsGetNextRp
| CredentialManagementSubCommand::EnumerateCredentialsGetNextCredential => {}
@@ -302,11 +302,11 @@ pub fn process_credential_management(
let response = match sub_command {
CredentialManagementSubCommand::GetCredsMetadata => {
pin_protocol_v1.has_no_rp_id_permission()?;
client_pin.has_no_rp_id_permission()?;
Some(process_get_creds_metadata(persistent_store)?)
}
CredentialManagementSubCommand::EnumerateRpsBegin => {
pin_protocol_v1.has_no_rp_id_permission()?;
client_pin.has_no_rp_id_permission()?;
Some(process_enumerate_rps_begin(
persistent_store,
stateful_command_permission,
@@ -320,7 +320,7 @@ pub fn process_credential_management(
Some(process_enumerate_credentials_begin(
persistent_store,
stateful_command_permission,
pin_protocol_v1,
client_pin,
sub_command_params.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?,
now,
)?)
@@ -334,7 +334,7 @@ pub fn process_credential_management(
CredentialManagementSubCommand::DeleteCredential => {
process_delete_credential(
persistent_store,
pin_protocol_v1,
client_pin,
sub_command_params.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?,
)?;
None
@@ -342,7 +342,7 @@ pub fn process_credential_management(
CredentialManagementSubCommand::UpdateUserInformation => {
process_update_user_information(
persistent_store,
pin_protocol_v1,
client_pin,
sub_command_params.ok_or(Ctap2StatusCode::CTAP2_ERR_MISSING_PARAMETER)?,
)?;
None
@@ -384,12 +384,12 @@ mod test {
let mut rng = ThreadRng256 {};
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let credential_source = create_credential_source(&mut rng);
let user_immediately_present = |_| Ok(());
let mut ctap_state = CtapState::new(&mut rng, user_immediately_present, DUMMY_CLOCK_VALUE);
ctap_state.pin_protocol_v1 = pin_protocol_v1;
ctap_state.client_pin = client_pin;
ctap_state.persistent_store.set_pin(&[0u8; 16], 4).unwrap();
let pin_auth = Some(vec![
@@ -400,13 +400,13 @@ mod test {
let cred_management_params = AuthenticatorCredentialManagementParameters {
sub_command: CredentialManagementSubCommand::GetCredsMetadata,
sub_command_params: None,
pin_protocol: Some(1),
pin_uv_auth_protocol: Some(1),
pin_auth: pin_auth.clone(),
};
let cred_management_response = process_credential_management(
&mut ctap_state.persistent_store,
&mut ctap_state.stateful_command_permission,
&mut ctap_state.pin_protocol_v1,
&mut ctap_state.client_pin,
cred_management_params,
DUMMY_CLOCK_VALUE,
);
@@ -428,13 +428,13 @@ mod test {
let cred_management_params = AuthenticatorCredentialManagementParameters {
sub_command: CredentialManagementSubCommand::GetCredsMetadata,
sub_command_params: None,
pin_protocol: Some(1),
pin_uv_auth_protocol: Some(1),
pin_auth,
};
let cred_management_response = process_credential_management(
&mut ctap_state.persistent_store,
&mut ctap_state.stateful_command_permission,
&mut ctap_state.pin_protocol_v1,
&mut ctap_state.client_pin,
cred_management_params,
DUMMY_CLOCK_VALUE,
);
@@ -455,14 +455,14 @@ mod test {
let mut rng = ThreadRng256 {};
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let credential_source1 = create_credential_source(&mut rng);
let mut credential_source2 = create_credential_source(&mut rng);
credential_source2.rp_id = "another.example.com".to_string();
let user_immediately_present = |_| Ok(());
let mut ctap_state = CtapState::new(&mut rng, user_immediately_present, DUMMY_CLOCK_VALUE);
ctap_state.pin_protocol_v1 = pin_protocol_v1;
ctap_state.client_pin = client_pin;
ctap_state
.persistent_store
@@ -482,13 +482,13 @@ mod test {
let cred_management_params = AuthenticatorCredentialManagementParameters {
sub_command: CredentialManagementSubCommand::EnumerateRpsBegin,
sub_command_params: None,
pin_protocol: Some(1),
pin_uv_auth_protocol: Some(1),
pin_auth,
};
let cred_management_response = process_credential_management(
&mut ctap_state.persistent_store,
&mut ctap_state.stateful_command_permission,
&mut ctap_state.pin_protocol_v1,
&mut ctap_state.client_pin,
cred_management_params,
DUMMY_CLOCK_VALUE,
);
@@ -506,13 +506,13 @@ mod test {
let cred_management_params = AuthenticatorCredentialManagementParameters {
sub_command: CredentialManagementSubCommand::EnumerateRpsGetNextRp,
sub_command_params: None,
pin_protocol: None,
pin_uv_auth_protocol: None,
pin_auth: None,
};
let cred_management_response = process_credential_management(
&mut ctap_state.persistent_store,
&mut ctap_state.stateful_command_permission,
&mut ctap_state.pin_protocol_v1,
&mut ctap_state.client_pin,
cred_management_params,
DUMMY_CLOCK_VALUE,
);
@@ -531,13 +531,13 @@ mod test {
let cred_management_params = AuthenticatorCredentialManagementParameters {
sub_command: CredentialManagementSubCommand::EnumerateRpsGetNextRp,
sub_command_params: None,
pin_protocol: None,
pin_uv_auth_protocol: None,
pin_auth: None,
};
let cred_management_response = process_credential_management(
&mut ctap_state.persistent_store,
&mut ctap_state.stateful_command_permission,
&mut ctap_state.pin_protocol_v1,
&mut ctap_state.client_pin,
cred_management_params,
DUMMY_CLOCK_VALUE,
);
@@ -552,12 +552,12 @@ mod test {
let mut rng = ThreadRng256 {};
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let credential_source = create_credential_source(&mut rng);
let user_immediately_present = |_| Ok(());
let mut ctap_state = CtapState::new(&mut rng, user_immediately_present, DUMMY_CLOCK_VALUE);
ctap_state.pin_protocol_v1 = pin_protocol_v1;
ctap_state.client_pin = client_pin;
const NUM_CREDENTIALS: usize = 20;
for i in 0..NUM_CREDENTIALS {
@@ -581,7 +581,7 @@ mod test {
let mut cred_management_params = AuthenticatorCredentialManagementParameters {
sub_command: CredentialManagementSubCommand::EnumerateRpsBegin,
sub_command_params: None,
pin_protocol: Some(1),
pin_uv_auth_protocol: Some(1),
pin_auth,
};
@@ -589,7 +589,7 @@ mod test {
let cred_management_response = process_credential_management(
&mut ctap_state.persistent_store,
&mut ctap_state.stateful_command_permission,
&mut ctap_state.pin_protocol_v1,
&mut ctap_state.client_pin,
cred_management_params,
DUMMY_CLOCK_VALUE,
);
@@ -611,7 +611,7 @@ mod test {
cred_management_params = AuthenticatorCredentialManagementParameters {
sub_command: CredentialManagementSubCommand::EnumerateRpsGetNextRp,
sub_command_params: None,
pin_protocol: None,
pin_uv_auth_protocol: None,
pin_auth: None,
};
}
@@ -619,7 +619,7 @@ mod test {
let cred_management_response = process_credential_management(
&mut ctap_state.persistent_store,
&mut ctap_state.stateful_command_permission,
&mut ctap_state.pin_protocol_v1,
&mut ctap_state.client_pin,
cred_management_params,
DUMMY_CLOCK_VALUE,
);
@@ -634,7 +634,7 @@ mod test {
let mut rng = ThreadRng256 {};
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let credential_source1 = create_credential_source(&mut rng);
let mut credential_source2 = create_credential_source(&mut rng);
credential_source2.user_handle = vec![0x02];
@@ -644,7 +644,7 @@ mod test {
let user_immediately_present = |_| Ok(());
let mut ctap_state = CtapState::new(&mut rng, user_immediately_present, DUMMY_CLOCK_VALUE);
ctap_state.pin_protocol_v1 = pin_protocol_v1;
ctap_state.client_pin = client_pin;
ctap_state
.persistent_store
@@ -671,13 +671,13 @@ mod test {
let cred_management_params = AuthenticatorCredentialManagementParameters {
sub_command: CredentialManagementSubCommand::EnumerateCredentialsBegin,
sub_command_params: Some(sub_command_params),
pin_protocol: Some(1),
pin_uv_auth_protocol: Some(1),
pin_auth,
};
let cred_management_response = process_credential_management(
&mut ctap_state.persistent_store,
&mut ctap_state.stateful_command_permission,
&mut ctap_state.pin_protocol_v1,
&mut ctap_state.client_pin,
cred_management_params,
DUMMY_CLOCK_VALUE,
);
@@ -694,13 +694,13 @@ mod test {
let cred_management_params = AuthenticatorCredentialManagementParameters {
sub_command: CredentialManagementSubCommand::EnumerateCredentialsGetNextCredential,
sub_command_params: None,
pin_protocol: None,
pin_uv_auth_protocol: None,
pin_auth: None,
};
let cred_management_response = process_credential_management(
&mut ctap_state.persistent_store,
&mut ctap_state.stateful_command_permission,
&mut ctap_state.pin_protocol_v1,
&mut ctap_state.client_pin,
cred_management_params,
DUMMY_CLOCK_VALUE,
);
@@ -718,13 +718,13 @@ mod test {
let cred_management_params = AuthenticatorCredentialManagementParameters {
sub_command: CredentialManagementSubCommand::EnumerateCredentialsGetNextCredential,
sub_command_params: None,
pin_protocol: None,
pin_uv_auth_protocol: None,
pin_auth: None,
};
let cred_management_response = process_credential_management(
&mut ctap_state.persistent_store,
&mut ctap_state.stateful_command_permission,
&mut ctap_state.pin_protocol_v1,
&mut ctap_state.client_pin,
cred_management_params,
DUMMY_CLOCK_VALUE,
);
@@ -739,13 +739,13 @@ mod test {
let mut rng = ThreadRng256 {};
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let mut credential_source = create_credential_source(&mut rng);
credential_source.credential_id = vec![0x1D; 32];
let user_immediately_present = |_| Ok(());
let mut ctap_state = CtapState::new(&mut rng, user_immediately_present, DUMMY_CLOCK_VALUE);
ctap_state.pin_protocol_v1 = pin_protocol_v1;
ctap_state.client_pin = client_pin;
ctap_state
.persistent_store
@@ -771,13 +771,13 @@ mod test {
let cred_management_params = AuthenticatorCredentialManagementParameters {
sub_command: CredentialManagementSubCommand::DeleteCredential,
sub_command_params: Some(sub_command_params.clone()),
pin_protocol: Some(1),
pin_uv_auth_protocol: Some(1),
pin_auth: pin_auth.clone(),
};
let cred_management_response = process_credential_management(
&mut ctap_state.persistent_store,
&mut ctap_state.stateful_command_permission,
&mut ctap_state.pin_protocol_v1,
&mut ctap_state.client_pin,
cred_management_params,
DUMMY_CLOCK_VALUE,
);
@@ -789,13 +789,13 @@ mod test {
let cred_management_params = AuthenticatorCredentialManagementParameters {
sub_command: CredentialManagementSubCommand::DeleteCredential,
sub_command_params: Some(sub_command_params),
pin_protocol: Some(1),
pin_uv_auth_protocol: Some(1),
pin_auth,
};
let cred_management_response = process_credential_management(
&mut ctap_state.persistent_store,
&mut ctap_state.stateful_command_permission,
&mut ctap_state.pin_protocol_v1,
&mut ctap_state.client_pin,
cred_management_params,
DUMMY_CLOCK_VALUE,
);
@@ -810,13 +810,13 @@ mod test {
let mut rng = ThreadRng256 {};
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let mut credential_source = create_credential_source(&mut rng);
credential_source.credential_id = vec![0x1D; 32];
let user_immediately_present = |_| Ok(());
let mut ctap_state = CtapState::new(&mut rng, user_immediately_present, DUMMY_CLOCK_VALUE);
ctap_state.pin_protocol_v1 = pin_protocol_v1;
ctap_state.client_pin = client_pin;
ctap_state
.persistent_store
@@ -848,13 +848,13 @@ mod test {
let cred_management_params = AuthenticatorCredentialManagementParameters {
sub_command: CredentialManagementSubCommand::UpdateUserInformation,
sub_command_params: Some(sub_command_params),
pin_protocol: Some(1),
pin_uv_auth_protocol: Some(1),
pin_auth,
};
let cred_management_response = process_credential_management(
&mut ctap_state.persistent_store,
&mut ctap_state.stateful_command_permission,
&mut ctap_state.pin_protocol_v1,
&mut ctap_state.client_pin,
cred_management_params,
DUMMY_CLOCK_VALUE,
);
@@ -878,15 +878,15 @@ mod test {
}
#[test]
fn test_process_credential_management_invalid_pin_protocol() {
fn test_process_credential_management_invalid_pin_uv_auth_protocol() {
let mut rng = ThreadRng256 {};
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let user_immediately_present = |_| Ok(());
let mut ctap_state = CtapState::new(&mut rng, user_immediately_present, DUMMY_CLOCK_VALUE);
ctap_state.pin_protocol_v1 = pin_protocol_v1;
ctap_state.client_pin = client_pin;
ctap_state.persistent_store.set_pin(&[0u8; 16], 4).unwrap();
let pin_auth = Some(vec![
@@ -897,13 +897,13 @@ mod test {
let cred_management_params = AuthenticatorCredentialManagementParameters {
sub_command: CredentialManagementSubCommand::GetCredsMetadata,
sub_command_params: None,
pin_protocol: Some(123456),
pin_uv_auth_protocol: Some(123456),
pin_auth,
};
let cred_management_response = process_credential_management(
&mut ctap_state.persistent_store,
&mut ctap_state.stateful_command_permission,
&mut ctap_state.pin_protocol_v1,
&mut ctap_state.client_pin,
cred_management_params,
DUMMY_CLOCK_VALUE,
);
@@ -924,13 +924,13 @@ mod test {
let cred_management_params = AuthenticatorCredentialManagementParameters {
sub_command: CredentialManagementSubCommand::GetCredsMetadata,
sub_command_params: None,
pin_protocol: Some(1),
pin_uv_auth_protocol: Some(1),
pin_auth: Some(vec![0u8; 16]),
};
let cred_management_response = process_credential_management(
&mut ctap_state.persistent_store,
&mut ctap_state.stateful_command_permission,
&mut ctap_state.pin_protocol_v1,
&mut ctap_state.client_pin,
cred_management_params,
DUMMY_CLOCK_VALUE,
);

View File

@@ -13,8 +13,8 @@
// limitations under the License.
use super::check_pin_uv_auth_protocol;
use super::client_pin::{ClientPin, PinPermission};
use super::command::AuthenticatorLargeBlobsParameters;
use super::pin_protocol_v1::{PinPermission, PinProtocolV1};
use super::response::{AuthenticatorLargeBlobsResponse, ResponseData};
use super::status_code::Ctap2StatusCode;
use super::storage::PersistentStore;
@@ -51,7 +51,7 @@ impl LargeBlobs {
pub fn process_command(
&mut self,
persistent_store: &mut PersistentStore,
pin_protocol_v1: &mut PinProtocolV1,
client_pin: &mut ClientPin,
large_blobs_params: AuthenticatorLargeBlobsParameters,
) -> Result<ResponseData, Ctap2StatusCode> {
let AuthenticatorLargeBlobsParameters {
@@ -94,14 +94,14 @@ impl LargeBlobs {
// TODO(kaczmarczyck) Error codes for PIN protocol differ across commands.
// Change to Ctap2StatusCode::CTAP2_ERR_PUAT_REQUIRED for None?
check_pin_uv_auth_protocol(pin_uv_auth_protocol)?;
pin_protocol_v1.has_permission(PinPermission::LargeBlobWrite)?;
client_pin.has_permission(PinPermission::LargeBlobWrite)?;
let mut message = vec![0xFF; 32];
message.extend(&[0x0C, 0x00]);
let mut offset_bytes = [0u8; 4];
LittleEndian::write_u32(&mut offset_bytes, offset as u32);
message.extend(&offset_bytes);
message.extend(&Sha256::hash(set.as_slice()));
if !pin_protocol_v1.verify_pin_auth_token(&message, &pin_uv_auth_param) {
if !client_pin.verify_pin_auth_token(&message, &pin_uv_auth_param) {
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID);
}
}
@@ -146,7 +146,7 @@ mod test {
let mut persistent_store = PersistentStore::new(&mut rng);
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let mut pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let mut client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let mut large_blobs = LargeBlobs::new();
let large_blob = vec![
@@ -161,11 +161,8 @@ mod test {
pin_uv_auth_param: None,
pin_uv_auth_protocol: None,
};
let large_blobs_response = large_blobs.process_command(
&mut persistent_store,
&mut pin_protocol_v1,
large_blobs_params,
);
let large_blobs_response =
large_blobs.process_command(&mut persistent_store, &mut client_pin, large_blobs_params);
match large_blobs_response.unwrap() {
ResponseData::AuthenticatorLargeBlobs(Some(response)) => {
assert_eq!(response.config, large_blob);
@@ -180,7 +177,7 @@ mod test {
let mut persistent_store = PersistentStore::new(&mut rng);
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let mut pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let mut client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let mut large_blobs = LargeBlobs::new();
const BLOB_LEN: usize = 200;
@@ -196,11 +193,8 @@ mod test {
pin_uv_auth_param: None,
pin_uv_auth_protocol: None,
};
let large_blobs_response = large_blobs.process_command(
&mut persistent_store,
&mut pin_protocol_v1,
large_blobs_params,
);
let large_blobs_response =
large_blobs.process_command(&mut persistent_store, &mut client_pin, large_blobs_params);
assert_eq!(
large_blobs_response,
Ok(ResponseData::AuthenticatorLargeBlobs(None))
@@ -214,11 +208,8 @@ mod test {
pin_uv_auth_param: None,
pin_uv_auth_protocol: None,
};
let large_blobs_response = large_blobs.process_command(
&mut persistent_store,
&mut pin_protocol_v1,
large_blobs_params,
);
let large_blobs_response =
large_blobs.process_command(&mut persistent_store, &mut client_pin, large_blobs_params);
assert_eq!(
large_blobs_response,
Ok(ResponseData::AuthenticatorLargeBlobs(None))
@@ -232,11 +223,8 @@ mod test {
pin_uv_auth_param: None,
pin_uv_auth_protocol: None,
};
let large_blobs_response = large_blobs.process_command(
&mut persistent_store,
&mut pin_protocol_v1,
large_blobs_params,
);
let large_blobs_response =
large_blobs.process_command(&mut persistent_store, &mut client_pin, large_blobs_params);
match large_blobs_response.unwrap() {
ResponseData::AuthenticatorLargeBlobs(Some(response)) => {
assert_eq!(response.config, large_blob);
@@ -251,7 +239,7 @@ mod test {
let mut persistent_store = PersistentStore::new(&mut rng);
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let mut pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let mut client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let mut large_blobs = LargeBlobs::new();
const BLOB_LEN: usize = 200;
@@ -267,11 +255,8 @@ mod test {
pin_uv_auth_param: None,
pin_uv_auth_protocol: None,
};
let large_blobs_response = large_blobs.process_command(
&mut persistent_store,
&mut pin_protocol_v1,
large_blobs_params,
);
let large_blobs_response =
large_blobs.process_command(&mut persistent_store, &mut client_pin, large_blobs_params);
assert_eq!(
large_blobs_response,
Ok(ResponseData::AuthenticatorLargeBlobs(None))
@@ -286,11 +271,8 @@ mod test {
pin_uv_auth_param: None,
pin_uv_auth_protocol: None,
};
let large_blobs_response = large_blobs.process_command(
&mut persistent_store,
&mut pin_protocol_v1,
large_blobs_params,
);
let large_blobs_response =
large_blobs.process_command(&mut persistent_store, &mut client_pin, large_blobs_params);
assert_eq!(
large_blobs_response,
Err(Ctap2StatusCode::CTAP1_ERR_INVALID_SEQ),
@@ -303,7 +285,7 @@ mod test {
let mut persistent_store = PersistentStore::new(&mut rng);
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let mut pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let mut client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let mut large_blobs = LargeBlobs::new();
const BLOB_LEN: usize = 200;
@@ -320,11 +302,8 @@ mod test {
pin_uv_auth_param: None,
pin_uv_auth_protocol: None,
};
let large_blobs_response = large_blobs.process_command(
&mut persistent_store,
&mut pin_protocol_v1,
large_blobs_params,
);
let large_blobs_response =
large_blobs.process_command(&mut persistent_store, &mut client_pin, large_blobs_params);
assert_eq!(
large_blobs_response,
Ok(ResponseData::AuthenticatorLargeBlobs(None))
@@ -338,11 +317,8 @@ mod test {
pin_uv_auth_param: None,
pin_uv_auth_protocol: None,
};
let large_blobs_response = large_blobs.process_command(
&mut persistent_store,
&mut pin_protocol_v1,
large_blobs_params,
);
let large_blobs_response =
large_blobs.process_command(&mut persistent_store, &mut client_pin, large_blobs_params);
assert_eq!(
large_blobs_response,
Err(Ctap2StatusCode::CTAP1_ERR_INVALID_PARAMETER),
@@ -355,7 +331,7 @@ mod test {
let mut persistent_store = PersistentStore::new(&mut rng);
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let mut pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let mut client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let mut large_blobs = LargeBlobs::new();
const BLOB_LEN: usize = 20;
@@ -370,11 +346,8 @@ mod test {
pin_uv_auth_param: None,
pin_uv_auth_protocol: None,
};
let large_blobs_response = large_blobs.process_command(
&mut persistent_store,
&mut pin_protocol_v1,
large_blobs_params,
);
let large_blobs_response =
large_blobs.process_command(&mut persistent_store, &mut client_pin, large_blobs_params);
assert_eq!(
large_blobs_response,
Err(Ctap2StatusCode::CTAP2_ERR_INTEGRITY_FAILURE),
@@ -387,7 +360,7 @@ mod test {
let mut persistent_store = PersistentStore::new(&mut rng);
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x55; 32];
let mut pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let mut client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let mut large_blobs = LargeBlobs::new();
const BLOB_LEN: usize = 20;
@@ -409,11 +382,8 @@ mod test {
pin_uv_auth_param,
pin_uv_auth_protocol: Some(1),
};
let large_blobs_response = large_blobs.process_command(
&mut persistent_store,
&mut pin_protocol_v1,
large_blobs_params,
);
let large_blobs_response =
large_blobs.process_command(&mut persistent_store, &mut client_pin, large_blobs_params);
assert_eq!(
large_blobs_response,
Ok(ResponseData::AuthenticatorLargeBlobs(None))

View File

@@ -13,6 +13,7 @@
// limitations under the License.
pub mod apdu;
mod client_pin;
pub mod command;
mod config_command;
mod credential_management;
@@ -23,15 +24,15 @@ pub mod data_formats;
pub mod hid;
mod key_material;
mod large_blobs;
mod pin_protocol_v1;
pub mod response;
pub mod status_code;
mod storage;
mod timed_permission;
use self::client_pin::{ClientPin, PinPermission};
use self::command::{
AuthenticatorClientPinParameters, AuthenticatorGetAssertionParameters,
AuthenticatorMakeCredentialParameters, AuthenticatorVendorConfigureParameters, Command,
AuthenticatorGetAssertionParameters, AuthenticatorMakeCredentialParameters,
AuthenticatorVendorConfigureParameters, Command,
};
use self::config_command::process_config;
use self::credential_management::process_credential_management;
@@ -48,7 +49,6 @@ use self::data_formats::{
};
use self::hid::ChannelID;
use self::large_blobs::{LargeBlobs, MAX_MSG_SIZE};
use self::pin_protocol_v1::{PinPermission, PinProtocolV1};
use self::response::{
AuthenticatorGetAssertionResponse, AuthenticatorGetInfoResponse,
AuthenticatorMakeCredentialResponse, AuthenticatorVendorResponse, ResponseData,
@@ -278,7 +278,7 @@ pub struct CtapState<'a, R: Rng256, CheckUserPresence: Fn(ChannelID) -> Result<(
// false otherwise.
check_user_presence: CheckUserPresence,
persistent_store: PersistentStore,
pin_protocol_v1: PinProtocolV1,
client_pin: ClientPin,
#[cfg(feature = "with_ctap1")]
pub u2f_up_state: U2fUserPresenceState,
// The state initializes to Reset and its timeout, and never goes back to Reset.
@@ -297,12 +297,12 @@ where
now: ClockValue,
) -> CtapState<'a, R, CheckUserPresence> {
let persistent_store = PersistentStore::new(rng);
let pin_protocol_v1 = PinProtocolV1::new(rng);
let client_pin = ClientPin::new(rng);
CtapState {
rng,
check_user_presence,
persistent_store,
pin_protocol_v1,
client_pin,
#[cfg(feature = "with_ctap1")]
u2f_up_state: U2fUserPresenceState::new(
U2F_UP_PROMPT_TIMEOUT,
@@ -473,13 +473,17 @@ where
}
Command::AuthenticatorGetNextAssertion => self.process_get_next_assertion(now),
Command::AuthenticatorGetInfo => self.process_get_info(),
Command::AuthenticatorClientPin(params) => self.process_client_pin(params),
Command::AuthenticatorClientPin(params) => self.client_pin.process_command(
self.rng,
&mut self.persistent_store,
params,
),
Command::AuthenticatorReset => self.process_reset(cid, now),
Command::AuthenticatorCredentialManagement(params) => {
process_credential_management(
&mut self.persistent_store,
&mut self.stateful_command_permission,
&mut self.pin_protocol_v1,
&mut self.client_pin,
params,
now,
)
@@ -487,14 +491,12 @@ where
Command::AuthenticatorSelection => self.process_selection(cid),
Command::AuthenticatorLargeBlobs(params) => self.large_blobs.process_command(
&mut self.persistent_store,
&mut self.pin_protocol_v1,
params,
),
Command::AuthenticatorConfig(params) => process_config(
&mut self.persistent_store,
&mut self.pin_protocol_v1,
&mut self.client_pin,
params,
),
Command::AuthenticatorConfig(params) => {
process_config(&mut self.persistent_store, &mut self.client_pin, params)
}
// Vendor specific commands
Command::AuthenticatorVendorConfigure(params) => {
self.process_vendor_configure(params, cid)
@@ -647,14 +649,14 @@ where
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_NOT_SET);
}
if !self
.pin_protocol_v1
.client_pin
.verify_pin_auth_token(&client_data_hash, &pin_auth)
{
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID);
}
self.pin_protocol_v1
self.client_pin
.has_permission(PinPermission::MakeCredential)?;
self.pin_protocol_v1.ensure_rp_id_permission(&rp_id)?;
self.client_pin.ensure_rp_id_permission(&rp_id)?;
UP_FLAG | UV_FLAG | AT_FLAG | ed_flag
}
None => {
@@ -815,7 +817,7 @@ where
let encrypted_output = if let Some(hmac_secret_input) = extensions.hmac_secret {
let cred_random = self.generate_cred_random(&credential.private_key, has_uv)?;
Some(
self.pin_protocol_v1
self.client_pin
.process_hmac_secret(hmac_secret_input, &cred_random)?,
)
} else {
@@ -938,14 +940,14 @@ where
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_NOT_SET);
}
if !self
.pin_protocol_v1
.client_pin
.verify_pin_auth_token(&client_data_hash, &pin_auth)
{
return Err(Ctap2StatusCode::CTAP2_ERR_PIN_AUTH_INVALID);
}
self.pin_protocol_v1
self.client_pin
.has_permission(PinPermission::GetAssertion)?;
self.pin_protocol_v1.ensure_rp_id_permission(&rp_id)?;
self.client_pin.ensure_rp_id_permission(&rp_id)?;
UV_FLAG
}
None => {
@@ -1104,17 +1106,6 @@ where
))
}
fn process_client_pin(
&mut self,
client_pin_params: AuthenticatorClientPinParameters,
) -> Result<ResponseData, Ctap2StatusCode> {
self.pin_protocol_v1.process_subcommand(
self.rng,
&mut self.persistent_store,
client_pin_params,
)
}
fn process_reset(
&mut self,
cid: ChannelID,
@@ -1129,7 +1120,7 @@ where
(self.check_user_presence)(cid)?;
self.persistent_store.reset(self.rng)?;
self.pin_protocol_v1.reset(self.rng);
self.client_pin.reset(self.rng);
#[cfg(feature = "with_ctap1")]
{
self.u2f_up_state = U2fUserPresenceState::new(
@@ -2332,11 +2323,11 @@ mod test {
let mut rng = ThreadRng256 {};
let key_agreement_key = crypto::ecdh::SecKey::gensk(&mut rng);
let pin_uv_auth_token = [0x88; 32];
let pin_protocol_v1 = PinProtocolV1::new_test(key_agreement_key, pin_uv_auth_token);
let client_pin = ClientPin::new_test(key_agreement_key, pin_uv_auth_token);
let user_immediately_present = |_| Ok(());
let mut ctap_state = CtapState::new(&mut rng, user_immediately_present, DUMMY_CLOCK_VALUE);
ctap_state.pin_protocol_v1 = pin_protocol_v1;
ctap_state.client_pin = client_pin;
let mut make_credential_params = create_minimal_make_credential_parameters();
let user1 = PublicKeyCredentialUserEntity {

View File

@@ -14,6 +14,7 @@
mod key;
use crate::ctap::client_pin::PIN_AUTH_LENGTH;
use crate::ctap::customization::{
DEFAULT_MIN_PIN_LENGTH, DEFAULT_MIN_PIN_LENGTH_RP_IDS, ENFORCE_ALWAYS_UV,
MAX_LARGE_BLOB_ARRAY_SIZE, MAX_PIN_RETRIES, MAX_RP_IDS_LENGTH, MAX_SUPPORTED_RESIDENT_KEYS,
@@ -24,7 +25,6 @@ use crate::ctap::data_formats::{
PublicKeyCredentialUserEntity,
};
use crate::ctap::key_material;
use crate::ctap::pin_protocol_v1::PIN_AUTH_LENGTH;
use crate::ctap::status_code::Ctap2StatusCode;
use crate::ctap::INITIAL_SIGNATURE_COUNTER;
use crate::embedded_flash::{new_storage, Storage};