blob: 044e61174440279ab2936a2aa1ca4a712678c4f6 [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/fido/ec_public_key.h"
#include <utility>
#include "components/cbor/cbor_writer.h"
#include "device/fido/u2f_parsing_utils.h"
namespace device {
namespace {
// The key is located after the first byte of the response
// (which is a reserved byte).
// The uncompressed form consists of 65 bytes:
// - a constant 0x04 prefix
// - the 32-byte x coordinate
// - the 32-byte y coordinate.
constexpr size_t kHeaderLength = 2; // Account for reserved byte and prefix.
constexpr size_t kKeyLength = 32;
} // namespace
// static
std::unique_ptr<ECPublicKey> ECPublicKey::ExtractFromU2fRegistrationResponse(
std::string algorithm,
base::span<const uint8_t> u2f_data) {
std::vector<uint8_t> x =
u2f_parsing_utils::Extract(u2f_data, kHeaderLength, kKeyLength);
if (x.empty())
return nullptr;
std::vector<uint8_t> y = u2f_parsing_utils::Extract(
u2f_data, kHeaderLength + kKeyLength, kKeyLength);
if (y.empty())
return nullptr;
return std::make_unique<ECPublicKey>(std::move(algorithm), std::move(x),
std::move(y));
}
ECPublicKey::ECPublicKey(std::string algorithm,
std::vector<uint8_t> x,
std::vector<uint8_t> y)
: PublicKey(std::move(algorithm)),
x_coordinate_(std::move(x)),
y_coordinate_(std::move(y)) {
DCHECK_EQ(x_coordinate_.size(), kKeyLength);
DCHECK_EQ(y_coordinate_.size(), kKeyLength);
}
ECPublicKey::~ECPublicKey() = default;
std::vector<uint8_t> ECPublicKey::EncodeAsCOSEKey() const {
cbor::CBORValue::MapValue map;
map[cbor::CBORValue(1)] = cbor::CBORValue(2);
map[cbor::CBORValue(3)] = cbor::CBORValue(-7);
map[cbor::CBORValue(-1)] = cbor::CBORValue(1);
map[cbor::CBORValue(-2)] = cbor::CBORValue(x_coordinate_);
map[cbor::CBORValue(-3)] = cbor::CBORValue(y_coordinate_);
return *cbor::CBORWriter::Write(cbor::CBORValue(std::move(map)));
}
} // namespace device