• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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