return prf_values;
}
-/* Webauthn specific functions*/
+/* Webauthn functions*/
template <class T>
wauthn_const_buffer_s ToWauthnConstBuff(T& x) noexcept {
x.size()};
}
-inline wauthn_const_buffer_s ToWauthnConstBuff(
- const char* stringLiteral) noexcept {
- return wauthn_const_buffer_s{reinterpret_cast<const u_int8_t*>(stringLiteral),
- std::strlen(stringLiteral)};
-}
-
typedef std::vector<uint8_t> Buffer;
Buffer ToBuffer(wauthn_const_buffer_s buff) {
return res;
}
-struct TestContents {
- bool succeeded;
- int statusMC;
- int statusGA;
- int updateMCRet = -1;
- int updateGARet = -1;
- std::string path;
- Buffer credentialRawId;
- Buffer userId;
- unsigned transports = WAUTHN_TRANSPORT_NONE;
- std::optional<LinkedData> linkedData;
- bool negative;
- RenderFrameHost* RFH;
-
- std::mutex mutex;
-
- void UpdateLinkedData(const wauthn_hybrid_linked_data_s* ld) {
- if (ld) {
- linkedData.emplace();
- linkedData->contactId = ToBuffer(*ld->contact_id);
- linkedData->linkId = ToBuffer(*ld->link_id);
- linkedData->linkSecret = ToBuffer(*ld->link_secret);
- linkedData->authenticatorPubKey = ToBuffer(*ld->authenticator_pubkey);
- linkedData->authenticatorName = ToBuffer(*ld->authenticator_name);
- linkedData->signature = ToBuffer(*ld->signature);
- linkedData->tunnelServerDomain = ToBuffer(*ld->tunnel_server_domain);
- linkedData->identityKey = ToBuffer(*ld->identity_key);
- } else {
- linkedData = std::nullopt;
- }
- }
-};
-
void MCUpdateLinkedDataCallback(const wauthn_hybrid_linked_data_s* linked_data,
wauthn_error_e result,
void* data) {
void* data) {
AuthenticatorCommonTizen* thiz =
reinterpret_cast<AuthenticatorCommonTizen*>(data);
- AttestationErasureOption attestation_erasure =
- AttestationErasureOption::kIncludeAttestation;
+
+ RenderFrameHostImpl* const render_frame_host_impl =
+ static_cast<RenderFrameHostImpl*>(thiz->GetRenderFrameHost());
+
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(&RenderFrameHostImpl::CloseQRCode,
+ base::Unretained(render_frame_host_impl)));
+
+ if (pubkey_cred == nullptr || result != WAUTHN_ERROR_NONE) {
+ thiz->CompleteMakeCredentialRequest(
+ blink::mojom::AuthenticatorStatus::UNKNOWN_ERROR);
+ return;
+ }
+
thiz->CompleteMakeCredentialRequest(
blink::mojom::AuthenticatorStatus::SUCCESS,
- thiz->CreateMakeCredentialResponse(std::move(pubkey_cred),
- attestation_erasure),
+ thiz->CreateMakeCredentialResponse(
+ std::move(pubkey_cred),
+ AttestationErasureOption::kEraseAttestationAndAaguid),
nullptr, Focus::kDoCheck);
}
void* data) {
AuthenticatorCommonTizen* thiz =
reinterpret_cast<AuthenticatorCommonTizen*>(data);
+
+ RenderFrameHostImpl* const render_frame_host_impl =
+ static_cast<RenderFrameHostImpl*>(thiz->GetRenderFrameHost());
+
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(&RenderFrameHostImpl::CloseQRCode,
+ base::Unretained(render_frame_host_impl)));
+
+ if (pubkey_cred == nullptr || result != WAUTHN_ERROR_NONE) {
+ thiz->CompleteGetAssertionRequest(
+ blink::mojom::AuthenticatorStatus::UNKNOWN_ERROR);
+ return;
+ }
+
thiz->CompleteGetAssertionRequest(
blink::mojom::AuthenticatorStatus::SUCCESS,
thiz->CreateGetAssertionResponse(std::move(pubkey_cred)));
// static
std::unique_ptr<AuthenticatorCommon> AuthenticatorCommon::Create(
RenderFrameHost* render_frame_host) {
- return std::make_unique<AuthenticatorCommonTizen>(
- render_frame_host,
- AuthenticatorCommonTizen::ServingRequestsFor::kInternalUses);
+ return std::make_unique<AuthenticatorCommonTizen>(render_frame_host);
}
AuthenticatorCommonTizen::AuthenticatorCommonTizen(
- RenderFrameHost* render_frame_host,
- ServingRequestsFor serving_requests_for)
+ RenderFrameHost* render_frame_host)
: render_frame_host_id_(render_frame_host->GetGlobalId()),
- serving_requests_for_(serving_requests_for),
security_checker_(static_cast<RenderFrameHostImpl*>(render_frame_host)
->GetWebAuthRequestSecurityChecker()) {
// Disable the back-forward cache for any document that makes WebAuthn
return delegate;
}
-void AuthenticatorCommonTizen::StartMakeCredentialRequest(
- bool allow_skipping_pin_touch) {
- InitDiscoveryFactory();
-
- discovery_factory()->no_cable_linking = req_state_->no_cable_linking;
- req_state_->request_delegate->ConfigureDiscoveries(
- req_state_->caller_origin, req_state_->relying_party_id, RequestSource(),
- device::FidoRequestType::kMakeCredential,
- req_state_->make_credential_options->resident_key,
- base::span<const device::CableDiscoveryData>(), discovery_factory());
-
- req_state_->make_credential_options->allow_skipping_pin_touch =
- allow_skipping_pin_touch;
-
- base::flat_set<device::FidoTransportProtocol> transports =
- GetWebAuthnTransports(
- GetRenderFrameHost(), discovery_factory(),
- UsesDiscoverableCreds(*req_state_->make_credential_options));
-
- req_state_->request_handler =
- std::make_unique<device::MakeCredentialRequestHandler>(
- discovery_factory(), transports,
- *req_state_->ctap_make_credential_request,
- *req_state_->make_credential_options,
- base::BindOnce(&AuthenticatorCommonTizen::OnRegisterResponse,
- weak_factory_.GetWeakPtr()));
-
- req_state_->request_delegate->RegisterActionCallbacks(
- base::BindOnce(&AuthenticatorCommonTizen::OnCancelFromUI,
- weak_factory_.GetWeakPtr()) /* cancel_callback */,
- base::BindRepeating(
- &AuthenticatorCommonTizen::StartMakeCredentialRequest,
- weak_factory_.GetWeakPtr(),
- /*allow_skipping_pin_touch=*/false) /* start_over_callback */,
- base::DoNothing() /* account_preselected_callback */,
- base::BindRepeating(
- &device::FidoRequestHandlerBase::StartAuthenticatorRequest,
- req_state_->request_handler->GetWeakPtr()) /* request_callback */,
- base::BindRepeating(
- &device::FidoRequestHandlerBase::PowerOnBluetoothAdapter,
- req_state_->request_handler
- ->GetWeakPtr()) /* bluetooth_adapter_power_on_callback */);
- req_state_->request_handler->set_observer(req_state_->request_delegate.get());
+bool AuthenticatorCommonTizen::IsFocused() const {
+ return GetRenderFrameHost()->IsActive() &&
+ GetWebAuthenticationDelegate()->IsFocused(
+ WebContents::FromRenderFrameHost(GetRenderFrameHost()));
}
-void AuthenticatorCommonTizen::StartGetAssertionRequest(
- bool allow_skipping_pin_touch) {
- req_state_->get_assertion_result.reset();
- InitDiscoveryFactory();
-
- discovery_factory()->no_cable_linking = req_state_->no_cable_linking;
- base::span<const device::CableDiscoveryData> cable_pairings;
- if (req_state_->ctap_get_assertion_request->cable_extension && IsFocused()) {
- cable_pairings = *req_state_->ctap_get_assertion_request->cable_extension;
- }
- req_state_->request_delegate->ConfigureDiscoveries(
- req_state_->caller_origin, req_state_->relying_party_id, RequestSource(),
- device::FidoRequestType::kGetAssertion,
- /*resident_key_requirement=*/absl::nullopt, cable_pairings,
- discovery_factory());
-#if BUILDFLAG(IS_CHROMEOS)
- discovery_factory()->set_get_assertion_request_for_legacy_credential_check(
- *req_state_->ctap_get_assertion_request);
-#endif
+void AuthenticatorCommonTizen::PopulateMCWebauthnArgs(
+ blink::mojom::PublicKeyCredentialCreationOptionsPtr options) {
+ // Chrome clientData -> Webauthn clientData
+ std::string client_data_json_string = req_state_->client_data_json;
+ client_data_vector_.clear();
+ client_data_vector_.insert(client_data_vector_.begin(),
+ client_data_json_string.begin(),
+ client_data_json_string.end());
+ client_data_vector_.push_back('\0');
+ client_data_json_buff_ = ToWauthnConstBuff(client_data_vector_);
+
+ mc_client_data_.client_data_json = &client_data_json_buff_;
+ mc_client_data_.hash_alg = WAUTHN_HASH_ALGORITHM_SHA_256;
+
+ // Chrome RP -> Webauthn RP
+ rel_party_id_ = options->relying_party.id;
+ rel_party_id_.push_back('\0');
+ rp_.id = rel_party_id_.c_str();
+
+ // options->relying_party.name is of type std::optional(std::string)
+ rel_party_name_ = options->relying_party.name.value();
+ rel_party_name_.push_back('\0');
+ rp_.name = rel_party_name_.c_str();
+
+ // Chrome User -> Webauthn User
+ user_id_vector_ = options->user.id;
+ user_id_vector_.push_back('\0');
+ user_id_buff_ = ToWauthnConstBuff(user_id_vector_);
+ user_.id = &user_id_buff_;
+
+ user_name_string_ = *options->user.name;
+ user_name_string_.push_back('\0');
+ user_.name = user_name_string_.c_str();
+
+ user_display_name_string_ = *options->user.display_name;
+ user_display_name_string_.push_back('\0');
+ user_.display_name = user_display_name_string_.c_str();
+
+ // Chrome Pubkey Params -> Webauthn Pubkey Params
+ std::unordered_map<int, wauthn_cose_algorithm_e>
+ mapping_identifier_to_algorithm;
+ mapping_identifier_to_algorithm[-7] =
+ WAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256;
+ mapping_identifier_to_algorithm[-35] =
+ WAUTHN_COSE_ALGORITHM_ECDSA_P384_WITH_SHA384;
+ mapping_identifier_to_algorithm[-36] =
+ WAUTHN_COSE_ALGORITHM_ECDSA_P521_WITH_SHA512;
+ mapping_identifier_to_algorithm[-8] = WAUTHN_COSE_ALGORITHM_EDDSA;
+ mapping_identifier_to_algorithm[-37] =
+ WAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA256;
+ mapping_identifier_to_algorithm[-38] =
+ WAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA384;
+ mapping_identifier_to_algorithm[-39] =
+ WAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA512;
+ mapping_identifier_to_algorithm[-257] =
+ WAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA256;
+ mapping_identifier_to_algorithm[-258] =
+ WAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA384;
+ mapping_identifier_to_algorithm[-259] =
+ WAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA512;
+
+ int num_pubkey_params = options->public_key_parameters.size();
+ wauthn_pubkey_cred_param_s temp_pubkey_cred_param;
+ temp_pubkey_cred_param.type = PCT_PUBLIC_KEY;
+ params_vector_.clear();
+ for (int iter = 0; iter < num_pubkey_params; iter++) {
+ temp_pubkey_cred_param.alg =
+ mapping_identifier_to_algorithm[options->public_key_parameters[iter]
+ .algorithm];
+ params_vector_.push_back(temp_pubkey_cred_param);
+ }
+ pubkey_cred_params_.params = ¶ms_vector_[0];
+ pubkey_cred_params_.size = num_pubkey_params;
+
+ // Chrome Timeout -> Webauthn Timeout
+ if (options->timeout) {
+ mc_options_.timeout = options->timeout->InMilliseconds();
+ }
+
+ // Chrome Excluded Credentials -> Webauthn Excluded Credentials
+ if (!options->exclude_credentials.empty()) {
+ std::unordered_map<device::FidoTransportProtocol, unsigned int>
+ mapping_transport_to_unsigned_int;
+ mapping_transport_to_unsigned_int
+ [device::FidoTransportProtocol::kUsbHumanInterfaceDevice] = 0x00000001;
+ mapping_transport_to_unsigned_int
+ [device::FidoTransportProtocol::kNearFieldCommunication] = 0x00000002;
+ mapping_transport_to_unsigned_int
+ [device::FidoTransportProtocol::kBluetoothLowEnergy] = 0x00000004;
+ mapping_transport_to_unsigned_int[device::FidoTransportProtocol::kHybrid] =
+ 0x00000010;
+ mapping_transport_to_unsigned_int
+ [device::FidoTransportProtocol::kInternal] = 0x00000020;
+
+ int num_excluded_credentials = options->exclude_credentials.size();
+ wauthn_pubkey_cred_descriptor_s temp_excluded_credential;
+ temp_excluded_credential.type = PCT_PUBLIC_KEY;
+ excluded_creds_vector_.clear();
+ excluded_creds_id_vector_.clear();
+
+ for (int iter = 0; iter < num_excluded_credentials; iter++) {
+ excluded_creds_id_vector_.push_back(
+ ToWauthnConstBuff(options->exclude_credentials[iter].id));
+ temp_excluded_credential.id = &excluded_creds_id_vector_[iter];
+
+ temp_excluded_credential.transports = 0x00000000;
+ if (!options->exclude_credentials[iter].transports.empty()) {
+ for (auto jter = options->exclude_credentials[iter].transports.begin();
+ jter != options->exclude_credentials[iter].transports.end();
+ jter++) {
+ temp_excluded_credential.transports |=
+ mapping_transport_to_unsigned_int[*jter];
+ }
+ }
+ excluded_creds_vector_.push_back(temp_excluded_credential);
+ }
+ excluded_credentials_.descriptors = &excluded_creds_vector_[0];
+ excluded_credentials_.size = num_excluded_credentials;
+
+ mc_options_.exclude_credentials = &excluded_credentials_;
+ }
+
+ // Chrome Attestation Preference -> Webauthn Attestation Preference
+ std::unordered_map<::device::AttestationConveyancePreference,
+ wauthn_attestation_pref_e>
+ mapping_attestation_preference;
+ mapping_attestation_preference
+ [::device::AttestationConveyancePreference::kNone] = AP_NONE;
+ mapping_attestation_preference
+ [::device::AttestationConveyancePreference::kIndirect] = AP_INDIRECT;
+ mapping_attestation_preference
+ [::device::AttestationConveyancePreference::kDirect] = AP_DIRECT;
+ mapping_attestation_preference[::device::AttestationConveyancePreference::
+ kEnterpriseIfRPListedOnAuthenticator] =
+ AP_ENTERPRISE;
+ mapping_attestation_preference[::device::AttestationConveyancePreference::
+ kEnterpriseApprovedByBrowser] =
+ AP_ENTERPRISE;
+
+ // Chrome Authenticator Selection -> Webauthn Authenticator Selection
+ if (options->authenticator_selection) {
+ std::unordered_map<device::AuthenticatorAttachment,
+ wauthn_authenticator_attachment_e>
+ mapping_authenticator_attachment;
+ mapping_authenticator_attachment[device::AuthenticatorAttachment::kAny] =
+ AA_NONE;
+ mapping_authenticator_attachment
+ [device::AuthenticatorAttachment::kPlatform] = AA_PLATFORM;
+ mapping_authenticator_attachment
+ [device::AuthenticatorAttachment::kCrossPlatform] = AA_CROSS_PLATFORM;
+
+ if (options->authenticator_selection->authenticator_attachment !=
+ device::AuthenticatorAttachment::kAny) {
+ mc_authenticator_selection_criteria_.attachment =
+ mapping_authenticator_attachment[options->authenticator_selection
+ ->authenticator_attachment];
+ }
+
+ std::unordered_map<device::ResidentKeyRequirement,
+ wauthn_resident_key_requirement_e>
+ mapping_resident_key_requirement;
+ mapping_resident_key_requirement
+ [device::ResidentKeyRequirement::kDiscouraged] = RKR_DISCOURAGED;
+ mapping_resident_key_requirement
+ [device::ResidentKeyRequirement::kPreferred] = RKR_PREFERRED;
+ mapping_resident_key_requirement
+ [device::ResidentKeyRequirement::kRequired] = RKR_REQUIRED;
+
+ mc_authenticator_selection_criteria_.resident_key =
+ mapping_resident_key_requirement[options->authenticator_selection
+ ->resident_key];
+ mc_authenticator_selection_criteria_.require_resident_key =
+ mc_authenticator_selection_criteria_.resident_key == RKR_REQUIRED;
+
+ std::unordered_map<device::UserVerificationRequirement,
+ wauthn_user_verification_requirement_e>
+ mapping_user_verification_requirement;
+ mapping_user_verification_requirement
+ [device::UserVerificationRequirement::kRequired] = UVR_REQUIRED;
+ mapping_user_verification_requirement
+ [device::UserVerificationRequirement::kPreferred] = UVR_PREFERRED;
+ mapping_user_verification_requirement
+ [device::UserVerificationRequirement::kDiscouraged] = UVR_DISCOURAGED;
+
+ mc_authenticator_selection_criteria_.user_verification =
+ mapping_user_verification_requirement
+ [options->authenticator_selection->user_verification_requirement];
+
+ mc_options_.authenticator_selection = &mc_authenticator_selection_criteria_;
+ }
+
+ // Chrome Attestation Formats -> Webauthn Attestation Formats
+ if (options->device_public_key) {
+ num_attestation_formats_ =
+ options->device_public_key->attestation_formats.size();
+ wauthn_const_buffer_s temp_attestation_format;
+ mc_attestation_formats_vector_.clear();
+
+ for (int iter = 0; iter < num_attestation_formats_; iter++) {
+ mc_attestation_formats_string_vector_.push_back(
+ options->device_public_key->attestation_formats[iter]);
+ mc_attestation_formats_string_vector_[iter].push_back('\0');
+
+ temp_attestation_format =
+ ToWauthnConstBuff(mc_attestation_formats_string_vector_[iter]);
+ mc_attestation_formats_vector_.push_back(temp_attestation_format);
+ }
+
+ mc_attestation_formats_.attestation_formats =
+ &mc_attestation_formats_vector_[0];
+ mc_attestation_formats_.size = num_attestation_formats_;
+
+ mc_options_.attestation_formats = &mc_attestation_formats_;
+ }
- base::flat_set<device::FidoTransportProtocol> transports =
- GetWebAuthnTransports(
- GetRenderFrameHost(), discovery_factory(),
- UsesDiscoverableCreds(*req_state_->ctap_get_assertion_request));
-
- auto request_handler = std::make_unique<device::GetAssertionRequestHandler>(
- discovery_factory(), transports, *req_state_->ctap_get_assertion_request,
- *req_state_->ctap_get_assertion_options, allow_skipping_pin_touch,
- base::BindOnce(&AuthenticatorCommonTizen::OnSignResponse,
- weak_factory_.GetWeakPtr()));
- request_handler->transport_availability_info().conditional_ui_treatment =
- req_state_->conditional_ui_treatment;
-
- req_state_->request_delegate->RegisterActionCallbacks(
- base::BindOnce(&AuthenticatorCommonTizen::OnCancelFromUI,
- weak_factory_.GetWeakPtr()) /* cancel_callback */,
- base::BindRepeating(
- &AuthenticatorCommonTizen::StartGetAssertionRequest,
- weak_factory_.GetWeakPtr(),
- /*allow_skipping_pin_touch=*/false) /* start_over_callback */,
- base::BindRepeating(
- &device::GetAssertionRequestHandler::PreselectAccount,
- request_handler->GetWeakPtr()) /* account_preselected_callback */,
- base::BindRepeating(
- &device::GetAssertionRequestHandler::StartAuthenticatorRequest,
- request_handler->GetWeakPtr()) /* request_callback */,
- base::BindRepeating(
- &device::FidoRequestHandlerBase::PowerOnBluetoothAdapter,
- request_handler
- ->GetWeakPtr()) /* bluetooth_adapter_power_on_callback */);
-
- request_handler->set_observer(req_state_->request_delegate.get());
- req_state_->request_handler = std::move(request_handler);
+ std::memset(&mc_options_, 0, sizeof(mc_options_));
+ mc_options_.rp = &rp_;
+ mc_options_.user = &user_;
+ mc_options_.pubkey_cred_params = &pubkey_cred_params_;
+ mc_options_.attestation =
+ mapping_attestation_preference[options->attestation];
+
+ mc_callbacks_.qrcode_callback = DisplayQRCallback;
+ mc_callbacks_.response_callback = MCCallback;
+ mc_callbacks_.linked_data_callback = MCUpdateLinkedDataCallback;
+ mc_callbacks_.user_data = this;
}
-bool AuthenticatorCommonTizen::IsFocused() const {
- return GetRenderFrameHost()->IsActive() &&
- GetWebAuthenticationDelegate()->IsFocused(
- WebContents::FromRenderFrameHost(GetRenderFrameHost()));
+void AuthenticatorCommonTizen::PopulateGAWebauthnArgs(
+ blink::mojom::PublicKeyCredentialRequestOptionsPtr options) {
+ // Chrome clientData -> Webauthn clientData
+ std::string client_data_json_string = req_state_->client_data_json;
+ client_data_vector_.clear();
+ client_data_vector_.insert(client_data_vector_.begin(),
+ client_data_json_string.begin(),
+ client_data_json_string.end());
+ client_data_vector_.push_back('\0');
+ client_data_json_buff_ = ToWauthnConstBuff(client_data_vector_);
+
+ ga_client_data_.client_data_json = &client_data_json_buff_;
+ ga_client_data_.hash_alg = WAUTHN_HASH_ALGORITHM_SHA_256;
+
+ // Chrome Timeout -> Webauthn Timeout
+ if (options->timeout) {
+ ga_options_.timeout = options->timeout->InMilliseconds();
+ }
+
+ // Chrome RP -> Webauthn RP
+ rp_id_string_ = options->relying_party_id;
+ rp_id_string_.push_back('\0');
+
+ // Chrome Allow Credentials -> Webauthn Allow Credentials
+ if (!options->allow_credentials.empty()) {
+ int num_allow_credentials = options->allow_credentials.size();
+ wauthn_pubkey_cred_descriptor_s temp_pubkey_cred_descriptor;
+ temp_pubkey_cred_descriptor.type = PCT_PUBLIC_KEY;
+ pubkey_cred_descriptor_vector_.clear();
+ pubkey_cred_id_vector_.clear();
+
+ for (int iter = 0; iter < num_allow_credentials; iter++) {
+ pubkey_cred_id_vector_.push_back(
+ ToWauthnConstBuff(options->allow_credentials[iter].id));
+ temp_pubkey_cred_descriptor.id = &pubkey_cred_id_vector_[iter];
+
+ temp_pubkey_cred_descriptor.transports = 0x00000000;
+ for (const auto& transport :
+ options->allow_credentials[iter].transports) {
+ if (transport ==
+ device::FidoTransportProtocol::kUsbHumanInterfaceDevice) {
+ temp_pubkey_cred_descriptor.transports |= 0x00000001;
+ }
+ if (transport ==
+ device::FidoTransportProtocol::kNearFieldCommunication) {
+ temp_pubkey_cred_descriptor.transports |= 0x00000002;
+ }
+ if (transport == device::FidoTransportProtocol::kBluetoothLowEnergy) {
+ temp_pubkey_cred_descriptor.transports |= 0x00000004;
+ }
+ if (transport == device::FidoTransportProtocol::kHybrid) {
+ temp_pubkey_cred_descriptor.transports |= 0x00000010;
+ }
+ if (transport == device::FidoTransportProtocol::kInternal) {
+ temp_pubkey_cred_descriptor.transports |= 0x00000020;
+ }
+ }
+ pubkey_cred_descriptor_vector_.push_back(temp_pubkey_cred_descriptor);
+ }
+ pubkey_cred_descriptors_.descriptors = &pubkey_cred_descriptor_vector_[0];
+ pubkey_cred_descriptors_.size = num_allow_credentials;
+
+ ga_options_.allow_credentials = &pubkey_cred_descriptors_;
+ }
+
+ // Chrome User Verification -> Webauthn User Verification
+ std::unordered_map<device::UserVerificationRequirement,
+ wauthn_user_verification_requirement_e>
+ mapping_user_verification_requirement;
+ mapping_user_verification_requirement
+ [device::UserVerificationRequirement::kRequired] = UVR_REQUIRED;
+ mapping_user_verification_requirement
+ [device::UserVerificationRequirement::kPreferred] = UVR_PREFERRED;
+ mapping_user_verification_requirement
+ [device::UserVerificationRequirement::kDiscouraged] = UVR_DISCOURAGED;
+
+ ga_options_.user_verification =
+ mapping_user_verification_requirement[options->user_verification];
+
+ std::memset(&ga_options_, 0, sizeof(ga_options_));
+ ga_options_.rpId = rp_id_string_.c_str();
+ ga_options_.hints = nullptr;
+ ga_options_.attestation = device_attestation_;
+ ga_options_.extensions = nullptr;
+ ga_options_.linked_device = nullptr;
+
+ ga_callbacks_.qrcode_callback = DisplayQRCallback;
+ ga_callbacks_.response_callback = GACallback;
+ ga_callbacks_.linked_data_callback = GAUpdateLinkedDataCallback;
+ ga_callbacks_.user_data = this;
}
// mojom::Authenticator
req_state_->make_credential_options->resident_key !=
device::ResidentKeyRequirement::kDiscouraged;
- // Below check is currently disabled to test further functionality
+ // TODO: Handle unsupported residential credentials for Tizen
#if (0)
if (might_create_resident_key &&
!GetWebAuthenticationDelegate()->SupportsResidentKeys(
device::ResidentKeyRequirement::kDiscouraged;
}
#endif // if(0)
+
// Reject any non-sensical credProtect extension values.
if ( // Can't require the default policy (or no policy).
(options->enforce_protection_policy &&
req_state_->ctap_make_credential_request->attestation_preference =
attestation;
- // Chrome clientData -> Webauthn clientData
- std::string clientDataJsonString = req_state_->client_data_json;
-
- char tempCharStar[clientDataJsonString.size() + 1];
- strcpy(tempCharStar, clientDataJsonString.c_str());
- unsigned char* clientDataJson =
- reinterpret_cast<unsigned char*>(tempCharStar);
-
- wauthn_const_buffer_s clientDataJsonBuff;
- clientDataJsonBuff.data = clientDataJson;
- clientDataJsonBuff.size = clientDataJsonString.size();
-
- mcClientData.client_data_json = &clientDataJsonBuff;
- mcClientData.hash_alg = WAUTHN_HASH_ALGORITHM_SHA_256;
-
- // Chrome RP -> Webauthn RP
- wauthn_rp_entity_s rp;
- std::string rel_party_id = options->relying_party.id;
- // Field relying_party.name is of type std::optional(std::string)
- std::string rel_party_name = options->relying_party.name.value();
- rp.id = rel_party_id.c_str();
- rp.name = rel_party_name.c_str();
-
- // Chrome User -> Webauthn User
- wauthn_user_entity_s user;
- unsigned char* userId = &(options->user.id)[0];
-
- wauthn_const_buffer_s userIdBuff;
- userIdBuff.data = userId;
- userIdBuff.size = sizeof(userId) - 1;
-
- user.id = &userIdBuff;
- user.name = (options->user.name)->c_str();
- user.display_name = (options->user.display_name)->c_str();
-
- // Chrome Pubkey Params -> Webauthn Pubkey Params
- int num_pubkey_params = options->public_key_parameters.size();
- wauthn_pubkey_cred_param_s params[num_pubkey_params];
-
- std::unordered_map<int, wauthn_cose_algorithm_e>
- mapping_identifier_to_algorithm;
- mapping_identifier_to_algorithm[-7] =
- WAUTHN_COSE_ALGORITHM_ECDSA_P256_WITH_SHA256;
- mapping_identifier_to_algorithm[-35] =
- WAUTHN_COSE_ALGORITHM_ECDSA_P384_WITH_SHA384;
- mapping_identifier_to_algorithm[-36] =
- WAUTHN_COSE_ALGORITHM_ECDSA_P521_WITH_SHA512;
- mapping_identifier_to_algorithm[-8] = WAUTHN_COSE_ALGORITHM_EDDSA;
- mapping_identifier_to_algorithm[-37] =
- WAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA256;
- mapping_identifier_to_algorithm[-38] =
- WAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA384;
- mapping_identifier_to_algorithm[-39] =
- WAUTHN_COSE_ALGORITHM_RSA_PSS_WITH_SHA512;
- mapping_identifier_to_algorithm[-257] =
- WAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA256;
- mapping_identifier_to_algorithm[-258] =
- WAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA384;
- mapping_identifier_to_algorithm[-259] =
- WAUTHN_COSE_ALGORITHM_RSASSA_PKCS1_V1_5_WITH_SHA512;
-
- wauthn_pubkey_cred_param_s temp_pubkey_cred_param;
- for (int temp = 0; temp < num_pubkey_params; temp++) {
- temp_pubkey_cred_param.type = PCT_PUBLIC_KEY;
- temp_pubkey_cred_param.alg =
- mapping_identifier_to_algorithm[options->public_key_parameters[temp]
- .algorithm];
- params[temp] = temp_pubkey_cred_param;
- }
-
- wauthn_pubkey_cred_params_s pubkeyCredParams;
- pubkeyCredParams.params = params;
- pubkeyCredParams.size = sizeof(params) / sizeof(*params);
-
- std::memset(&mcOptions, 0, sizeof(mcOptions));
- mcOptions.rp = &rp;
- mcOptions.user = &user;
- mcOptions.pubkey_cred_params = &pubkeyCredParams;
- mcOptions.timeout = options->timeout->InMilliseconds();
-
- mcCallbacks.qrcode_callback = DisplayQRCallback;
- mcCallbacks.response_callback = MCCallback;
- mcCallbacks.linked_data_callback = MCUpdateLinkedDataCallback;
- mcCallbacks.user_data = this;
-
- int ret = wauthn_make_credential(&mcClientData, &mcOptions, &mcCallbacks);
+ PopulateMCWebauthnArgs(std::move(options));
+ wauthn_make_credential(&mc_client_data_, &mc_options_, &mc_callbacks_);
}
void AuthenticatorCommonTizen::GetAssertion(
options->allow_credentials =
std::vector<device::PublicKeyCredentialDescriptor>();
}
+
+ // TODO: Handle unsupported residential credentials for Tizen
#if (0)
if (options->allow_credentials.empty()) {
if (!GetWebAuthenticationDelegate()->SupportsResidentKeys(
req_state_->discoverable_credential_request = true;
}
#endif
+
if (options->extensions->large_blob_read &&
options->extensions->large_blob_write) {
CompleteGetAssertionRequest(
blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
break;
}
+
+ // Device Public Key Attestation
+ switch (device_public_key.attestation) {
+ case device::AttestationConveyancePreference::kNone:
+ device_attestation_ = AP_NONE;
+ break;
+ case device::AttestationConveyancePreference::kDirect:
+ device_attestation_ = AP_DIRECT;
+ break;
+ case device::AttestationConveyancePreference::kIndirect:
+ device_attestation_ = AP_INDIRECT;
+ break;
+ case device::AttestationConveyancePreference::
+ kEnterpriseIfRPListedOnAuthenticator:
+ case device::AttestationConveyancePreference::
+ kEnterpriseApprovedByBrowser:
+ device_attestation_ = AP_ENTERPRISE;
+ }
+
+ num_attestation_formats_ = device_public_key.attestation_formats.size();
+ wauthn_const_buffer_s temp_wauthn_const_buffer_s;
+
+ for (int iter = 0; iter < num_attestation_formats_; iter++) {
+ std::string temp_attestation_formats_string(
+ device_public_key.attestation_formats[iter]);
+ temp_attestation_formats_string.push_back('\0');
+ ga_attestation_formats_string_vector_.push_back(
+ temp_attestation_formats_string);
+
+ temp_wauthn_const_buffer_s =
+ ToWauthnConstBuff(ga_attestation_formats_string_vector_[iter]);
+ ga_attestation_formats_vector_.push_back(temp_wauthn_const_buffer_s);
+ }
+ device_attestation_formats_.attestation_formats =
+ &ga_attestation_formats_vector_[0];
+ device_attestation_formats_.size = num_attestation_formats_;
}
+ ga_options_.attestation_formats =
+ num_attestation_formats_ ? &device_attestation_formats_ : nullptr;
if (options->extensions->get_cred_blob) {
req_state_->requested_extensions.insert(RequestExtension::kGetCredBlob);
req_state_->ctap_get_assertion_options->large_blob_write =
options->extensions->large_blob_write;
- char tempCharStar[req_state_->client_data_json.size() + 1];
- strcpy(tempCharStar, req_state_->client_data_json.c_str());
- unsigned char* clientDataJson =
- reinterpret_cast<unsigned char*>(tempCharStar);
-
- wauthn_const_buffer_s clientDataJsonBuff;
- clientDataJsonBuff.data = clientDataJson;
- clientDataJsonBuff.size = req_state_->client_data_json.size();
-
- gaClientData.client_data_json = &clientDataJsonBuff;
- gaClientData.hash_alg = WAUTHN_HASH_ALGORITHM_SHA_256;
-
- // Temp User Data
- TestContents testContents = {true,
- 0,
- 0,
- -1,
- -1,
- "/tmp/webauthn-qrcode.png",
- {},
- {},
- WAUTHN_TRANSPORT_NONE,
- std::nullopt,
- false,
- GetRenderFrameHost(),
- {}};
- auto lock = std::unique_lock{testContents.mutex};
-
- wauthn_const_buffer_s credentialId =
- ToWauthnConstBuff(testContents.credentialRawId);
-
- wauthn_pubkey_cred_descriptor_s pubkeyCredDescriptor;
- pubkeyCredDescriptor.type = PCT_PUBLIC_KEY;
- pubkeyCredDescriptor.id = &credentialId;
- pubkeyCredDescriptor.transports = testContents.transports;
-
- wauthn_pubkey_cred_descriptors_s pubkeyCredDescriptors;
- pubkeyCredDescriptors.size = 1;
- pubkeyCredDescriptors.descriptors = &pubkeyCredDescriptor;
-
- wauthn_const_buffer_s contactId;
- wauthn_const_buffer_s linkId;
- wauthn_const_buffer_s linkSecret;
- wauthn_const_buffer_s authenticatorPubKey;
- wauthn_const_buffer_s authenticatorName;
- wauthn_const_buffer_s signature;
- wauthn_const_buffer_s tunnelServerDomain;
- wauthn_const_buffer_s identityKey;
-
- wauthn_hybrid_linked_data_s linkedDevice;
- if (testContents.linkedData) {
- std::cout << "linkedData is exist" << std::endl;
- contactId = ToWauthnConstBuff(testContents.linkedData->contactId);
- linkId = ToWauthnConstBuff(testContents.linkedData->linkId);
- linkSecret = ToWauthnConstBuff(testContents.linkedData->linkSecret);
- authenticatorPubKey =
- ToWauthnConstBuff(testContents.linkedData->authenticatorPubKey);
- authenticatorName =
- ToWauthnConstBuff(testContents.linkedData->authenticatorName);
- signature = ToWauthnConstBuff(testContents.linkedData->signature);
- tunnelServerDomain =
- ToWauthnConstBuff(testContents.linkedData->tunnelServerDomain);
- identityKey = ToWauthnConstBuff(testContents.linkedData->identityKey);
-
- linkedDevice.contact_id = &contactId;
- linkedDevice.link_id = &linkId;
- linkedDevice.link_secret = &linkSecret;
- linkedDevice.authenticator_pubkey = &authenticatorPubKey;
- linkedDevice.authenticator_name = &authenticatorName;
- linkedDevice.signature = &signature;
- linkedDevice.tunnel_server_domain = &tunnelServerDomain;
- linkedDevice.identity_key = &identityKey;
- }
-
- std::memset(&gaOptions, 0, sizeof(gaOptions)); // For future compatibility.
- gaOptions.timeout = 120000; // 120s
- gaOptions.rpId = options->relying_party_id.c_str();
- gaOptions.user_verification = UVR_REQUIRED;
- gaOptions.allow_credentials = std::move(&pubkeyCredDescriptors);
- gaOptions.hints = nullptr;
- gaOptions.attestation = AP_NONE;
- gaOptions.attestation_formats = nullptr;
- gaOptions.extensions = nullptr;
- gaOptions.linked_device = testContents.linkedData ? &linkedDevice : nullptr;
-
- gaCallbacks.qrcode_callback = DisplayQRCallback;
- gaCallbacks.response_callback = GACallback;
- gaCallbacks.linked_data_callback = GAUpdateLinkedDataCallback;
- gaCallbacks.user_data = this;
-
- int ret = wauthn_get_assertion(&gaClientData, &gaOptions, &gaCallbacks);
+ PopulateGAWebauthnArgs(std::move(options));
+ wauthn_get_assertion(&ga_client_data_, &ga_options_, &ga_callbacks_);
}
void AuthenticatorCommonTizen::IsUserVerifyingPlatformAuthenticatorAvailable(
CancelWithStatus(blink::mojom::AuthenticatorStatus::ABORT_ERROR);
}
-void AuthenticatorCommonTizen::OnRegisterResponse(
- device::MakeCredentialStatus status_code,
- absl::optional<device::AuthenticatorMakeCredentialResponse> response_data,
- const device::FidoAuthenticator* authenticator) {
- if (!req_state_->request_handler) {
- // Either the callback was called immediately and
- // |req_state_->request_handler| has not yet been assigned (this is a bug),
- // or a navigation caused the request to be canceled while a callback was
- // enqueued.
- return;
- }
-
- switch (status_code) {
- case device::MakeCredentialStatus::kUserConsentButCredentialExcluded:
- case device::MakeCredentialStatus::kWinInvalidStateError:
- // Duplicate registration: the new credential would be created on an
- // authenticator that already contains one of the credentials in
- // |exclude_credentials|. If the request specified that only a platform
- // authenticator was acceptable then we don't show an error message
- // because there's no other authenticator that could be used for this
- // request. Instead the RP learns of the result via the distinctive
- // InvalidStateError result. This tells them that the platform
- // authenticator is already registered with one of the credential IDs that
- // they already know about.
- //
- // Windows already behaves like this and so its representation of
- // InvalidStateError is handled this way too.
- if (req_state_->make_credential_options->authenticator_attachment ==
- device::AuthenticatorAttachment::kPlatform ||
- status_code == device::MakeCredentialStatus::kWinInvalidStateError) {
- CompleteMakeCredentialRequest(
- blink::mojom::AuthenticatorStatus::CREDENTIAL_EXCLUDED, nullptr,
- nullptr, Focus::kDoCheck);
- } else {
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kKeyAlreadyRegistered,
- blink::mojom::AuthenticatorStatus::CREDENTIAL_EXCLUDED);
- }
- return;
- case device::MakeCredentialStatus::kAuthenticatorResponseInvalid:
- // The response from the authenticator was corrupted.
- CompleteMakeCredentialRequest(
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, nullptr,
- nullptr, Focus::kDoCheck);
- return;
- case device::MakeCredentialStatus::kHybridTransportError:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kHybridTransportError,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::MakeCredentialStatus::kUserConsentDenied:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kUserConsentDenied,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::MakeCredentialStatus::kSoftPINBlock:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kSoftPINBlock,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::MakeCredentialStatus::kHardPINBlock:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kHardPINBlock,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::MakeCredentialStatus::kAuthenticatorRemovedDuringPINEntry:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kAuthenticatorRemovedDuringPINEntry,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::MakeCredentialStatus::kAuthenticatorMissingResidentKeys:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kAuthenticatorMissingResidentKeys,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::MakeCredentialStatus::kAuthenticatorMissingUserVerification:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kAuthenticatorMissingUserVerification,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::MakeCredentialStatus::kAuthenticatorMissingLargeBlob:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kAuthenticatorMissingLargeBlob,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::MakeCredentialStatus::kNoCommonAlgorithms:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kNoCommonAlgorithms,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::MakeCredentialStatus::kStorageFull:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kStorageFull,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::MakeCredentialStatus::kWinNotAllowedError:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kWinUserCancelled,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::MakeCredentialStatus::kSuccess:
- break;
- }
-
- DCHECK(response_data.has_value());
- DCHECK(authenticator);
-
- req_state_->request_delegate->OnTransactionSuccessful(
- RequestSource(), device::FidoRequestType::kMakeCredential,
- authenticator->GetType());
-
- absl::optional<device::FidoTransportProtocol> transport =
- authenticator->AuthenticatorTransport();
- bool is_transport_used_internal = false;
- bool is_transport_used_cable = false;
- if (transport) {
- is_transport_used_internal =
- *transport == device::FidoTransportProtocol::kInternal;
- is_transport_used_cable =
- *transport == device::FidoTransportProtocol::kHybrid;
- }
-
- absl::optional<device::DevicePublicKeyOutput> device_public_key_output =
- response_data->GetDevicePublicKeyResponse();
- const bool have_enterprise_attestation =
- response_data->enterprise_attestation_returned ||
- (device_public_key_output &&
- device_public_key_output->enterprise_attestation_returned);
- const bool device_public_key_included_attestation =
- device_public_key_output &&
- device_public_key_output->attestation_format !=
- device::kNoneAttestationValue;
- const auto attestation =
- req_state_->ctap_make_credential_request->attestation_preference;
- absl::optional<AttestationErasureOption> attestation_erasure;
-
- if (response_data->attestation_should_be_filtered &&
- !GetWebAuthenticationDelegate()->ShouldPermitIndividualAttestation(
- GetBrowserContext(), req_state_->caller_origin,
- req_state_->relying_party_id)) {
- attestation_erasure = AttestationErasureOption::kEraseAttestationAndAaguid;
- } else if (attestation == device::AttestationConveyancePreference::
- kEnterpriseApprovedByBrowser) {
- // If enterprise attestation was approved by policy then it can be
- // returned immediately.
- attestation_erasure = AttestationErasureOption::kIncludeAttestation;
- } else if (attestation == device::AttestationConveyancePreference::
- kEnterpriseIfRPListedOnAuthenticator &&
- !response_data->enterprise_attestation_returned) {
- // If enterprise attestation was requested, not approved by policy, and
- // not approved by the authenticator, then any attestation is stripped.
- attestation_erasure = AttestationErasureOption::kEraseAttestationAndAaguid;
- } else if (is_transport_used_cable) {
- // Attestation is not returned when caBLEv2 is used, but the AAGUID is
- // maintained.
- attestation_erasure =
- AttestationErasureOption::kEraseAttestationButIncludeAaguid;
- } else if (is_transport_used_internal) {
- // Direct attestation from platform authenticators is known to be
- // privacy preserving, so we always return it when requested. Also,
- // counter to what the WebAuthn spec says, we do not erase the AAGUID
- // even when attestation wasn't requested.
- attestation_erasure =
- attestation != device::AttestationConveyancePreference::kNone
- ? AttestationErasureOption::kIncludeAttestation
- : AttestationErasureOption::kEraseAttestationButIncludeAaguid;
- } else if (attestation == device::AttestationConveyancePreference::kNone &&
- response_data->attestation_object.IsSelfAttestation()) {
- attestation_erasure = AttestationErasureOption::kIncludeAttestation;
- } else if (attestation == device::AttestationConveyancePreference::kNone) {
- attestation_erasure = AttestationErasureOption::kEraseAttestationAndAaguid;
- }
-
- if (attestation_erasure.has_value() &&
- // If a DPK attestation was requested then we show a prompt. (If
- // the RP ID is allowlisted by policy then the prompt will be
- // resolved immediately and never actually shown.)
- !req_state_->device_public_key_attestation_requested) {
-#if (0)
- CompleteMakeCredentialRequest(
- blink::mojom::AuthenticatorStatus::SUCCESS,
- CreateMakeCredentialResponse(std::move(*response_data),
- *attestation_erasure),
- nullptr, Focus::kDoCheck);
-#endif
- } else {
- req_state_->awaiting_attestation_response = true;
- req_state_->request_delegate->ShouldReturnAttestation(
- req_state_->relying_party_id, authenticator,
- have_enterprise_attestation,
- base::BindOnce(
- &AuthenticatorCommonTizen::OnRegisterResponseAttestationDecided,
- weak_factory_.GetWeakPtr(),
- attestation_erasure.value_or(
- AttestationErasureOption::kIncludeAttestation),
- device_public_key_output.has_value(),
- device_public_key_included_attestation, std::move(*response_data)));
- }
-}
-
-void AuthenticatorCommonTizen::OnRegisterResponseAttestationDecided(
- AttestationErasureOption attestation_erasure,
- const bool has_device_public_key_output,
- const bool device_public_key_included_attestation,
- device::AuthenticatorMakeCredentialResponse response_data,
- bool attestation_permitted) {
- req_state_->awaiting_attestation_response = false;
- if (!req_state_->request_handler) {
- // The request has already been cleaned up, probably because a navigation
- // occurred while the permissions prompt was pending.
- return;
- }
-
- if (!attestation_permitted) {
- attestation_erasure = AttestationErasureOption::kEraseAttestationAndAaguid;
- }
-
- // The check for IsAttestationCertificateInappropriatelyIdentifying is
- // performed after the permissions prompt, even though we know the answer
- // before, because this still effectively discloses the make & model of
- // the authenticator: If an RP sees a "none" attestation from Chrome after
- // requesting direct attestation then it knows that it was one of the
- // tokens with inappropriate certs.
- if (response_data.attestation_object
- .IsAttestationCertificateInappropriatelyIdentifying() &&
- !GetWebAuthenticationDelegate()->ShouldPermitIndividualAttestation(
- GetBrowserContext(), req_state_->caller_origin,
- req_state_->relying_party_id)) {
- // The attestation response is incorrectly individually identifiable, but
- // the consent is for make & model information about a token, not for
- // individually-identifiable information. Erase the attestation to stop it
- // begin a tracking signal.
-
- // The only way to get the underlying attestation will be to list the RP ID
- // in the enterprise policy, because that enables the individual attestation
- // bit in the register request and permits individual attestation generally.
- attestation_erasure = AttestationErasureOption::kEraseAttestationAndAaguid;
- }
-#if (0)
- CompleteMakeCredentialRequest(
- blink::mojom::AuthenticatorStatus::SUCCESS,
- CreateMakeCredentialResponse(std::move(response_data),
- attestation_erasure),
- nullptr, Focus::kDoCheck);
-#endif
-}
-
-void AuthenticatorCommonTizen::OnSignResponse(
- device::GetAssertionStatus status_code,
- absl::optional<std::vector<device::AuthenticatorGetAssertionResponse>>
- response_data,
- device::FidoAuthenticator* authenticator) {
- DCHECK(!response_data || !response_data->empty()); // empty vector is invalid
- if (!req_state_->request_handler) {
- // Either the callback was called immediately and
- // |req_state_->request_handler| has not yet been assigned (this is a bug),
- // or a navigation caused the request to be canceled while a callback was
- // enqueued.
- return;
- }
-
- switch (authenticator->GetType()) {
- case device::AuthenticatorType::kChromeOS:
- req_state_->get_assertion_result =
- status_code == device::GetAssertionStatus::kSuccess
- ? GetAssertionResult::kChromeOSSuccess
- : GetAssertionResult::kChromeOSError;
- break;
- case device::AuthenticatorType::kEnclave:
- req_state_->get_assertion_result =
- status_code == device::GetAssertionStatus::kSuccess
- ? GetAssertionResult::kEnclaveSuccess
- : GetAssertionResult::kEnclaveError;
- break;
- case device::AuthenticatorType::kICloudKeychain:
- req_state_->get_assertion_result =
- status_code == device::GetAssertionStatus::kSuccess
- ? GetAssertionResult::kICloudKeychainSuccess
- : GetAssertionResult::kICloudKeychainError;
- break;
- case device::AuthenticatorType::kOther:
- req_state_->get_assertion_result =
- status_code == device::GetAssertionStatus::kSuccess
- ? GetAssertionResult::kOtherSuccess
- : GetAssertionResult::kOtherError;
- break;
- case device::AuthenticatorType::kPhone:
- req_state_->get_assertion_result =
- status_code == device::GetAssertionStatus::kSuccess
- ? GetAssertionResult::kPhoneSuccess
- : GetAssertionResult::kPhoneError;
- break;
- case device::AuthenticatorType::kTouchID:
- req_state_->get_assertion_result =
- status_code == device::GetAssertionStatus::kSuccess
- ? GetAssertionResult::kTouchIDSuccess
- : GetAssertionResult::kTouchIDError;
- break;
- case device::AuthenticatorType::kWinNative:
- req_state_->get_assertion_result =
- status_code == device::GetAssertionStatus::kSuccess
- ? GetAssertionResult::kWinNativeSuccess
- : GetAssertionResult::kWinNativeError;
- break;
- }
-
- switch (status_code) {
- case device::GetAssertionStatus::kUserConsentButCredentialNotRecognized:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kKeyNotRegistered,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::GetAssertionStatus::kAuthenticatorResponseInvalid:
- // The response from the authenticator was corrupted.
- CompleteGetAssertionRequest(
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::GetAssertionStatus::kUserConsentDenied:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kUserConsentDenied,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::GetAssertionStatus::kSoftPINBlock:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kSoftPINBlock,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::GetAssertionStatus::kHardPINBlock:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kHardPINBlock,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::GetAssertionStatus::kAuthenticatorRemovedDuringPINEntry:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kAuthenticatorRemovedDuringPINEntry,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::GetAssertionStatus::kAuthenticatorMissingResidentKeys:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kAuthenticatorMissingResidentKeys,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::GetAssertionStatus::kAuthenticatorMissingUserVerification:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kAuthenticatorMissingUserVerification,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::GetAssertionStatus::kWinNotAllowedError:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kWinUserCancelled,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::GetAssertionStatus::kHybridTransportError:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kHybridTransportError,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::GetAssertionStatus::kICloudKeychainNoCredentials:
- SignalFailureToRequestDelegate(
- AuthenticatorRequestClientDelegate::InterestingFailureReason::
- kNoPasskeys,
- blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR);
- return;
- case device::GetAssertionStatus::kSuccess:
- break;
- }
-
- DCHECK_EQ(status_code, device::GetAssertionStatus::kSuccess);
- DCHECK(response_data.has_value());
-
- req_state_->request_delegate->OnTransactionSuccessful(
- RequestSource(), device::FidoRequestType::kGetAssertion,
- authenticator->GetType());
-
- // Show an account picker for discoverable credential requests (empty allow
- // lists). Responses with a single credential are considered pre-selected if
- // one of the following is true:
- // - The authenticator omitted user entity information because only one
- // credential matched (only valid in CTAP 2.0).
- // - The `userSelected` flag is set, because the user chose an account on an
- // integrated authenticator UI (CTAP 2.1).
- // - The user already pre-selected a platform authenticator credential from
- // browser UI prior to the actual GetAssertion request. (The request handler
- // set the `userSelected` flag in this case.)
- if (response_data->size() == 1) {
- const device::AuthenticatorGetAssertionResponse& response =
- response_data->at(0);
- if (!req_state_->discoverable_credential_request ||
- response.user_selected || !response.user_entity ||
- !response.user_entity->name || !response.user_entity->display_name) {
- OnAccountSelected(std::move(response_data->at(0)));
- return;
- }
- }
-
- // Discoverable credential request without preselection UI. Show an account
- // picker.
- std::vector<device::PublicKeyCredentialUserEntity> users_list;
- users_list.reserve(response_data->size());
- for (const auto& response : *response_data) {
- if (response.user_entity) {
- users_list.push_back(*response.user_entity);
- }
- }
- req_state_->request_delegate->SelectAccount(
- std::move(*response_data),
- base::BindOnce(&AuthenticatorCommonTizen::OnAccountSelected,
- weak_factory_.GetWeakPtr()));
-}
-
-void AuthenticatorCommonTizen::OnAccountSelected(
- device::AuthenticatorGetAssertionResponse response) {}
-
void AuthenticatorCommonTizen::SignalFailureToRequestDelegate(
AuthenticatorRequestClientDelegate::InterestingFailureReason reason,
blink::mojom::AuthenticatorStatus status) {
AttestationErasureOption attestation_erasure) {
auto response = blink::mojom::MakeCredentialAuthenticatorResponse::New();
auto common_info = blink::mojom::CommonCredentialInfo::New();
+
std::string client_data_json = reinterpret_cast<const char*>(
pubkey_cred->response->client_data_json->data);
+
common_info->client_data_json.assign(client_data_json.begin(),
client_data_json.end());
-
- common_info->raw_id =
- std::vector<uint8_t>(pubkey_cred->rawId->data,
- pubkey_cred->rawId->data + pubkey_cred->rawId->size);
+ common_info->raw_id = ToBuffer(*(pubkey_cred->rawId));
common_info->id = Base64UrlEncode(common_info->raw_id);
device::FidoTransportProtocol transport_used;
}
response->attestation_object =
- std::vector<uint8_t>(pubkey_cred->response->attestation_object->data,
- pubkey_cred->response->attestation_object->data +
- pubkey_cred->response->attestation_object->size);
-
+ ToBuffer(*(pubkey_cred->response->attestation_object));
common_info->authenticator_data =
- std::vector<uint8_t>(pubkey_cred->response->authenticator_data->data,
- pubkey_cred->response->authenticator_data->data +
- pubkey_cred->response->authenticator_data->size);
+ ToBuffer(*(pubkey_cred->response->authenticator_data));
response->info = std::move(common_info);
response->public_key_algo = pubkey_cred->response->pubkey_alg;
+
return response;
}
std::move(req_state_->make_credential_response_callback)
.Run(status, std::move(response), std::move(dom_exception_details));
}
-
Cleanup();
}
const wauthn_pubkey_credential_assertion_s* pubkey_cred) {
auto response = blink::mojom::GetAssertionAuthenticatorResponse::New();
auto common_info = blink::mojom::CommonCredentialInfo::New();
+
std::string client_data_json = reinterpret_cast<const char*>(
pubkey_cred->response->client_data_json->data);
+
auto response_extensions =
blink::mojom::AuthenticationExtensionsClientOutputs::New();
common_info->client_data_json.assign(client_data_json.begin(),
client_data_json.end());
- common_info->raw_id =
- std::vector<uint8_t>(pubkey_cred->rawId->data,
- pubkey_cred->rawId->data + pubkey_cred->rawId->size);
+ common_info->raw_id = ToBuffer(*(pubkey_cred->rawId));
common_info->id = Base64UrlEncode(common_info->raw_id);
response->info = std::move(common_info);
response->info->authenticator_data =
- std::vector<uint8_t>(pubkey_cred->response->authenticator_data->data,
- pubkey_cred->response->authenticator_data->data +
- pubkey_cred->response->authenticator_data->size);
- response->signature =
- std::vector<uint8_t>(pubkey_cred->response->signature->data,
- pubkey_cred->response->signature->data +
- pubkey_cred->response->signature->size);
+ ToBuffer(*(pubkey_cred->response->authenticator_data));
+ response->signature = ToBuffer(*(pubkey_cred->response->signature));
+
response->authenticator_attachment =
pubkey_cred->authenticator_attachment
? pubkey_cred->authenticator_attachment ==
pubkey_cred->response->user_handle->size
? response->user_handle.emplace(
- std::vector<uint8_t>(pubkey_cred->response->user_handle->data,
- pubkey_cred->response->user_handle->data +
- pubkey_cred->response->user_handle->size))
+ ToBuffer(*(pubkey_cred->response->user_handle)))
: response->user_handle.emplace();
response->extensions = std::move(response_extensions);
+
return response;
}
AuthenticatorRequestClientDelegate::RequestSource
AuthenticatorCommonTizen::RequestSource() const {
- if (serving_requests_for_ == ServingRequestsFor::kInternalUses) {
- return AuthenticatorRequestClientDelegate::RequestSource::kInternal;
- }
if (req_state_->is_payment_request) {
return AuthenticatorRequestClientDelegate::RequestSource::
kSecurePaymentConfirmation;
return GetRenderFrameHost()->GetBrowserContext();
}
-device::FidoDiscoveryFactory* AuthenticatorCommonTizen::discovery_factory() {
- DCHECK(req_state_->discovery_factory);
- return req_state_->discovery_factory_testing_override
- ? req_state_->discovery_factory_testing_override.get()
- : req_state_->discovery_factory.get();
-}
-
-void AuthenticatorCommonTizen::InitDiscoveryFactory() {
- req_state_->discovery_factory = MakeDiscoveryFactory(GetRenderFrameHost());
- // TODO(martinkr): |discovery_factory_testing_override_| is a long-lived
- // VirtualFidoDeviceDiscovery so that tests can maintain and alter virtual
- // authenticator state in between requests. We should extract a longer-lived
- // configuration object from VirtualFidoDeviceDiscovery, so we can simply
- // stick a short-lived instance into |discovery_factory_| and eliminate
- // |discovery_factory_testing_override_|.
- req_state_->discovery_factory_testing_override =
- AuthenticatorEnvironment::GetInstance()
- ->MaybeGetDiscoveryFactoryTestOverride();
-}
-
void AuthenticatorCommonTizen::EnableRequestProxyExtensionsAPISupport() {
enable_request_proxy_api_ = true;
}