blob: b4187bd47b245649e1feaf7eefc6cd7b82bc6d6c [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 <utility>
#include "device/fido/fido_transport_protocol.h"
#include "device/fido/public_key_credential_descriptor.h"
namespace device {
namespace {
// Keys for storing credential descriptor information in CBOR map.
constexpr char kCredentialIdKey[] = "id";
constexpr char kCredentialTypeKey[] = "type";
} // namespace
// static
absl::optional<PublicKeyCredentialDescriptor>
PublicKeyCredentialDescriptor::CreateFromCBORValue(const cbor::Value& cbor) {
if (!cbor.is_map()) {
return absl::nullopt;
}
const cbor::Value::MapValue& map = cbor.GetMap();
auto type = map.find(cbor::Value(kCredentialTypeKey));
if (type == map.end() || !type->second.is_string() ||
type->second.GetString() != kPublicKey)
return absl::nullopt;
auto id = map.find(cbor::Value(kCredentialIdKey));
if (id == map.end() || !id->second.is_bytestring())
return absl::nullopt;
auto ret = PublicKeyCredentialDescriptor(CredentialType::kPublicKey,
id->second.GetBytestring());
// If the map had other keys then this fact is recorded for testing because
// some security keys appear to have a parsing bug in this case. See
// crbug.com/1270757.
ret.had_other_keys = map.size() > 2;
return ret;
}
PublicKeyCredentialDescriptor::PublicKeyCredentialDescriptor() = default;
PublicKeyCredentialDescriptor::PublicKeyCredentialDescriptor(
CredentialType credential_type,
std::vector<uint8_t> id)
: PublicKeyCredentialDescriptor(credential_type, std::move(id), {}) {}
PublicKeyCredentialDescriptor::PublicKeyCredentialDescriptor(
CredentialType credential_type,
std::vector<uint8_t> id,
base::flat_set<FidoTransportProtocol> transports)
: credential_type(credential_type),
id(std::move(id)),
transports(std::move(transports)) {}
PublicKeyCredentialDescriptor::PublicKeyCredentialDescriptor(
const PublicKeyCredentialDescriptor& other) = default;
PublicKeyCredentialDescriptor::PublicKeyCredentialDescriptor(
PublicKeyCredentialDescriptor&& other) = default;
PublicKeyCredentialDescriptor& PublicKeyCredentialDescriptor::operator=(
const PublicKeyCredentialDescriptor& other) = default;
PublicKeyCredentialDescriptor& PublicKeyCredentialDescriptor::operator=(
PublicKeyCredentialDescriptor&& other) = default;
PublicKeyCredentialDescriptor::~PublicKeyCredentialDescriptor() = default;
bool PublicKeyCredentialDescriptor::operator==(
const PublicKeyCredentialDescriptor& other) const {
return credential_type == other.credential_type && id == other.id &&
transports == other.transports;
}
cbor::Value AsCBOR(const PublicKeyCredentialDescriptor& desc) {
cbor::Value::MapValue cbor_descriptor_map;
cbor_descriptor_map[cbor::Value(kCredentialIdKey)] = cbor::Value(desc.id);
cbor_descriptor_map[cbor::Value(kCredentialTypeKey)] =
cbor::Value(CredentialTypeToString(desc.credential_type));
// Transports are omitted from CBOR serialization. They aren't useful for
// security keys to process. Some existing devices even refuse to parse them
// (see https://crbug.com/1270757).
return cbor::Value(std::move(cbor_descriptor_map));
}
} // namespace device