1 // Copyright 2015 The Chromium Authors
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 "verify_name_match.h"
6
7 #include "string_util.h"
8 #include "test_helpers.h"
9 #include <gtest/gtest.h>
10
11 namespace bssl {
12 namespace {
13
14 // Loads test data from file. The filename is constructed from the parameters:
15 // |prefix| describes the type of data being tested, e.g. "ascii",
16 // "unicode_bmp", "unicode_supplementary", and "invalid".
17 // |value_type| indicates what ASN.1 type is used to encode the data.
18 // |suffix| indicates any additional modifications, such as caseswapping,
19 // whitespace adding, etc.
LoadTestData(const std::string & prefix,const std::string & value_type,const std::string & suffix,std::string * result)20 ::testing::AssertionResult LoadTestData(const std::string& prefix,
21 const std::string& value_type,
22 const std::string& suffix,
23 std::string* result) {
24 std::string path = "testdata/verify_name_match_unittest/names/" + prefix +
25 "-" + value_type + "-" + suffix + ".pem";
26
27 const PemBlockMapping mappings[] = {
28 {"NAME", result},
29 };
30
31 return ReadTestDataFromPemFile(path, mappings);
32 }
33
TypesAreComparable(const std::string & type_1,const std::string & type_2)34 bool TypesAreComparable(const std::string& type_1, const std::string& type_2) {
35 if (type_1 == type_2)
36 return true;
37 if ((type_1 == "PRINTABLESTRING" || type_1 == "UTF8" ||
38 type_1 == "BMPSTRING" || type_1 == "UNIVERSALSTRING") &&
39 (type_2 == "PRINTABLESTRING" || type_2 == "UTF8" ||
40 type_2 == "BMPSTRING" || type_2 == "UNIVERSALSTRING")) {
41 return true;
42 }
43 return false;
44 }
45
46 // All string types.
47 static const char* kValueTypes[] = {"PRINTABLESTRING", "T61STRING", "UTF8",
48 "BMPSTRING", "UNIVERSALSTRING"};
49 // String types that can encode the Unicode Basic Multilingual Plane.
50 static const char* kUnicodeBMPValueTypes[] = {"UTF8", "BMPSTRING",
51 "UNIVERSALSTRING"};
52 // String types that can encode the Unicode Supplementary Planes.
53 static const char* kUnicodeSupplementaryValueTypes[] = {"UTF8",
54 "UNIVERSALSTRING"};
55
56 static const char* kMangleTypes[] = {"unmangled", "case_swap",
57 "extra_whitespace"};
58
59 } // namespace
60
61 class VerifyNameMatchSimpleTest
62 : public ::testing::TestWithParam<
63 ::testing::tuple<const char*, const char*>> {
64 public:
value_type() const65 std::string value_type() const { return ::testing::get<0>(GetParam()); }
suffix() const66 std::string suffix() const { return ::testing::get<1>(GetParam()); }
67 };
68
69 // Compare each input against itself, verifies that all input data is parsed
70 // successfully.
TEST_P(VerifyNameMatchSimpleTest,ExactEquality)71 TEST_P(VerifyNameMatchSimpleTest, ExactEquality) {
72 std::string der;
73 ASSERT_TRUE(LoadTestData("ascii", value_type(), suffix(), &der));
74 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(der),
75 SequenceValueFromString(der)));
76
77 std::string der_extra_attr;
78 ASSERT_TRUE(LoadTestData("ascii", value_type(), suffix() + "-extra_attr",
79 &der_extra_attr));
80 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(der_extra_attr),
81 SequenceValueFromString(der_extra_attr)));
82
83 std::string der_extra_rdn;
84 ASSERT_TRUE(LoadTestData("ascii", value_type(), suffix() + "-extra_rdn",
85 &der_extra_rdn));
86 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(der_extra_rdn),
87 SequenceValueFromString(der_extra_rdn)));
88 }
89
90 // Ensure that a Name does not match another Name which is exactly the same but
91 // with an extra attribute in one Relative Distinguished Name.
TEST_P(VerifyNameMatchSimpleTest,ExtraAttrDoesNotMatch)92 TEST_P(VerifyNameMatchSimpleTest, ExtraAttrDoesNotMatch) {
93 std::string der;
94 ASSERT_TRUE(LoadTestData("ascii", value_type(), suffix(), &der));
95 std::string der_extra_attr;
96 ASSERT_TRUE(LoadTestData("ascii", value_type(), suffix() + "-extra_attr",
97 &der_extra_attr));
98 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(der),
99 SequenceValueFromString(der_extra_attr)));
100 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(der_extra_attr),
101 SequenceValueFromString(der)));
102 }
103
104 // Ensure that a Name does not match another Name which has the same number of
105 // RDNs and attributes, but where one of the attributes is duplicated in one of
106 // the names but not in the other.
TEST_P(VerifyNameMatchSimpleTest,DupeAttrDoesNotMatch)107 TEST_P(VerifyNameMatchSimpleTest, DupeAttrDoesNotMatch) {
108 std::string der_dupe_attr;
109 ASSERT_TRUE(LoadTestData("ascii", value_type(), suffix() + "-dupe_attr",
110 &der_dupe_attr));
111 std::string der_extra_attr;
112 ASSERT_TRUE(LoadTestData("ascii", value_type(), suffix() + "-extra_attr",
113 &der_extra_attr));
114 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(der_dupe_attr),
115 SequenceValueFromString(der_extra_attr)));
116 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(der_extra_attr),
117 SequenceValueFromString(der_dupe_attr)));
118 // However, the name with a dupe attribute should match itself.
119 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(der_dupe_attr),
120 SequenceValueFromString(der_dupe_attr)));
121 }
122
123 // Ensure that a Name does not match another Name which is exactly the same but
124 // with an extra Relative Distinguished Name.
TEST_P(VerifyNameMatchSimpleTest,ExtraRdnDoesNotMatch)125 TEST_P(VerifyNameMatchSimpleTest, ExtraRdnDoesNotMatch) {
126 std::string der;
127 ASSERT_TRUE(LoadTestData("ascii", value_type(), suffix(), &der));
128 std::string der_extra_rdn;
129 ASSERT_TRUE(LoadTestData("ascii", value_type(), suffix() + "-extra_rdn",
130 &der_extra_rdn));
131 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(der),
132 SequenceValueFromString(der_extra_rdn)));
133 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(der_extra_rdn),
134 SequenceValueFromString(der)));
135 }
136
137 // Runs VerifyNameMatchSimpleTest for all combinations of value_type and and
138 // suffix.
139 INSTANTIATE_TEST_SUITE_P(InstantiationName,
140 VerifyNameMatchSimpleTest,
141 ::testing::Combine(::testing::ValuesIn(kValueTypes),
142 ::testing::ValuesIn(kMangleTypes)));
143
144 class VerifyNameMatchNormalizationTest
145 : public ::testing::TestWithParam<::testing::tuple<bool, const char*>> {
146 public:
expected_result() const147 bool expected_result() const { return ::testing::get<0>(GetParam()); }
value_type() const148 std::string value_type() const { return ::testing::get<1>(GetParam()); }
149 };
150
151 // Verify matching is case insensitive (for the types which currently support
152 // normalization).
TEST_P(VerifyNameMatchNormalizationTest,CaseInsensitivity)153 TEST_P(VerifyNameMatchNormalizationTest, CaseInsensitivity) {
154 std::string normal;
155 ASSERT_TRUE(LoadTestData("ascii", value_type(), "unmangled", &normal));
156 std::string case_swap;
157 ASSERT_TRUE(LoadTestData("ascii", value_type(), "case_swap", &case_swap));
158 EXPECT_EQ(expected_result(),
159 VerifyNameMatch(SequenceValueFromString(normal),
160 SequenceValueFromString(case_swap)));
161 EXPECT_EQ(expected_result(),
162 VerifyNameMatch(SequenceValueFromString(case_swap),
163 SequenceValueFromString(normal)));
164 }
165
166 // Verify matching folds whitespace (for the types which currently support
167 // normalization).
TEST_P(VerifyNameMatchNormalizationTest,CollapseWhitespace)168 TEST_P(VerifyNameMatchNormalizationTest, CollapseWhitespace) {
169 std::string normal;
170 ASSERT_TRUE(LoadTestData("ascii", value_type(), "unmangled", &normal));
171 std::string whitespace;
172 ASSERT_TRUE(
173 LoadTestData("ascii", value_type(), "extra_whitespace", &whitespace));
174 EXPECT_EQ(expected_result(),
175 VerifyNameMatch(SequenceValueFromString(normal),
176 SequenceValueFromString(whitespace)));
177 EXPECT_EQ(expected_result(),
178 VerifyNameMatch(SequenceValueFromString(whitespace),
179 SequenceValueFromString(normal)));
180 }
181
182 // Runs VerifyNameMatchNormalizationTest for each (expected_result, value_type)
183 // tuple.
184 INSTANTIATE_TEST_SUITE_P(
185 InstantiationName,
186 VerifyNameMatchNormalizationTest,
187 ::testing::Values(
188 ::testing::make_tuple(true,
189 static_cast<const char*>("PRINTABLESTRING")),
190 ::testing::make_tuple(false, static_cast<const char*>("T61STRING")),
191 ::testing::make_tuple(true, static_cast<const char*>("UTF8")),
192 ::testing::make_tuple(true, static_cast<const char*>("BMPSTRING")),
193 ::testing::make_tuple(true,
194 static_cast<const char*>("UNIVERSALSTRING"))));
195
196 class VerifyNameMatchDifferingTypesTest
197 : public ::testing::TestWithParam<
198 ::testing::tuple<const char*, const char*>> {
199 public:
value_type_1() const200 std::string value_type_1() const { return ::testing::get<0>(GetParam()); }
value_type_2() const201 std::string value_type_2() const { return ::testing::get<1>(GetParam()); }
202 };
203
TEST_P(VerifyNameMatchDifferingTypesTest,NormalizableTypesAreEqual)204 TEST_P(VerifyNameMatchDifferingTypesTest, NormalizableTypesAreEqual) {
205 std::string der_1;
206 ASSERT_TRUE(LoadTestData("ascii", value_type_1(), "unmangled", &der_1));
207 std::string der_2;
208 ASSERT_TRUE(LoadTestData("ascii", value_type_2(), "unmangled", &der_2));
209 if (TypesAreComparable(value_type_1(), value_type_2())) {
210 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(der_1),
211 SequenceValueFromString(der_2)));
212 } else {
213 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(der_1),
214 SequenceValueFromString(der_2)));
215 }
216 }
217
TEST_P(VerifyNameMatchDifferingTypesTest,NormalizableTypesInSubtrees)218 TEST_P(VerifyNameMatchDifferingTypesTest, NormalizableTypesInSubtrees) {
219 std::string der_1;
220 ASSERT_TRUE(LoadTestData("ascii", value_type_1(), "unmangled", &der_1));
221 std::string der_1_extra_rdn;
222 ASSERT_TRUE(LoadTestData("ascii", value_type_1(), "unmangled-extra_rdn",
223 &der_1_extra_rdn));
224 std::string der_1_extra_attr;
225 ASSERT_TRUE(LoadTestData("ascii", value_type_1(), "unmangled-extra_attr",
226 &der_1_extra_attr));
227 std::string der_2;
228 ASSERT_TRUE(LoadTestData("ascii", value_type_2(), "unmangled", &der_2));
229 std::string der_2_extra_rdn;
230 ASSERT_TRUE(LoadTestData("ascii", value_type_2(), "unmangled-extra_rdn",
231 &der_2_extra_rdn));
232 std::string der_2_extra_attr;
233 ASSERT_TRUE(LoadTestData("ascii", value_type_2(), "unmangled-extra_attr",
234 &der_2_extra_attr));
235
236 if (TypesAreComparable(value_type_1(), value_type_2())) {
237 EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(der_1),
238 SequenceValueFromString(der_2)));
239 EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(der_2),
240 SequenceValueFromString(der_1)));
241 EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(der_1_extra_rdn),
242 SequenceValueFromString(der_2)));
243 EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(der_2_extra_rdn),
244 SequenceValueFromString(der_1)));
245 } else {
246 EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(der_1),
247 SequenceValueFromString(der_2)));
248 EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(der_2),
249 SequenceValueFromString(der_1)));
250 EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(der_1_extra_rdn),
251 SequenceValueFromString(der_2)));
252 EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(der_2_extra_rdn),
253 SequenceValueFromString(der_1)));
254 }
255
256 EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(der_1),
257 SequenceValueFromString(der_2_extra_rdn)));
258 EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(der_2),
259 SequenceValueFromString(der_1_extra_rdn)));
260 EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(der_1_extra_attr),
261 SequenceValueFromString(der_2)));
262 EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(der_2_extra_attr),
263 SequenceValueFromString(der_1)));
264 EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(der_1),
265 SequenceValueFromString(der_2_extra_attr)));
266 EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(der_2),
267 SequenceValueFromString(der_1_extra_attr)));
268 }
269
270 // Runs VerifyNameMatchDifferingTypesTest for all combinations of value types in
271 // value_type1 and value_type_2.
272 INSTANTIATE_TEST_SUITE_P(InstantiationName,
273 VerifyNameMatchDifferingTypesTest,
274 ::testing::Combine(::testing::ValuesIn(kValueTypes),
275 ::testing::ValuesIn(kValueTypes)));
276
277 class VerifyNameMatchUnicodeConversionTest
278 : public ::testing::TestWithParam<
279 ::testing::tuple<const char*,
280 ::testing::tuple<const char*, const char*>>> {
281 public:
prefix() const282 std::string prefix() const { return ::testing::get<0>(GetParam()); }
value_type_1() const283 std::string value_type_1() const {
284 return ::testing::get<0>(::testing::get<1>(GetParam()));
285 }
value_type_2() const286 std::string value_type_2() const {
287 return ::testing::get<1>(::testing::get<1>(GetParam()));
288 }
289 };
290
TEST_P(VerifyNameMatchUnicodeConversionTest,UnicodeConversionsAreEqual)291 TEST_P(VerifyNameMatchUnicodeConversionTest, UnicodeConversionsAreEqual) {
292 std::string der_1;
293 ASSERT_TRUE(LoadTestData(prefix(), value_type_1(), "unmangled", &der_1));
294 std::string der_2;
295 ASSERT_TRUE(LoadTestData(prefix(), value_type_2(), "unmangled", &der_2));
296 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(der_1),
297 SequenceValueFromString(der_2)));
298 }
299
300 // Runs VerifyNameMatchUnicodeConversionTest with prefix="unicode_bmp" for all
301 // combinations of Basic Multilingual Plane-capable value types in value_type1
302 // and value_type_2.
303 INSTANTIATE_TEST_SUITE_P(
304 BMPConversion,
305 VerifyNameMatchUnicodeConversionTest,
306 ::testing::Combine(
307 ::testing::Values("unicode_bmp"),
308 ::testing::Combine(::testing::ValuesIn(kUnicodeBMPValueTypes),
309 ::testing::ValuesIn(kUnicodeBMPValueTypes))));
310
311 // Runs VerifyNameMatchUnicodeConversionTest with prefix="unicode_supplementary"
312 // for all combinations of Unicode Supplementary Plane-capable value types in
313 // value_type1 and value_type_2.
314 INSTANTIATE_TEST_SUITE_P(
315 SMPConversion,
316 VerifyNameMatchUnicodeConversionTest,
317 ::testing::Combine(
318 ::testing::Values("unicode_supplementary"),
319 ::testing::Combine(
320 ::testing::ValuesIn(kUnicodeSupplementaryValueTypes),
321 ::testing::ValuesIn(kUnicodeSupplementaryValueTypes))));
322
323 // Matching should fail if a PrintableString contains invalid characters.
TEST(VerifyNameMatchInvalidDataTest,FailOnInvalidPrintableStringChars)324 TEST(VerifyNameMatchInvalidDataTest, FailOnInvalidPrintableStringChars) {
325 std::string der;
326 ASSERT_TRUE(LoadTestData("ascii", "PRINTABLESTRING", "unmangled", &der));
327 // Find a known location inside a PrintableString in the DER-encoded data.
328 size_t replace_location = der.find("0123456789");
329 ASSERT_NE(std::string::npos, replace_location);
330 for (int c = 0; c < 256; ++c) {
331 SCOPED_TRACE(c);
332 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
333 (c >= '0' && c <= '9')) {
334 continue;
335 }
336 switch (c) {
337 case ' ':
338 case '\'':
339 case '(':
340 case ')':
341 case '*':
342 case '+':
343 case ',':
344 case '-':
345 case '.':
346 case '/':
347 case ':':
348 case '=':
349 case '?':
350 continue;
351 }
352 der.replace(replace_location, 1, 1, c);
353 // Verification should fail due to the invalid character.
354 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(der),
355 SequenceValueFromString(der)));
356 std::string normalized_der;
357 CertErrors errors;
358 EXPECT_FALSE(
359 NormalizeName(SequenceValueFromString(der), &normalized_der, &errors));
360 }
361 }
362
363 // Matching should fail if an IA5String contains invalid characters.
TEST(VerifyNameMatchInvalidDataTest,FailOnInvalidIA5StringChars)364 TEST(VerifyNameMatchInvalidDataTest, FailOnInvalidIA5StringChars) {
365 std::string der;
366 ASSERT_TRUE(LoadTestData("ascii", "mixed", "rdn_dupetype_sorting_1", &der));
367 // Find a known location inside an IA5String in the DER-encoded data.
368 size_t replace_location = der.find("eXaMple");
369 ASSERT_NE(std::string::npos, replace_location);
370 for (int c = 0; c < 256; ++c) {
371 SCOPED_TRACE(c);
372 der.replace(replace_location, 1, 1, c);
373 bool expected_result = (c <= 127);
374 EXPECT_EQ(expected_result, VerifyNameMatch(SequenceValueFromString(der),
375 SequenceValueFromString(der)));
376 std::string normalized_der;
377 CertErrors errors;
378 EXPECT_EQ(expected_result, NormalizeName(SequenceValueFromString(der),
379 &normalized_der, &errors));
380 }
381 }
382
TEST(VerifyNameMatchInvalidDataTest,FailOnAttributeTypeAndValueExtraData)383 TEST(VerifyNameMatchInvalidDataTest, FailOnAttributeTypeAndValueExtraData) {
384 std::string invalid;
385 ASSERT_TRUE(
386 LoadTestData("invalid", "AttributeTypeAndValue", "extradata", &invalid));
387 // Verification should fail due to extra element in AttributeTypeAndValue
388 // sequence.
389 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(invalid),
390 SequenceValueFromString(invalid)));
391 std::string normalized_der;
392 CertErrors errors;
393 EXPECT_FALSE(NormalizeName(SequenceValueFromString(invalid), &normalized_der,
394 &errors));
395 }
396
TEST(VerifyNameMatchInvalidDataTest,FailOnAttributeTypeAndValueShort)397 TEST(VerifyNameMatchInvalidDataTest, FailOnAttributeTypeAndValueShort) {
398 std::string invalid;
399 ASSERT_TRUE(LoadTestData("invalid", "AttributeTypeAndValue", "onlyOneElement",
400 &invalid));
401 // Verification should fail due to AttributeTypeAndValue sequence having only
402 // one element.
403 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(invalid),
404 SequenceValueFromString(invalid)));
405 std::string normalized_der;
406 CertErrors errors;
407 EXPECT_FALSE(NormalizeName(SequenceValueFromString(invalid), &normalized_der,
408 &errors));
409 }
410
TEST(VerifyNameMatchInvalidDataTest,FailOnAttributeTypeAndValueEmpty)411 TEST(VerifyNameMatchInvalidDataTest, FailOnAttributeTypeAndValueEmpty) {
412 std::string invalid;
413 ASSERT_TRUE(
414 LoadTestData("invalid", "AttributeTypeAndValue", "empty", &invalid));
415 // Verification should fail due to empty AttributeTypeAndValue sequence.
416 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(invalid),
417 SequenceValueFromString(invalid)));
418 std::string normalized_der;
419 CertErrors errors;
420 EXPECT_FALSE(NormalizeName(SequenceValueFromString(invalid), &normalized_der,
421 &errors));
422 }
423
TEST(VerifyNameMatchInvalidDataTest,FailOnBadAttributeType)424 TEST(VerifyNameMatchInvalidDataTest, FailOnBadAttributeType) {
425 std::string invalid;
426 ASSERT_TRUE(LoadTestData("invalid", "AttributeTypeAndValue",
427 "badAttributeType", &invalid));
428 // Verification should fail due to Attribute Type not being an OID.
429 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(invalid),
430 SequenceValueFromString(invalid)));
431 std::string normalized_der;
432 CertErrors errors;
433 EXPECT_FALSE(NormalizeName(SequenceValueFromString(invalid), &normalized_der,
434 &errors));
435 }
436
TEST(VerifyNameMatchInvalidDataTest,FailOnAttributeTypeAndValueNotSequence)437 TEST(VerifyNameMatchInvalidDataTest, FailOnAttributeTypeAndValueNotSequence) {
438 std::string invalid;
439 ASSERT_TRUE(LoadTestData("invalid", "AttributeTypeAndValue", "setNotSequence",
440 &invalid));
441 // Verification should fail due to AttributeTypeAndValue being a Set instead
442 // of a Sequence.
443 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(invalid),
444 SequenceValueFromString(invalid)));
445 std::string normalized_der;
446 CertErrors errors;
447 EXPECT_FALSE(NormalizeName(SequenceValueFromString(invalid), &normalized_der,
448 &errors));
449 }
450
TEST(VerifyNameMatchInvalidDataTest,FailOnRdnNotSet)451 TEST(VerifyNameMatchInvalidDataTest, FailOnRdnNotSet) {
452 std::string invalid;
453 ASSERT_TRUE(LoadTestData("invalid", "RDN", "sequenceInsteadOfSet", &invalid));
454 // Verification should fail due to RDN being a Sequence instead of a Set.
455 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(invalid),
456 SequenceValueFromString(invalid)));
457 std::string normalized_der;
458 CertErrors errors;
459 EXPECT_FALSE(NormalizeName(SequenceValueFromString(invalid), &normalized_der,
460 &errors));
461 }
462
TEST(VerifyNameMatchInvalidDataTest,FailOnEmptyRdn)463 TEST(VerifyNameMatchInvalidDataTest, FailOnEmptyRdn) {
464 std::string invalid;
465 ASSERT_TRUE(LoadTestData("invalid", "RDN", "empty", &invalid));
466 // Verification should fail due to RDN having zero AttributeTypeAndValues.
467 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(invalid),
468 SequenceValueFromString(invalid)));
469 std::string normalized_der;
470 CertErrors errors;
471 EXPECT_FALSE(NormalizeName(SequenceValueFromString(invalid), &normalized_der,
472 &errors));
473 }
474
475 // Matching should fail if a BMPString contains surrogates.
TEST(VerifyNameMatchInvalidDataTest,FailOnBmpStringSurrogates)476 TEST(VerifyNameMatchInvalidDataTest, FailOnBmpStringSurrogates) {
477 std::string normal;
478 ASSERT_TRUE(LoadTestData("unicode_bmp", "BMPSTRING", "unmangled", &normal));
479 // Find a known location inside a BMPSTRING in the DER-encoded data.
480 size_t replace_location = normal.find("\x67\x71\x4e\xac");
481 ASSERT_NE(std::string::npos, replace_location);
482 // Replace with U+1D400 MATHEMATICAL BOLD CAPITAL A, which requires surrogates
483 // to represent.
484 std::string invalid =
485 normal.replace(replace_location, 4, std::string("\xd8\x35\xdc\x00", 4));
486 // Verification should fail due to the invalid codepoints.
487 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(invalid),
488 SequenceValueFromString(invalid)));
489 std::string normalized_der;
490 CertErrors errors;
491 EXPECT_FALSE(NormalizeName(SequenceValueFromString(invalid), &normalized_der,
492 &errors));
493 }
494
TEST(VerifyNameMatchTest,EmptyNameMatching)495 TEST(VerifyNameMatchTest, EmptyNameMatching) {
496 std::string empty;
497 ASSERT_TRUE(LoadTestData("valid", "Name", "empty", &empty));
498 // Empty names are equal.
499 EXPECT_TRUE(VerifyNameMatch(SequenceValueFromString(empty),
500 SequenceValueFromString(empty)));
501 // An empty name normalized is unchanged.
502 std::string normalized_empty_der;
503 CertErrors errors;
504 EXPECT_TRUE(NormalizeName(SequenceValueFromString(empty),
505 &normalized_empty_der, &errors));
506 EXPECT_EQ(SequenceValueFromString(empty), der::Input(normalized_empty_der));
507
508 // An empty name is not equal to non-empty name.
509 std::string non_empty;
510 ASSERT_TRUE(
511 LoadTestData("ascii", "PRINTABLESTRING", "unmangled", &non_empty));
512 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(empty),
513 SequenceValueFromString(non_empty)));
514 EXPECT_FALSE(VerifyNameMatch(SequenceValueFromString(non_empty),
515 SequenceValueFromString(empty)));
516 }
517
518 // Matching should succeed when the RDNs are sorted differently but are still
519 // equal after normalizing.
TEST(VerifyNameMatchRDNSorting,Simple)520 TEST(VerifyNameMatchRDNSorting, Simple) {
521 std::string a;
522 ASSERT_TRUE(LoadTestData("ascii", "PRINTABLESTRING", "rdn_sorting_1", &a));
523 std::string b;
524 ASSERT_TRUE(LoadTestData("ascii", "PRINTABLESTRING", "rdn_sorting_2", &b));
525 EXPECT_TRUE(
526 VerifyNameMatch(SequenceValueFromString(a), SequenceValueFromString(b)));
527 EXPECT_TRUE(
528 VerifyNameMatch(SequenceValueFromString(b), SequenceValueFromString(a)));
529 }
530
531 // Matching should succeed when the RDNs are sorted differently but are still
532 // equal after normalizing, even in malformed RDNs that contain multiple
533 // elements with the same type.
TEST(VerifyNameMatchRDNSorting,DuplicateTypes)534 TEST(VerifyNameMatchRDNSorting, DuplicateTypes) {
535 std::string a;
536 ASSERT_TRUE(LoadTestData("ascii", "mixed", "rdn_dupetype_sorting_1", &a));
537 std::string b;
538 ASSERT_TRUE(LoadTestData("ascii", "mixed", "rdn_dupetype_sorting_2", &b));
539 EXPECT_TRUE(
540 VerifyNameMatch(SequenceValueFromString(a), SequenceValueFromString(b)));
541 EXPECT_TRUE(
542 VerifyNameMatch(SequenceValueFromString(b), SequenceValueFromString(a)));
543 }
544
TEST(VerifyNameInSubtreeInvalidDataTest,FailOnEmptyRdn)545 TEST(VerifyNameInSubtreeInvalidDataTest, FailOnEmptyRdn) {
546 std::string valid;
547 ASSERT_TRUE(LoadTestData("ascii", "PRINTABLESTRING", "unmangled", &valid));
548 std::string invalid;
549 ASSERT_TRUE(LoadTestData("invalid", "RDN", "empty", &invalid));
550 // For both |name| and |parent|, a RelativeDistinguishedName must have at
551 // least one AttributeTypeAndValue.
552 EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(valid),
553 SequenceValueFromString(invalid)));
554 EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(invalid),
555 SequenceValueFromString(valid)));
556 EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(invalid),
557 SequenceValueFromString(invalid)));
558 }
559
TEST(VerifyNameInSubtreeTest,EmptyNameMatching)560 TEST(VerifyNameInSubtreeTest, EmptyNameMatching) {
561 std::string empty;
562 ASSERT_TRUE(LoadTestData("valid", "Name", "empty", &empty));
563 std::string non_empty;
564 ASSERT_TRUE(
565 LoadTestData("ascii", "PRINTABLESTRING", "unmangled", &non_empty));
566 // Empty name is in the subtree defined by empty name.
567 EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(empty),
568 SequenceValueFromString(empty)));
569 // Any non-empty name is in the subtree defined by empty name.
570 EXPECT_TRUE(VerifyNameInSubtree(SequenceValueFromString(non_empty),
571 SequenceValueFromString(empty)));
572 // Empty name is not in the subtree defined by non-empty name.
573 EXPECT_FALSE(VerifyNameInSubtree(SequenceValueFromString(empty),
574 SequenceValueFromString(non_empty)));
575 }
576
577 // Verify that the normalized output matches the pre-generated expected value
578 // for a single larger input that exercises all of the string types, unicode
579 // (basic and supplemental planes), whitespace collapsing, case folding, as
580 // well as SET sorting.
TEST(NameNormalizationTest,TestEverything)581 TEST(NameNormalizationTest, TestEverything) {
582 std::string expected_normalized_der;
583 ASSERT_TRUE(
584 LoadTestData("unicode", "mixed", "normalized", &expected_normalized_der));
585
586 std::string raw_der;
587 ASSERT_TRUE(LoadTestData("unicode", "mixed", "unnormalized", &raw_der));
588 std::string normalized_der;
589 CertErrors errors;
590 ASSERT_TRUE(NormalizeName(SequenceValueFromString(raw_der), &normalized_der,
591 &errors));
592 EXPECT_EQ(SequenceValueFromString(expected_normalized_der),
593 der::Input(normalized_der));
594 // Re-normalizing an already normalized Name should not change it.
595 std::string renormalized_der;
596 ASSERT_TRUE(
597 NormalizeName(der::Input(normalized_der), &renormalized_der, &errors));
598 EXPECT_EQ(normalized_der, renormalized_der);
599 }
600
601 // Unknown AttributeValue types normalize as-is, even non-primitive tags.
TEST(NameNormalizationTest,NormalizeCustom)602 TEST(NameNormalizationTest, NormalizeCustom) {
603 std::string raw_der;
604 ASSERT_TRUE(LoadTestData("custom", "custom", "normalized", &raw_der));
605
606 std::string normalized_der;
607 CertErrors errors;
608 ASSERT_TRUE(NormalizeName(SequenceValueFromString(raw_der), &normalized_der,
609 &errors));
610 EXPECT_EQ(SequenceValueFromString(raw_der), der::Input(normalized_der));
611 }
612
613 } // namespace net
614