blob: 283f78c6b94a0866bdff4010b679fb4fe96d2133 [file] [log] [blame]
// Copyright 2017 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/u2f/attested_credential_data.h"
#include <utility>
#include "base/numerics/safe_math.h"
#include "device/u2f/public_key.h"
#include "device/u2f/u2f_parsing_utils.h"
namespace device {
// static
base::Optional<AttestedCredentialData>
AttestedCredentialData::CreateFromU2fRegisterResponse(
base::span<const uint8_t> u2f_data,
std::vector<uint8_t> aaguid,
std::unique_ptr<PublicKey> public_key) {
// TODO(crbug/799075): Introduce a CredentialID class to do this extraction.
// Extract the length of the credential (i.e. of the U2FResponse key
// handle). Length is big endian.
std::vector<uint8_t> extracted_length = u2f_parsing_utils::Extract(
u2f_data, u2f_parsing_utils::kU2fResponseKeyHandleLengthPos, 1);
if (extracted_length.empty()) {
return base::nullopt;
}
// Note that U2F responses only use one byte for length.
std::vector<uint8_t> credential_id_length = {0, extracted_length[0]};
// Extract the credential id (i.e. key handle).
std::vector<uint8_t> credential_id = u2f_parsing_utils::Extract(
u2f_data, u2f_parsing_utils::kU2fResponseKeyHandleStartPos,
base::strict_cast<size_t>(credential_id_length[1]));
if (credential_id.empty()) {
return base::nullopt;
}
return AttestedCredentialData(
std::move(aaguid), std::move(credential_id_length),
std::move(credential_id), std::move(public_key));
}
AttestedCredentialData::AttestedCredentialData(
std::vector<uint8_t> aaguid,
std::vector<uint8_t> length,
std::vector<uint8_t> credential_id,
std::unique_ptr<PublicKey> public_key)
: aaguid_(std::move(aaguid)),
credential_id_length_(std::move(length)),
credential_id_(std::move(credential_id)),
public_key_(std::move(public_key)) {}
AttestedCredentialData::AttestedCredentialData(AttestedCredentialData&& other) =
default;
AttestedCredentialData& AttestedCredentialData::operator=(
AttestedCredentialData&& other) = default;
AttestedCredentialData::~AttestedCredentialData() = default;
std::vector<uint8_t> AttestedCredentialData::SerializeAsBytes() const {
std::vector<uint8_t> attestation_data;
u2f_parsing_utils::Append(&attestation_data, aaguid_);
u2f_parsing_utils::Append(&attestation_data, credential_id_length_);
u2f_parsing_utils::Append(&attestation_data, credential_id_);
u2f_parsing_utils::Append(&attestation_data, public_key_->EncodeAsCOSEKey());
return attestation_data;
}
} // namespace device