1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "device/fido/public_key_credential_user_entity.h"
6 
7 #include <utility>
8 
9 #include "device/fido/fido_constants.h"
10 
11 namespace device {
12 
13 // static
14 base::Optional<PublicKeyCredentialUserEntity>
CreateFromCBORValue(const cbor::Value & cbor)15 PublicKeyCredentialUserEntity::CreateFromCBORValue(const cbor::Value& cbor) {
16   if (!cbor.is_map())
17     return base::nullopt;
18 
19   const cbor::Value::MapValue& cbor_map = cbor.GetMap();
20 
21   auto id_it = cbor_map.find(cbor::Value(kEntityIdMapKey));
22   if (id_it == cbor_map.end() || !id_it->second.is_bytestring())
23     return base::nullopt;
24 
25   PublicKeyCredentialUserEntity user(id_it->second.GetBytestring());
26 
27   auto name_it = cbor_map.find(cbor::Value(kEntityNameMapKey));
28   if (name_it != cbor_map.end()) {
29     if (!name_it->second.is_string()) {
30       return base::nullopt;
31     }
32     user.name = name_it->second.GetString();
33   }
34 
35   auto display_name_it = cbor_map.find(cbor::Value(kDisplayNameMapKey));
36   if (display_name_it != cbor_map.end()) {
37     if (!display_name_it->second.is_string()) {
38       return base::nullopt;
39     }
40     user.display_name = display_name_it->second.GetString();
41   }
42 
43   auto icon_it = cbor_map.find(cbor::Value(kIconUrlMapKey));
44   if (icon_it != cbor_map.end()) {
45     if (!icon_it->second.is_string()) {
46       return base::nullopt;
47     }
48     user.icon_url = GURL(icon_it->second.GetString());
49     if (!user.icon_url->is_valid()) {
50       return base::nullopt;
51     }
52   }
53 
54   return user;
55 }
56 
57 PublicKeyCredentialUserEntity::PublicKeyCredentialUserEntity() = default;
58 
PublicKeyCredentialUserEntity(std::vector<uint8_t> id_)59 PublicKeyCredentialUserEntity::PublicKeyCredentialUserEntity(
60     std::vector<uint8_t> id_)
61     : id(std::move(id_)) {}
62 
PublicKeyCredentialUserEntity(std::vector<uint8_t> id_,base::Optional<std::string> name_,base::Optional<std::string> display_name_,base::Optional<GURL> icon_url_)63 PublicKeyCredentialUserEntity::PublicKeyCredentialUserEntity(
64     std::vector<uint8_t> id_,
65     base::Optional<std::string> name_,
66     base::Optional<std::string> display_name_,
67     base::Optional<GURL> icon_url_)
68     : id(std::move(id_)),
69       name(std::move(name_)),
70       display_name(std::move(display_name_)),
71       icon_url(std::move(icon_url_)) {}
72 
73 PublicKeyCredentialUserEntity::PublicKeyCredentialUserEntity(
74     const PublicKeyCredentialUserEntity& other) = default;
75 
76 PublicKeyCredentialUserEntity::PublicKeyCredentialUserEntity(
77     PublicKeyCredentialUserEntity&& other) = default;
78 
79 PublicKeyCredentialUserEntity& PublicKeyCredentialUserEntity::operator=(
80     const PublicKeyCredentialUserEntity& other) = default;
81 
82 PublicKeyCredentialUserEntity& PublicKeyCredentialUserEntity::operator=(
83     PublicKeyCredentialUserEntity&& other) = default;
84 
85 PublicKeyCredentialUserEntity::~PublicKeyCredentialUserEntity() = default;
86 
operator ==(const PublicKeyCredentialUserEntity & other) const87 bool PublicKeyCredentialUserEntity::operator==(
88     const PublicKeyCredentialUserEntity& other) const {
89   return id == other.id && name == other.name &&
90          display_name == other.display_name && icon_url == other.icon_url;
91 }
92 
AsCBOR(const PublicKeyCredentialUserEntity & user)93 cbor::Value AsCBOR(const PublicKeyCredentialUserEntity& user) {
94   cbor::Value::MapValue user_map;
95   user_map.emplace(kEntityIdMapKey, user.id);
96   if (user.name)
97     user_map.emplace(kEntityNameMapKey, *user.name);
98   // Empty icon URLs result in CTAP1_ERR_INVALID_LENGTH on some security keys.
99   if (user.icon_url && !user.icon_url->is_empty())
100     user_map.emplace(kIconUrlMapKey, user.icon_url->spec());
101   if (user.display_name)
102     user_map.emplace(kDisplayNameMapKey, *user.display_name);
103   return cbor::Value(std::move(user_map));
104 }
105 
106 }  // namespace device
107