Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: net/cert/internal/verify_name_match_unittest.cc

Issue 1125333005: RFC 2459 name comparison. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: review changes Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/cert/internal/verify_name_match.h" 5 #include "net/cert/internal/verify_name_match.h"
6 6
7 #include "base/base_paths.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/path_service.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h"
7 #include "net/der/input.h" 13 #include "net/der/input.h"
8 #include "testing/gtest/include/gtest/gtest.h" 14 #include "testing/gtest/include/gtest/gtest.h"
9 15
10 namespace net { 16 namespace net {
17 namespace {
11 18
12 TEST(VerifyNameMatchTest, Simple) { 19 std::string LoadTestData(const std::string& prefix,
13 // TODO(mattm): Use valid Names. 20 const std::string& value_type,
14 EXPECT_TRUE(VerifyNameMatch(der::Input("hello"), der::Input("hello"))); 21 const std::string& suffix) {
15 EXPECT_FALSE(VerifyNameMatch(der::Input("aello"), der::Input("hello"))); 22 base::FilePath src_root;
16 EXPECT_FALSE(VerifyNameMatch(der::Input("hello"), der::Input("hello1"))); 23 PathService::Get(base::DIR_SOURCE_ROOT, &src_root);
17 EXPECT_FALSE(VerifyNameMatch(der::Input("hello1"), der::Input("hello"))); 24 std::string filename = prefix + "-" + value_type + "-" + suffix + ".der";
25 base::FilePath filepath =
26 src_root.Append("net/data/verify_name_match_unittest/names")
27 .Append(filename);
28 std::string result;
29 bool success = base::ReadFileToString(filepath, &result);
30 EXPECT_TRUE(success);
31 return result;
32 }
33
34 static const char* kValueTypes[] = {"PRINTABLESTRING",
35 "T61STRING",
36 "UTF8",
37 "BMPSTRING",
38 "UNIVERSALSTRING"};
39 static const char* kMangleTypes[] = {"unmangled",
40 "case_swap",
41 "extra_whitespace"};
42
43 } // namespace
44
45 class VerifyNameMatchSimpleTest
46 : public ::testing::TestWithParam<
47 ::testing::tuple<const char*, const char*>> {
48 public:
49 std::string value_type() const { return ::testing::get<0>(GetParam()); }
50 std::string suffix() const { return ::testing::get<1>(GetParam()); }
51 };
52
53 // Compare each input against itself, verifies that all input data is parsed
54 // successfully.
55 TEST_P(VerifyNameMatchSimpleTest, ExactEquality) {
56 std::string der = LoadTestData("ascii", value_type(), suffix());
57 EXPECT_TRUE(VerifyNameMatch(der::Input(der), der::Input(der)));
58
59 std::string der_extra_attr =
60 LoadTestData("ascii", value_type(), suffix() + "-extra_attr");
61 EXPECT_TRUE(
62 VerifyNameMatch(der::Input(der_extra_attr), der::Input(der_extra_attr)));
63
64 std::string der_extra_rdn =
65 LoadTestData("ascii", value_type(), suffix() + "-extra_rdn");
66 EXPECT_TRUE(
67 VerifyNameMatch(der::Input(der_extra_rdn), der::Input(der_extra_rdn)));
68 }
69
70 // Ensure that a Name does not match another Name which is exactly the same but
71 // with an extra attribute in one Relative Distinguished Name.
72 TEST_P(VerifyNameMatchSimpleTest, ExtraAttrDoesNotMatch) {
73 std::string der = LoadTestData("ascii", value_type(), suffix());
74 std::string der_extra_attr =
75 LoadTestData("ascii", value_type(), suffix() + "-extra_attr");
76 EXPECT_FALSE(VerifyNameMatch(der::Input(der), der::Input(der_extra_attr)));
77 EXPECT_FALSE(VerifyNameMatch(der::Input(der_extra_attr), der::Input(der)));
78 }
79
80 // Ensure that a Name does not match another Name which is exactly the same but
81 // with an extra Relative Distinguished Name.
82 TEST_P(VerifyNameMatchSimpleTest, ExtraRdnDoesNotMatch) {
83 std::string der = LoadTestData("ascii", value_type(), suffix());
84 std::string der_extra_rdn =
85 LoadTestData("ascii", value_type(), suffix() + "-extra_rdn");
86 EXPECT_FALSE(VerifyNameMatch(der::Input(der), der::Input(der_extra_rdn)));
87 EXPECT_FALSE(VerifyNameMatch(der::Input(der_extra_rdn), der::Input(der)));
88 }
89
90 INSTANTIATE_TEST_CASE_P(InstantiationName,
91 VerifyNameMatchSimpleTest,
92 ::testing::Combine(::testing::ValuesIn(kValueTypes),
93 ::testing::ValuesIn(kMangleTypes)));
94
95 class VerifyNameMatchNormalizationTest
96 : public ::testing::TestWithParam<::testing::tuple<bool, const char*>> {
97 public:
98 bool expected_result() const { return ::testing::get<0>(GetParam()); }
99 std::string value_type() const { return ::testing::get<1>(GetParam()); }
100 };
101
102 // Verify matching is case insensitive (for the types which currently support
103 // normalization).
104 TEST_P(VerifyNameMatchNormalizationTest, CaseInsensitivity) {
105 std::string normal = LoadTestData("ascii", value_type(), "unmangled");
106 std::string case_swap = LoadTestData("ascii", value_type(), "case_swap");
107 EXPECT_EQ(expected_result(),
108 VerifyNameMatch(der::Input(normal), der::Input(case_swap)));
109 EXPECT_EQ(expected_result(),
110 VerifyNameMatch(der::Input(case_swap), der::Input(normal)));
111 }
112
113 // Verify matching folds whitespace (for the types which currently support
114 // normalization).
115 TEST_P(VerifyNameMatchNormalizationTest, CollapseWhitespace) {
116 std::string normal = LoadTestData("ascii", value_type(), "unmangled");
117 std::string whitespace =
118 LoadTestData("ascii", value_type(), "extra_whitespace");
119 EXPECT_EQ(expected_result(),
120 VerifyNameMatch(der::Input(normal), der::Input(whitespace)));
121 EXPECT_EQ(expected_result(),
122 VerifyNameMatch(der::Input(whitespace), der::Input(normal)));
123 }
124
125 // TODO(mattm): Current implementation uses RFC 2459 rules, where only
126 // PRINTABLESTRING is normalized. Change the false values below to true when
127 // updating to RFC 5280 (at least for UTF8, handling the others is optional).
128 INSTANTIATE_TEST_CASE_P(
129 InstantiationName,
130 VerifyNameMatchNormalizationTest,
131 ::testing::Values(std::tr1::make_tuple(true, "PRINTABLESTRING"),
132 std::tr1::make_tuple(false, "T61STRING"),
133 std::tr1::make_tuple(false, "UTF8"),
134 std::tr1::make_tuple(false, "BMPSTRING"),
135 std::tr1::make_tuple(false, "UNIVERSALSTRING")));
nharper 2015/05/14 19:21:44 Should these be ::testing::make_tuple?
mattm 2015/05/14 21:38:57 oops, done.
136
137 class VerifyNameMatchDifferingTypesTest
138 : public ::testing::TestWithParam<
139 ::testing::tuple<const char*, const char*>> {
140 public:
141 std::string value_type_1() const { return ::testing::get<0>(GetParam()); }
142 std::string value_type_2() const { return ::testing::get<1>(GetParam()); }
143 };
144
145 // TODO(mattm): in RFC 2459, different value types are assumed unequal. In RFC
146 // 5280, different types are transcoded to Unicode, so this will need to be
147 // updated.
148 TEST_P(VerifyNameMatchDifferingTypesTest, DifferentTypesAreNonEqual) {
149 std::string der_1 = LoadTestData("ascii", value_type_1(), "unmangled");
150 std::string der_2 = LoadTestData("ascii", value_type_2(), "unmangled");
151 if (value_type_1() == value_type_2())
152 EXPECT_TRUE(VerifyNameMatch(der::Input(der_1), der::Input(der_2)));
153 else
154 EXPECT_FALSE(VerifyNameMatch(der::Input(der_1), der::Input(der_2)));
155 }
156
157 INSTANTIATE_TEST_CASE_P(InstantiationName,
158 VerifyNameMatchDifferingTypesTest,
159 ::testing::Combine(::testing::ValuesIn(kValueTypes),
160 ::testing::ValuesIn(kValueTypes)));
161
162 // Matching should fail if a PrintableString contains invalid characters.
163 TEST(VerifyNameMatchPrintableStringValidity, FailOnInvalidChars) {
164 std::string normal = LoadTestData("ascii", "PRINTABLESTRING", "unmangled");
165 // Find a known location inside a PrintableString in the DER-encoded data.
166 size_t replace_location = normal.find("0123456789");
167 ASSERT_NE(std::string::npos, replace_location);
168 for (int c = 0; c < 256; ++c) {
169 SCOPED_TRACE(base::IntToString(c));
170 if (IsAsciiAlpha(c) || IsAsciiDigit(c))
171 continue;
172 switch (c) {
173 case ' ':
174 case '\'':
175 case '(':
176 case ')':
177 case '+':
178 case ',':
179 case '-':
180 case '.':
181 case '/':
182 case ':':
183 case '=':
184 case '?':
185 continue;
186 }
187 std::string invalid = normal.replace(replace_location, 1, 1, c);
188 // Verification should fail due to the invalid character.
189 EXPECT_FALSE(VerifyNameMatch(der::Input(invalid), der::Input(invalid)));
190 }
18 } 191 }
nharper 2015/05/14 19:21:44 All of these test cases assume a valid ASN.1 struc
mattm 2015/05/14 21:38:57 Good idea, done. (And fixed some cases allowing em
19 192
20 } // namespace net 193 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698