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