Commit 31474e8b authored by Jun Choi's avatar Jun Choi Committed by Commit Bot

Implement ConvertTou2fCheckOnlySignCommand()

Implement function to extract U2F check only sign command from
CtapMakeCredentialRequest. This is used to iterate through key handles
in the exclude list to prevent duplicate registration.

Bug: 798573
Change-Id: I51ab3dc21c6a7229e99dd513dae4ec9322014a75
Reviewed-on: https://chromium-review.googlesource.com/1032257Reviewed-by: default avatarJan Wilken Dörrie <jdoerrie@chromium.org>
Commit-Queue: Jun Choi <hongjunchoi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#555863}
parent 49c90a4a
...@@ -44,6 +44,17 @@ base::Optional<std::vector<uint8_t>> ConvertToU2fRegisterCommand( ...@@ -44,6 +44,17 @@ base::Optional<std::vector<uint8_t>> ConvertToU2fRegisterCommand(
request.client_data_hash()); request.client_data_hash());
} }
base::Optional<std::vector<uint8_t>> ConvertToU2fCheckOnlySignCommand(
const CtapMakeCredentialRequest& request,
const PublicKeyCredentialDescriptor& key_handle) {
if (key_handle.credential_type() != kPublicKey)
return base::nullopt;
return ConstructU2fSignCommand(
fido_parsing_utils::CreateSHA256Hash(request.rp().rp_id()),
request.client_data_hash(), key_handle.id(), true /* check_only */);
}
base::Optional<std::vector<uint8_t>> ConvertToU2fSignCommand( base::Optional<std::vector<uint8_t>> ConvertToU2fSignCommand(
const CtapGetAssertionRequest& request, const CtapGetAssertionRequest& request,
ApplicationParameterType application_parameter_type, ApplicationParameterType application_parameter_type,
......
...@@ -38,6 +38,14 @@ COMPONENT_EXPORT(DEVICE_FIDO) ...@@ -38,6 +38,14 @@ COMPONENT_EXPORT(DEVICE_FIDO)
base::Optional<std::vector<uint8_t>> ConvertToU2fRegisterCommand( base::Optional<std::vector<uint8_t>> ConvertToU2fRegisterCommand(
const CtapMakeCredentialRequest& request); const CtapMakeCredentialRequest& request);
// Extracts APDU encoded U2F check only sign command from
// CtapMakeCredentialRequest. Invoked when U2F register operation includes key
// handles in exclude list.
COMPONENT_EXPORT(DEVICE_FIDO)
base::Optional<std::vector<uint8_t>> ConvertToU2fCheckOnlySignCommand(
const CtapMakeCredentialRequest& request,
const PublicKeyCredentialDescriptor& key_handle);
// Extracts APDU encoded U2F sign command from CtapGetAssertionRequest. // Extracts APDU encoded U2F sign command from CtapGetAssertionRequest.
COMPONENT_EXPORT(DEVICE_FIDO) COMPONENT_EXPORT(DEVICE_FIDO)
base::Optional<std::vector<uint8_t>> ConvertToU2fSignCommand( base::Optional<std::vector<uint8_t>> ConvertToU2fSignCommand(
......
...@@ -16,6 +16,32 @@ ...@@ -16,6 +16,32 @@
namespace device { namespace device {
namespace {
CtapMakeCredentialRequest ConstructMakeCredentialRequest() {
PublicKeyCredentialRpEntity rp("acme.com");
rp.SetRpName("acme.com");
PublicKeyCredentialUserEntity user(
fido_parsing_utils::Materialize(test_data::kUserId));
user.SetUserName("johnpsmith@example.com")
.SetDisplayName("John P. Smith")
.SetIconUrl(GURL("https://pics.acme.com/00/p/aBjjjpqPb.png"));
return CtapMakeCredentialRequest(
fido_parsing_utils::Materialize(test_data::kClientDataHash),
std::move(rp), std::move(user),
PublicKeyCredentialParams(PublicKeyCredentialParams(
std::vector<PublicKeyCredentialParams::CredentialInfo>(1))));
}
CtapGetAssertionRequest ConstructGetAssertionRequest() {
return CtapGetAssertionRequest(
"acme.com", fido_parsing_utils::Materialize(test_data::kClientDataHash));
}
} // namespace
TEST(U2fCommandConstructorTest, TestCreateU2fRegisterCommand) { TEST(U2fCommandConstructorTest, TestCreateU2fRegisterCommand) {
const auto& register_command_without_individual_attestation = const auto& register_command_without_individual_attestation =
ConstructU2fRegisterCommand(test_data::kApplicationParameter, ConstructU2fRegisterCommand(test_data::kApplicationParameter,
...@@ -78,20 +104,7 @@ TEST(U2fCommandConstructorTest, TestCreateRegisterWithIncorrectParameters) { ...@@ -78,20 +104,7 @@ TEST(U2fCommandConstructorTest, TestCreateRegisterWithIncorrectParameters) {
} }
TEST(U2fCommandConstructorTest, TestConvertCtapMakeCredentialToU2fRegister) { TEST(U2fCommandConstructorTest, TestConvertCtapMakeCredentialToU2fRegister) {
PublicKeyCredentialRpEntity rp("acme.com"); const auto make_credential_param = ConstructMakeCredentialRequest();
rp.SetRpName("acme.com");
PublicKeyCredentialUserEntity user(
fido_parsing_utils::Materialize(test_data::kUserId));
user.SetUserName("johnpsmith@example.com")
.SetDisplayName("John P. Smith")
.SetIconUrl(GURL("https://pics.acme.com/00/p/aBjjjpqPb.png"));
CtapMakeCredentialRequest make_credential_param(
fido_parsing_utils::Materialize(test_data::kClientDataHash),
std::move(rp), std::move(user),
PublicKeyCredentialParams({{CredentialType::kPublicKey, -7},
{CredentialType::kPublicKey, -257}}));
EXPECT_TRUE(IsConvertibleToU2fRegisterCommand(make_credential_param)); EXPECT_TRUE(IsConvertibleToU2fRegisterCommand(make_credential_param));
...@@ -102,6 +115,43 @@ TEST(U2fCommandConstructorTest, TestConvertCtapMakeCredentialToU2fRegister) { ...@@ -102,6 +115,43 @@ TEST(U2fCommandConstructorTest, TestConvertCtapMakeCredentialToU2fRegister) {
::testing::ElementsAreArray(test_data::kU2fRegisterCommandApdu)); ::testing::ElementsAreArray(test_data::kU2fRegisterCommandApdu));
} }
TEST(U2fCommandConstructorTest,
TestConvertCtapMakeCredentialToU2fCheckOnlySign) {
auto make_credential_param = ConstructMakeCredentialRequest();
PublicKeyCredentialDescriptor credential_descriptor(
kPublicKey,
fido_parsing_utils::Materialize(test_data::kU2fSignKeyHandle));
std::vector<PublicKeyCredentialDescriptor> exclude_list;
exclude_list.push_back(credential_descriptor);
make_credential_param.SetExcludeList(std::move(exclude_list));
EXPECT_TRUE(IsConvertibleToU2fRegisterCommand(make_credential_param));
const auto u2f_check_only_sign = ConvertToU2fCheckOnlySignCommand(
make_credential_param, credential_descriptor);
ASSERT_TRUE(u2f_check_only_sign);
EXPECT_THAT(
*u2f_check_only_sign,
::testing::ElementsAreArray(test_data::kU2fCheckOnlySignCommandApdu));
}
TEST(U2fCommandConstructorTest,
TestConvertCtapMakeCredentialToU2fCheckOnlySignWithInvalidCredentialType) {
auto make_credential_param = ConstructMakeCredentialRequest();
PublicKeyCredentialDescriptor credential_descriptor(
"UnknownCredentialType",
fido_parsing_utils::Materialize(test_data::kU2fSignKeyHandle));
std::vector<PublicKeyCredentialDescriptor> exclude_list;
exclude_list.push_back(credential_descriptor);
make_credential_param.SetExcludeList(std::move(exclude_list));
EXPECT_TRUE(IsConvertibleToU2fRegisterCommand(make_credential_param));
const auto u2f_check_only_sign = ConvertToU2fCheckOnlySignCommand(
make_credential_param, credential_descriptor);
EXPECT_FALSE(u2f_check_only_sign);
}
TEST(U2fCommandConstructorTest, TestU2fRegisterCredentialAlgorithmRequirement) { TEST(U2fCommandConstructorTest, TestU2fRegisterCredentialAlgorithmRequirement) {
PublicKeyCredentialRpEntity rp("acme.com"); PublicKeyCredentialRpEntity rp("acme.com");
rp.SetRpName("acme.com"); rp.SetRpName("acme.com");
...@@ -121,38 +171,14 @@ TEST(U2fCommandConstructorTest, TestU2fRegisterCredentialAlgorithmRequirement) { ...@@ -121,38 +171,14 @@ TEST(U2fCommandConstructorTest, TestU2fRegisterCredentialAlgorithmRequirement) {
} }
TEST(U2fCommandConstructorTest, TestU2fRegisterUserVerificationRequirement) { TEST(U2fCommandConstructorTest, TestU2fRegisterUserVerificationRequirement) {
PublicKeyCredentialRpEntity rp("acme.com"); auto make_credential_param = ConstructMakeCredentialRequest();
rp.SetRpName("acme.com");
PublicKeyCredentialUserEntity user(
fido_parsing_utils::Materialize(test_data::kUserId));
user.SetUserName("johnpsmith@example.com")
.SetDisplayName("John P. Smith")
.SetIconUrl(GURL("https://pics.acme.com/00/p/aBjjjpqPb.png"));
CtapMakeCredentialRequest make_credential_param(
fido_parsing_utils::Materialize(test_data::kClientDataHash),
std::move(rp), std::move(user),
PublicKeyCredentialParams({{CredentialType::kPublicKey, -7}}));
make_credential_param.SetUserVerificationRequired(true); make_credential_param.SetUserVerificationRequired(true);
EXPECT_FALSE(IsConvertibleToU2fRegisterCommand(make_credential_param)); EXPECT_FALSE(IsConvertibleToU2fRegisterCommand(make_credential_param));
} }
TEST(U2fCommandConstructorTest, TestU2fRegisterResidentKeyRequirement) { TEST(U2fCommandConstructorTest, TestU2fRegisterResidentKeyRequirement) {
PublicKeyCredentialRpEntity rp("acme.com"); auto make_credential_param = ConstructMakeCredentialRequest();
rp.SetRpName("acme.com");
PublicKeyCredentialUserEntity user(
fido_parsing_utils::Materialize(test_data::kUserId));
user.SetUserName("johnpsmith@example.com")
.SetDisplayName("John P. Smith")
.SetIconUrl(GURL("https://pics.acme.com/00/p/aBjjjpqPb.png"));
CtapMakeCredentialRequest make_credential_param(
fido_parsing_utils::Materialize(test_data::kClientDataHash),
std::move(rp), std::move(user),
PublicKeyCredentialParams({{CredentialType::kPublicKey, -7}}));
make_credential_param.SetResidentKeySupported(true); make_credential_param.SetResidentKeySupported(true);
EXPECT_FALSE(IsConvertibleToU2fRegisterCommand(make_credential_param)); EXPECT_FALSE(IsConvertibleToU2fRegisterCommand(make_credential_param));
...@@ -176,8 +202,7 @@ TEST(U2fCommandConstructorTest, TestCreateSignApduCommand) { ...@@ -176,8 +202,7 @@ TEST(U2fCommandConstructorTest, TestCreateSignApduCommand) {
} }
TEST(U2fCommandConstructorTest, TestConvertCtapGetAssertionToU2fSignRequest) { TEST(U2fCommandConstructorTest, TestConvertCtapGetAssertionToU2fSignRequest) {
CtapGetAssertionRequest get_assertion_req( auto get_assertion_req = ConstructGetAssertionRequest();
"acme.com", fido_parsing_utils::Materialize(test_data::kClientDataHash));
std::vector<PublicKeyCredentialDescriptor> allowed_list; std::vector<PublicKeyCredentialDescriptor> allowed_list;
allowed_list.push_back(PublicKeyCredentialDescriptor( allowed_list.push_back(PublicKeyCredentialDescriptor(
kPublicKey, kPublicKey,
...@@ -195,15 +220,12 @@ TEST(U2fCommandConstructorTest, TestConvertCtapGetAssertionToU2fSignRequest) { ...@@ -195,15 +220,12 @@ TEST(U2fCommandConstructorTest, TestConvertCtapGetAssertionToU2fSignRequest) {
} }
TEST(U2fCommandConstructorTest, TestU2fSignAllowListRequirement) { TEST(U2fCommandConstructorTest, TestU2fSignAllowListRequirement) {
CtapGetAssertionRequest get_assertion_req( auto get_assertion_req = ConstructGetAssertionRequest();
"acme.com", fido_parsing_utils::Materialize(test_data::kClientDataHash));
EXPECT_FALSE(IsConvertibleToU2fSignCommand(get_assertion_req)); EXPECT_FALSE(IsConvertibleToU2fSignCommand(get_assertion_req));
} }
TEST(U2fCommandConstructorTest, TestU2fSignUserVerificationRequirement) { TEST(U2fCommandConstructorTest, TestU2fSignUserVerificationRequirement) {
CtapGetAssertionRequest get_assertion_req( auto get_assertion_req = ConstructGetAssertionRequest();
"acme.com", fido_parsing_utils::Materialize(test_data::kClientDataHash));
std::vector<PublicKeyCredentialDescriptor> allowed_list; std::vector<PublicKeyCredentialDescriptor> allowed_list;
allowed_list.push_back(PublicKeyCredentialDescriptor( allowed_list.push_back(PublicKeyCredentialDescriptor(
kPublicKey, kPublicKey,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment