1 // Copyright 2019 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 "content/browser/webauth/authenticator_mojom_traits.h"
6
7 #include <vector>
8
9 #include "base/optional.h"
10 #include "device/fido/authenticator_selection_criteria.h"
11 #include "device/fido/cable/cable_discovery_data.h"
12 #include "device/fido/fido_constants.h"
13 #include "device/fido/fido_transport_protocol.h"
14 #include "device/fido/public_key_credential_descriptor.h"
15 #include "device/fido/public_key_credential_params.h"
16 #include "device/fido/public_key_credential_rp_entity.h"
17 #include "device/fido/public_key_credential_user_entity.h"
18 #include "mojo/public/cpp/test_support/test_utils.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "third_party/blink/public/mojom/webauthn/authenticator.mojom.h"
21 #include "url/gurl.h"
22 #include "url/mojom/url_gurl_mojom_traits.h"
23
24 namespace mojo {
25
26 using device::AuthenticatorAttachment;
27 using device::AuthenticatorSelectionCriteria;
28 using device::CableDiscoveryData;
29 using device::CableEidArray;
30 using device::CableSessionPreKeyArray;
31 using device::CoseAlgorithmIdentifier;
32 using device::CredentialType;
33 using device::FidoTransportProtocol;
34 using device::PublicKeyCredentialDescriptor;
35 using device::PublicKeyCredentialParams;
36 using device::PublicKeyCredentialRpEntity;
37 using device::PublicKeyCredentialUserEntity;
38 using device::ResidentKeyRequirement;
39 using device::UserVerificationRequirement;
40
41 const std::vector<uint8_t> kDescriptorId = {'d', 'e', 's', 'c'};
42 constexpr char kRpId[] = "google.com";
43 constexpr char kRpName[] = "Google";
44 constexpr char kTestURL[] = "https://gstatic.com/fakeurl2.png";
45 constexpr CableEidArray kClientEid = {{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
46 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13,
47 0x14, 0x15}};
48 constexpr CableEidArray kAuthenticatorEid = {
49 {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
50 0x01, 0x01, 0x01, 0x01}};
51 constexpr CableSessionPreKeyArray kSessionPreKey = {
52 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
53 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
54 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
55
56 namespace {
57
58 template <typename MojomType, typename UserType>
AssertSerializeAndDeserializeSucceeds(std::vector<UserType> test_cases)59 void AssertSerializeAndDeserializeSucceeds(std::vector<UserType> test_cases) {
60 for (auto original : test_cases) {
61 UserType copied;
62 EXPECT_TRUE(
63 mojo::test::SerializeAndDeserialize<MojomType>(&original, &copied));
64 EXPECT_EQ(original, copied);
65 }
66 }
67
68 } // namespace
69
70 // Verify serialization and deserialization of PublicKeyCredentialParams.
TEST(AuthenticatorMojomTraitsTest,SerializeCredentialParams)71 TEST(AuthenticatorMojomTraitsTest, SerializeCredentialParams) {
72 std::vector<PublicKeyCredentialParams::CredentialInfo> success_cases = {
73 {CredentialType::kPublicKey,
74 base::strict_cast<int>(CoseAlgorithmIdentifier::kEs256)}};
75
76 AssertSerializeAndDeserializeSucceeds<
77 blink::mojom::PublicKeyCredentialParameters,
78 PublicKeyCredentialParams::CredentialInfo>(success_cases);
79 }
80
81 // Verify serialization and deserialization of PublicKeyCredentialDescriptor.
TEST(AuthenticatorMojomTraitsTest,SerializeCredentialDescriptors)82 TEST(AuthenticatorMojomTraitsTest, SerializeCredentialDescriptors) {
83 std::vector<PublicKeyCredentialDescriptor> success_cases = {
84 PublicKeyCredentialDescriptor(CredentialType::kPublicKey, kDescriptorId),
85 PublicKeyCredentialDescriptor(CredentialType::kPublicKey, kDescriptorId),
86 PublicKeyCredentialDescriptor(CredentialType::kPublicKey, kDescriptorId)};
87 success_cases[1].GetTransportsForTesting().emplace(
88 FidoTransportProtocol::kInternal);
89 success_cases[2].GetTransportsForTesting().emplace(
90 FidoTransportProtocol::kInternal);
91 success_cases[2].GetTransportsForTesting().emplace(
92 FidoTransportProtocol::kUsbHumanInterfaceDevice);
93 success_cases[2].GetTransportsForTesting().emplace(
94 FidoTransportProtocol::kNearFieldCommunication);
95 success_cases[2].GetTransportsForTesting().emplace(
96 FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy);
97 success_cases[2].GetTransportsForTesting().emplace(
98 FidoTransportProtocol::kBluetoothLowEnergy);
99
100 AssertSerializeAndDeserializeSucceeds<
101 blink::mojom::PublicKeyCredentialDescriptor,
102 PublicKeyCredentialDescriptor>(success_cases);
103 }
104
105 // Verify serialization and deserialization of AuthenticatorSelectionCriteria.
TEST(AuthenticatorMojomTraitsTest,SerializeAuthenticatorSelectionCriteria)106 TEST(AuthenticatorMojomTraitsTest, SerializeAuthenticatorSelectionCriteria) {
107 std::vector<AuthenticatorSelectionCriteria> success_cases = {
108 AuthenticatorSelectionCriteria(AuthenticatorAttachment::kAny,
109 ResidentKeyRequirement::kRequired,
110 UserVerificationRequirement::kRequired),
111 AuthenticatorSelectionCriteria(AuthenticatorAttachment::kPlatform,
112 ResidentKeyRequirement::kPreferred,
113 UserVerificationRequirement::kPreferred),
114 AuthenticatorSelectionCriteria(AuthenticatorAttachment::kPlatform,
115 ResidentKeyRequirement::kDiscouraged,
116 UserVerificationRequirement::kPreferred),
117 AuthenticatorSelectionCriteria(
118 AuthenticatorAttachment::kCrossPlatform,
119 ResidentKeyRequirement::kRequired,
120 UserVerificationRequirement::kDiscouraged)};
121
122 AssertSerializeAndDeserializeSucceeds<
123 blink::mojom::AuthenticatorSelectionCriteria,
124 AuthenticatorSelectionCriteria>(success_cases);
125 }
126
127 // Verify serialization and deserialization of PublicKeyCredentialRpEntity.
TEST(AuthenticatorMojomTraitsTest,SerializePublicKeyCredentialRpEntity)128 TEST(AuthenticatorMojomTraitsTest, SerializePublicKeyCredentialRpEntity) {
129 std::vector<PublicKeyCredentialRpEntity> success_cases = {
130 PublicKeyCredentialRpEntity(std::string(kRpId)),
131 PublicKeyCredentialRpEntity(std::string(kRpId))};
132 // TODO(kenrb): There is a mismatch between the types, where
133 // device::PublicKeyCredentialRpEntity can have base::nullopt for
134 // the name but the mapped mojom type is not optional. This should
135 // be corrected at some point. We can't currently test base::nullopt
136 // because it won't serialize.
137 success_cases[0].name = std::string(kRpName);
138 success_cases[0].icon_url = base::nullopt;
139 success_cases[1].name = std::string(kRpName);
140 success_cases[1].icon_url = GURL(kTestURL);
141
142 AssertSerializeAndDeserializeSucceeds<
143 blink::mojom::PublicKeyCredentialRpEntity, PublicKeyCredentialRpEntity>(
144 success_cases);
145 }
146
147 // Verify serialization and deserialization of PublicKeyCredentialUserEntity.
TEST(AuthenticatorMojomTraitsTest,SerializePublicKeyCredentialUserEntity)148 TEST(AuthenticatorMojomTraitsTest, SerializePublicKeyCredentialUserEntity) {
149 std::vector<PublicKeyCredentialUserEntity> success_cases = {
150 PublicKeyCredentialUserEntity(kDescriptorId),
151 PublicKeyCredentialUserEntity(kDescriptorId)};
152 // TODO(kenrb): |name| and |display_name| have the same issue as
153 // PublicKeyCredentialRpEntity::name above.
154 success_cases[0].name = std::string(kRpName);
155 success_cases[0].display_name = std::string(kRpName);
156 success_cases[0].icon_url = base::nullopt;
157 success_cases[1].name = std::string(kRpName);
158 success_cases[1].display_name = std::string(kRpName);
159 success_cases[1].icon_url = GURL(kTestURL);
160
161 AssertSerializeAndDeserializeSucceeds<
162 blink::mojom::PublicKeyCredentialUserEntity,
163 PublicKeyCredentialUserEntity>(success_cases);
164 }
165
166 // Verify serialization and deserialization of CableDiscoveryData.
TEST(AuthenticatorMojomTraitsTest,SerializeCableDiscoveryData)167 TEST(AuthenticatorMojomTraitsTest, SerializeCableDiscoveryData) {
168 std::vector<CableDiscoveryData> success_cases = {
169 CableDiscoveryData(CableDiscoveryData::Version::V1, kClientEid,
170 kAuthenticatorEid, kSessionPreKey)};
171
172 AssertSerializeAndDeserializeSucceeds<blink::mojom::CableAuthentication,
173 CableDiscoveryData>(success_cases);
174 }
175
176 } // namespace mojo
177