Commit 2d2ea265 authored by Martin Kreichgauer's avatar Martin Kreichgauer Committed by Commit Bot

fido: make PublicKeyCredentialRpEntity a struct

This aligns it with e.g. PublicKeyCredentialUserEntity.

Change-Id: I907d97d03e529eb44fcc14e9cf5ce0cd9ab77f27
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1610656Reviewed-by: default avatarNina Satragno <nsatragno@chromium.org>
Reviewed-by: default avatarChris Palmer <palmer@chromium.org>
Commit-Queue: Martin Kreichgauer <martinkr@google.com>
Cr-Commit-Position: refs/heads/master@{#661129}
parent 0894cf89
...@@ -168,10 +168,10 @@ TypeConverter<::device::PublicKeyCredentialRpEntity, ...@@ -168,10 +168,10 @@ TypeConverter<::device::PublicKeyCredentialRpEntity,
PublicKeyCredentialRpEntityPtr>:: PublicKeyCredentialRpEntityPtr>::
Convert(const PublicKeyCredentialRpEntityPtr& input) { Convert(const PublicKeyCredentialRpEntityPtr& input) {
device::PublicKeyCredentialRpEntity rp_entity(input->id); device::PublicKeyCredentialRpEntity rp_entity(input->id);
rp_entity.SetRpName(input->name); rp_entity.name = input->name;
if (input->icon) if (input->icon) {
rp_entity.SetRpIconUrl(*input->icon); rp_entity.icon_url = input->icon;
}
return rp_entity; return rp_entity;
} }
......
...@@ -47,7 +47,8 @@ CtapMakeCredentialRequest::EncodeAsCBOR( ...@@ -47,7 +47,8 @@ CtapMakeCredentialRequest::EncodeAsCBOR(
const CtapMakeCredentialRequest& request) { const CtapMakeCredentialRequest& request) {
cbor::Value::MapValue cbor_map; cbor::Value::MapValue cbor_map;
cbor_map[cbor::Value(1)] = cbor::Value(request.client_data_hash); cbor_map[cbor::Value(1)] = cbor::Value(request.client_data_hash);
cbor_map[cbor::Value(2)] = request.rp.ConvertToCBOR(); cbor_map[cbor::Value(2)] =
PublicKeyCredentialRpEntity::ConvertToCBOR(request.rp);
cbor_map[cbor::Value(3)] = cbor_map[cbor::Value(3)] =
PublicKeyCredentialUserEntity::ConvertToCBOR(request.user); PublicKeyCredentialUserEntity::ConvertToCBOR(request.user);
cbor_map[cbor::Value(4)] = cbor_map[cbor::Value(4)] =
......
...@@ -20,7 +20,7 @@ namespace device { ...@@ -20,7 +20,7 @@ namespace device {
// https://fidoalliance.org/specs/fido-v2.0-rd-20170927/fido-client-to-authenticator-protocol-v2.0-rd-20170927.html // https://fidoalliance.org/specs/fido-v2.0-rd-20170927/fido-client-to-authenticator-protocol-v2.0-rd-20170927.html
TEST(CTAPRequestTest, TestConstructMakeCredentialRequestParam) { TEST(CTAPRequestTest, TestConstructMakeCredentialRequestParam) {
PublicKeyCredentialRpEntity rp("acme.com"); PublicKeyCredentialRpEntity rp("acme.com");
rp.SetRpName("Acme"); rp.name = "Acme";
PublicKeyCredentialUserEntity user( PublicKeyCredentialUserEntity user(
fido_parsing_utils::Materialize(test_data::kUserId)); fido_parsing_utils::Materialize(test_data::kUserId));
...@@ -98,8 +98,8 @@ TEST(VirtualCtap2DeviceTest, ParseMakeCredentialRequestForVirtualCtapKey) { ...@@ -98,8 +98,8 @@ TEST(VirtualCtap2DeviceTest, ParseMakeCredentialRequestForVirtualCtapKey) {
auto client_data_hash = std::get<1>(*request_and_hash); auto client_data_hash = std::get<1>(*request_and_hash);
EXPECT_THAT(client_data_hash, EXPECT_THAT(client_data_hash,
::testing::ElementsAreArray(test_data::kClientDataHash)); ::testing::ElementsAreArray(test_data::kClientDataHash));
EXPECT_EQ(test_data::kRelyingPartyId, request.rp.rp_id()); EXPECT_EQ(test_data::kRelyingPartyId, request.rp.id);
EXPECT_EQ("Acme", request.rp.rp_name()); EXPECT_EQ("Acme", request.rp.name);
EXPECT_THAT(request.user.id, ::testing::ElementsAreArray(test_data::kUserId)); EXPECT_THAT(request.user.id, ::testing::ElementsAreArray(test_data::kUserId));
ASSERT_TRUE(request.user.name); ASSERT_TRUE(request.user.name);
EXPECT_EQ("johnpsmith@example.com", *request.user.name); EXPECT_EQ("johnpsmith@example.com", *request.user.name);
......
...@@ -45,7 +45,7 @@ MakeCredentialOperation::MakeCredentialOperation( ...@@ -45,7 +45,7 @@ MakeCredentialOperation::MakeCredentialOperation(
MakeCredentialOperation::~MakeCredentialOperation() = default; MakeCredentialOperation::~MakeCredentialOperation() = default;
const std::string& MakeCredentialOperation::RpId() const { const std::string& MakeCredentialOperation::RpId() const {
return request().rp.rp_id(); return request().rp.id;
} }
void MakeCredentialOperation::Run() { void MakeCredentialOperation::Run() {
......
...@@ -340,8 +340,7 @@ void MakeCredentialRequestHandler::HandleResponse( ...@@ -340,8 +340,7 @@ void MakeCredentialRequestHandler::HandleResponse(
return; return;
} }
const auto rp_id_hash = const auto rp_id_hash = fido_parsing_utils::CreateSHA256Hash(request_.rp.id);
fido_parsing_utils::CreateSHA256Hash(request_.rp.rp_id());
if (!response || response->GetRpIdHash() != rp_id_hash) { if (!response || response->GetRpIdHash() != rp_id_hash) {
FIDO_LOG(ERROR) << "Failing assertion request due to bad response from " FIDO_LOG(ERROR) << "Failing assertion request due to bad response from "
......
...@@ -125,7 +125,7 @@ void MakeCredentialTask::StartTask() { ...@@ -125,7 +125,7 @@ void MakeCredentialTask::StartTask() {
CtapGetAssertionRequest MakeCredentialTask::NextSilentSignRequest() { CtapGetAssertionRequest MakeCredentialTask::NextSilentSignRequest() {
DCHECK(request_.exclude_list && DCHECK(request_.exclude_list &&
current_credential_ < request_.exclude_list->size()); current_credential_ < request_.exclude_list->size());
CtapGetAssertionRequest request(request_.rp.rp_id(), CtapGetAssertionRequest request(request_.rp.id,
/*client_data_json=*/""); /*client_data_json=*/"");
request.allow_list = {{request_.exclude_list->at(current_credential_)}}; request.allow_list = {{request_.exclude_list->at(current_credential_)}};
request.user_presence_required = false; request.user_presence_required = false;
......
...@@ -14,41 +14,52 @@ namespace device { ...@@ -14,41 +14,52 @@ namespace device {
// static // static
base::Optional<PublicKeyCredentialRpEntity> base::Optional<PublicKeyCredentialRpEntity>
PublicKeyCredentialRpEntity::CreateFromCBORValue(const cbor::Value& cbor) { PublicKeyCredentialRpEntity::CreateFromCBORValue(const cbor::Value& cbor) {
if (!cbor.is_map() || cbor.GetMap().size() > 3) if (!cbor.is_map() || cbor.GetMap().size() > 3) {
return base::nullopt; return base::nullopt;
}
const auto& rp_map = cbor.GetMap(); const cbor::Value::MapValue& rp_map = cbor.GetMap();
bool is_rp_map_format_correct = for (const auto& element : rp_map) {
std::all_of(rp_map.begin(), rp_map.end(), [](const auto& element) { if (!element.first.is_string() || !element.second.is_string()) {
if (!element.first.is_string() || !element.second.is_string()) return base::nullopt;
return false; }
const std::string& key = element.first.GetString();
const auto& key = element.first.GetString(); if (key != kEntityIdMapKey && key != kEntityNameMapKey &&
return (key == kEntityIdMapKey || key == kEntityNameMapKey || key != kIconUrlMapKey) {
key == kIconUrlMapKey); return base::nullopt;
}); }
}
if (!is_rp_map_format_correct) const auto id_it = rp_map.find(cbor::Value(kEntityIdMapKey));
return base::nullopt; if (id_it == rp_map.end()) {
const auto& id_it = rp_map.find(cbor::Value(kEntityIdMapKey));
const auto& name_it = rp_map.find(cbor::Value(kEntityNameMapKey));
const auto& icon_it = rp_map.find(cbor::Value(kIconUrlMapKey));
if (id_it == rp_map.end())
return base::nullopt; return base::nullopt;
}
PublicKeyCredentialRpEntity rp(id_it->second.GetString()); PublicKeyCredentialRpEntity rp(id_it->second.GetString());
const auto name_it = rp_map.find(cbor::Value(kEntityNameMapKey));
if (name_it != rp_map.end()) if (name_it != rp_map.end()) {
rp.SetRpName(name_it->second.GetString()); rp.name = name_it->second.GetString();
}
if (icon_it != rp_map.end()) const auto icon_it = rp_map.find(cbor::Value(kIconUrlMapKey));
rp.SetRpIconUrl(GURL(icon_it->second.GetString())); if (icon_it != rp_map.end()) {
rp.icon_url = GURL(icon_it->second.GetString());
}
return rp; return rp;
} }
// static
cbor::Value PublicKeyCredentialRpEntity::ConvertToCBOR(
const PublicKeyCredentialRpEntity& rp) {
cbor::Value::MapValue rp_map;
rp_map.emplace(kEntityIdMapKey, rp.id);
if (rp.name) {
rp_map.emplace(kEntityNameMapKey, *rp.name);
}
if (rp.icon_url) {
rp_map.emplace(kIconUrlMapKey, rp.icon_url->spec());
}
return cbor::Value(std::move(rp_map));
}
PublicKeyCredentialRpEntity::PublicKeyCredentialRpEntity(std::string rp_id) PublicKeyCredentialRpEntity::PublicKeyCredentialRpEntity(std::string rp_id)
: rp_id_(std::move(rp_id)) {} : id(std::move(rp_id)) {}
PublicKeyCredentialRpEntity::PublicKeyCredentialRpEntity( PublicKeyCredentialRpEntity::PublicKeyCredentialRpEntity(
const PublicKeyCredentialRpEntity& other) = default; const PublicKeyCredentialRpEntity& other) = default;
...@@ -64,28 +75,4 @@ PublicKeyCredentialRpEntity& PublicKeyCredentialRpEntity::operator=( ...@@ -64,28 +75,4 @@ PublicKeyCredentialRpEntity& PublicKeyCredentialRpEntity::operator=(
PublicKeyCredentialRpEntity::~PublicKeyCredentialRpEntity() = default; PublicKeyCredentialRpEntity::~PublicKeyCredentialRpEntity() = default;
PublicKeyCredentialRpEntity& PublicKeyCredentialRpEntity::SetRpName(
std::string rp_name) {
rp_name_ = std::move(rp_name);
return *this;
}
PublicKeyCredentialRpEntity& PublicKeyCredentialRpEntity::SetRpIconUrl(
GURL icon_url) {
rp_icon_url_ = std::move(icon_url);
return *this;
}
cbor::Value PublicKeyCredentialRpEntity::ConvertToCBOR() const {
cbor::Value::MapValue rp_map;
rp_map.emplace(kEntityIdMapKey, rp_id_);
if (rp_name_)
rp_map.emplace(kEntityNameMapKey, *rp_name_);
if (rp_icon_url_)
rp_map.emplace(kIconUrlMapKey, rp_icon_url_->spec());
return cbor::Value(std::move(rp_map));
}
} // namespace device } // namespace device
...@@ -16,13 +16,15 @@ ...@@ -16,13 +16,15 @@
namespace device { namespace device {
// Data structure containing information about relying party that invoked // PublicKeyCredentialRpEntity identifies the web application creating or
// WebAuth API. Includes a relying party id, an optional relying party name,, // challenging a WebAuthn credential.
// and optional relying party display image url. //
class COMPONENT_EXPORT(DEVICE_FIDO) PublicKeyCredentialRpEntity { // https://www.w3.org/TR/webauthn/#dictdef-publickeycredentialrpentity
struct COMPONENT_EXPORT(DEVICE_FIDO) PublicKeyCredentialRpEntity {
public: public:
static base::Optional<PublicKeyCredentialRpEntity> CreateFromCBORValue( static base::Optional<PublicKeyCredentialRpEntity> CreateFromCBORValue(
const cbor::Value& cbor); const cbor::Value& cbor);
static cbor::Value ConvertToCBOR(const PublicKeyCredentialRpEntity&);
explicit PublicKeyCredentialRpEntity(std::string rp_id); explicit PublicKeyCredentialRpEntity(std::string rp_id);
PublicKeyCredentialRpEntity(const PublicKeyCredentialRpEntity& other); PublicKeyCredentialRpEntity(const PublicKeyCredentialRpEntity& other);
...@@ -32,19 +34,9 @@ class COMPONENT_EXPORT(DEVICE_FIDO) PublicKeyCredentialRpEntity { ...@@ -32,19 +34,9 @@ class COMPONENT_EXPORT(DEVICE_FIDO) PublicKeyCredentialRpEntity {
PublicKeyCredentialRpEntity& operator=(PublicKeyCredentialRpEntity&& other); PublicKeyCredentialRpEntity& operator=(PublicKeyCredentialRpEntity&& other);
~PublicKeyCredentialRpEntity(); ~PublicKeyCredentialRpEntity();
cbor::Value ConvertToCBOR() const; std::string id;
base::Optional<std::string> name;
PublicKeyCredentialRpEntity& SetRpName(std::string rp_name); base::Optional<GURL> icon_url;
PublicKeyCredentialRpEntity& SetRpIconUrl(GURL icon_url);
const std::string& rp_id() const { return rp_id_; }
const base::Optional<std::string>& rp_name() const { return rp_name_; }
const base::Optional<GURL>& rp_icon_url() const { return rp_icon_url_; }
private:
std::string rp_id_;
base::Optional<std::string> rp_name_;
base::Optional<GURL> rp_icon_url_;
}; };
} // namespace device } // namespace device
......
...@@ -49,7 +49,7 @@ base::Optional<std::vector<uint8_t>> ConvertToU2fRegisterCommand( ...@@ -49,7 +49,7 @@ base::Optional<std::vector<uint8_t>> ConvertToU2fRegisterCommand(
request.attestation_preference == request.attestation_preference ==
AttestationConveyancePreference::ENTERPRISE; AttestationConveyancePreference::ENTERPRISE;
return ConstructU2fRegisterCommand( return ConstructU2fRegisterCommand(
fido_parsing_utils::CreateSHA256Hash(request.rp.rp_id()), fido_parsing_utils::CreateSHA256Hash(request.rp.id),
request.client_data_hash, is_invidual_attestation); request.client_data_hash, is_invidual_attestation);
} }
...@@ -57,7 +57,7 @@ base::Optional<std::vector<uint8_t>> ConvertToU2fSignCommand( ...@@ -57,7 +57,7 @@ base::Optional<std::vector<uint8_t>> ConvertToU2fSignCommand(
const CtapMakeCredentialRequest& request, const CtapMakeCredentialRequest& request,
base::span<const uint8_t> key_handle) { base::span<const uint8_t> key_handle) {
return ConstructU2fSignCommand( return ConstructU2fSignCommand(
fido_parsing_utils::CreateSHA256Hash(request.rp.rp_id()), fido_parsing_utils::CreateSHA256Hash(request.rp.id),
request.client_data_hash, key_handle); request.client_data_hash, key_handle);
} }
......
...@@ -20,7 +20,7 @@ namespace { ...@@ -20,7 +20,7 @@ namespace {
CtapMakeCredentialRequest ConstructMakeCredentialRequest() { CtapMakeCredentialRequest ConstructMakeCredentialRequest() {
PublicKeyCredentialRpEntity rp("acme.com"); PublicKeyCredentialRpEntity rp("acme.com");
rp.SetRpName("acme.com"); rp.name = "acme.com";
PublicKeyCredentialUserEntity user( PublicKeyCredentialUserEntity user(
fido_parsing_utils::Materialize(test_data::kUserId)); fido_parsing_utils::Materialize(test_data::kUserId));
...@@ -73,7 +73,7 @@ TEST(U2fCommandConstructorTest, TestConvertCtapMakeCredentialToU2fRegister) { ...@@ -73,7 +73,7 @@ TEST(U2fCommandConstructorTest, TestConvertCtapMakeCredentialToU2fRegister) {
TEST(U2fCommandConstructorTest, TestU2fRegisterCredentialAlgorithmRequirement) { TEST(U2fCommandConstructorTest, TestU2fRegisterCredentialAlgorithmRequirement) {
PublicKeyCredentialRpEntity rp("acme.com"); PublicKeyCredentialRpEntity rp("acme.com");
rp.SetRpName("acme.com"); rp.name = "acme.com";
PublicKeyCredentialUserEntity user( PublicKeyCredentialUserEntity user(
fido_parsing_utils::Materialize(test_data::kUserId)); fido_parsing_utils::Materialize(test_data::kUserId));
......
...@@ -147,7 +147,7 @@ void U2fRegisterOperation::OnRegisterResponseReceived( ...@@ -147,7 +147,7 @@ void U2fRegisterOperation::OnRegisterResponseReceived(
auto response = auto response =
AuthenticatorMakeCredentialResponse::CreateFromU2fRegisterResponse( AuthenticatorMakeCredentialResponse::CreateFromU2fRegisterResponse(
device()->DeviceTransport(), device()->DeviceTransport(),
fido_parsing_utils::CreateSHA256Hash(request().rp.rp_id()), fido_parsing_utils::CreateSHA256Hash(request().rp.id),
apdu_response->data()); apdu_response->data());
std::move(callback()) std::move(callback())
.Run(CtapDeviceResponseCode::kSuccess, std::move(response)); .Run(CtapDeviceResponseCode::kSuccess, std::move(response));
......
...@@ -604,8 +604,7 @@ CtapDeviceResponseCode VirtualCtap2Device::OnMakeCredential( ...@@ -604,8 +604,7 @@ CtapDeviceResponseCode VirtualCtap2Device::OnMakeCredential(
} }
// 6. Check for already registered credentials. // 6. Check for already registered credentials.
const auto rp_id_hash = const auto rp_id_hash = fido_parsing_utils::CreateSHA256Hash(request.rp.id);
fido_parsing_utils::CreateSHA256Hash(request.rp.rp_id());
if (request.exclude_list) { if (request.exclude_list) {
if (config_.reject_large_allow_and_exclude_lists && if (config_.reject_large_allow_and_exclude_lists &&
request.exclude_list->size() > 1) { request.exclude_list->size() > 1) {
...@@ -1302,7 +1301,7 @@ void VirtualCtap2Device::InitPendingRPs() { ...@@ -1302,7 +1301,7 @@ void VirtualCtap2Device::InitPendingRPs() {
DCHECK(!registration.second.is_u2f); DCHECK(!registration.second.is_u2f);
DCHECK(registration.second.user); DCHECK(registration.second.user);
DCHECK(registration.second.rp); DCHECK(registration.second.rp);
if (!base::ContainsKey(rp_ids, registration.second.rp->rp_id())) { if (!base::ContainsKey(rp_ids, registration.second.rp->id)) {
mutable_state()->pending_rps.push_back(*registration.second.rp); mutable_state()->pending_rps.push_back(*registration.second.rp);
} }
} }
...@@ -1345,11 +1344,12 @@ void VirtualCtap2Device::InitPendingRegistrations( ...@@ -1345,11 +1344,12 @@ void VirtualCtap2Device::InitPendingRegistrations(
void VirtualCtap2Device::GetNextRP(cbor::Value::MapValue* response_map) { void VirtualCtap2Device::GetNextRP(cbor::Value::MapValue* response_map) {
DCHECK(!mutable_state()->pending_rps.empty()); DCHECK(!mutable_state()->pending_rps.empty());
response_map->emplace(static_cast<int>(CredentialManagementResponseKey::kRP), response_map->emplace(static_cast<int>(CredentialManagementResponseKey::kRP),
mutable_state()->pending_rps.front().ConvertToCBOR()); PublicKeyCredentialRpEntity::ConvertToCBOR(
mutable_state()->pending_rps.front()));
response_map->emplace( response_map->emplace(
static_cast<int>(CredentialManagementResponseKey::kRPIDHash), static_cast<int>(CredentialManagementResponseKey::kRPIDHash),
fido_parsing_utils::CreateSHA256Hash( fido_parsing_utils::CreateSHA256Hash(
mutable_state()->pending_rps.front().rp_id())); mutable_state()->pending_rps.front().id));
mutable_state()->pending_rps.pop_front(); mutable_state()->pending_rps.pop_front();
} }
......
...@@ -196,9 +196,9 @@ AuthenticatorMakeCredentialBlocking(WinWebAuthnApi* webauthn_api, ...@@ -196,9 +196,9 @@ AuthenticatorMakeCredentialBlocking(WinWebAuthnApi* webauthn_api,
CtapMakeCredentialRequest request) { CtapMakeCredentialRequest request) {
DCHECK(webauthn_api->IsAvailable()); DCHECK(webauthn_api->IsAvailable());
base::string16 rp_id = base::UTF8ToUTF16(request.rp.rp_id()); base::string16 rp_id = base::UTF8ToUTF16(request.rp.id);
base::string16 rp_name = base::UTF8ToUTF16(request.rp.rp_name().value_or("")); base::string16 rp_name = base::UTF8ToUTF16(request.rp.name.value_or(""));
base::string16 rp_icon_url = OptionalGURLToUTF16(request.rp.rp_icon_url()); base::string16 rp_icon_url = OptionalGURLToUTF16(request.rp.icon_url);
WEBAUTHN_RP_ENTITY_INFORMATION rp_info{ WEBAUTHN_RP_ENTITY_INFORMATION rp_info{
WEBAUTHN_RP_ENTITY_INFORMATION_CURRENT_VERSION, base::as_wcstr(rp_id), WEBAUTHN_RP_ENTITY_INFORMATION_CURRENT_VERSION, base::as_wcstr(rp_id),
base::as_wcstr(rp_name), base::as_wcstr(rp_icon_url)}; base::as_wcstr(rp_name), base::as_wcstr(rp_icon_url)};
......
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