[go: nahoru, domu]

blob: df6218850984166fa14bceb3ac3f1e2c4eb31043 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device/fido/authenticator_make_credential_response.h"
#include <utility>
#include "components/cbor/writer.h"
#include "device/fido/attestation_object.h"
#include "device/fido/attestation_statement_formats.h"
#include "device/fido/attested_credential_data.h"
#include "device/fido/authenticator_data.h"
#include "device/fido/fido_parsing_utils.h"
#include "device/fido/p256_public_key.h"
#include "device/fido/public_key.h"
namespace device {
// static
absl::optional<AuthenticatorMakeCredentialResponse>
AuthenticatorMakeCredentialResponse::CreateFromU2fRegisterResponse(
absl::optional<FidoTransportProtocol> transport_used,
base::span<const uint8_t, kRpIdHashLength> relying_party_id_hash,
base::span<const uint8_t> u2f_data) {
auto public_key = P256PublicKey::ExtractFromU2fRegistrationResponse(
static_cast<int32_t>(CoseAlgorithmIdentifier::kEs256), u2f_data);
if (!public_key)
return absl::nullopt;
auto attested_credential_data =
AttestedCredentialData::CreateFromU2fRegisterResponse(
u2f_data, std::move(public_key));
if (!attested_credential_data)
return absl::nullopt;
// Extract the credential_id for packing into the response data.
std::vector<uint8_t> credential_id =
attested_credential_data->credential_id();
// The counter is zeroed out for Register requests.
std::array<uint8_t, 4> counter = {};
constexpr uint8_t flags =
static_cast<uint8_t>(AuthenticatorData::Flag::kTestOfUserPresence) |
static_cast<uint8_t>(AuthenticatorData::Flag::kAttestation);
AuthenticatorData authenticator_data(relying_party_id_hash, flags, counter,
std::move(attested_credential_data));
auto fido_attestation_statement =
FidoAttestationStatement::CreateFromU2fRegisterResponse(u2f_data);
if (!fido_attestation_statement)
return absl::nullopt;
AuthenticatorMakeCredentialResponse response(
transport_used, AttestationObject(std::move(authenticator_data),
std::move(fido_attestation_statement)));
response.is_resident_key = false;
return response;
}
AuthenticatorMakeCredentialResponse::AuthenticatorMakeCredentialResponse(
absl::optional<FidoTransportProtocol> transport_used,
AttestationObject attestation_object)
: attestation_object_(std::move(attestation_object)),
transport_used_(transport_used) {}
AuthenticatorMakeCredentialResponse::AuthenticatorMakeCredentialResponse(
AuthenticatorMakeCredentialResponse&& that) = default;
AuthenticatorMakeCredentialResponse&
AuthenticatorMakeCredentialResponse::operator=(
AuthenticatorMakeCredentialResponse&& other) = default;
AuthenticatorMakeCredentialResponse::~AuthenticatorMakeCredentialResponse() =
default;
std::vector<uint8_t>
AuthenticatorMakeCredentialResponse::GetCBOREncodedAttestationObject() const {
return cbor::Writer::Write(AsCBOR(attestation_object_))
.value_or(std::vector<uint8_t>());
}
void AuthenticatorMakeCredentialResponse::EraseAttestationStatement(
AttestationObject::AAGUID erase_aaguid) {
attestation_object_.EraseAttestationStatement(erase_aaguid);
}
bool AuthenticatorMakeCredentialResponse::IsSelfAttestation() {
return attestation_object_.IsSelfAttestation();
}
bool AuthenticatorMakeCredentialResponse::
IsAttestationCertificateInappropriatelyIdentifying() {
return attestation_object_
.IsAttestationCertificateInappropriatelyIdentifying();
}
const std::array<uint8_t, kRpIdHashLength>&
AuthenticatorMakeCredentialResponse::GetRpIdHash() const {
return attestation_object_.rp_id_hash();
}
void AuthenticatorMakeCredentialResponse::set_large_blob_key(
const base::span<const uint8_t, kLargeBlobKeyLength> large_blob_key) {
large_blob_key_ = fido_parsing_utils::Materialize(large_blob_key);
}
std::vector<uint8_t> AsCTAPStyleCBORBytes(
const AuthenticatorMakeCredentialResponse& response) {
const AttestationObject& object = response.attestation_object();
cbor::Value::MapValue map;
map.emplace(1, object.attestation_statement().format_name());
map.emplace(2, object.authenticator_data().SerializeToByteArray());
map.emplace(3, AsCBOR(object.attestation_statement()));
if (response.enterprise_attestation_returned) {
map.emplace(4, true);
}
if (response.large_blob_key()) {
map.emplace(5, cbor::Value(*response.large_blob_key()));
}
auto encoded_bytes = cbor::Writer::Write(cbor::Value(std::move(map)));
DCHECK(encoded_bytes);
return std::move(*encoded_bytes);
}
} // namespace device