1 //
2 //
3 // Copyright 2020 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18
19 #include "src/core/lib/security/credentials/xds/xds_credentials.h"
20
21 #include <grpc/grpc.h>
22 #include <gtest/gtest.h>
23
24 #include "test/core/test_util/test_config.h"
25
26 namespace grpc_core {
27 namespace testing {
28
29 namespace {
30
ExactMatcher(const char * string)31 StringMatcher ExactMatcher(const char* string) {
32 return StringMatcher::Create(StringMatcher::Type::kExact, string).value();
33 }
34
PrefixMatcher(const char * string,bool case_sensitive=true)35 StringMatcher PrefixMatcher(const char* string, bool case_sensitive = true) {
36 return StringMatcher::Create(StringMatcher::Type::kPrefix, string,
37 case_sensitive)
38 .value();
39 }
40
SuffixMatcher(const char * string,bool case_sensitive=true)41 StringMatcher SuffixMatcher(const char* string, bool case_sensitive = true) {
42 return StringMatcher::Create(StringMatcher::Type::kSuffix, string,
43 case_sensitive)
44 .value();
45 }
46
ContainsMatcher(const char * string,bool case_sensitive=true)47 StringMatcher ContainsMatcher(const char* string, bool case_sensitive = true) {
48 return StringMatcher::Create(StringMatcher::Type::kContains, string,
49 case_sensitive)
50 .value();
51 }
52
SafeRegexMatcher(const char * string)53 StringMatcher SafeRegexMatcher(const char* string) {
54 return StringMatcher::Create(StringMatcher::Type::kSafeRegex, string).value();
55 }
56
TEST(XdsSanMatchingTest,EmptySansList)57 TEST(XdsSanMatchingTest, EmptySansList) {
58 std::vector<const char*> sans = {};
59 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
60 sans.data(), sans.size(),
61 {ExactMatcher("a.example.com"), ExactMatcher("b.example.com")}));
62 }
63
TEST(XdsSanMatchingTest,EmptyMatchersList)64 TEST(XdsSanMatchingTest, EmptyMatchersList) {
65 std::vector<const char*> sans = {"a.example.com", "foo.example.com"};
66 EXPECT_TRUE(
67 TestOnlyXdsVerifySubjectAlternativeNames(sans.data(), sans.size(), {}));
68 }
69
TEST(XdsSanMatchingTest,ExactMatchIllegalValues)70 TEST(XdsSanMatchingTest, ExactMatchIllegalValues) {
71 std::vector<const char*> sans = {".a.example.com"};
72 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
73 sans.data(), sans.size(),
74 {ExactMatcher(""), ExactMatcher("a.example.com"),
75 ExactMatcher(".a.example.com")}));
76 sans = {""};
77 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
78 sans.data(), sans.size(),
79 {ExactMatcher(""), ExactMatcher("a.example.com"),
80 ExactMatcher(".a.example.com")}));
81 sans = {"a.example.com"};
82 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
83 sans.data(), sans.size(),
84 {ExactMatcher(""), ExactMatcher("a.example.com"),
85 ExactMatcher(".a.example.com")}));
86 }
87
TEST(XdsSanMatchingTest,ExactMatchDns)88 TEST(XdsSanMatchingTest, ExactMatchDns) {
89 std::vector<const char*> sans = {"a.example.com"};
90 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
91 sans.data(), sans.size(), {ExactMatcher("a.example.com")}));
92 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
93 sans.data(), sans.size(), {ExactMatcher("b.example.com")}));
94 sans = {"b.example.com."};
95 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
96 sans.data(), sans.size(), {ExactMatcher("a.example.com.")}));
97 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
98 sans.data(), sans.size(), {ExactMatcher("b.example.com.")}));
99 }
100
TEST(XdsSanMatchingTest,ExactMatchWithFullyQualifiedSan)101 TEST(XdsSanMatchingTest, ExactMatchWithFullyQualifiedSan) {
102 std::vector<const char*> sans = {"a.example.com."};
103 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
104 sans.data(), sans.size(), {ExactMatcher("a.example.com")}));
105 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
106 sans.data(), sans.size(), {ExactMatcher("b.example.com")}));
107 }
108
TEST(XdsSanMatchingTest,ExactMatchWithFullyQualifiedMatcher)109 TEST(XdsSanMatchingTest, ExactMatchWithFullyQualifiedMatcher) {
110 std::vector<const char*> sans = {"a.example.com"};
111 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
112 sans.data(), sans.size(), {ExactMatcher("a.example.com.")}));
113 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
114 sans.data(), sans.size(), {ExactMatcher("b.example.com.")}));
115 }
116
TEST(XdsSanMatchingTest,ExactMatchDnsCaseInsensitive)117 TEST(XdsSanMatchingTest, ExactMatchDnsCaseInsensitive) {
118 std::vector<const char*> sans = {"A.eXaMpLe.CoM"};
119 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
120 sans.data(), sans.size(), {ExactMatcher("a.example.com")}));
121 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
122 sans.data(), sans.size(), {ExactMatcher("a.ExAmPlE.cOm")}));
123 }
124
TEST(XdsSanMatchingTest,ExactMatchMultipleSansMultipleMatchers)125 TEST(XdsSanMatchingTest, ExactMatchMultipleSansMultipleMatchers) {
126 std::vector<const char*> sans = {"a.example.com", "foo.example.com",
127 "b.example.com"};
128 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
129 sans.data(), sans.size(),
130 {ExactMatcher("abc.example.com"), ExactMatcher("foo.example.com"),
131 ExactMatcher("xyz.example.com")}));
132 }
133
TEST(XdsSanMatchingTest,ExactMatchWildCard)134 TEST(XdsSanMatchingTest, ExactMatchWildCard) {
135 std::vector<const char*> sans = {"*.example.com"};
136 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
137 sans.data(), sans.size(), {ExactMatcher("a.example.com")}));
138 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
139 sans.data(), sans.size(), {ExactMatcher("fOo.ExAmPlE.cOm")}));
140 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
141 sans.data(), sans.size(), {ExactMatcher("BaR.eXaMpLe.CoM")}));
142 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
143 sans.data(), sans.size(), {ExactMatcher(".example.com")}));
144 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
145 sans.data(), sans.size(), {ExactMatcher("example.com")}));
146 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
147 sans.data(), sans.size(), {ExactMatcher("foo.bar.com")}));
148 }
149
TEST(XdsSanMatchingTest,ExactMatchWildCardDoesNotMatchSingleLabelDomain)150 TEST(XdsSanMatchingTest, ExactMatchWildCardDoesNotMatchSingleLabelDomain) {
151 std::vector<const char*> sans = {"*"};
152 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
153 sans.data(), sans.size(), {ExactMatcher("abc")}));
154 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
155 sans.data(), sans.size(), {ExactMatcher("abc.com.")}));
156 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
157 sans.data(), sans.size(), {ExactMatcher("bar.baz.com")}));
158 sans = {"*."};
159 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
160 sans.data(), sans.size(), {ExactMatcher("abc")}));
161 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
162 sans.data(), sans.size(), {ExactMatcher("abc.com.")}));
163 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
164 sans.data(), sans.size(), {ExactMatcher("bar.baz.com")}));
165 }
166
TEST(XdsSanMatchingTest,ExactMatchAsteriskOnlyPermittedInLeftMostDomainName)167 TEST(XdsSanMatchingTest, ExactMatchAsteriskOnlyPermittedInLeftMostDomainName) {
168 std::vector<const char*> sans = {"*.example.*.com"};
169 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
170 sans.data(), sans.size(), {ExactMatcher("abc.example.xyz.com")}));
171 sans = {"*.exam*ple.com"};
172 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
173 sans.data(), sans.size(), {ExactMatcher("abc.example.com")}));
174 }
175
TEST(XdsSanMatchingTest,ExactMatchAsteriskMustBeOnlyCharacterInLeftMostDomainName)176 TEST(XdsSanMatchingTest,
177 ExactMatchAsteriskMustBeOnlyCharacterInLeftMostDomainName) {
178 std::vector<const char*> sans = {"*c.example.com"};
179 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
180 sans.data(), sans.size(), {ExactMatcher("abc.example.com")}));
181 }
182
TEST(XdsSanMatchingTest,ExactMatchAsteriskMatchingAcrossDomainLabelsNotPermitted)183 TEST(XdsSanMatchingTest,
184 ExactMatchAsteriskMatchingAcrossDomainLabelsNotPermitted) {
185 std::vector<const char*> sans = {"*.com"};
186 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
187 sans.data(), sans.size(), {ExactMatcher("abc.example.com")}));
188 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
189 sans.data(), sans.size(), {ExactMatcher("foo.bar.baz.com")}));
190 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
191 sans.data(), sans.size(), {ExactMatcher("abc.com")}));
192 }
193
TEST(XdsSanMatchingTest,PrefixMatch)194 TEST(XdsSanMatchingTest, PrefixMatch) {
195 std::vector<const char*> sans = {"abc.com"};
196 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(sans.data(), sans.size(),
197 {PrefixMatcher("abc")}));
198 sans = {"AbC.CoM"};
199 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
200 sans.data(), sans.size(), {PrefixMatcher("abc")}));
201 sans = {"xyz.com"};
202 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
203 sans.data(), sans.size(), {PrefixMatcher("abc")}));
204 }
205
TEST(XdsSanMatchingTest,PrefixMatchIgnoreCase)206 TEST(XdsSanMatchingTest, PrefixMatchIgnoreCase) {
207 std::vector<const char*> sans = {"aBc.cOm"};
208 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
209 sans.data(), sans.size(),
210 {PrefixMatcher("AbC", false /* case_sensitive */)}));
211 sans = {"abc.com"};
212 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
213 sans.data(), sans.size(),
214 {PrefixMatcher("AbC", false /* case_sensitive */)}));
215 sans = {"xyz.com"};
216 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
217 sans.data(), sans.size(),
218 {PrefixMatcher("AbC", false /* case_sensitive */)}));
219 }
220
TEST(XdsSanMatchingTest,SuffixMatch)221 TEST(XdsSanMatchingTest, SuffixMatch) {
222 std::vector<const char*> sans = {"abc.com"};
223 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
224 sans.data(), sans.size(), {SuffixMatcher(".com")}));
225 sans = {"AbC.CoM"};
226 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
227 sans.data(), sans.size(), {SuffixMatcher(".com")}));
228 sans = {"abc.xyz"};
229 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
230 sans.data(), sans.size(), {SuffixMatcher(".com")}));
231 }
232
TEST(XdsSanMatchingTest,SuffixMatchIgnoreCase)233 TEST(XdsSanMatchingTest, SuffixMatchIgnoreCase) {
234 std::vector<const char*> sans = {"abc.com"};
235 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
236 sans.data(), sans.size(),
237 {SuffixMatcher(".CoM", false /* case_sensitive */)}));
238 sans = {"AbC.cOm"};
239 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
240 sans.data(), sans.size(),
241 {SuffixMatcher(".CoM", false /* case_sensitive */)}));
242 sans = {"abc.xyz"};
243 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
244 sans.data(), sans.size(),
245 {SuffixMatcher(".CoM", false /* case_sensitive */)}));
246 }
247
TEST(XdsSanMatchingTest,ContainsMatch)248 TEST(XdsSanMatchingTest, ContainsMatch) {
249 std::vector<const char*> sans = {"abc.com"};
250 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
251 sans.data(), sans.size(), {ContainsMatcher("abc")}));
252 sans = {"xyz.abc.com"};
253 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
254 sans.data(), sans.size(), {ContainsMatcher("abc")}));
255 sans = {"foo.AbC.com"};
256 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
257 sans.data(), sans.size(), {ContainsMatcher("abc")}));
258 }
259
TEST(XdsSanMatchingTest,ContainsMatchIgnoresCase)260 TEST(XdsSanMatchingTest, ContainsMatchIgnoresCase) {
261 std::vector<const char*> sans = {"abc.com"};
262 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
263 sans.data(), sans.size(),
264 {ContainsMatcher("AbC", false /* case_sensitive */)}));
265 sans = {"xyz.abc.com"};
266 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
267 sans.data(), sans.size(),
268 {ContainsMatcher("AbC", false /* case_sensitive */)}));
269 sans = {"foo.aBc.com"};
270 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
271 sans.data(), sans.size(),
272 {ContainsMatcher("AbC", false /* case_sensitive */)}));
273 sans = {"foo.Ab.com"};
274 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
275 sans.data(), sans.size(),
276 {ContainsMatcher("AbC", false /* case_sensitive */)}));
277 }
278
TEST(XdsSanMatchingTest,RegexMatch)279 TEST(XdsSanMatchingTest, RegexMatch) {
280 std::vector<const char*> sans = {"abc.example.com"};
281 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
282 sans.data(), sans.size(), {SafeRegexMatcher("(abc|xyz).example.com")}));
283 sans = {"xyz.example.com"};
284 EXPECT_TRUE(TestOnlyXdsVerifySubjectAlternativeNames(
285 sans.data(), sans.size(), {SafeRegexMatcher("(abc|xyz).example.com")}));
286 sans = {"foo.example.com"};
287 EXPECT_FALSE(TestOnlyXdsVerifySubjectAlternativeNames(
288 sans.data(), sans.size(), {SafeRegexMatcher("(abc|xyz).example.com")}));
289 }
290
TEST(XdsCertificateVerifierTest,CompareSuccess)291 TEST(XdsCertificateVerifierTest, CompareSuccess) {
292 XdsCertificateVerifier verifier_1(nullptr);
293 XdsCertificateVerifier verifier_2(nullptr);
294 EXPECT_EQ(verifier_1.Compare(&verifier_2), 0);
295 EXPECT_EQ(verifier_2.Compare(&verifier_1), 0);
296 }
297
TEST(XdsCertificateVerifierTest,CompareFailureDifferentCertificateProviders)298 TEST(XdsCertificateVerifierTest, CompareFailureDifferentCertificateProviders) {
299 XdsCertificateVerifier verifier_1(
300 MakeRefCounted<XdsCertificateProvider>(nullptr, "", nullptr, "", false));
301 XdsCertificateVerifier verifier_2(
302 MakeRefCounted<XdsCertificateProvider>(nullptr, "", nullptr, "", false));
303 EXPECT_NE(verifier_1.Compare(&verifier_2), 0);
304 EXPECT_NE(verifier_2.Compare(&verifier_1), 0);
305 }
306
307 } // namespace
308
309 } // namespace testing
310 } // namespace grpc_core
311
main(int argc,char ** argv)312 int main(int argc, char** argv) {
313 ::testing::InitGoogleTest(&argc, argv);
314 grpc::testing::TestEnvironment env(&argc, argv);
315 grpc_init();
316 auto result = RUN_ALL_TESTS();
317 grpc_shutdown();
318 return result;
319 }
320