Revert "Fix broken channel icon in chrome://help on CrOS" and try again
[chromium-blink-merge.git] / net / cert / internal / verify_name_match_unittest.cc
blob667581273c3239abc862b7b11e8b143fcdebdef3
1 // Copyright 2015 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.
5 #include "net/cert/internal/verify_name_match.h"
7 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/string_util.h"
9 #include "net/cert/internal/test_helpers.h"
10 #include "net/der/input.h"
11 #include "net/der/parser.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 namespace net {
15 namespace {
17 der::Input SequenceValueFromString(const std::string* s) {
18 der::Parser parser(InputFromString(s));
19 der::Input data;
20 if (!parser.ReadTag(der::kSequence, &data)) {
21 ADD_FAILURE();
22 return der::Input();
24 if (parser.HasMore()) {
25 ADD_FAILURE();
26 return der::Input();
28 return data;
31 // Loads test data from file. The filename is constructed from the parameters:
32 // |prefix| describes the type of data being tested, e.g. "ascii",
33 // "unicode_bmp", "unicode_supplementary", and "invalid".
34 // |value_type| indicates what ASN.1 type is used to encode the data.
35 // |suffix| indicates any additional modifications, such as caseswapping,
36 // whitespace adding, etc.
37 ::testing::AssertionResult LoadTestData(const std::string& prefix,
38 const std::string& value_type,
39 const std::string& suffix,
40 std::string* result) {
41 std::string path = "net/data/verify_name_match_unittest/names/" + prefix +
42 "-" + value_type + "-" + suffix + ".pem";
44 const PemBlockMapping mappings[] = {
45 {"NAME", result},
48 return ReadTestDataFromPemFile(path, mappings);
51 bool TypesAreComparable(const std::string& type_1, const std::string& type_2) {
52 if (type_1 == type_2)
53 return true;
54 if ((type_1 == "PRINTABLESTRING" || type_1 == "UTF8" ||
55 type_1 == "BMPSTRING" || type_1 == "UNIVERSALSTRING") &&
56 (type_2 == "PRINTABLESTRING" || type_2 == "UTF8" ||
57 type_2 == "BMPSTRING" || type_2 == "UNIVERSALSTRING")) {
58 return true;
60 return false;
63 // All string types.
64 static const char* kValueTypes[] = {"PRINTABLESTRING", "T61STRING", "UTF8",
65 "BMPSTRING", "UNIVERSALSTRING"};
66 // String types that can encode the Unicode Basic Multilingual Plane.
67 static const char* kUnicodeBMPValueTypes[] = {"UTF8", "BMPSTRING",
68 "UNIVERSALSTRING"};
69 // String types that can encode the Unicode Supplementary Planes.
70 static const char* kUnicodeSupplementaryValueTypes[] = {"UTF8",
71 "UNIVERSALSTRING"};
73 static const char* kMangleTypes[] = {"unmangled", "case_swap",
74 "extra_whitespace"};
76 } // namespace
78 class VerifyNameMatchSimpleTest
79 : public ::testing::TestWithParam<
80 ::testing::tuple<const char*, const char*>> {
81 public:
82 std::string value_type() const { return ::testing::get<0>(GetParam()); }
83 std::string suffix() const { return ::testing::get<1>(GetParam()); }
86 // Compare each input against itself, verifies that all input data is parsed
87 // successfully.
88 TEST_P(VerifyNameMatchSimpleTest, ExactEquality) {
89 std::string der;
90 ASSERT_TRUE(LoadTestData("ascii", value_type(), suffix(), &der));
91 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(&der),
92 SequenceValueFromString(&der)));
94 std::string der_extra_attr;
95 ASSERT_TRUE(LoadTestData("ascii", value_type(), suffix() + "-extra_attr",
96 &der_extra_attr));
97 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(&der_extra_attr),
98 SequenceValueFromString(&der_extra_attr)));
100 std::string der_extra_rdn;
101 ASSERT_TRUE(LoadTestData("ascii", value_type(), suffix() + "-extra_rdn",
102 &der_extra_rdn));
103 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(&der_extra_rdn),
104 SequenceValueFromString(&der_extra_rdn)));
107 // Ensure that a Name does not match another Name which is exactly the same but
108 // with an extra attribute in one Relative Distinguished Name.
109 TEST_P(VerifyNameMatchSimpleTest, ExtraAttrDoesNotMatch) {
110 std::string der;
111 ASSERT_TRUE(LoadTestData("ascii", value_type(), suffix(), &der));
112 std::string der_extra_attr;
113 ASSERT_TRUE(LoadTestData("ascii", value_type(), suffix() + "-extra_attr",
114 &der_extra_attr));
115 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(&der),
116 SequenceValueFromString(&der_extra_attr)));
117 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(&der_extra_attr),
118 SequenceValueFromString(&der)));
121 // Ensure that a Name does not match another Name which is exactly the same but
122 // with an extra Relative Distinguished Name.
123 TEST_P(VerifyNameMatchSimpleTest, ExtraRdnDoesNotMatch) {
124 std::string der;
125 ASSERT_TRUE(LoadTestData("ascii", value_type(), suffix(), &der));
126 std::string der_extra_rdn;
127 ASSERT_TRUE(LoadTestData("ascii", value_type(), suffix() + "-extra_rdn",
128 &der_extra_rdn));
129 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(&der),
130 SequenceValueFromString(&der_extra_rdn)));
131 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(&der_extra_rdn),
132 SequenceValueFromString(&der)));
135 // Runs VerifyNameMatchSimpleTest for all combinations of value_type and and
136 // suffix.
137 INSTANTIATE_TEST_CASE_P(InstantiationName,
138 VerifyNameMatchSimpleTest,
139 ::testing::Combine(::testing::ValuesIn(kValueTypes),
140 ::testing::ValuesIn(kMangleTypes)));
142 class VerifyNameMatchNormalizationTest
143 : public ::testing::TestWithParam<::testing::tuple<bool, const char*>> {
144 public:
145 bool expected_result() const { return ::testing::get<0>(GetParam()); }
146 std::string value_type() const { return ::testing::get<1>(GetParam()); }
149 // Verify matching is case insensitive (for the types which currently support
150 // normalization).
151 TEST_P(VerifyNameMatchNormalizationTest, CaseInsensitivity) {
152 std::string normal;
153 ASSERT_TRUE(LoadTestData("ascii", value_type(), "unmangled", &normal));
154 std::string case_swap;
155 ASSERT_TRUE(LoadTestData("ascii", value_type(), "case_swap", &case_swap));
156 EXPECT_EQ(expected_result(),
157 VerifyNameMatch(SequenceValueFromString(&normal),
158 SequenceValueFromString(&case_swap)));
159 EXPECT_EQ(expected_result(),
160 VerifyNameMatch(SequenceValueFromString(&case_swap),
161 SequenceValueFromString(&normal)));
164 // Verify matching folds whitespace (for the types which currently support
165 // normalization).
166 TEST_P(VerifyNameMatchNormalizationTest, CollapseWhitespace) {
167 std::string normal;
168 ASSERT_TRUE(LoadTestData("ascii", value_type(), "unmangled", &normal));
169 std::string whitespace;
170 ASSERT_TRUE(
171 LoadTestData("ascii", value_type(), "extra_whitespace", &whitespace));
172 EXPECT_EQ(expected_result(),
173 VerifyNameMatch(SequenceValueFromString(&normal),
174 SequenceValueFromString(&whitespace)));
175 EXPECT_EQ(expected_result(),
176 VerifyNameMatch(SequenceValueFromString(&whitespace),
177 SequenceValueFromString(&normal)));
180 // Runs VerifyNameMatchNormalizationTest for each (expected_result, value_type)
181 // tuple.
182 INSTANTIATE_TEST_CASE_P(
183 InstantiationName,
184 VerifyNameMatchNormalizationTest,
185 ::testing::Values(
186 ::testing::make_tuple(true,
187 static_cast<const char*>("PRINTABLESTRING")),
188 ::testing::make_tuple(false, static_cast<const char*>("T61STRING")),
189 ::testing::make_tuple(true, static_cast<const char*>("UTF8")),
190 ::testing::make_tuple(true, static_cast<const char*>("BMPSTRING")),
191 ::testing::make_tuple(true,
192 static_cast<const char*>("UNIVERSALSTRING"))));
194 class VerifyNameMatchDifferingTypesTest
195 : public ::testing::TestWithParam<
196 ::testing::tuple<const char*, const char*>> {
197 public:
198 std::string value_type_1() const { return ::testing::get<0>(GetParam()); }
199 std::string value_type_2() const { return ::testing::get<1>(GetParam()); }
202 TEST_P(VerifyNameMatchDifferingTypesTest, NormalizableTypesAreEqual) {
203 std::string der_1;
204 ASSERT_TRUE(LoadTestData("ascii", value_type_1(), "unmangled", &der_1));
205 std::string der_2;
206 ASSERT_TRUE(LoadTestData("ascii", value_type_2(), "unmangled", &der_2));
207 if (TypesAreComparable(value_type_1(), value_type_2())) {
208 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(&der_1),
209 SequenceValueFromString(&der_2)));
210 } else {
211 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(&der_1),
212 SequenceValueFromString(&der_2)));
216 // Runs VerifyNameMatchDifferingTypesTest for all combinations of value types in
217 // value_type1 and value_type_2.
218 INSTANTIATE_TEST_CASE_P(InstantiationName,
219 VerifyNameMatchDifferingTypesTest,
220 ::testing::Combine(::testing::ValuesIn(kValueTypes),
221 ::testing::ValuesIn(kValueTypes)));
223 class VerifyNameMatchUnicodeConversionTest
224 : public ::testing::TestWithParam<
225 ::testing::tuple<const char*,
226 ::testing::tuple<const char*, const char*>>> {
227 public:
228 std::string prefix() const { return ::testing::get<0>(GetParam()); }
229 std::string value_type_1() const {
230 return ::testing::get<0>(::testing::get<1>(GetParam()));
232 std::string value_type_2() const {
233 return ::testing::get<1>(::testing::get<1>(GetParam()));
237 TEST_P(VerifyNameMatchUnicodeConversionTest, UnicodeConversionsAreEqual) {
238 std::string der_1;
239 ASSERT_TRUE(LoadTestData(prefix(), value_type_1(), "unmangled", &der_1));
240 std::string der_2;
241 ASSERT_TRUE(LoadTestData(prefix(), value_type_2(), "unmangled", &der_2));
242 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(&der_1),
243 SequenceValueFromString(&der_2)));
246 // Runs VerifyNameMatchUnicodeConversionTest with prefix="unicode_bmp" for all
247 // combinations of Basic Multilingual Plane-capable value types in value_type1
248 // and value_type_2.
249 INSTANTIATE_TEST_CASE_P(
250 BMPConversion,
251 VerifyNameMatchUnicodeConversionTest,
252 ::testing::Combine(
253 ::testing::Values("unicode_bmp"),
254 ::testing::Combine(::testing::ValuesIn(kUnicodeBMPValueTypes),
255 ::testing::ValuesIn(kUnicodeBMPValueTypes))));
257 // Runs VerifyNameMatchUnicodeConversionTest with prefix="unicode_supplementary"
258 // for all combinations of Unicode Supplementary Plane-capable value types in
259 // value_type1 and value_type_2.
260 INSTANTIATE_TEST_CASE_P(
261 SMPConversion,
262 VerifyNameMatchUnicodeConversionTest,
263 ::testing::Combine(
264 ::testing::Values("unicode_supplementary"),
265 ::testing::Combine(
266 ::testing::ValuesIn(kUnicodeSupplementaryValueTypes),
267 ::testing::ValuesIn(kUnicodeSupplementaryValueTypes))));
269 // Matching should fail if a PrintableString contains invalid characters.
270 TEST(VerifyNameMatchInvalidDataTest, FailOnInvalidPrintableStringChars) {
271 std::string der;
272 ASSERT_TRUE(LoadTestData("ascii", "PRINTABLESTRING", "unmangled", &der));
273 // Find a known location inside a PrintableString in the DER-encoded data.
274 size_t replace_location = der.find("0123456789");
275 ASSERT_NE(std::string::npos, replace_location);
276 for (int c = 0; c < 256; ++c) {
277 SCOPED_TRACE(base::IntToString(c));
278 if (base::IsAsciiAlpha(c) || base::IsAsciiDigit(c))
279 continue;
280 switch (c) {
281 case ' ':
282 case '\'':
283 case '(':
284 case ')':
285 case '*':
286 case '+':
287 case ',':
288 case '-':
289 case '.':
290 case '/':
291 case ':':
292 case '=':
293 case '?':
294 continue;
296 der.replace(replace_location, 1, 1, c);
297 // Verification should fail due to the invalid character.
298 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(&der),
299 SequenceValueFromString(&der)));
303 // Matching should fail if an IA5String contains invalid characters.
304 TEST(VerifyNameMatchInvalidDataTest, FailOnInvalidIA5StringChars) {
305 std::string der;
306 ASSERT_TRUE(LoadTestData("ascii", "mixed", "rdn_dupetype_sorting_1", &der));
307 // Find a known location inside an IA5String in the DER-encoded data.
308 size_t replace_location = der.find("eXaMple");
309 ASSERT_NE(std::string::npos, replace_location);
310 for (int c = 0; c < 256; ++c) {
311 SCOPED_TRACE(base::IntToString(c));
312 der.replace(replace_location, 1, 1, c);
313 bool expected_result = (c <= 127);
314 EXPECT_EQ(expected_result, VerifyNameMatch(SequenceValueFromString(&der),
315 SequenceValueFromString(&der)));
319 TEST(VerifyNameMatchInvalidDataTest, FailOnAttributeTypeAndValueExtraData) {
320 std::string invalid;
321 ASSERT_TRUE(
322 LoadTestData("invalid", "AttributeTypeAndValue", "extradata", &invalid));
323 // Verification should fail due to extra element in AttributeTypeAndValue
324 // sequence.
325 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(&invalid),
326 SequenceValueFromString(&invalid)));
329 TEST(VerifyNameMatchInvalidDataTest, FailOnAttributeTypeAndValueShort) {
330 std::string invalid;
331 ASSERT_TRUE(LoadTestData("invalid", "AttributeTypeAndValue", "onlyOneElement",
332 &invalid));
333 // Verification should fail due to AttributeTypeAndValue sequence having only
334 // one element.
335 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(&invalid),
336 SequenceValueFromString(&invalid)));
339 TEST(VerifyNameMatchInvalidDataTest, FailOnAttributeTypeAndValueEmpty) {
340 std::string invalid;
341 ASSERT_TRUE(
342 LoadTestData("invalid", "AttributeTypeAndValue", "empty", &invalid));
343 // Verification should fail due to empty AttributeTypeAndValue sequence.
344 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(&invalid),
345 SequenceValueFromString(&invalid)));
348 TEST(VerifyNameMatchInvalidDataTest, FailOnBadAttributeType) {
349 std::string invalid;
350 ASSERT_TRUE(LoadTestData("invalid", "AttributeTypeAndValue",
351 "badAttributeType", &invalid));
352 // Verification should fail due to Attribute Type not being an OID.
353 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(&invalid),
354 SequenceValueFromString(&invalid)));
357 TEST(VerifyNameMatchInvalidDataTest, FailOnAttributeTypeAndValueNotSequence) {
358 std::string invalid;
359 ASSERT_TRUE(LoadTestData("invalid", "AttributeTypeAndValue", "setNotSequence",
360 &invalid));
361 // Verification should fail due to AttributeTypeAndValue being a Set instead
362 // of a Sequence.
363 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(&invalid),
364 SequenceValueFromString(&invalid)));
367 TEST(VerifyNameMatchInvalidDataTest, FailOnRdnNotSet) {
368 std::string invalid;
369 ASSERT_TRUE(LoadTestData("invalid", "RDN", "sequenceInsteadOfSet", &invalid));
370 // Verification should fail due to RDN being a Sequence instead of a Set.
371 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(&invalid),
372 SequenceValueFromString(&invalid)));
375 TEST(VerifyNameMatchInvalidDataTest, FailOnEmptyRdn) {
376 std::string invalid;
377 ASSERT_TRUE(LoadTestData("invalid", "RDN", "empty", &invalid));
378 // Verification should fail due to RDN having zero AttributeTypeAndValues.
379 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(&invalid),
380 SequenceValueFromString(&invalid)));
383 // Matching should fail if a BMPString contains surrogates.
384 TEST(VerifyNameMatchInvalidDataTest, FailOnBmpStringSurrogates) {
385 std::string normal;
386 ASSERT_TRUE(LoadTestData("unicode_bmp", "BMPSTRING", "unmangled", &normal));
387 // Find a known location inside a BMPSTRING in the DER-encoded data.
388 size_t replace_location = normal.find("\x67\x71\x4e\xac");
389 ASSERT_NE(std::string::npos, replace_location);
390 // Replace with U+1D400 MATHEMATICAL BOLD CAPITAL A, which requires surrogates
391 // to represent.
392 std::string invalid =
393 normal.replace(replace_location, 4, std::string("\xd8\x35\xdc\x00", 4));
394 // Verification should fail due to the invalid codepoints.
395 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(&invalid),
396 SequenceValueFromString(&invalid)));
399 TEST(VerifyNameMatchTest, EmptyNameMatching) {
400 std::string empty;
401 ASSERT_TRUE(LoadTestData("valid", "Name", "empty", &empty));
402 // Empty names are equal.
403 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(&empty),
404 SequenceValueFromString(&empty)));
406 // An empty name is not equal to non-empty name.
407 std::string non_empty;
408 ASSERT_TRUE(
409 LoadTestData("ascii", "PRINTABLESTRING", "unmangled", &non_empty));
410 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(&empty),
411 SequenceValueFromString(&non_empty)));
412 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(&non_empty),
413 SequenceValueFromString(&empty)));
416 // Matching should succeed when the RDNs are sorted differently but are still
417 // equal after normalizing.
418 TEST(VerifyNameMatchRDNSorting, Simple) {
419 std::string a;
420 ASSERT_TRUE(LoadTestData("ascii", "PRINTABLESTRING", "rdn_sorting_1", &a));
421 std::string b;
422 ASSERT_TRUE(LoadTestData("ascii", "PRINTABLESTRING", "rdn_sorting_2", &b));
423 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(&a),
424 SequenceValueFromString(&b)));
425 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(&b),
426 SequenceValueFromString(&a)));
429 // Matching should succeed when the RDNs are sorted differently but are still
430 // equal after normalizing, even in malformed RDNs that contain multiple
431 // elements with the same type.
432 TEST(VerifyNameMatchRDNSorting, DuplicateTypes) {
433 std::string a;
434 ASSERT_TRUE(LoadTestData("ascii", "mixed", "rdn_dupetype_sorting_1", &a));
435 std::string b;
436 ASSERT_TRUE(LoadTestData("ascii", "mixed", "rdn_dupetype_sorting_2", &b));
437 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(&a),
438 SequenceValueFromString(&b)));
439 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(&b),
440 SequenceValueFromString(&a)));
443 } // namespace net