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