1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This code is made available to you under your choice of the following sets
4 * of licensing terms:
5 */
6 /* This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 */
10 /* Copyright 2014 Mozilla Contributors
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 */
24 #include "pkixgtest.h"
25
26 #include "mozpkix/pkixcheck.h"
27 #include "mozpkix/pkixder.h"
28 #include "mozpkix/pkixutil.h"
29
30 namespace mozilla { namespace pkix {
31
32 Result MatchPresentedDNSIDWithReferenceDNSID(Input presentedDNSID,
33 Input referenceDNSID,
34 /*out*/ bool& matches);
35
36 bool IsValidReferenceDNSID(Input hostname);
37 bool IsValidPresentedDNSID(Input hostname);
38 bool ParseIPv4Address(Input hostname, /*out*/ uint8_t (&out)[4]);
39 bool ParseIPv6Address(Input hostname, /*out*/ uint8_t (&out)[16]);
40
41 } } // namespace mozilla::pkix
42
43 using namespace mozilla::pkix;
44 using namespace mozilla::pkix::test;
45
46 struct PresentedMatchesReference
47 {
48 ByteString presentedDNSID;
49 ByteString referenceDNSID;
50 Result expectedResult;
51 bool expectedMatches; // only valid when expectedResult == Success
52 };
53
operator <<(::std::ostream & os,const PresentedMatchesReference &)54 ::std::ostream& operator<<(::std::ostream& os, const PresentedMatchesReference&)
55 {
56 return os << "TODO (bug 1318770)";
57 }
58
59 #define DNS_ID_MATCH(a, b) \
60 { \
61 ByteString(reinterpret_cast<const uint8_t*>(a), sizeof(a) - 1), \
62 ByteString(reinterpret_cast<const uint8_t*>(b), sizeof(b) - 1), \
63 Success, \
64 true \
65 }
66
67 #define DNS_ID_MISMATCH(a, b) \
68 { \
69 ByteString(reinterpret_cast<const uint8_t*>(a), sizeof(a) - 1), \
70 ByteString(reinterpret_cast<const uint8_t*>(b), sizeof(b) - 1), \
71 Success, \
72 false \
73 }
74
75 #define DNS_ID_BAD_DER(a, b) \
76 { \
77 ByteString(reinterpret_cast<const uint8_t*>(a), sizeof(a) - 1), \
78 ByteString(reinterpret_cast<const uint8_t*>(b), sizeof(b) - 1), \
79 Result::ERROR_BAD_DER, \
80 false \
81 }
82
83 static const PresentedMatchesReference DNSID_MATCH_PARAMS[] =
84 {
85 DNS_ID_BAD_DER("", "a"),
86
87 DNS_ID_MATCH("a", "a"),
88 DNS_ID_MISMATCH("b", "a"),
89
90 DNS_ID_MATCH("*.b.a", "c.b.a"),
91 DNS_ID_MISMATCH("*.b.a", "b.a"),
92 DNS_ID_MISMATCH("*.b.a", "b.a."),
93
94 // We allow underscores for compatibility with existing practices.
95 DNS_ID_MATCH("a_b", "a_b"),
96 DNS_ID_MATCH("*.example.com", "uses_underscore.example.com"),
97 DNS_ID_MATCH("*.uses_underscore.example.com", "a.uses_underscore.example.com"),
98
99 // See bug 1139039
100 DNS_ID_MATCH("_.example.com", "_.example.com"),
101 DNS_ID_MATCH("*.example.com", "_.example.com"),
102 DNS_ID_MATCH("_", "_"),
103 DNS_ID_MATCH("___", "___"),
104 DNS_ID_MATCH("example_", "example_"),
105 DNS_ID_MATCH("_example", "_example"),
106 DNS_ID_MATCH("*._._", "x._._"),
107
108 // See bug 1139039
109 // A DNS-ID must not end in an all-numeric label. We don't consider
110 // underscores to be numeric.
111 DNS_ID_MATCH("_1", "_1"),
112 DNS_ID_MATCH("example._1", "example._1"),
113 DNS_ID_MATCH("example.1_", "example.1_"),
114
115 // Wildcard not in leftmost label
116 DNS_ID_MATCH("d.c.b.a", "d.c.b.a"),
117 DNS_ID_BAD_DER("d.*.b.a", "d.c.b.a"),
118 DNS_ID_BAD_DER("d.c*.b.a", "d.c.b.a"),
119 DNS_ID_BAD_DER("d.c*.b.a", "d.cc.b.a"),
120
121 // case sensitivity
122 DNS_ID_MATCH("abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
123 DNS_ID_MATCH("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz"),
124 DNS_ID_MATCH("aBc", "Abc"),
125
126 // digits
127 DNS_ID_MATCH("a1", "a1"),
128
129 // A trailing dot indicates an absolute name. Absolute presented names are
130 // not allowed, but absolute reference names are allowed.
131 DNS_ID_MATCH("example", "example"),
132 DNS_ID_BAD_DER("example.", "example."),
133 DNS_ID_MATCH("example", "example."),
134 DNS_ID_BAD_DER("example.", "example"),
135 DNS_ID_MATCH("example.com", "example.com"),
136 DNS_ID_BAD_DER("example.com.", "example.com."),
137 DNS_ID_MATCH("example.com", "example.com."),
138 DNS_ID_BAD_DER("example.com.", "example.com"),
139 DNS_ID_BAD_DER("example.com..", "example.com."),
140 DNS_ID_BAD_DER("example.com..", "example.com"),
141 DNS_ID_BAD_DER("example.com...", "example.com."),
142
143 // xn-- IDN prefix
144 DNS_ID_BAD_DER("x*.b.a", "xa.b.a"),
145 DNS_ID_BAD_DER("x*.b.a", "xna.b.a"),
146 DNS_ID_BAD_DER("x*.b.a", "xn-a.b.a"),
147 DNS_ID_BAD_DER("x*.b.a", "xn--a.b.a"),
148 DNS_ID_BAD_DER("xn*.b.a", "xn--a.b.a"),
149 DNS_ID_BAD_DER("xn-*.b.a", "xn--a.b.a"),
150 DNS_ID_BAD_DER("xn--*.b.a", "xn--a.b.a"),
151 DNS_ID_BAD_DER("xn*.b.a", "xn--a.b.a"),
152 DNS_ID_BAD_DER("xn-*.b.a", "xn--a.b.a"),
153 DNS_ID_BAD_DER("xn--*.b.a", "xn--a.b.a"),
154 DNS_ID_BAD_DER("xn---*.b.a", "xn--a.b.a"),
155
156 // "*" cannot expand to nothing.
157 DNS_ID_BAD_DER("c*.b.a", "c.b.a"),
158
159 /////////////////////////////////////////////////////////////////////////////
160 // These are test cases adapted from Chromium's x509_certificate_unittest.cc.
161 // The parameter order is the opposite in Chromium's tests. Also, some tests
162 // were modified to fit into this framework or due to intentional differences
163 // between mozilla::pkix and Chromium.
164
165 DNS_ID_MATCH("foo.com", "foo.com"),
166 DNS_ID_MATCH("f", "f"),
167 DNS_ID_MISMATCH("i", "h"),
168 DNS_ID_MATCH("*.foo.com", "bar.foo.com"),
169 DNS_ID_MATCH("*.test.fr", "www.test.fr"),
170 DNS_ID_MATCH("*.test.FR", "wwW.tESt.fr"),
171 DNS_ID_BAD_DER(".uk", "f.uk"),
172 DNS_ID_BAD_DER("?.bar.foo.com", "w.bar.foo.com"),
173 DNS_ID_BAD_DER("(www|ftp).foo.com", "www.foo.com"), // regex!
174 DNS_ID_BAD_DER("www.foo.com\0", "www.foo.com"),
175 DNS_ID_BAD_DER("www.foo.com\0*.foo.com", "www.foo.com"),
176 DNS_ID_MISMATCH("ww.house.example", "www.house.example"),
177 DNS_ID_MISMATCH("www.test.org", "test.org"),
178 DNS_ID_MISMATCH("*.test.org", "test.org"),
179 DNS_ID_BAD_DER("*.org", "test.org"),
180 DNS_ID_BAD_DER("w*.bar.foo.com", "w.bar.foo.com"),
181 DNS_ID_BAD_DER("ww*ww.bar.foo.com", "www.bar.foo.com"),
182 DNS_ID_BAD_DER("ww*ww.bar.foo.com", "wwww.bar.foo.com"),
183
184 // Different than Chromium, matches NSS.
185 DNS_ID_BAD_DER("w*w.bar.foo.com", "wwww.bar.foo.com"),
186
187 DNS_ID_BAD_DER("w*w.bar.foo.c0m", "wwww.bar.foo.com"),
188
189 // '*' must be the only character in the wildcard label
190 DNS_ID_BAD_DER("wa*.bar.foo.com", "WALLY.bar.foo.com"),
191
192 // We require "*" to be the last character in a wildcard label, but
193 // Chromium does not.
194 DNS_ID_BAD_DER("*Ly.bar.foo.com", "wally.bar.foo.com"),
195
196 // Chromium does URL decoding of the reference ID, but we don't, and we also
197 // require that the reference ID is valid, so we can't test these two.
198 // DNS_ID_MATCH("www.foo.com", "ww%57.foo.com"),
199 // DNS_ID_MATCH("www&.foo.com", "www%26.foo.com"),
200
201 DNS_ID_MISMATCH("*.test.de", "www.test.co.jp"),
202 DNS_ID_BAD_DER("*.jp", "www.test.co.jp"),
203 DNS_ID_MISMATCH("www.test.co.uk", "www.test.co.jp"),
204 DNS_ID_BAD_DER("www.*.co.jp", "www.test.co.jp"),
205 DNS_ID_MATCH("www.bar.foo.com", "www.bar.foo.com"),
206 DNS_ID_MISMATCH("*.foo.com", "www.bar.foo.com"),
207 DNS_ID_BAD_DER("*.*.foo.com", "www.bar.foo.com"),
208 DNS_ID_BAD_DER("*.*.foo.com", "www.bar.foo.com"),
209
210 // Our matcher requires the reference ID to be a valid DNS name, so we cannot
211 // test this case.
212 //DNS_ID_BAD_DER("*.*.bar.foo.com", "*..bar.foo.com"),
213
214 DNS_ID_MATCH("www.bath.org", "www.bath.org"),
215
216 // Our matcher requires the reference ID to be a valid DNS name, so we cannot
217 // test these cases.
218 // DNS_ID_BAD_DER("www.bath.org", ""),
219 // DNS_ID_BAD_DER("www.bath.org", "20.30.40.50"),
220 // DNS_ID_BAD_DER("www.bath.org", "66.77.88.99"),
221
222 // IDN tests
223 DNS_ID_MATCH("xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br"),
224 DNS_ID_MATCH("*.xn--poema-9qae5a.com.br", "www.xn--poema-9qae5a.com.br"),
225 DNS_ID_MISMATCH("*.xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br"),
226 DNS_ID_BAD_DER("xn--poema-*.com.br", "xn--poema-9qae5a.com.br"),
227 DNS_ID_BAD_DER("xn--*-9qae5a.com.br", "xn--poema-9qae5a.com.br"),
228 DNS_ID_BAD_DER("*--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br"),
229
230 // The following are adapted from the examples quoted from
231 // http://tools.ietf.org/html/rfc6125#section-6.4.3
232 // (e.g., *.example.com would match foo.example.com but
233 // not bar.foo.example.com or example.com).
234 DNS_ID_MATCH("*.example.com", "foo.example.com"),
235 DNS_ID_MISMATCH("*.example.com", "bar.foo.example.com"),
236 DNS_ID_MISMATCH("*.example.com", "example.com"),
237 // (e.g., baz*.example.net and *baz.example.net and b*z.example.net would
238 // be taken to match baz1.example.net and foobaz.example.net and
239 // buzz.example.net, respectively. However, we don't allow any characters
240 // other than '*' in the wildcard label.
241 DNS_ID_BAD_DER("baz*.example.net", "baz1.example.net"),
242
243 // Both of these are different from Chromium, but match NSS, becaues the
244 // wildcard character "*" is not the last character of the label.
245 DNS_ID_BAD_DER("*baz.example.net", "foobaz.example.net"),
246 DNS_ID_BAD_DER("b*z.example.net", "buzz.example.net"),
247
248 // Wildcards should not be valid for public registry controlled domains,
249 // and unknown/unrecognized domains, at least three domain components must
250 // be present. For mozilla::pkix and NSS, there must always be at least two
251 // labels after the wildcard label.
252 DNS_ID_MATCH("*.test.example", "www.test.example"),
253 DNS_ID_MATCH("*.example.co.uk", "test.example.co.uk"),
254 DNS_ID_BAD_DER("*.exmaple", "test.example"),
255
256 // The result is different than Chromium, because Chromium takes into account
257 // the additional knowledge it has that "co.uk" is a TLD. mozilla::pkix does
258 // not know that.
259 DNS_ID_MATCH("*.co.uk", "example.co.uk"),
260
261 DNS_ID_BAD_DER("*.com", "foo.com"),
262 DNS_ID_BAD_DER("*.us", "foo.us"),
263 DNS_ID_BAD_DER("*", "foo"),
264
265 // IDN variants of wildcards and registry controlled domains.
266 DNS_ID_MATCH("*.xn--poema-9qae5a.com.br", "www.xn--poema-9qae5a.com.br"),
267 DNS_ID_MATCH("*.example.xn--mgbaam7a8h", "test.example.xn--mgbaam7a8h"),
268
269 // RFC6126 allows this, and NSS accepts it, but Chromium disallows it.
270 // TODO: File bug against Chromium.
271 DNS_ID_MATCH("*.com.br", "xn--poema-9qae5a.com.br"),
272
273 DNS_ID_BAD_DER("*.xn--mgbaam7a8h", "example.xn--mgbaam7a8h"),
274 // Wildcards should be permissible for 'private' registry-controlled
275 // domains. (In mozilla::pkix, we do not know if it is a private registry-
276 // controlled domain or not.)
277 DNS_ID_MATCH("*.appspot.com", "www.appspot.com"),
278 DNS_ID_MATCH("*.s3.amazonaws.com", "foo.s3.amazonaws.com"),
279
280 // Multiple wildcards are not valid.
281 DNS_ID_BAD_DER("*.*.com", "foo.example.com"),
282 DNS_ID_BAD_DER("*.bar.*.com", "foo.bar.example.com"),
283
284 // Absolute vs relative DNS name tests. Although not explicitly specified
285 // in RFC 6125, absolute reference names (those ending in a .) should
286 // match either absolute or relative presented names. We don't allow
287 // absolute presented names.
288 // TODO: File errata against RFC 6125 about this.
289 DNS_ID_BAD_DER("foo.com.", "foo.com"),
290 DNS_ID_MATCH("foo.com", "foo.com."),
291 DNS_ID_BAD_DER("foo.com.", "foo.com."),
292 DNS_ID_BAD_DER("f.", "f"),
293 DNS_ID_MATCH("f", "f."),
294 DNS_ID_BAD_DER("f.", "f."),
295 DNS_ID_BAD_DER("*.bar.foo.com.", "www-3.bar.foo.com"),
296 DNS_ID_MATCH("*.bar.foo.com", "www-3.bar.foo.com."),
297 DNS_ID_BAD_DER("*.bar.foo.com.", "www-3.bar.foo.com."),
298
299 // We require the reference ID to be a valid DNS name, so we cannot test this
300 // case.
301 // DNS_ID_MISMATCH(".", "."),
302
303 DNS_ID_BAD_DER("*.com.", "example.com"),
304 DNS_ID_BAD_DER("*.com", "example.com."),
305 DNS_ID_BAD_DER("*.com.", "example.com."),
306 DNS_ID_BAD_DER("*.", "foo."),
307 DNS_ID_BAD_DER("*.", "foo"),
308
309 // The result is different than Chromium because we don't know that co.uk is
310 // a TLD.
311 DNS_ID_MATCH("*.co.uk", "foo.co.uk"),
312 DNS_ID_MATCH("*.co.uk", "foo.co.uk."),
313 DNS_ID_BAD_DER("*.co.uk.", "foo.co.uk"),
314 DNS_ID_BAD_DER("*.co.uk.", "foo.co.uk."),
315
316 DNS_ID_MISMATCH("*.example.com", "localhost"),
317 DNS_ID_MISMATCH("*.example.com", "localhost."),
318 // Note that we already have the testcase DNS_ID_BAD_DER("*", "foo") above
319 };
320
321 struct InputValidity
322 {
323 ByteString input;
324 bool isValidReferenceID;
325 bool isValidPresentedID;
326 };
327
operator <<(::std::ostream & os,const InputValidity &)328 ::std::ostream& operator<<(::std::ostream& os, const InputValidity&)
329 {
330 return os << "TODO (bug 1318770)";
331 }
332
333 // str is null-terminated, which is why we subtract 1. str may contain embedded
334 // nulls (including at the end) preceding the null terminator though.
335 #define I(str, validReferenceID, validPresentedID) \
336 { \
337 ByteString(reinterpret_cast<const uint8_t*>(str), sizeof(str) - 1), \
338 validReferenceID, \
339 validPresentedID, \
340 }
341
342 static const InputValidity DNSNAMES_VALIDITY[] =
343 {
344 I("a", true, true),
345 I("a.b", true, true),
346 I("a.b.c", true, true),
347 I("a.b.c.d", true, true),
348
349 // empty labels
350 I("", false, false),
351 I(".", false, false),
352 I("a", true, true),
353 I(".a", false, false),
354 I(".a.b", false, false),
355 I("..a", false, false),
356 I("a..b", false, false),
357 I("a...b", false, false),
358 I("a..b.c", false, false),
359 I("a.b..c", false, false),
360 I(".a.b.c.", false, false),
361
362 // absolute names (only allowed for reference names)
363 I("a.", true, false),
364 I("a.b.", true, false),
365 I("a.b.c.", true, false),
366
367 // absolute names with empty label at end
368 I("a..", false, false),
369 I("a.b..", false, false),
370 I("a.b.c..", false, false),
371 I("a...", false, false),
372
373 // Punycode
374 I("xn--", false, false),
375 I("xn--.", false, false),
376 I("xn--.a", false, false),
377 I("a.xn--", false, false),
378 I("a.xn--.", false, false),
379 I("a.xn--.b", false, false),
380 I("a.xn--.b", false, false),
381 I("a.xn--\0.b", false, false),
382 I("a.xn--a.b", true, true),
383 I("xn--a", true, true),
384 I("a.xn--a", true, true),
385 I("a.xn--a.a", true, true),
386 I("\xc4\x95.com", false, false), // UTF-8 ĕ
387 I("xn--jea.com", true, true), // punycode ĕ
388 I("xn--\xc4\x95.com", false, false), // UTF-8 ĕ, malformed punycode + UTF-8 mashup
389
390 // Surprising punycode
391 I("xn--google.com", true, true), // 䕮䕵䕶䕱.com
392 I("xn--citibank.com", true, true), // 岍岊岊岅岉岎.com
393 I("xn--cnn.com", true, true), // 䁾.com
394 I("a.xn--cnn", true, true), // a.䁾
395 I("a.xn--cnn.com", true, true), // a.䁾.com
396
397 I("1.2.3.4", false, false), // IPv4 address
398 I("1::2", false, false), // IPV6 address
399
400 // whitespace not allowed anywhere.
401 I(" ", false, false),
402 I(" a", false, false),
403 I("a ", false, false),
404 I("a b", false, false),
405 I("a.b 1", false, false),
406 I("a\t", false, false),
407
408 // Nulls not allowed
409 I("\0", false, false),
410 I("a\0", false, false),
411 I("example.org\0.example.com", false, false), // Hi Moxie!
412 I("\0a", false, false),
413 I("xn--\0", false, false),
414
415 // Allowed character set
416 I("a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z", true, true),
417 I("A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z", true, true),
418 I("0.1.2.3.4.5.6.7.8.9.a", true, true), // "a" needed to avoid numeric last label
419 I("a-b", true, true), // hyphen (a label cannot start or end with a hyphen)
420
421 // Underscores
422 I("a_b", true, true),
423 // See bug 1139039
424 I("_", true, true),
425 I("a_", true, true),
426 I("_a", true, true),
427 I("_1", true, true),
428 I("1_", true, true),
429 I("___", true, true),
430
431 // An invalid character in various positions
432 I("!", false, false),
433 I("!a", false, false),
434 I("a!", false, false),
435 I("a!b", false, false),
436 I("a.!", false, false),
437 I("a.a!", false, false),
438 I("a.!a", false, false),
439 I("a.a!a", false, false),
440 I("a.!a.a", false, false),
441 I("a.a!.a", false, false),
442 I("a.a!a.a", false, false),
443
444 // Various other invalid characters
445 I("a!", false, false),
446 I("a@", false, false),
447 I("a#", false, false),
448 I("a$", false, false),
449 I("a%", false, false),
450 I("a^", false, false),
451 I("a&", false, false),
452 I("a*", false, false),
453 I("a(", false, false),
454 I("a)", false, false),
455
456 // last label can't be fully numeric
457 I("1", false, false),
458 I("a.1", false, false),
459
460 // other labels can be fully numeric
461 I("1.a", true, true),
462 I("1.2.a", true, true),
463 I("1.2.3.a", true, true),
464
465 // last label can be *partly* numeric
466 I("1a", true, true),
467 I("1.1a", true, true),
468 I("1-1", true, true),
469 I("a.1-1", true, true),
470 I("a.1-a", true, true),
471
472 // labels cannot start with a hyphen
473 I("-", false, false),
474 I("-1", false, false),
475
476 // labels cannot end with a hyphen
477 I("1-", false, false),
478 I("1-.a", false, false),
479 I("a-", false, false),
480 I("a-.a", false, false),
481 I("a.1-.a", false, false),
482 I("a.a-.a", false, false),
483
484 // labels can contain a hyphen in the middle
485 I("a-b", true, true),
486 I("1-2", true, true),
487 I("a.a-1", true, true),
488
489 // multiple consecutive hyphens allowed
490 I("a--1", true, true),
491 I("1---a", true, true),
492 I("a-----------------b", true, true),
493
494 // Wildcard specifications are not valid reference names, but are valid
495 // presented names if there are enough labels and if '*' is the only
496 // character in the wildcard label.
497 I("*.a", false, false),
498 I("a*", false, false),
499 I("a*.", false, false),
500 I("a*.a", false, false),
501 I("a*.a.", false, false),
502 I("*.a.b", false, true),
503 I("*.a.b.", false, false),
504 I("a*.b.c", false, false),
505 I("*.a.b.c", false, true),
506 I("a*.b.c.d", false, false),
507
508 // Multiple wildcards are not allowed.
509 I("a**.b.c", false, false),
510 I("a*b*.c.d", false, false),
511 I("a*.b*.c", false, false),
512
513 // Wildcards are only allowed in the first label.
514 I("a.*", false, false),
515 I("a.*.b", false, false),
516 I("a.b.*", false, false),
517 I("a.b*.c", false, false),
518 I("*.b*.c", false, false),
519 I(".*.a.b", false, false),
520 I(".a*.b.c", false, false),
521
522 // Wildcards must be at the *end* of the first label.
523 I("*a.b.c", false, false),
524 I("a*b.c.d", false, false),
525
526 // Wildcards not allowed with IDNA prefix
527 I("x*.a.b", false, false),
528 I("xn*.a.b", false, false),
529 I("xn-*.a.b", false, false),
530 I("xn--*.a.b", false, false),
531 I("xn--w*.a.b", false, false),
532
533 // Redacted labels from RFC6962bis draft 4
534 // https://tools.ietf.org/html/draft-ietf-trans-rfc6962-bis-04#section-3.2.2
535 I("(PRIVATE).foo", false, false),
536
537 // maximum label length is 63 characters
538 I("1234567890" "1234567890" "1234567890"
539 "1234567890" "1234567890" "1234567890" "abc", true, true),
540 I("1234567890" "1234567890" "1234567890"
541 "1234567890" "1234567890" "1234567890" "abcd", false, false),
542
543 // maximum total length is 253 characters
544 I("1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "."
545 "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "."
546 "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "."
547 "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "."
548 "1234567890" "1234567890" "1234567890" "1234567890" "12345678" "a",
549 true, true),
550 I("1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "."
551 "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "."
552 "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "."
553 "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "."
554 "1234567890" "1234567890" "1234567890" "1234567890" "123456789" "a",
555 false, false),
556 };
557
558 static const InputValidity DNSNAMES_VALIDITY_TURKISH_I[] =
559 {
560 // http://en.wikipedia.org/wiki/Dotted_and_dotless_I#In_computing
561 // IDN registration rules disallow "latin capital letter i with dot above,"
562 // but our checks aren't intended to enforce those rules.
563 I("I", true, true), // ASCII capital I
564 I("i", true, true), // ASCII lowercase i
565 I("\xC4\xB0", false, false), // latin capital letter i with dot above
566 I("\xC4\xB1", false, false), // latin small letter dotless i
567 I("xn--i-9bb", true, true), // latin capital letter i with dot above, in punycode
568 I("xn--cfa", true, true), // latin small letter dotless i, in punycode
569 I("xn--\xC4\xB0", false, false), // latin capital letter i with dot above, mashup
570 I("xn--\xC4\xB1", false, false), // latin small letter dotless i, mashup
571 };
572
573 static const uint8_t LOWERCASE_I_VALUE[1] = { 'i' };
574 static const uint8_t UPPERCASE_I_VALUE[1] = { 'I' };
575 static const Input LOWERCASE_I(LOWERCASE_I_VALUE);
576 static const Input UPPERCASE_I(UPPERCASE_I_VALUE);
577
578 template <unsigned int L>
579 struct IPAddressParams
580 {
581 ByteString input;
582 bool isValid;
583 uint8_t expectedValueIfValid[L];
584 };
585
586 template <unsigned int L>
operator <<(::std::ostream & os,const IPAddressParams<L> &)587 ::std::ostream& operator<<(::std::ostream& os, const IPAddressParams<L>&)
588 {
589 return os << "TODO (bug 1318770)";
590 }
591
592 #define IPV4_VALID(str, a, b, c, d) \
593 { \
594 ByteString(reinterpret_cast<const uint8_t*>(str), sizeof(str) - 1), \
595 true, \
596 { a, b, c, d } \
597 }
598
599 // The value of expectedValueIfValid must be ignored for invalid IP addresses.
600 // The value { 73, 73, 73, 73 } is used because it is unlikely to result in an
601 // accidental match, unlike { 0, 0, 0, 0 }, which is a value we actually test.
602 #define IPV4_INVALID(str) \
603 { \
604 ByteString(reinterpret_cast<const uint8_t*>(str), sizeof(str) - 1), \
605 false, \
606 { 73, 73, 73, 73 } \
607 }
608
609 static const IPAddressParams<4> IPV4_ADDRESSES[] =
610 {
611 IPV4_INVALID(""),
612 IPV4_INVALID("1"),
613 IPV4_INVALID("1.2"),
614 IPV4_INVALID("1.2.3"),
615 IPV4_VALID("1.2.3.4", 1, 2, 3, 4),
616 IPV4_INVALID("1.2.3.4.5"),
617
618 IPV4_INVALID("1.2.3.4a"), // a DNSName!
619 IPV4_INVALID("a.2.3.4"), // not even a DNSName!
620 IPV4_INVALID("1::2"), // IPv6 address
621
622 // Whitespace not allowed
623 IPV4_INVALID(" 1.2.3.4"),
624 IPV4_INVALID("1.2.3.4 "),
625 IPV4_INVALID("1 .2.3.4"),
626 IPV4_INVALID("\n1.2.3.4"),
627 IPV4_INVALID("1.2.3.4\n"),
628
629 // Nulls not allowed
630 IPV4_INVALID("\0"),
631 IPV4_INVALID("\0" "1.2.3.4"),
632 IPV4_INVALID("1.2.3.4\0"),
633 IPV4_INVALID("1.2.3.4\0.5"),
634
635 // Range
636 IPV4_VALID("0.0.0.0", 0, 0, 0, 0),
637 IPV4_VALID("255.255.255.255", 255, 255, 255, 255),
638 IPV4_INVALID("256.0.0.0"),
639 IPV4_INVALID("0.256.0.0"),
640 IPV4_INVALID("0.0.256.0"),
641 IPV4_INVALID("0.0.0.256"),
642 IPV4_INVALID("999.0.0.0"),
643 IPV4_INVALID("9999999999999999999.0.0.0"),
644
645 // All digits allowed
646 IPV4_VALID("0.1.2.3", 0, 1, 2, 3),
647 IPV4_VALID("4.5.6.7", 4, 5, 6, 7),
648 IPV4_VALID("8.9.0.1", 8, 9, 0, 1),
649
650 // Leading zeros not allowed
651 IPV4_INVALID("01.2.3.4"),
652 IPV4_INVALID("001.2.3.4"),
653 IPV4_INVALID("00000000001.2.3.4"),
654 IPV4_INVALID("010.2.3.4"),
655 IPV4_INVALID("1.02.3.4"),
656 IPV4_INVALID("1.2.03.4"),
657 IPV4_INVALID("1.2.3.04"),
658
659 // Empty components
660 IPV4_INVALID(".2.3.4"),
661 IPV4_INVALID("1..3.4"),
662 IPV4_INVALID("1.2..4"),
663 IPV4_INVALID("1.2.3."),
664
665 // Too many components
666 IPV4_INVALID("1.2.3.4.5"),
667 IPV4_INVALID("1.2.3.4.5.6"),
668 IPV4_INVALID("0.1.2.3.4"),
669 IPV4_INVALID("1.2.3.4.0"),
670
671 // Leading/trailing dot
672 IPV4_INVALID(".1.2.3.4"),
673 IPV4_INVALID("1.2.3.4."),
674
675 // Other common forms of IPv4 address
676 // http://en.wikipedia.org/wiki/IPv4#Address_representations
677 IPV4_VALID("192.0.2.235", 192, 0, 2, 235), // dotted decimal (control value)
678 IPV4_INVALID("0xC0.0x00.0x02.0xEB"), // dotted hex
679 IPV4_INVALID("0301.0000.0002.0353"), // dotted octal
680 IPV4_INVALID("0xC00002EB"), // non-dotted hex
681 IPV4_INVALID("3221226219"), // non-dotted decimal
682 IPV4_INVALID("030000001353"), // non-dotted octal
683 IPV4_INVALID("192.0.0002.0xEB"), // mixed
684 };
685
686 #define IPV6_VALID(str, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \
687 { \
688 ByteString(reinterpret_cast<const uint8_t*>(str), sizeof(str) - 1), \
689 true, \
690 { a, b, c, d, \
691 e, f, g, h, \
692 i, j, k, l, \
693 m, n, o, p } \
694 }
695
696 #define IPV6_INVALID(str) \
697 { \
698 ByteString(reinterpret_cast<const uint8_t*>(str), sizeof(str) - 1), \
699 false, \
700 { 73, 73, 73, 73, \
701 73, 73, 73, 73, \
702 73, 73, 73, 73, \
703 73, 73, 73, 73 } \
704 }
705
706 static const IPAddressParams<16> IPV6_ADDRESSES[] =
707 {
708 IPV6_INVALID(""),
709 IPV6_INVALID("1234"),
710 IPV6_INVALID("1234:5678"),
711 IPV6_INVALID("1234:5678:9abc"),
712 IPV6_INVALID("1234:5678:9abc:def0"),
713 IPV6_INVALID("1234:5678:9abc:def0:1234:"),
714 IPV6_INVALID("1234:5678:9abc:def0:1234:5678:"),
715 IPV6_INVALID("1234:5678:9abc:def0:1234:5678:9abc:"),
716 IPV6_VALID("1234:5678:9abc:def0:1234:5678:9abc:def0",
717 0x12, 0x34, 0x56, 0x78,
718 0x9a, 0xbc, 0xde, 0xf0,
719 0x12, 0x34, 0x56, 0x78,
720 0x9a, 0xbc, 0xde, 0xf0),
721 IPV6_INVALID("1234:5678:9abc:def0:1234:5678:9abc:def0:"),
722 IPV6_INVALID(":1234:5678:9abc:def0:1234:5678:9abc:def0"),
723 IPV6_INVALID("1234:5678:9abc:def0:1234:5678:9abc:def0:0000"),
724
725 // Valid contractions
726 IPV6_VALID("::1",
727 0x00, 0x00, 0x00, 0x00,
728 0x00, 0x00, 0x00, 0x00,
729 0x00, 0x00, 0x00, 0x00,
730 0x00, 0x00, 0x00, 0x01),
731 IPV6_VALID("::1234",
732 0x00, 0x00, 0x00, 0x00,
733 0x00, 0x00, 0x00, 0x00,
734 0x00, 0x00, 0x00, 0x00,
735 0x00, 0x00, 0x12, 0x34),
736 IPV6_VALID("1234::",
737 0x12, 0x34, 0x00, 0x00,
738 0x00, 0x00, 0x00, 0x00,
739 0x00, 0x00, 0x00, 0x00,
740 0x00, 0x00, 0x00, 0x00),
741 IPV6_VALID("1234::5678",
742 0x12, 0x34, 0x00, 0x00,
743 0x00, 0x00, 0x00, 0x00,
744 0x00, 0x00, 0x00, 0x00,
745 0x00, 0x00, 0x56, 0x78),
746 IPV6_VALID("1234:5678::abcd",
747 0x12, 0x34, 0x56, 0x78,
748 0x00, 0x00, 0x00, 0x00,
749 0x00, 0x00, 0x00, 0x00,
750 0x00, 0x00, 0xab, 0xcd),
751 IPV6_VALID("1234:5678:9abc:def0:1234:5678:9abc::",
752 0x12, 0x34, 0x56, 0x78,
753 0x9a, 0xbc, 0xde, 0xf0,
754 0x12, 0x34, 0x56, 0x78,
755 0x9a, 0xbc, 0x00, 0x00),
756
757 // Contraction in full IPv6 addresses not allowed
758 IPV6_INVALID("::1234:5678:9abc:def0:1234:5678:9abc:def0"), // start
759 IPV6_INVALID("1234:5678:9abc:def0:1234:5678:9abc:def0::"), // end
760 IPV6_INVALID("1234:5678::9abc:def0:1234:5678:9abc:def0"), // interior
761
762 // Multiple contractions not allowed
763 IPV6_INVALID("::1::"),
764 IPV6_INVALID("::1::2"),
765 IPV6_INVALID("1::2::"),
766
767 // Colon madness!
768 IPV6_INVALID(":"),
769 IPV6_INVALID("::"),
770 IPV6_INVALID(":::"),
771 IPV6_INVALID("::::"),
772 IPV6_INVALID(":::1"),
773 IPV6_INVALID("::::1"),
774 IPV6_INVALID("1:::2"),
775 IPV6_INVALID("1::::2"),
776 IPV6_INVALID("1:2:::"),
777 IPV6_INVALID("1:2::::"),
778 IPV6_INVALID("::1234:"),
779 IPV6_INVALID(":1234::"),
780
781 IPV6_INVALID("01234::"), // too many digits, even if zero
782 IPV6_INVALID("12345678::"), // too many digits or missing colon
783
784 // uppercase
785 IPV6_VALID("ABCD:EFAB::",
786 0xab, 0xcd, 0xef, 0xab,
787 0x00, 0x00, 0x00, 0x00,
788 0x00, 0x00, 0x00, 0x00,
789 0x00, 0x00, 0x00, 0x00),
790
791 // miXeD CAse
792 IPV6_VALID("aBcd:eFAb::",
793 0xab, 0xcd, 0xef, 0xab,
794 0x00, 0x00, 0x00, 0x00,
795 0x00, 0x00, 0x00, 0x00,
796 0x00, 0x00, 0x00, 0x00),
797
798 // IPv4-style
799 IPV6_VALID("::2.3.4.5",
800 0x00, 0x00, 0x00, 0x00,
801 0x00, 0x00, 0x00, 0x00,
802 0x00, 0x00, 0x00, 0x00,
803 0x02, 0x03, 0x04, 0x05),
804 IPV6_VALID("1234::2.3.4.5",
805 0x12, 0x34, 0x00, 0x00,
806 0x00, 0x00, 0x00, 0x00,
807 0x00, 0x00, 0x00, 0x00,
808 0x02, 0x03, 0x04, 0x05),
809 IPV6_VALID("::abcd:2.3.4.5",
810 0x00, 0x00, 0x00, 0x00,
811 0x00, 0x00, 0x00, 0x00,
812 0x00, 0x00, 0xab, 0xcd,
813 0x02, 0x03, 0x04, 0x05),
814 IPV6_VALID("1234:5678:9abc:def0:1234:5678:252.253.254.255",
815 0x12, 0x34, 0x56, 0x78,
816 0x9a, 0xbc, 0xde, 0xf0,
817 0x12, 0x34, 0x56, 0x78,
818 252, 253, 254, 255),
819 IPV6_VALID("1234:5678:9abc:def0:1234::252.253.254.255",
820 0x12, 0x34, 0x56, 0x78,
821 0x9a, 0xbc, 0xde, 0xf0,
822 0x12, 0x34, 0x00, 0x00,
823 252, 253, 254, 255),
824 IPV6_INVALID("1234::252.253.254"),
825 IPV6_INVALID("::252.253.254"),
826 IPV6_INVALID("::252.253.254.300"),
827 IPV6_INVALID("1234::252.253.254.255:"),
828 IPV6_INVALID("1234::252.253.254.255:5678"),
829
830 // Contractions that don't contract
831 IPV6_INVALID("::1234:5678:9abc:def0:1234:5678:9abc:def0"),
832 IPV6_INVALID("1234:5678:9abc:def0:1234:5678:9abc:def0::"),
833 IPV6_INVALID("1234:5678:9abc:def0::1234:5678:9abc:def0"),
834 IPV6_INVALID("1234:5678:9abc:def0:1234:5678::252.253.254.255"),
835
836 // With and without leading zeros
837 IPV6_VALID("::123",
838 0x00, 0x00, 0x00, 0x00,
839 0x00, 0x00, 0x00, 0x00,
840 0x00, 0x00, 0x00, 0x00,
841 0x00, 0x00, 0x01, 0x23),
842 IPV6_VALID("::0123",
843 0x00, 0x00, 0x00, 0x00,
844 0x00, 0x00, 0x00, 0x00,
845 0x00, 0x00, 0x00, 0x00,
846 0x00, 0x00, 0x01, 0x23),
847 IPV6_VALID("::012",
848 0x00, 0x00, 0x00, 0x00,
849 0x00, 0x00, 0x00, 0x00,
850 0x00, 0x00, 0x00, 0x00,
851 0x00, 0x00, 0x00, 0x12),
852 IPV6_VALID("::0012",
853 0x00, 0x00, 0x00, 0x00,
854 0x00, 0x00, 0x00, 0x00,
855 0x00, 0x00, 0x00, 0x00,
856 0x00, 0x00, 0x00, 0x12),
857 IPV6_VALID("::01",
858 0x00, 0x00, 0x00, 0x00,
859 0x00, 0x00, 0x00, 0x00,
860 0x00, 0x00, 0x00, 0x00,
861 0x00, 0x00, 0x00, 0x01),
862 IPV6_VALID("::001",
863 0x00, 0x00, 0x00, 0x00,
864 0x00, 0x00, 0x00, 0x00,
865 0x00, 0x00, 0x00, 0x00,
866 0x00, 0x00, 0x00, 0x01),
867 IPV6_VALID("::0001",
868 0x00, 0x00, 0x00, 0x00,
869 0x00, 0x00, 0x00, 0x00,
870 0x00, 0x00, 0x00, 0x00,
871 0x00, 0x00, 0x00, 0x01),
872 IPV6_VALID("::0",
873 0x00, 0x00, 0x00, 0x00,
874 0x00, 0x00, 0x00, 0x00,
875 0x00, 0x00, 0x00, 0x00,
876 0x00, 0x00, 0x00, 0x00),
877 IPV6_VALID("::00",
878 0x00, 0x00, 0x00, 0x00,
879 0x00, 0x00, 0x00, 0x00,
880 0x00, 0x00, 0x00, 0x00,
881 0x00, 0x00, 0x00, 0x00),
882 IPV6_VALID("::000",
883 0x00, 0x00, 0x00, 0x00,
884 0x00, 0x00, 0x00, 0x00,
885 0x00, 0x00, 0x00, 0x00,
886 0x00, 0x00, 0x00, 0x00),
887 IPV6_VALID("::0000",
888 0x00, 0x00, 0x00, 0x00,
889 0x00, 0x00, 0x00, 0x00,
890 0x00, 0x00, 0x00, 0x00,
891 0x00, 0x00, 0x00, 0x00),
892 IPV6_INVALID("::01234"),
893 IPV6_INVALID("::00123"),
894 IPV6_INVALID("::000123"),
895
896 // Trailing zero
897 IPV6_INVALID("::12340"),
898
899 // Whitespace
900 IPV6_INVALID(" 1234:5678:9abc:def0:1234:5678:9abc:def0"),
901 IPV6_INVALID("\t1234:5678:9abc:def0:1234:5678:9abc:def0"),
902 IPV6_INVALID("\t1234:5678:9abc:def0:1234:5678:9abc:def0\n"),
903 IPV6_INVALID("1234 :5678:9abc:def0:1234:5678:9abc:def0"),
904 IPV6_INVALID("1234: 5678:9abc:def0:1234:5678:9abc:def0"),
905 IPV6_INVALID(":: 2.3.4.5"),
906 IPV6_INVALID("1234::252.253.254.255 "),
907 IPV6_INVALID("1234::252.253.254.255\n"),
908 IPV6_INVALID("1234::252.253. 254.255"),
909
910 // Nulls
911 IPV6_INVALID("\0"),
912 IPV6_INVALID("::1\0:2"),
913 IPV6_INVALID("::1\0"),
914 IPV6_INVALID("::1.2.3.4\0"),
915 IPV6_INVALID("::1.2\02.3.4"),
916 };
917
918 class pkixnames_MatchPresentedDNSIDWithReferenceDNSID
919 : public ::testing::Test
920 , public ::testing::WithParamInterface<PresentedMatchesReference>
921 {
922 public:
923 DefaultNameMatchingPolicy mNameMatchingPolicy;
924 };
925
TEST_P(pkixnames_MatchPresentedDNSIDWithReferenceDNSID,MatchPresentedDNSIDWithReferenceDNSID)926 TEST_P(pkixnames_MatchPresentedDNSIDWithReferenceDNSID,
927 MatchPresentedDNSIDWithReferenceDNSID)
928 {
929 const PresentedMatchesReference& param(GetParam());
930 SCOPED_TRACE(param.presentedDNSID.c_str());
931 SCOPED_TRACE(param.referenceDNSID.c_str());
932 Input presented;
933 ASSERT_EQ(Success, presented.Init(param.presentedDNSID.data(),
934 param.presentedDNSID.length()));
935 Input reference;
936 ASSERT_EQ(Success, reference.Init(param.referenceDNSID.data(),
937 param.referenceDNSID.length()));
938
939 // sanity check that test makes sense
940 ASSERT_TRUE(IsValidReferenceDNSID(reference));
941
942 bool matches;
943 ASSERT_EQ(param.expectedResult,
944 MatchPresentedDNSIDWithReferenceDNSID(presented, reference,
945 matches));
946 if (param.expectedResult == Success) {
947 ASSERT_EQ(param.expectedMatches, matches);
948 }
949 }
950
951 INSTANTIATE_TEST_SUITE_P(pkixnames_MatchPresentedDNSIDWithReferenceDNSID,
952 pkixnames_MatchPresentedDNSIDWithReferenceDNSID,
953 testing::ValuesIn(DNSID_MATCH_PARAMS));
954
955 class pkixnames_Turkish_I_Comparison
956 : public ::testing::Test
957 , public ::testing::WithParamInterface<InputValidity>
958 {
959 public:
960 DefaultNameMatchingPolicy mNameMatchingPolicy;
961 };
962
TEST_P(pkixnames_Turkish_I_Comparison,MatchPresentedDNSIDWithReferenceDNSID)963 TEST_P(pkixnames_Turkish_I_Comparison, MatchPresentedDNSIDWithReferenceDNSID)
964 {
965 // Make sure we don't have the similar problems that strcasecmp and others
966 // have with the other kinds of "i" and "I" commonly used in Turkish locales.
967
968 const InputValidity& inputValidity(GetParam());
969 SCOPED_TRACE(inputValidity.input.c_str());
970 Input input;
971 ASSERT_EQ(Success, input.Init(inputValidity.input.data(),
972 inputValidity.input.length()));
973
974 bool isASCII = InputsAreEqual(LOWERCASE_I, input) ||
975 InputsAreEqual(UPPERCASE_I, input);
976 {
977 bool matches;
978 ASSERT_EQ(inputValidity.isValidPresentedID ? Success
979 : Result::ERROR_BAD_DER,
980 MatchPresentedDNSIDWithReferenceDNSID(input, LOWERCASE_I,
981 matches));
982 if (inputValidity.isValidPresentedID) {
983 ASSERT_EQ(isASCII, matches);
984 }
985 }
986 {
987 bool matches;
988 ASSERT_EQ(inputValidity.isValidPresentedID ? Success
989 : Result::ERROR_BAD_DER,
990 MatchPresentedDNSIDWithReferenceDNSID(input, UPPERCASE_I,
991 matches));
992 if (inputValidity.isValidPresentedID) {
993 ASSERT_EQ(isASCII, matches);
994 }
995 }
996 }
997
998 INSTANTIATE_TEST_SUITE_P(pkixnames_Turkish_I_Comparison,
999 pkixnames_Turkish_I_Comparison,
1000 testing::ValuesIn(DNSNAMES_VALIDITY_TURKISH_I));
1001
1002 class pkixnames_IsValidReferenceDNSID
1003 : public ::testing::Test
1004 , public ::testing::WithParamInterface<InputValidity>
1005 {
1006 public:
1007 DefaultNameMatchingPolicy mNameMatchingPolicy;
1008 };
1009
TEST_P(pkixnames_IsValidReferenceDNSID,IsValidReferenceDNSID)1010 TEST_P(pkixnames_IsValidReferenceDNSID, IsValidReferenceDNSID)
1011 {
1012 const InputValidity& inputValidity(GetParam());
1013 SCOPED_TRACE(inputValidity.input.c_str());
1014 Input input;
1015 ASSERT_EQ(Success, input.Init(inputValidity.input.data(),
1016 inputValidity.input.length()));
1017 ASSERT_EQ(inputValidity.isValidReferenceID, IsValidReferenceDNSID(input));
1018 ASSERT_EQ(inputValidity.isValidPresentedID, IsValidPresentedDNSID(input));
1019 }
1020
1021 INSTANTIATE_TEST_SUITE_P(pkixnames_IsValidReferenceDNSID,
1022 pkixnames_IsValidReferenceDNSID,
1023 testing::ValuesIn(DNSNAMES_VALIDITY));
1024 INSTANTIATE_TEST_SUITE_P(pkixnames_IsValidReferenceDNSID_Turkish_I,
1025 pkixnames_IsValidReferenceDNSID,
1026 testing::ValuesIn(DNSNAMES_VALIDITY_TURKISH_I));
1027
1028 class pkixnames_ParseIPv4Address
1029 : public ::testing::Test
1030 , public ::testing::WithParamInterface<IPAddressParams<4>>
1031 {
1032 public:
1033 DefaultNameMatchingPolicy mNameMatchingPolicy;
1034 };
1035
TEST_P(pkixnames_ParseIPv4Address,ParseIPv4Address)1036 TEST_P(pkixnames_ParseIPv4Address, ParseIPv4Address)
1037 {
1038 const IPAddressParams<4>& param(GetParam());
1039 SCOPED_TRACE(param.input.c_str());
1040 Input input;
1041 ASSERT_EQ(Success, input.Init(param.input.data(),
1042 param.input.length()));
1043 uint8_t ipAddress[4];
1044 ASSERT_EQ(param.isValid, ParseIPv4Address(input, ipAddress));
1045 if (param.isValid) {
1046 for (size_t i = 0; i < sizeof(ipAddress); ++i) {
1047 ASSERT_EQ(param.expectedValueIfValid[i], ipAddress[i]);
1048 }
1049 }
1050 }
1051
1052 INSTANTIATE_TEST_SUITE_P(pkixnames_ParseIPv4Address,
1053 pkixnames_ParseIPv4Address,
1054 testing::ValuesIn(IPV4_ADDRESSES));
1055
1056 class pkixnames_ParseIPv6Address
1057 : public ::testing::Test
1058 , public ::testing::WithParamInterface<IPAddressParams<16>>
1059 {
1060 public:
1061 DefaultNameMatchingPolicy mNameMatchingPolicy;
1062 };
1063
TEST_P(pkixnames_ParseIPv6Address,ParseIPv6Address)1064 TEST_P(pkixnames_ParseIPv6Address, ParseIPv6Address)
1065 {
1066 const IPAddressParams<16>& param(GetParam());
1067 SCOPED_TRACE(param.input.c_str());
1068 Input input;
1069 ASSERT_EQ(Success, input.Init(param.input.data(),
1070 param.input.length()));
1071 uint8_t ipAddress[16];
1072 ASSERT_EQ(param.isValid, ParseIPv6Address(input, ipAddress));
1073 if (param.isValid) {
1074 for (size_t i = 0; i < sizeof(ipAddress); ++i) {
1075 ASSERT_EQ(param.expectedValueIfValid[i], ipAddress[i]);
1076 }
1077 }
1078 }
1079
1080 INSTANTIATE_TEST_SUITE_P(pkixnames_ParseIPv6Address,
1081 pkixnames_ParseIPv6Address,
1082 testing::ValuesIn(IPV6_ADDRESSES));
1083
1084 // This is an arbitrary string that is used to indicate that no SAN extension
1085 // should be put into the generated certificate. It needs to be different from
1086 // "" or any other subjectAltName value that we actually want to test, but its
1087 // actual value does not matter. Note that this isn't a correctly-encoded SAN
1088 // extension value!
1089 static const ByteString
1090 NO_SAN(reinterpret_cast<const uint8_t*>("I'm a bad, bad, certificate"));
1091
1092 struct CheckCertHostnameParams
1093 {
1094 ByteString hostname;
1095 ByteString subject;
1096 ByteString subjectAltName;
1097 Result result;
1098 };
1099
operator <<(::std::ostream & os,const CheckCertHostnameParams &)1100 ::std::ostream& operator<<(::std::ostream& os, const CheckCertHostnameParams&)
1101 {
1102 return os << "TODO (bug 1318770)";
1103 }
1104
1105 class pkixnames_CheckCertHostname
1106 : public ::testing::Test
1107 , public ::testing::WithParamInterface<CheckCertHostnameParams>
1108 {
1109 public:
1110 DefaultNameMatchingPolicy mNameMatchingPolicy;
1111 };
1112
1113 #define WITH_SAN(r, ps, psan, result) \
1114 { \
1115 ByteString(reinterpret_cast<const uint8_t*>(r), sizeof(r) - 1), \
1116 ps, \
1117 psan, \
1118 result \
1119 }
1120
1121 #define WITHOUT_SAN(r, ps, result) \
1122 { \
1123 ByteString(reinterpret_cast<const uint8_t*>(r), sizeof(r) - 1), \
1124 ps, \
1125 NO_SAN, \
1126 result \
1127 }
1128
1129 static const uint8_t example_com[] = {
1130 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'
1131 };
1132
1133 // Note that We avoid zero-valued bytes in these IP addresses so that we don't
1134 // get false negatives from anti-NULL-byte defenses in dNSName decoding.
1135 static const uint8_t ipv4_addr_bytes[] = {
1136 1, 2, 3, 4
1137 };
1138 static const uint8_t ipv4_addr_bytes_as_str[] = "\x01\x02\x03\x04";
1139 static const uint8_t ipv4_addr_str[] = "1.2.3.4";
1140 static const uint8_t ipv4_addr_bytes_FFFFFFFF[8] = {
1141 1, 2, 3, 4, 0xff, 0xff, 0xff, 0xff
1142 };
1143
1144 static const uint8_t ipv4_compatible_ipv6_addr_bytes[] = {
1145 0, 0, 0, 0,
1146 0, 0, 0, 0,
1147 0, 0, 0, 0,
1148 1, 2, 3, 4
1149 };
1150 static const uint8_t ipv4_compatible_ipv6_addr_str[] = "::1.2.3.4";
1151
1152 static const uint8_t ipv4_mapped_ipv6_addr_bytes[] = {
1153 0, 0, 0, 0,
1154 0, 0, 0, 0,
1155 0, 0, 0xFF, 0xFF,
1156 1, 2, 3, 4
1157 };
1158 static const uint8_t ipv4_mapped_ipv6_addr_str[] = "::FFFF:1.2.3.4";
1159
1160 static const uint8_t ipv6_addr_bytes[] = {
1161 0x11, 0x22, 0x33, 0x44,
1162 0x55, 0x66, 0x77, 0x88,
1163 0x99, 0xaa, 0xbb, 0xcc,
1164 0xdd, 0xee, 0xff, 0x11
1165 };
1166 static const uint8_t ipv6_addr_bytes_as_str[] =
1167 "\x11\x22\x33\x44"
1168 "\x55\x66\x77\x88"
1169 "\x99\xaa\xbb\xcc"
1170 "\xdd\xee\xff\x11";
1171
1172 static const uint8_t ipv6_addr_str[] =
1173 "1122:3344:5566:7788:99aa:bbcc:ddee:ff11";
1174
1175 static const uint8_t ipv6_other_addr_bytes[] = {
1176 0xff, 0xee, 0xdd, 0xcc,
1177 0xbb, 0xaa, 0x99, 0x88,
1178 0x77, 0x66, 0x55, 0x44,
1179 0x33, 0x22, 0x11, 0x00,
1180 };
1181
1182 static const uint8_t ipv4_other_addr_bytes[] = {
1183 5, 6, 7, 8
1184 };
1185 static const uint8_t ipv4_other_addr_bytes_FFFFFFFF[] = {
1186 5, 6, 7, 8, 0xff, 0xff, 0xff, 0xff
1187 };
1188
1189 static const uint8_t ipv4_addr_00000000_bytes[] = {
1190 0, 0, 0, 0
1191 };
1192 static const uint8_t ipv4_addr_FFFFFFFF_bytes[] = {
1193 0, 0, 0, 0
1194 };
1195
1196 static const uint8_t ipv4_constraint_all_zeros_bytes[] = {
1197 0, 0, 0, 0, 0, 0, 0, 0
1198 };
1199
1200 static const uint8_t ipv6_addr_all_zeros_bytes[] = {
1201 0, 0, 0, 0, 0, 0, 0, 0,
1202 0, 0, 0, 0, 0, 0, 0, 0,
1203 };
1204
1205 static const uint8_t ipv6_constraint_all_zeros_bytes[] = {
1206 0, 0, 0, 0, 0, 0, 0, 0,
1207 0, 0, 0, 0, 0, 0, 0, 0,
1208 0, 0, 0, 0, 0, 0, 0, 0,
1209 0, 0, 0, 0, 0, 0, 0, 0
1210 };
1211
1212 static const uint8_t ipv4_constraint_CIDR_16_bytes[] = {
1213 1, 2, 0, 0, 0xff, 0xff, 0, 0
1214 };
1215 static const uint8_t ipv4_constraint_CIDR_17_bytes[] = {
1216 1, 2, 0, 0, 0xff, 0xff, 0x80, 0
1217 };
1218
1219 // The subnet is 1.2.0.0/16 but it is specified as 1.2.3.0/16
1220 static const uint8_t ipv4_constraint_CIDR_16_bad_addr_bytes[] = {
1221 1, 2, 3, 0, 0xff, 0xff, 0, 0
1222 };
1223
1224 // Masks are supposed to be of the form <ones><zeros>, but this one is of the
1225 // form <ones><zeros><ones><zeros>.
1226 static const uint8_t ipv4_constraint_bad_mask_bytes[] = {
1227 1, 2, 3, 0, 0xff, 0, 0xff, 0
1228 };
1229
1230 static const uint8_t ipv6_constraint_CIDR_16_bytes[] = {
1231 0x11, 0x22, 0, 0, 0, 0, 0, 0,
1232 0, 0, 0, 0, 0, 0, 0, 0,
1233 0xff, 0xff, 0, 0, 0, 0, 0, 0,
1234 0, 0, 0, 0, 0, 0, 0, 0
1235 };
1236
1237 // The subnet is 1122::/16 but it is specified as 1122:3344::/16
1238 static const uint8_t ipv6_constraint_CIDR_16_bad_addr_bytes[] = {
1239 0x11, 0x22, 0x33, 0x44, 0, 0, 0, 0,
1240 0, 0, 0, 0, 0, 0, 0, 0,
1241 0xff, 0xff, 0, 0, 0, 0, 0, 0,
1242 0, 0, 0, 0, 0, 0, 0, 0
1243 };
1244
1245 // Masks are supposed to be of the form <ones><zeros>, but this one is of the
1246 // form <ones><zeros><ones><zeros>.
1247 static const uint8_t ipv6_constraint_bad_mask_bytes[] = {
1248 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0, 0,
1249 0, 0, 0, 0, 0, 0, 0, 0,
1250 0xff, 0xff, 0, 0, 0xff, 0xff, 0, 0,
1251 0, 0, 0, 0, 0, 0, 0, 0,
1252 };
1253
1254 static const uint8_t ipv4_addr_truncated_bytes[] = {
1255 1, 2, 3
1256 };
1257 static const uint8_t ipv4_addr_overlong_bytes[] = {
1258 1, 2, 3, 4, 5
1259 };
1260 static const uint8_t ipv4_constraint_truncated_bytes[] = {
1261 0, 0, 0, 0,
1262 0, 0, 0,
1263 };
1264 static const uint8_t ipv4_constraint_overlong_bytes[] = {
1265 0, 0, 0, 0,
1266 0, 0, 0, 0, 0
1267 };
1268
1269 static const uint8_t ipv6_addr_truncated_bytes[] = {
1270 0x11, 0x22, 0x33, 0x44,
1271 0x55, 0x66, 0x77, 0x88,
1272 0x99, 0xaa, 0xbb, 0xcc,
1273 0xdd, 0xee, 0xff
1274 };
1275 static const uint8_t ipv6_addr_overlong_bytes[] = {
1276 0x11, 0x22, 0x33, 0x44,
1277 0x55, 0x66, 0x77, 0x88,
1278 0x99, 0xaa, 0xbb, 0xcc,
1279 0xdd, 0xee, 0xff, 0x11, 0x00
1280 };
1281 static const uint8_t ipv6_constraint_truncated_bytes[] = {
1282 0x11, 0x22, 0, 0, 0, 0, 0, 0,
1283 0, 0, 0, 0, 0, 0, 0, 0,
1284 0xff, 0xff, 0, 0, 0, 0, 0, 0,
1285 0, 0, 0, 0, 0, 0, 0
1286 };
1287 static const uint8_t ipv6_constraint_overlong_bytes[] = {
1288 0x11, 0x22, 0, 0, 0, 0, 0, 0,
1289 0, 0, 0, 0, 0, 0, 0, 0,
1290 0xff, 0xff, 0, 0, 0, 0, 0, 0,
1291 0, 0, 0, 0, 0, 0, 0, 0, 0
1292 };
1293
1294 // Note that, for DNSNames, these test cases in CHECK_CERT_HOSTNAME_PARAMS are
1295 // mostly about testing different scenerios regarding the structure of entries
1296 // in the subjectAltName and subject of the certificate, than about the how
1297 // specific presented identifier values are matched against the reference
1298 // identifier values. This is because we also use the test cases in
1299 // DNSNAMES_VALIDITY to test CheckCertHostname. Consequently, tests about
1300 // whether specific presented DNSNames (including wildcards, in particular) are
1301 // matched against a reference DNSName only need to be added to
1302 // DNSNAMES_VALIDITY, and not here.
1303 static const CheckCertHostnameParams CHECK_CERT_HOSTNAME_PARAMS[] =
1304 {
1305 // This is technically illegal. PrintableString is defined in such a way that
1306 // '*' is not an allowed character, but there are many real-world certificates
1307 // that are encoded this way.
1308 WITHOUT_SAN("foo.example.com", RDN(CN("*.example.com", der::PrintableString)),
1309 Success),
1310 WITHOUT_SAN("foo.example.com", RDN(CN("*.example.com", der::UTF8String)),
1311 Success),
1312
1313 // Many certificates use TeletexString when encoding wildcards in CN-IDs
1314 // because PrintableString is defined as not allowing '*' and UTF8String was,
1315 // at one point in history, considered too new to depend on for compatibility.
1316 // We accept TeletexString-encoded CN-IDs when they don't contain any escape
1317 // sequences. The reference I used for the escape codes was
1318 // https://tools.ietf.org/html/rfc1468. The escaping mechanism is actually
1319 // pretty complex and these tests don't even come close to testing all the
1320 // possibilities.
1321 WITHOUT_SAN("foo.example.com", RDN(CN("*.example.com", der::TeletexString)),
1322 Success),
1323 // "ESC ( B" ({0x1B,0x50,0x42}) is the escape code to switch to ASCII, which
1324 // is redundant because it already the default.
1325 WITHOUT_SAN("foo.example.com",
1326 RDN(CN("\x1B(B*.example.com", der::TeletexString)),
1327 Result::ERROR_BAD_CERT_DOMAIN),
1328 WITHOUT_SAN("foo.example.com",
1329 RDN(CN("*.example\x1B(B.com", der::TeletexString)),
1330 Result::ERROR_BAD_CERT_DOMAIN),
1331 WITHOUT_SAN("foo.example.com",
1332 RDN(CN("*.example.com\x1B(B", der::TeletexString)),
1333 Result::ERROR_BAD_CERT_DOMAIN),
1334 // "ESC $ B" ({0x1B,0x24,0x42}) is the escape code to switch to
1335 // JIS X 0208-1983 (a Japanese character set).
1336 WITHOUT_SAN("foo.example.com",
1337 RDN(CN("\x1B$B*.example.com", der::TeletexString)),
1338 Result::ERROR_BAD_CERT_DOMAIN),
1339 WITHOUT_SAN("foo.example.com",
1340 RDN(CN("*.example.com\x1B$B", der::TeletexString)),
1341 Result::ERROR_BAD_CERT_DOMAIN),
1342
1343 // Match a DNSName SAN entry with a redundant (ignored) matching CN-ID.
1344 WITH_SAN("a", RDN(CN("a")), DNSName("a"), Success),
1345 // Match a DNSName SAN entry when there is an CN-ID that doesn't match.
1346 WITH_SAN("b", RDN(CN("a")), DNSName("b"), Success),
1347 // Do not match a CN-ID when there is a valid DNSName SAN Entry.
1348 WITH_SAN("a", RDN(CN("a")), DNSName("b"), Result::ERROR_BAD_CERT_DOMAIN),
1349 // Do not match a CN-ID when there is a malformed DNSName SAN Entry.
1350 WITH_SAN("a", RDN(CN("a")), DNSName("!"), Result::ERROR_BAD_DER),
1351 // Do not match a matching CN-ID when there is a valid IPAddress SAN entry.
1352 WITH_SAN("a", RDN(CN("a")), IPAddress(ipv4_addr_bytes),
1353 Result::ERROR_BAD_CERT_DOMAIN),
1354 // Do not match a matching CN-ID when there is a malformed IPAddress SAN entry.
1355 WITH_SAN("a", RDN(CN("a")), IPAddress(example_com),
1356 Result::ERROR_BAD_CERT_DOMAIN),
1357 // Match a DNSName against a matching CN-ID when there is a SAN, but the SAN
1358 // does not contain an DNSName or IPAddress entry.
1359 WITH_SAN("a", RDN(CN("a")), RFC822Name("foo@example.com"), Success),
1360 // Match a matching CN-ID when there is no SAN.
1361 WITHOUT_SAN("a", RDN(CN("a")), Success),
1362 // Do not match a mismatching CN-ID when there is no SAN.
1363 WITHOUT_SAN("a", RDN(CN("b")), Result::ERROR_BAD_CERT_DOMAIN),
1364
1365 // The first DNSName matches.
1366 WITH_SAN("a", RDN(CN("foo")), DNSName("a") + DNSName("b"), Success),
1367 // The last DNSName matches.
1368 WITH_SAN("b", RDN(CN("foo")), DNSName("a") + DNSName("b"), Success),
1369 // The middle DNSName matches.
1370 WITH_SAN("b", RDN(CN("foo")),
1371 DNSName("a") + DNSName("b") + DNSName("c"), Success),
1372 // After an IP address.
1373 WITH_SAN("b", RDN(CN("foo")),
1374 IPAddress(ipv4_addr_bytes) + DNSName("b"), Success),
1375 // Before an IP address.
1376 WITH_SAN("a", RDN(CN("foo")),
1377 DNSName("a") + IPAddress(ipv4_addr_bytes), Success),
1378 // Between an RFC822Name and an IP address.
1379 WITH_SAN("b", RDN(CN("foo")),
1380 RFC822Name("foo@example.com") + DNSName("b") +
1381 IPAddress(ipv4_addr_bytes),
1382 Success),
1383 // Duplicate DNSName.
1384 WITH_SAN("a", RDN(CN("foo")), DNSName("a") + DNSName("a"), Success),
1385 // After an invalid DNSName.
1386 WITH_SAN("b", RDN(CN("foo")), DNSName("!") + DNSName("b"),
1387 Result::ERROR_BAD_DER),
1388
1389 // http://tools.ietf.org/html/rfc5280#section-4.2.1.6: "If the subjectAltName
1390 // extension is present, the sequence MUST contain at least one entry."
1391 // However, for compatibility reasons, this is not enforced. See bug 1143085.
1392 // This case is treated as if the extension is not present (i.e. name
1393 // matching falls back to the subject CN).
1394 WITH_SAN("a", RDN(CN("a")), ByteString(), Success),
1395 WITH_SAN("a", RDN(CN("b")), ByteString(), Result::ERROR_BAD_CERT_DOMAIN),
1396
1397 // http://tools.ietf.org/html/rfc5280#section-4.1.2.6 says "If subject naming
1398 // information is present only in the subjectAltName extension (e.g., a key
1399 // bound only to an email address or URI), then the subject name MUST be an
1400 // empty sequence and the subjectAltName extension MUST be critical." So, we
1401 // have to support an empty subject. We don't enforce that the SAN must be
1402 // critical or even that there is a SAN when the subject is empty, though.
1403 WITH_SAN("a", ByteString(), DNSName("a"), Success),
1404 // Make sure we return ERROR_BAD_CERT_DOMAIN and not ERROR_BAD_DER.
1405 WITHOUT_SAN("a", ByteString(), Result::ERROR_BAD_CERT_DOMAIN),
1406
1407 // Two CNs in the same RDN, both match.
1408 WITHOUT_SAN("a", RDN(CN("a") + CN("a")), Success),
1409 // Two CNs in the same RDN, both DNSNames, first one matches.
1410 WITHOUT_SAN("a", RDN(CN("a") + CN("b")),
1411 Result::ERROR_BAD_CERT_DOMAIN),
1412 // Two CNs in the same RDN, both DNSNames, last one matches.
1413 WITHOUT_SAN("b", RDN(CN("a") + CN("b")), Success),
1414 // Two CNs in the same RDN, first one matches, second isn't a DNSName.
1415 WITHOUT_SAN("a", RDN(CN("a") + CN("Not a DNSName")),
1416 Result::ERROR_BAD_CERT_DOMAIN),
1417 // Two CNs in the same RDN, first one not a DNSName, second matches.
1418 WITHOUT_SAN("b", RDN(CN("Not a DNSName") + CN("b")), Success),
1419
1420 // Two CNs in separate RDNs, both match.
1421 WITHOUT_SAN("a", RDN(CN("a")) + RDN(CN("a")), Success),
1422 // Two CNs in separate RDNs, both DNSNames, first one matches.
1423 WITHOUT_SAN("a", RDN(CN("a")) + RDN(CN("b")),
1424 Result::ERROR_BAD_CERT_DOMAIN),
1425 // Two CNs in separate RDNs, both DNSNames, last one matches.
1426 WITHOUT_SAN("b", RDN(CN("a")) + RDN(CN("b")), Success),
1427 // Two CNs in separate RDNs, first one matches, second isn't a DNSName.
1428 WITHOUT_SAN("a", RDN(CN("a")) + RDN(CN("Not a DNSName")),
1429 Result::ERROR_BAD_CERT_DOMAIN),
1430 // Two CNs in separate RDNs, first one not a DNSName, second matches.
1431 WITHOUT_SAN("b", RDN(CN("Not a DNSName")) + RDN(CN("b")), Success),
1432
1433 // One CN, one RDN, CN is the first AVA in the RDN, CN matches.
1434 WITHOUT_SAN("a", RDN(CN("a") + OU("b")), Success),
1435 // One CN, one RDN, CN is the first AVA in the RDN, CN does not match.
1436 WITHOUT_SAN("b", RDN(CN("a") + OU("b")),
1437 Result::ERROR_BAD_CERT_DOMAIN),
1438 // One CN, one RDN, CN is not the first AVA in the RDN, CN matches.
1439 WITHOUT_SAN("b", RDN(OU("a") + CN("b")), Success),
1440 // One CN, one RDN, CN is not the first AVA in the RDN, CN does not match.
1441 WITHOUT_SAN("a", RDN(OU("a") + CN("b")),
1442 Result::ERROR_BAD_CERT_DOMAIN),
1443
1444 // One CN, multiple RDNs, CN is in the first RDN, CN matches.
1445 WITHOUT_SAN("a", RDN(CN("a")) + RDN(OU("b")), Success),
1446 // One CN, multiple RDNs, CN is in the first RDN, CN does not match.
1447 WITHOUT_SAN("b", RDN(CN("a")) + RDN(OU("b")), Result::ERROR_BAD_CERT_DOMAIN),
1448 // One CN, multiple RDNs, CN is not in the first RDN, CN matches.
1449 WITHOUT_SAN("b", RDN(OU("a")) + RDN(CN("b")), Success),
1450 // One CN, multiple RDNs, CN is not in the first RDN, CN does not match.
1451 WITHOUT_SAN("a", RDN(OU("a")) + RDN(CN("b")), Result::ERROR_BAD_CERT_DOMAIN),
1452
1453 // One CN, one RDN, CN is not in the first or last AVA, CN matches.
1454 WITHOUT_SAN("b", RDN(OU("a") + CN("b") + OU("c")), Success),
1455 // One CN, multiple RDNs, CN is not in the first or last RDN, CN matches.
1456 WITHOUT_SAN("b", RDN(OU("a")) + RDN(CN("b")) + RDN(OU("c")), Success),
1457
1458 // Empty CN does not match.
1459 WITHOUT_SAN("example.com", RDN(CN("")), Result::ERROR_BAD_CERT_DOMAIN),
1460
1461 WITHOUT_SAN("uses_underscore.example.com", RDN(CN("*.example.com")), Success),
1462 WITHOUT_SAN("a.uses_underscore.example.com",
1463 RDN(CN("*.uses_underscore.example.com")), Success),
1464 WITH_SAN("uses_underscore.example.com", RDN(CN("foo")),
1465 DNSName("*.example.com"), Success),
1466 WITH_SAN("a.uses_underscore.example.com", RDN(CN("foo")),
1467 DNSName("*.uses_underscore.example.com"), Success),
1468
1469 // Do not match a DNSName that is encoded in a malformed IPAddress.
1470 WITH_SAN("example.com", RDN(CN("foo")), IPAddress(example_com),
1471 Result::ERROR_BAD_CERT_DOMAIN),
1472
1473 // We skip over the malformed IPAddress and match the DNSName entry because
1474 // we've heard reports of real-world certificates that have malformed
1475 // IPAddress SANs.
1476 WITH_SAN("example.org", RDN(CN("foo")),
1477 IPAddress(example_com) + DNSName("example.org"), Success),
1478
1479 WITH_SAN("example.com", RDN(CN("foo")),
1480 DNSName("!") + DNSName("example.com"), Result::ERROR_BAD_DER),
1481
1482 // Match a matching IPv4 address SAN entry.
1483 WITH_SAN(ipv4_addr_str, RDN(CN("foo")), IPAddress(ipv4_addr_bytes),
1484 Success),
1485 // Match a matching IPv4 addresses in the CN when there is no SAN
1486 WITHOUT_SAN(ipv4_addr_str, RDN(CN(ipv4_addr_str)), Success),
1487 // Do not match a matching IPv4 address in the CN when there is a SAN with
1488 // a DNSName entry.
1489 WITH_SAN(ipv4_addr_str, RDN(CN(ipv4_addr_str)),
1490 DNSName("example.com"), Result::ERROR_BAD_CERT_DOMAIN),
1491 // Do not match a matching IPv4 address in the CN when there is a SAN with
1492 // a non-matching IPAddress entry.
1493 WITH_SAN(ipv4_addr_str, RDN(CN(ipv4_addr_str)),
1494 IPAddress(ipv6_addr_bytes), Result::ERROR_BAD_CERT_DOMAIN),
1495 // Match a matching IPv4 address in the CN when there is a SAN with a
1496 // non-IPAddress, non-DNSName entry.
1497 WITH_SAN(ipv4_addr_str, RDN(CN(ipv4_addr_str)),
1498 RFC822Name("foo@example.com"), Success),
1499 // Do not match a matching IPv4 address in the CN when there is a SAN with a
1500 // malformed IPAddress entry.
1501 WITH_SAN(ipv4_addr_str, RDN(CN(ipv4_addr_str)),
1502 IPAddress(example_com), Result::ERROR_BAD_CERT_DOMAIN),
1503 // Do not match a matching IPv4 address in the CN when there is a SAN with a
1504 // malformed DNSName entry.
1505 WITH_SAN(ipv4_addr_str, RDN(CN(ipv4_addr_str)),
1506 DNSName("!"), Result::ERROR_BAD_CERT_DOMAIN),
1507
1508 // We don't match IPv6 addresses in the CN, regardless of whether there is
1509 // a SAN.
1510 WITHOUT_SAN(ipv6_addr_str, RDN(CN(ipv6_addr_str)),
1511 Result::ERROR_BAD_CERT_DOMAIN),
1512 WITH_SAN(ipv6_addr_str, RDN(CN(ipv6_addr_str)),
1513 DNSName("example.com"), Result::ERROR_BAD_CERT_DOMAIN),
1514 WITH_SAN(ipv6_addr_str, RDN(CN(ipv6_addr_str)),
1515 IPAddress(ipv6_addr_bytes), Success),
1516 WITH_SAN(ipv6_addr_str, RDN(CN("foo")), IPAddress(ipv6_addr_bytes),
1517 Success),
1518
1519 // We don't match the binary encoding of the bytes of IP addresses in the
1520 // CN.
1521 WITHOUT_SAN(ipv4_addr_str, RDN(CN(ipv4_addr_bytes_as_str)),
1522 Result::ERROR_BAD_CERT_DOMAIN),
1523 WITHOUT_SAN(ipv6_addr_str, RDN(CN(ipv6_addr_bytes_as_str)),
1524 Result::ERROR_BAD_CERT_DOMAIN),
1525
1526 // We don't match IP addresses with DNSName SANs.
1527 WITH_SAN(ipv4_addr_str, RDN(CN("foo")),
1528 DNSName(ipv4_addr_bytes_as_str), Result::ERROR_BAD_CERT_DOMAIN),
1529 WITH_SAN(ipv4_addr_str, RDN(CN("foo")), DNSName(ipv4_addr_str),
1530 Result::ERROR_BAD_CERT_DOMAIN),
1531 WITH_SAN(ipv6_addr_str, RDN(CN("foo")),
1532 DNSName(ipv6_addr_bytes_as_str), Result::ERROR_BAD_CERT_DOMAIN),
1533 WITH_SAN(ipv6_addr_str, RDN(CN("foo")), DNSName(ipv6_addr_str),
1534 Result::ERROR_BAD_CERT_DOMAIN),
1535
1536 // Do not match an IPv4 reference ID against the equivalent IPv4-compatible
1537 // IPv6 SAN entry.
1538 WITH_SAN(ipv4_addr_str, RDN(CN("foo")),
1539 IPAddress(ipv4_compatible_ipv6_addr_bytes),
1540 Result::ERROR_BAD_CERT_DOMAIN),
1541 // Do not match an IPv4 reference ID against the equivalent IPv4-mapped IPv6
1542 // SAN entry.
1543 WITH_SAN(ipv4_addr_str, RDN(CN("foo")),
1544 IPAddress(ipv4_mapped_ipv6_addr_bytes),
1545 Result::ERROR_BAD_CERT_DOMAIN),
1546 // Do not match an IPv4-compatible IPv6 reference ID against the equivalent
1547 // IPv4 SAN entry.
1548 WITH_SAN(ipv4_compatible_ipv6_addr_str, RDN(CN("foo")),
1549 IPAddress(ipv4_addr_bytes), Result::ERROR_BAD_CERT_DOMAIN),
1550 // Do not match an IPv4 reference ID against the equivalent IPv4-mapped IPv6
1551 // SAN entry.
1552 WITH_SAN(ipv4_mapped_ipv6_addr_str, RDN(CN("foo")),
1553 IPAddress(ipv4_addr_bytes),
1554 Result::ERROR_BAD_CERT_DOMAIN),
1555
1556 // Test that the presence of an otherName entry is handled appropriately.
1557 // (The actual value of the otherName entry isn't important - that's not what
1558 // we're testing here.)
1559 WITH_SAN("example.com", ByteString(),
1560 // The tag for otherName is CONTEXT_SPECIFIC | CONSTRUCTED | 0
1561 TLV((2 << 6) | (1 << 5) | 0, ByteString()) + DNSName("example.com"),
1562 Success),
1563 WITH_SAN("example.com", ByteString(),
1564 TLV((2 << 6) | (1 << 5) | 0, ByteString()),
1565 Result::ERROR_BAD_CERT_DOMAIN),
1566 };
1567
1568 ByteString
CreateCert(const ByteString & subject,const ByteString & subjectAltName,EndEntityOrCA endEntityOrCA=EndEntityOrCA::MustBeEndEntity)1569 CreateCert(const ByteString& subject, const ByteString& subjectAltName,
1570 EndEntityOrCA endEntityOrCA = EndEntityOrCA::MustBeEndEntity)
1571 {
1572 ByteString serialNumber(CreateEncodedSerialNumber(1));
1573 EXPECT_FALSE(ENCODING_FAILED(serialNumber));
1574
1575 ByteString issuerDER(Name(RDN(CN("issuer"))));
1576 EXPECT_FALSE(ENCODING_FAILED(issuerDER));
1577
1578 ByteString extensions[2];
1579 if (subjectAltName != NO_SAN) {
1580 extensions[0] = CreateEncodedSubjectAltName(subjectAltName);
1581 EXPECT_FALSE(ENCODING_FAILED(extensions[0]));
1582 }
1583 if (endEntityOrCA == EndEntityOrCA::MustBeCA) {
1584 // Currently, these tests assume that if we're creating a CA certificate, it
1585 // will not have a subjectAlternativeName extension. If that assumption
1586 // changes, this code will have to be updated. Ideally this would be
1587 // ASSERT_EQ, but that inserts a 'return;', which doesn't match this
1588 // function's return type.
1589 EXPECT_EQ(subjectAltName, NO_SAN);
1590 extensions[0] = CreateEncodedBasicConstraints(true, nullptr,
1591 Critical::Yes);
1592 EXPECT_FALSE(ENCODING_FAILED(extensions[0]));
1593 }
1594
1595 ScopedTestKeyPair keyPair(CloneReusedKeyPair());
1596 return CreateEncodedCertificate(
1597 v3, sha256WithRSAEncryption(), serialNumber, issuerDER,
1598 oneDayBeforeNow, oneDayAfterNow, Name(subject), *keyPair,
1599 extensions, *keyPair, sha256WithRSAEncryption());
1600 }
1601
TEST_P(pkixnames_CheckCertHostname,CheckCertHostname)1602 TEST_P(pkixnames_CheckCertHostname, CheckCertHostname)
1603 {
1604 const CheckCertHostnameParams& param(GetParam());
1605
1606 ByteString cert(CreateCert(param.subject, param.subjectAltName));
1607 ASSERT_FALSE(ENCODING_FAILED(cert));
1608 Input certInput;
1609 ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
1610
1611 Input hostnameInput;
1612 ASSERT_EQ(Success, hostnameInput.Init(param.hostname.data(),
1613 param.hostname.length()));
1614
1615 ASSERT_EQ(param.result, CheckCertHostname(certInput, hostnameInput,
1616 mNameMatchingPolicy));
1617 }
1618
1619 INSTANTIATE_TEST_SUITE_P(pkixnames_CheckCertHostname,
1620 pkixnames_CheckCertHostname,
1621 testing::ValuesIn(CHECK_CERT_HOSTNAME_PARAMS));
1622
TEST_F(pkixnames_CheckCertHostname,SANWithoutSequence)1623 TEST_F(pkixnames_CheckCertHostname, SANWithoutSequence)
1624 {
1625 // A certificate with a truly empty SAN extension (one that doesn't even
1626 // contain a SEQUENCE at all) is malformed. If we didn't treat this as
1627 // malformed then we'd have to treat it like the CN_EmptySAN cases.
1628
1629 ByteString serialNumber(CreateEncodedSerialNumber(1));
1630 EXPECT_FALSE(ENCODING_FAILED(serialNumber));
1631
1632 ByteString extensions[2];
1633 extensions[0] = CreateEncodedEmptySubjectAltName();
1634 ASSERT_FALSE(ENCODING_FAILED(extensions[0]));
1635
1636 ScopedTestKeyPair keyPair(CloneReusedKeyPair());
1637 ByteString certDER(CreateEncodedCertificate(
1638 v3, sha256WithRSAEncryption(), serialNumber,
1639 Name(RDN(CN("issuer"))), oneDayBeforeNow, oneDayAfterNow,
1640 Name(RDN(CN("a"))), *keyPair, extensions,
1641 *keyPair, sha256WithRSAEncryption()));
1642 ASSERT_FALSE(ENCODING_FAILED(certDER));
1643 Input certInput;
1644 ASSERT_EQ(Success, certInput.Init(certDER.data(), certDER.length()));
1645
1646 static const uint8_t a[] = { 'a' };
1647 ASSERT_EQ(Result::ERROR_EXTENSION_VALUE_INVALID,
1648 CheckCertHostname(certInput, Input(a), mNameMatchingPolicy));
1649 }
1650
1651 class pkixnames_CheckCertHostname_PresentedMatchesReference
1652 : public ::testing::Test
1653 , public ::testing::WithParamInterface<PresentedMatchesReference>
1654 {
1655 public:
1656 DefaultNameMatchingPolicy mNameMatchingPolicy;
1657 };
1658
TEST_P(pkixnames_CheckCertHostname_PresentedMatchesReference,CN_NoSAN)1659 TEST_P(pkixnames_CheckCertHostname_PresentedMatchesReference, CN_NoSAN)
1660 {
1661 // Since there is no SAN, a valid presented DNS ID in the subject CN field
1662 // should result in a match.
1663
1664 const PresentedMatchesReference& param(GetParam());
1665
1666 ByteString cert(CreateCert(RDN(CN(param.presentedDNSID)), NO_SAN));
1667 ASSERT_FALSE(ENCODING_FAILED(cert));
1668 Input certInput;
1669 ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
1670
1671 Input hostnameInput;
1672 ASSERT_EQ(Success, hostnameInput.Init(param.referenceDNSID.data(),
1673 param.referenceDNSID.length()));
1674
1675 ASSERT_EQ(param.expectedMatches ? Success : Result::ERROR_BAD_CERT_DOMAIN,
1676 CheckCertHostname(certInput, hostnameInput, mNameMatchingPolicy));
1677 }
1678
TEST_P(pkixnames_CheckCertHostname_PresentedMatchesReference,SubjectAltName_CNNotDNSName)1679 TEST_P(pkixnames_CheckCertHostname_PresentedMatchesReference,
1680 SubjectAltName_CNNotDNSName)
1681 {
1682 // A DNSName SAN entry should match, regardless of the contents of the
1683 // subject CN.
1684
1685 const PresentedMatchesReference& param(GetParam());
1686
1687 ByteString cert(CreateCert(RDN(CN("Common Name")),
1688 DNSName(param.presentedDNSID)));
1689 ASSERT_FALSE(ENCODING_FAILED(cert));
1690 Input certInput;
1691 ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
1692
1693 Input hostnameInput;
1694 ASSERT_EQ(Success, hostnameInput.Init(param.referenceDNSID.data(),
1695 param.referenceDNSID.length()));
1696 Result expectedResult
1697 = param.expectedResult != Success ? param.expectedResult
1698 : param.expectedMatches ? Success
1699 : Result::ERROR_BAD_CERT_DOMAIN;
1700 ASSERT_EQ(expectedResult, CheckCertHostname(certInput, hostnameInput,
1701 mNameMatchingPolicy));
1702 }
1703
1704 INSTANTIATE_TEST_SUITE_P(pkixnames_CheckCertHostname_DNSID_MATCH_PARAMS,
1705 pkixnames_CheckCertHostname_PresentedMatchesReference,
1706 testing::ValuesIn(DNSID_MATCH_PARAMS));
1707
TEST_P(pkixnames_Turkish_I_Comparison,CheckCertHostname_CN_NoSAN)1708 TEST_P(pkixnames_Turkish_I_Comparison, CheckCertHostname_CN_NoSAN)
1709 {
1710 // Make sure we don't have the similar problems that strcasecmp and others
1711 // have with the other kinds of "i" and "I" commonly used in Turkish locales,
1712 // when we're matching a CN due to lack of subjectAltName.
1713
1714 const InputValidity& param(GetParam());
1715 SCOPED_TRACE(param.input.c_str());
1716
1717 Input input;
1718 ASSERT_EQ(Success, input.Init(param.input.data(), param.input.length()));
1719
1720 ByteString cert(CreateCert(RDN(CN(param.input)), NO_SAN));
1721 ASSERT_FALSE(ENCODING_FAILED(cert));
1722 Input certInput;
1723 ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
1724
1725 Result expectedResult = (InputsAreEqual(LOWERCASE_I, input) ||
1726 InputsAreEqual(UPPERCASE_I, input))
1727 ? Success
1728 : Result::ERROR_BAD_CERT_DOMAIN;
1729
1730 ASSERT_EQ(expectedResult, CheckCertHostname(certInput, UPPERCASE_I,
1731 mNameMatchingPolicy));
1732 ASSERT_EQ(expectedResult, CheckCertHostname(certInput, LOWERCASE_I,
1733 mNameMatchingPolicy));
1734 }
1735
TEST_P(pkixnames_Turkish_I_Comparison,CheckCertHostname_SAN)1736 TEST_P(pkixnames_Turkish_I_Comparison, CheckCertHostname_SAN)
1737 {
1738 // Make sure we don't have the similar problems that strcasecmp and others
1739 // have with the other kinds of "i" and "I" commonly used in Turkish locales,
1740 // when we're matching a dNSName in the SAN.
1741
1742 const InputValidity& param(GetParam());
1743 SCOPED_TRACE(param.input.c_str());
1744
1745 Input input;
1746 ASSERT_EQ(Success, input.Init(param.input.data(), param.input.length()));
1747
1748 ByteString cert(CreateCert(RDN(CN("Common Name")), DNSName(param.input)));
1749 ASSERT_FALSE(ENCODING_FAILED(cert));
1750 Input certInput;
1751 ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
1752
1753 Result expectedResult
1754 = (!param.isValidPresentedID) ? Result::ERROR_BAD_DER
1755 : (InputsAreEqual(LOWERCASE_I, input) ||
1756 InputsAreEqual(UPPERCASE_I, input)) ? Success
1757 : Result::ERROR_BAD_CERT_DOMAIN;
1758
1759 ASSERT_EQ(expectedResult, CheckCertHostname(certInput, UPPERCASE_I,
1760 mNameMatchingPolicy));
1761 ASSERT_EQ(expectedResult, CheckCertHostname(certInput, LOWERCASE_I,
1762 mNameMatchingPolicy));
1763 }
1764
1765 class pkixnames_CheckCertHostname_IPV4_Addresses
1766 : public ::testing::Test
1767 , public ::testing::WithParamInterface<IPAddressParams<4>>
1768 {
1769 public:
1770 DefaultNameMatchingPolicy mNameMatchingPolicy;
1771 };
1772
TEST_P(pkixnames_CheckCertHostname_IPV4_Addresses,ValidIPv4AddressInIPAddressSAN)1773 TEST_P(pkixnames_CheckCertHostname_IPV4_Addresses,
1774 ValidIPv4AddressInIPAddressSAN)
1775 {
1776 // When the reference hostname is a valid IPv4 address, a correctly-formed
1777 // IPv4 Address SAN matches it.
1778
1779 const IPAddressParams<4>& param(GetParam());
1780
1781 ByteString cert(CreateCert(RDN(CN("Common Name")),
1782 IPAddress(param.expectedValueIfValid)));
1783 ASSERT_FALSE(ENCODING_FAILED(cert));
1784 Input certInput;
1785 ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
1786
1787 Input hostnameInput;
1788 ASSERT_EQ(Success, hostnameInput.Init(param.input.data(),
1789 param.input.length()));
1790
1791 ASSERT_EQ(param.isValid ? Success : Result::ERROR_BAD_CERT_DOMAIN,
1792 CheckCertHostname(certInput, hostnameInput, mNameMatchingPolicy));
1793 }
1794
TEST_P(pkixnames_CheckCertHostname_IPV4_Addresses,ValidIPv4AddressInCN_NoSAN)1795 TEST_P(pkixnames_CheckCertHostname_IPV4_Addresses,
1796 ValidIPv4AddressInCN_NoSAN)
1797 {
1798 // When the reference hostname is a valid IPv4 address, a correctly-formed
1799 // IPv4 Address in the CN matches it when there is no SAN.
1800
1801 const IPAddressParams<4>& param(GetParam());
1802
1803 SCOPED_TRACE(param.input.c_str());
1804
1805 ByteString cert(CreateCert(RDN(CN(param.input)), NO_SAN));
1806 ASSERT_FALSE(ENCODING_FAILED(cert));
1807 Input certInput;
1808 ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
1809
1810 Input hostnameInput;
1811 ASSERT_EQ(Success, hostnameInput.Init(param.input.data(),
1812 param.input.length()));
1813
1814 // Some of the invalid IPv4 addresses are valid DNS names!
1815 Result expectedResult = (param.isValid || IsValidReferenceDNSID(hostnameInput))
1816 ? Success
1817 : Result::ERROR_BAD_CERT_DOMAIN;
1818
1819 ASSERT_EQ(expectedResult, CheckCertHostname(certInput, hostnameInput,
1820 mNameMatchingPolicy));
1821 }
1822
1823 INSTANTIATE_TEST_SUITE_P(pkixnames_CheckCertHostname_IPV4_ADDRESSES,
1824 pkixnames_CheckCertHostname_IPV4_Addresses,
1825 testing::ValuesIn(IPV4_ADDRESSES));
1826
1827 struct NameConstraintParams
1828 {
1829 ByteString subject;
1830 ByteString subjectAltName;
1831 ByteString subtrees;
1832 Result expectedPermittedSubtreesResult;
1833 Result expectedExcludedSubtreesResult;
1834 };
1835
operator <<(::std::ostream & os,const NameConstraintParams &)1836 ::std::ostream& operator<<(::std::ostream& os, const NameConstraintParams&)
1837 {
1838 return os << "TODO (bug 1318770)";
1839 }
1840
1841 static ByteString
PermittedSubtrees(const ByteString & generalSubtrees)1842 PermittedSubtrees(const ByteString& generalSubtrees)
1843 {
1844 return TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0,
1845 generalSubtrees);
1846 }
1847
1848 static ByteString
ExcludedSubtrees(const ByteString & generalSubtrees)1849 ExcludedSubtrees(const ByteString& generalSubtrees)
1850 {
1851 return TLV(der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1,
1852 generalSubtrees);
1853 }
1854
1855 // Does not encode min or max.
1856 static ByteString
GeneralSubtree(const ByteString & base)1857 GeneralSubtree(const ByteString& base)
1858 {
1859 return TLV(der::SEQUENCE, base);
1860 }
1861
1862 static const NameConstraintParams NAME_CONSTRAINT_PARAMS[] =
1863 {
1864 /////////////////////////////////////////////////////////////////////////////
1865 // XXX: Malformed name constraints for supported types of names are ignored
1866 // when there are no names of that type to constrain.
1867 { ByteString(), NO_SAN,
1868 GeneralSubtree(DNSName("!")),
1869 Success, Success
1870 },
1871 { // DirectoryName constraints are an exception, because *every* certificate
1872 // has at least one DirectoryName (tbsCertificate.subject).
1873 ByteString(), NO_SAN,
1874 GeneralSubtree(Name(ByteString(reinterpret_cast<const uint8_t*>("!"), 1))),
1875 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
1876 },
1877 { ByteString(), NO_SAN,
1878 GeneralSubtree(IPAddress(ipv4_constraint_truncated_bytes)),
1879 Success, Success
1880 },
1881 { ByteString(), NO_SAN,
1882 GeneralSubtree(IPAddress(ipv4_constraint_overlong_bytes)),
1883 Success, Success
1884 },
1885 { ByteString(), NO_SAN,
1886 GeneralSubtree(IPAddress(ipv6_constraint_truncated_bytes)),
1887 Success, Success
1888 },
1889 { ByteString(), NO_SAN,
1890 GeneralSubtree(IPAddress(ipv6_constraint_overlong_bytes)),
1891 Success, Success
1892 },
1893 { ByteString(), NO_SAN,
1894 GeneralSubtree(RFC822Name("!")),
1895 Success, Success
1896 },
1897
1898 /////////////////////////////////////////////////////////////////////////////
1899 // Edge cases of name constraint absolute vs. relative and subdomain matching
1900 // that are not clearly explained in RFC 5280. (See the long comment above
1901 // MatchPresentedDNSIDWithReferenceDNSID.)
1902
1903 // Q: Does a presented identifier equal (case insensitive) to the name
1904 // constraint match the constraint? For example, does the presented
1905 // ID "host.example.com" match a "host.example.com" constraint?
1906 { ByteString(), DNSName("host.example.com"),
1907 GeneralSubtree(DNSName("host.example.com")),
1908 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
1909 },
1910 { // This test case is an example from RFC 5280.
1911 ByteString(), DNSName("host1.example.com"),
1912 GeneralSubtree(DNSName("host.example.com")),
1913 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
1914 },
1915 { ByteString(), RFC822Name("a@host.example.com"),
1916 GeneralSubtree(RFC822Name("host.example.com")),
1917 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
1918 },
1919 { // This test case is an example from RFC 5280.
1920 ByteString(), RFC822Name("a@host1.example.com"),
1921 GeneralSubtree(RFC822Name("host.example.com")),
1922 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
1923 },
1924
1925 // Q: When the name constraint does not start with ".", do subdomain
1926 // presented identifiers match it? For example, does the presented
1927 // ID "www.host.example.com" match a "host.example.com" constraint?
1928 { // This test case is an example from RFC 5280.
1929 ByteString(), DNSName("www.host.example.com"),
1930 GeneralSubtree(DNSName( "host.example.com")),
1931 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
1932 },
1933 { // The subdomain matching rule for host names that do not start with "." is
1934 // different for RFC822Names than for DNSNames!
1935 ByteString(), RFC822Name("a@www.host.example.com"),
1936 GeneralSubtree(RFC822Name( "host.example.com")),
1937 Result::ERROR_CERT_NOT_IN_NAME_SPACE,
1938 Success
1939 },
1940
1941 // Q: When the name constraint does not start with ".", does a
1942 // non-subdomain prefix match it? For example, does "bigfoo.bar.com"
1943 // match "foo.bar.com"?
1944 { ByteString(), DNSName("bigfoo.bar.com"),
1945 GeneralSubtree(DNSName( "foo.bar.com")),
1946 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
1947 },
1948 { ByteString(), RFC822Name("a@bigfoo.bar.com"),
1949 GeneralSubtree(RFC822Name( "foo.bar.com")),
1950 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
1951 },
1952
1953 // Q: Is a name constraint that starts with "." valid, and if so, what
1954 // semantics does it have? For example, does a presented ID of
1955 // "www.example.com" match a constraint of ".example.com"? Does a
1956 // presented ID of "example.com" match a constraint of ".example.com"?
1957 { ByteString(), DNSName("www.example.com"),
1958 GeneralSubtree(DNSName( ".example.com")),
1959 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
1960 },
1961 { // When there is no Local-part, an RFC822 name constraint's domain may
1962 // start with '.', and the semantics are the same as for DNSNames.
1963 ByteString(), RFC822Name("a@www.example.com"),
1964 GeneralSubtree(RFC822Name( ".example.com")),
1965 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
1966 },
1967 { // When there is a Local-part, an RFC822 name constraint's domain must not
1968 // start with '.'.
1969 ByteString(), RFC822Name("a@www.example.com"),
1970 GeneralSubtree(RFC822Name( "a@.example.com")),
1971 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
1972 },
1973 { // Check that we only allow subdomains to match.
1974 ByteString(), DNSName( "example.com"),
1975 GeneralSubtree(DNSName(".example.com")),
1976 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
1977 },
1978 { // Check that we only allow subdomains to match.
1979 ByteString(), RFC822Name("a@example.com"),
1980 GeneralSubtree(RFC822Name(".example.com")),
1981 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
1982 },
1983 { // Check that we don't get confused and consider "b" == "."
1984 ByteString(), DNSName("bexample.com"),
1985 GeneralSubtree(DNSName(".example.com")),
1986 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
1987 },
1988 { // Check that we don't get confused and consider "b" == "."
1989 ByteString(), RFC822Name("a@bexample.com"),
1990 GeneralSubtree(RFC822Name( ".example.com")),
1991 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
1992 },
1993
1994 // Q: Is there a way to prevent subdomain matches?
1995 // (This is tested in a different set of tests because it requires a
1996 // combination of permittedSubtrees and excludedSubtrees.)
1997
1998 // Q: Are name constraints allowed to be specified as absolute names?
1999 // For example, does a presented ID of "example.com" match a name
2000 // constraint of "example.com." and vice versa?
2001 //
2002 { // The DNSName in the constraint is not valid because constraint DNS IDs
2003 // are not allowed to be absolute.
2004 ByteString(), DNSName("example.com"),
2005 GeneralSubtree(DNSName("example.com.")),
2006 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER,
2007 },
2008 { ByteString(), RFC822Name("a@example.com"),
2009 GeneralSubtree(RFC822Name( "example.com.")),
2010 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER,
2011 },
2012 { // The DNSName in the SAN is not valid because presented DNS IDs are not
2013 // allowed to be absolute.
2014 ByteString(), DNSName("example.com."),
2015 GeneralSubtree(DNSName("example.com")),
2016 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER,
2017 },
2018 { ByteString(), RFC822Name("a@example.com."),
2019 GeneralSubtree(RFC822Name( "example.com")),
2020 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER,
2021 },
2022 { // The presented DNSName is the same length as the constraint, because the
2023 // subdomain is only one character long and because the constraint both
2024 // begins and ends with ".". But, it doesn't matter because absolute names
2025 // are not allowed for DNSName constraints.
2026 ByteString(), DNSName("p.example.com"),
2027 GeneralSubtree(DNSName(".example.com.")),
2028 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER,
2029 },
2030 { // The presented DNSName is the same length as the constraint, because the
2031 // subdomain is only one character long and because the constraint both
2032 // begins and ends with ".".
2033 ByteString(), RFC822Name("a@p.example.com"),
2034 GeneralSubtree(RFC822Name( ".example.com.")),
2035 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER,
2036 },
2037 { // Same as previous test case, but using a wildcard presented ID.
2038 ByteString(), DNSName("*.example.com"),
2039 GeneralSubtree(DNSName(".example.com.")),
2040 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2041 },
2042 { // Same as previous test case, but using a wildcard presented ID, which is
2043 // invalid in an RFC822Name.
2044 ByteString(), RFC822Name("a@*.example.com"),
2045 GeneralSubtree(RFC822Name( ".example.com.")),
2046 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2047 },
2048
2049 // Q: Are "" and "." valid DNSName constraints? If so, what do they mean?
2050 { ByteString(), DNSName("example.com"),
2051 GeneralSubtree(DNSName("")),
2052 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2053 },
2054 { ByteString(), RFC822Name("a@example.com"),
2055 GeneralSubtree(RFC822Name("")),
2056 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2057 },
2058 { // The malformed (absolute) presented ID does not match.
2059 ByteString(), DNSName("example.com."),
2060 GeneralSubtree(DNSName("")),
2061 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2062 },
2063 { ByteString(), RFC822Name("a@example.com."),
2064 GeneralSubtree(RFC822Name("")),
2065 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2066 },
2067 { // Invalid syntax in name constraint
2068 ByteString(), DNSName("example.com"),
2069 GeneralSubtree(DNSName(".")),
2070 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER,
2071 },
2072 { // Invalid syntax in name constraint
2073 ByteString(), RFC822Name("a@example.com"),
2074 GeneralSubtree(RFC822Name(".")),
2075 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER,
2076 },
2077 { ByteString(), DNSName("example.com."),
2078 GeneralSubtree(DNSName(".")),
2079 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2080 },
2081 { ByteString(), RFC822Name("a@example.com."),
2082 GeneralSubtree(RFC822Name(".")),
2083 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2084 },
2085
2086 /////////////////////////////////////////////////////////////////////////////
2087 // Basic IP Address constraints (non-CN-ID)
2088
2089 // The Mozilla CA Policy says this means "no IPv4 addresses allowed."
2090 { ByteString(), IPAddress(ipv4_addr_bytes),
2091 GeneralSubtree(IPAddress(ipv4_constraint_all_zeros_bytes)),
2092 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2093 },
2094 { ByteString(), IPAddress(ipv4_addr_00000000_bytes),
2095 GeneralSubtree(IPAddress(ipv4_constraint_all_zeros_bytes)),
2096 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2097 },
2098 { ByteString(), IPAddress(ipv4_addr_FFFFFFFF_bytes),
2099 GeneralSubtree(IPAddress(ipv4_constraint_all_zeros_bytes)),
2100 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2101 },
2102
2103 // The Mozilla CA Policy says this means "no IPv6 addresses allowed."
2104 { ByteString(), IPAddress(ipv6_addr_bytes),
2105 GeneralSubtree(IPAddress(ipv6_constraint_all_zeros_bytes)),
2106 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2107 },
2108 { ByteString(), IPAddress(ipv6_addr_all_zeros_bytes),
2109 GeneralSubtree(IPAddress(ipv6_constraint_all_zeros_bytes)),
2110 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2111 },
2112
2113 // RFC 5280 doesn't partition IP address constraints into separate IPv4 and
2114 // IPv6 categories, so a IPv4 permittedSubtrees constraint excludes all IPv6
2115 // addresses, and vice versa.
2116 { ByteString(), IPAddress(ipv4_addr_bytes),
2117 GeneralSubtree(IPAddress(ipv6_constraint_all_zeros_bytes)),
2118 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
2119 },
2120 { ByteString(), IPAddress(ipv6_addr_bytes),
2121 GeneralSubtree(IPAddress(ipv4_constraint_all_zeros_bytes)),
2122 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
2123 },
2124
2125 // IPv4 Subnets
2126 { ByteString(), IPAddress(ipv4_addr_bytes),
2127 GeneralSubtree(IPAddress(ipv4_constraint_CIDR_16_bytes)),
2128 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2129 },
2130 { ByteString(), IPAddress(ipv4_addr_bytes),
2131 GeneralSubtree(IPAddress(ipv4_constraint_CIDR_17_bytes)),
2132 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2133 },
2134 { ByteString(), IPAddress(ipv4_other_addr_bytes),
2135 GeneralSubtree(IPAddress(ipv4_constraint_CIDR_16_bytes)),
2136 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
2137 },
2138 { // XXX(bug 1089430): We don't reject this even though it is weird.
2139 ByteString(), IPAddress(ipv4_addr_bytes),
2140 GeneralSubtree(IPAddress(ipv4_constraint_CIDR_16_bad_addr_bytes)),
2141 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2142 },
2143 { // XXX(bug 1089430): We don't reject this even though it is weird.
2144 ByteString(), IPAddress(ipv4_other_addr_bytes),
2145 GeneralSubtree(IPAddress(ipv4_constraint_bad_mask_bytes)),
2146 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
2147 },
2148
2149 // IPv6 Subnets
2150 { ByteString(), IPAddress(ipv6_addr_bytes),
2151 GeneralSubtree(IPAddress(ipv6_constraint_CIDR_16_bytes)),
2152 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2153 },
2154 { ByteString(), IPAddress(ipv6_other_addr_bytes),
2155 GeneralSubtree(IPAddress(ipv6_constraint_CIDR_16_bytes)),
2156 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
2157 },
2158 { // XXX(bug 1089430): We don't reject this even though it is weird.
2159 ByteString(), IPAddress(ipv6_addr_bytes),
2160 GeneralSubtree(IPAddress(ipv6_constraint_CIDR_16_bad_addr_bytes)),
2161 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2162 },
2163 { // XXX(bug 1089430): We don't reject this even though it is weird.
2164 ByteString(), IPAddress(ipv6_other_addr_bytes),
2165 GeneralSubtree(IPAddress(ipv6_constraint_bad_mask_bytes)),
2166 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
2167 },
2168
2169 // Malformed presented IP addresses and constraints
2170
2171 { // The presented IPv4 address is empty
2172 ByteString(), IPAddress(),
2173 GeneralSubtree(IPAddress(ipv4_constraint_all_zeros_bytes)),
2174 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2175 },
2176 { // The presented IPv4 address is truncated
2177 ByteString(), IPAddress(ipv4_addr_truncated_bytes),
2178 GeneralSubtree(IPAddress(ipv4_constraint_all_zeros_bytes)),
2179 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2180 },
2181 { // The presented IPv4 address is too long
2182 ByteString(), IPAddress(ipv4_addr_overlong_bytes),
2183 GeneralSubtree(IPAddress(ipv4_constraint_all_zeros_bytes)),
2184 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2185 },
2186 { // The presented IPv4 constraint is empty
2187 ByteString(), IPAddress(ipv4_addr_bytes),
2188 GeneralSubtree(IPAddress()),
2189 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2190 },
2191 { // The presented IPv4 constraint is truncated
2192 ByteString(), IPAddress(ipv4_addr_bytes),
2193 GeneralSubtree(IPAddress(ipv4_constraint_truncated_bytes)),
2194 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2195 },
2196 { // The presented IPv4 constraint is too long
2197 ByteString(), IPAddress(ipv4_addr_bytes),
2198 GeneralSubtree(IPAddress(ipv4_constraint_overlong_bytes)),
2199 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2200 },
2201 { // The presented IPv6 address is empty
2202 ByteString(), IPAddress(),
2203 GeneralSubtree(IPAddress(ipv6_constraint_all_zeros_bytes)),
2204 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2205 },
2206 { // The presented IPv6 address is truncated
2207 ByteString(), IPAddress(ipv6_addr_truncated_bytes),
2208 GeneralSubtree(IPAddress(ipv6_constraint_all_zeros_bytes)),
2209 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2210 },
2211 { // The presented IPv6 address is too long
2212 ByteString(), IPAddress(ipv6_addr_overlong_bytes),
2213 GeneralSubtree(IPAddress(ipv6_constraint_all_zeros_bytes)),
2214 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2215 },
2216 { // The presented IPv6 constraint is empty
2217 ByteString(), IPAddress(ipv6_addr_bytes),
2218 GeneralSubtree(IPAddress()),
2219 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2220 },
2221 { // The presented IPv6 constraint is truncated
2222 ByteString(), IPAddress(ipv6_addr_bytes),
2223 GeneralSubtree(IPAddress(ipv6_constraint_truncated_bytes)),
2224 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2225 },
2226 { // The presented IPv6 constraint is too long
2227 ByteString(), IPAddress(ipv6_addr_bytes),
2228 GeneralSubtree(IPAddress(ipv6_constraint_overlong_bytes)),
2229 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2230 },
2231
2232 /////////////////////////////////////////////////////////////////////////////
2233 // XXX: We don't reject malformed name constraints when there are no names of
2234 // that type.
2235 { ByteString(), NO_SAN, GeneralSubtree(DNSName("!")),
2236 Success, Success
2237 },
2238 { ByteString(), NO_SAN, GeneralSubtree(IPAddress(ipv4_addr_overlong_bytes)),
2239 Success, Success
2240 },
2241 { ByteString(), NO_SAN, GeneralSubtree(IPAddress(ipv6_addr_overlong_bytes)),
2242 Success, Success
2243 },
2244 { ByteString(), NO_SAN, GeneralSubtree(RFC822Name("\0")),
2245 Success, Success
2246 },
2247
2248 /////////////////////////////////////////////////////////////////////////////
2249 // Basic CN-ID DNSName constraint tests.
2250
2251 { // Empty Name is ignored for DNSName constraints.
2252 ByteString(), NO_SAN, GeneralSubtree(DNSName("a.example.com")),
2253 Success, Success
2254 },
2255 { // Empty CN is ignored for DNSName constraints because it isn't a
2256 // syntactically-valid DNSName.
2257 //
2258 // NSS gives different results.
2259 RDN(CN("")), NO_SAN, GeneralSubtree(DNSName("a.example.com")),
2260 Success, Success
2261 },
2262 { // IP Address is ignored for DNSName constraints.
2263 //
2264 // NSS gives different results.
2265 RDN(CN("1.2.3.4")), NO_SAN, GeneralSubtree(DNSName("a.example.com")),
2266 Success, Success
2267 },
2268 { // OU has something that looks like a dNSName that matches.
2269 RDN(OU("a.example.com")), NO_SAN, GeneralSubtree(DNSName("a.example.com")),
2270 Success, Success
2271 },
2272 { // OU has something that looks like a dNSName that does not match.
2273 RDN(OU("b.example.com")), NO_SAN, GeneralSubtree(DNSName("a.example.com")),
2274 Success, Success
2275 },
2276 { // NSS gives different results.
2277 RDN(CN("Not a DNSName")), NO_SAN, GeneralSubtree(DNSName("a.example.com")),
2278 Success, Success
2279 },
2280 { RDN(CN("a.example.com")), NO_SAN, GeneralSubtree(DNSName("a.example.com")),
2281 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2282 },
2283 { RDN(CN("b.example.com")), NO_SAN, GeneralSubtree(DNSName("a.example.com")),
2284 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
2285 },
2286 { // DNSName CN-ID match is detected when there is a SAN w/o any DNSName or
2287 // IPAddress
2288 RDN(CN("a.example.com")), RFC822Name("foo@example.com"),
2289 GeneralSubtree(DNSName("a.example.com")),
2290 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2291 },
2292 { // DNSName CN-ID mismatch is detected when there is a SAN w/o any DNSName
2293 // or IPAddress
2294 RDN(CN("a.example.com")), RFC822Name("foo@example.com"),
2295 GeneralSubtree(DNSName("b.example.com")),
2296 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
2297 },
2298 { // DNSName CN-ID match not reported when there is a DNSName SAN
2299 RDN(CN("a.example.com")), DNSName("b.example.com"),
2300 GeneralSubtree(DNSName("a.example.com")),
2301 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
2302 },
2303 { // DNSName CN-ID mismatch not reported when there is a DNSName SAN
2304 RDN(CN("a.example.com")), DNSName("b.example.com"),
2305 GeneralSubtree(DNSName("b.example.com")),
2306 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE,
2307 },
2308 { // DNSName CN-ID match not reported when there is an IPAddress SAN
2309 RDN(CN("a.example.com")), IPAddress(ipv4_addr_bytes),
2310 GeneralSubtree(DNSName("a.example.com")),
2311 Success, Success
2312 },
2313 { // DNSName CN-ID mismatch not reported when there is an IPAddress SAN
2314 RDN(CN("a.example.com")), IPAddress(ipv4_addr_bytes),
2315 GeneralSubtree(DNSName("b.example.com")),
2316 Success, Success
2317 },
2318
2319 { // IPAddress CN-ID match is detected when there is a SAN w/o any DNSName or
2320 // IPAddress
2321 RDN(CN(ipv4_addr_str)), RFC822Name("foo@example.com"),
2322 GeneralSubtree(IPAddress(ipv4_addr_bytes_FFFFFFFF)),
2323 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2324 },
2325 { // IPAddress CN-ID mismatch is detected when there is a SAN w/o any DNSName
2326 // or IPAddress
2327 RDN(CN(ipv4_addr_str)), RFC822Name("foo@example.com"),
2328 GeneralSubtree(IPAddress(ipv4_other_addr_bytes_FFFFFFFF)),
2329 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
2330 },
2331 { // IPAddress CN-ID match not reported when there is a DNSName SAN
2332 RDN(CN(ipv4_addr_str)), DNSName("b.example.com"),
2333 GeneralSubtree(IPAddress(ipv4_addr_bytes_FFFFFFFF)),
2334 Success, Success
2335 },
2336 { // IPAddress CN-ID mismatch not reported when there is a DNSName SAN
2337 RDN(CN(ipv4_addr_str)), DNSName("b.example.com"),
2338 GeneralSubtree(IPAddress(ipv4_addr_bytes_FFFFFFFF)),
2339 Success, Success
2340 },
2341 { // IPAddress CN-ID match not reported when there is an IPAddress SAN
2342 RDN(CN(ipv4_addr_str)), IPAddress(ipv4_other_addr_bytes),
2343 GeneralSubtree(IPAddress(ipv4_addr_bytes_FFFFFFFF)),
2344 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
2345 },
2346 { // IPAddress CN-ID mismatch not reported when there is an IPAddress SAN
2347 RDN(CN(ipv4_addr_str)), IPAddress(ipv4_other_addr_bytes),
2348 GeneralSubtree(IPAddress(ipv4_other_addr_bytes_FFFFFFFF)),
2349 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2350 },
2351
2352 /////////////////////////////////////////////////////////////////////////////
2353 // Test that constraints are applied to the most specific (last) CN, and only
2354 // that CN-ID.
2355
2356 { // Name constraint only matches a.example.com, but the most specific CN
2357 // (i.e. the CN-ID) is b.example.com. (Two CNs in one RDN.)
2358 RDN(CN("a.example.com") + CN("b.example.com")), NO_SAN,
2359 GeneralSubtree(DNSName("a.example.com")),
2360 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
2361 },
2362 { // Name constraint only matches a.example.com, but the most specific CN
2363 // (i.e. the CN-ID) is b.example.com. (Two CNs in separate RDNs.)
2364 RDN(CN("a.example.com")) + RDN(CN("b.example.com")), NO_SAN,
2365 GeneralSubtree(DNSName("a.example.com")),
2366 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Success
2367 },
2368 { // Name constraint only permits b.example.com, and the most specific CN
2369 // (i.e. the CN-ID) is b.example.com. (Two CNs in one RDN.)
2370 RDN(CN("a.example.com") + CN("b.example.com")), NO_SAN,
2371 GeneralSubtree(DNSName("b.example.com")),
2372 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2373 },
2374 { // Name constraint only permits b.example.com, and the most specific CN
2375 // (i.e. the CN-ID) is b.example.com. (Two CNs in separate RDNs.)
2376 RDN(CN("a.example.com")) + RDN(CN("b.example.com")), NO_SAN,
2377 GeneralSubtree(DNSName("b.example.com")),
2378 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2379 },
2380
2381 /////////////////////////////////////////////////////////////////////////////
2382 // Additional RFC822 name constraint tests. There are more tests regarding
2383 // the DNSName part of the constraint mixed into the DNSName constraint
2384 // tests.
2385
2386 { ByteString(), RFC822Name("a@example.com"),
2387 GeneralSubtree(RFC822Name("a@example.com")),
2388 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2389 },
2390
2391 // Bug 1056773: name constraints that omit Local-part but include '@' are
2392 // invalid.
2393 { ByteString(), RFC822Name("a@example.com"),
2394 GeneralSubtree(RFC822Name("@example.com")),
2395 Result::ERROR_BAD_DER,
2396 Result::ERROR_BAD_DER
2397 },
2398 { ByteString(), RFC822Name("@example.com"),
2399 GeneralSubtree(RFC822Name("@example.com")),
2400 Result::ERROR_BAD_DER,
2401 Result::ERROR_BAD_DER
2402 },
2403 { ByteString(), RFC822Name("example.com"),
2404 GeneralSubtree(RFC822Name("@example.com")),
2405 Result::ERROR_BAD_DER,
2406 Result::ERROR_BAD_DER
2407 },
2408 { ByteString(), RFC822Name("a@mail.example.com"),
2409 GeneralSubtree(RFC822Name("a@*.example.com")),
2410 Result::ERROR_BAD_DER,
2411 Result::ERROR_BAD_DER
2412 },
2413 { ByteString(), RFC822Name("a@*.example.com"),
2414 GeneralSubtree(RFC822Name(".example.com")),
2415 Result::ERROR_BAD_DER,
2416 Result::ERROR_BAD_DER
2417 },
2418 { ByteString(), RFC822Name("@example.com"),
2419 GeneralSubtree(RFC822Name(".example.com")),
2420 Result::ERROR_BAD_DER,
2421 Result::ERROR_BAD_DER
2422 },
2423 { ByteString(), RFC822Name("@a.example.com"),
2424 GeneralSubtree(RFC822Name(".example.com")),
2425 Result::ERROR_BAD_DER,
2426 Result::ERROR_BAD_DER
2427 },
2428
2429 /////////////////////////////////////////////////////////////////////////////
2430 // Test name constraints with underscores.
2431 //
2432 { ByteString(), DNSName("uses_underscore.example.com"),
2433 GeneralSubtree(DNSName("uses_underscore.example.com")),
2434 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2435 },
2436 { ByteString(), DNSName("uses_underscore.example.com"),
2437 GeneralSubtree(DNSName("example.com")),
2438 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2439 },
2440 { ByteString(), DNSName("a.uses_underscore.example.com"),
2441 GeneralSubtree(DNSName("uses_underscore.example.com")),
2442 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2443 },
2444 { ByteString(), RFC822Name("a@uses_underscore.example.com"),
2445 GeneralSubtree(RFC822Name("uses_underscore.example.com")),
2446 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2447 },
2448 { ByteString(), RFC822Name("uses_underscore@example.com"),
2449 GeneralSubtree(RFC822Name("example.com")),
2450 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2451 },
2452 { ByteString(), RFC822Name("a@a.uses_underscore.example.com"),
2453 GeneralSubtree(RFC822Name(".uses_underscore.example.com")),
2454 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2455 },
2456
2457 /////////////////////////////////////////////////////////////////////////////
2458 // Name constraint tests that relate to having an empty SAN. According to RFC
2459 // 5280 this isn't valid, but we allow it for compatibility reasons (see bug
2460 // 1143085).
2461 { // For DNSNames, we fall back to the subject CN.
2462 RDN(CN("a.example.com")), ByteString(),
2463 GeneralSubtree(DNSName("a.example.com")),
2464 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2465 },
2466 { // For RFC822Names, we do not fall back to the subject emailAddress.
2467 // This new implementation seems to conform better to the standards for
2468 // RFC822 name constraints, by only applying the name constraints to
2469 // emailAddress names in the certificate subject if there is no
2470 // subjectAltName extension in the cert.
2471 // In this case, the presence of the (empty) SAN extension means that RFC822
2472 // name constraints are not enforced on the emailAddress attributes of the
2473 // subject.
2474 RDN(emailAddress("a@example.com")), ByteString(),
2475 GeneralSubtree(RFC822Name("a@example.com")),
2476 Success, Success
2477 },
2478 { // Compare this to the case where there is no SAN (i.e. the name
2479 // constraints are enforced, because the extension is not present at all).
2480 RDN(emailAddress("a@example.com")), NO_SAN,
2481 GeneralSubtree(RFC822Name("a@example.com")),
2482 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2483 },
2484
2485 /////////////////////////////////////////////////////////////////////////////
2486 // DirectoryName name constraint tests
2487
2488 { // One AVA per RDN
2489 RDN(OU("Example Organization")) + RDN(CN("example.com")), NO_SAN,
2490 GeneralSubtree(DirectoryName(Name(RDN(OU("Example Organization")) +
2491 RDN(CN("example.com"))))),
2492 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2493 },
2494 { // RDNs can have multiple AVAs.
2495 RDN(OU("Example Organization") + CN("example.com")), NO_SAN,
2496 GeneralSubtree(DirectoryName(Name(RDN(OU("Example Organization") +
2497 CN("example.com"))))),
2498 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2499 },
2500 { // The constraint is a prefix of the subject DN.
2501 RDN(OU("Example Organization")) + RDN(CN("example.com")), NO_SAN,
2502 GeneralSubtree(DirectoryName(Name(RDN(OU("Example Organization"))))),
2503 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2504 },
2505 { // The name constraint is not a prefix of the subject DN.
2506 // Note that for excludedSubtrees, we simply prohibit any non-empty
2507 // directoryName constraint to ensure we are not being too lenient.
2508 RDN(OU("Other Example Organization")) + RDN(CN("example.com")), NO_SAN,
2509 GeneralSubtree(DirectoryName(Name(RDN(OU("Example Organization")) +
2510 RDN(CN("example.com"))))),
2511 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2512 },
2513 { // Same as the previous one, but one RDN with multiple AVAs.
2514 RDN(OU("Other Example Organization") + CN("example.com")), NO_SAN,
2515 GeneralSubtree(DirectoryName(Name(RDN(OU("Example Organization") +
2516 CN("example.com"))))),
2517 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2518 },
2519 { // With multiple AVAs per RDN in the subject DN, the constraint is not a
2520 // prefix of the subject DN.
2521 RDN(OU("Example Organization") + CN("example.com")), NO_SAN,
2522 GeneralSubtree(DirectoryName(Name(RDN(OU("Example Organization"))))),
2523 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2524 },
2525 { // The subject DN RDN has multiple AVAs, but the name constraint has only
2526 // one AVA per RDN.
2527 RDN(OU("Example Organization") + CN("example.com")), NO_SAN,
2528 GeneralSubtree(DirectoryName(Name(RDN(OU("Example Organization")) +
2529 RDN(CN("example.com"))))),
2530 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2531 },
2532 { // The name constraint RDN has multiple AVAs, but the subject DN has only
2533 // one AVA per RDN.
2534 RDN(OU("Example Organization")) + RDN(CN("example.com")), NO_SAN,
2535 GeneralSubtree(DirectoryName(Name(RDN(OU("Example Organization") +
2536 CN("example.com"))))),
2537 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2538 },
2539 { // In this case, the constraint uses a different encoding from the subject.
2540 // We consider them to match because we allow UTF8String and
2541 // PrintableString to compare equal when their contents are equal.
2542 RDN(OU("Example Organization", der::UTF8String)) + RDN(CN("example.com")),
2543 NO_SAN, GeneralSubtree(DirectoryName(Name(RDN(OU("Example Organization",
2544 der::PrintableString)) +
2545 RDN(CN("example.com"))))),
2546 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2547 },
2548 { // Same as above, but with UTF8String/PrintableString switched.
2549 RDN(OU("Example Organization", der::PrintableString)) + RDN(CN("example.com")),
2550 NO_SAN, GeneralSubtree(DirectoryName(Name(RDN(OU("Example Organization",
2551 der::UTF8String)) +
2552 RDN(CN("example.com"))))),
2553 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2554 },
2555 { // If the contents aren't the same, then they shouldn't match.
2556 RDN(OU("Other Example Organization", der::UTF8String)) + RDN(CN("example.com")),
2557 NO_SAN, GeneralSubtree(DirectoryName(Name(RDN(OU("Example Organization",
2558 der::PrintableString)) +
2559 RDN(CN("example.com"))))),
2560 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2561 },
2562 { // Only UTF8String and PrintableString are considered equivalent.
2563 RDN(OU("Example Organization", der::PrintableString)) + RDN(CN("example.com")),
2564 NO_SAN, GeneralSubtree(DirectoryName(Name(RDN(OU("Example Organization",
2565 der::TeletexString)) +
2566 RDN(CN("example.com"))))),
2567 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2568 },
2569 // Some additional tests for completeness:
2570 // Ensure that wildcards are handled:
2571 { RDN(CN("*.example.com")), NO_SAN, GeneralSubtree(DNSName("example.com")),
2572 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2573 },
2574 { ByteString(), DNSName("*.example.com"),
2575 GeneralSubtree(DNSName("example.com")),
2576 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2577 },
2578 { ByteString(), DNSName("www.example.com"),
2579 GeneralSubtree(DNSName("*.example.com")),
2580 Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
2581 },
2582 // Handle multiple name constraint entries:
2583 { RDN(CN("example.com")), NO_SAN,
2584 GeneralSubtree(DNSName("example.org")) +
2585 GeneralSubtree(DNSName("example.com")),
2586 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2587 },
2588 { ByteString(), DNSName("example.com"),
2589 GeneralSubtree(DNSName("example.org")) +
2590 GeneralSubtree(DNSName("example.com")),
2591 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2592 },
2593 // Handle multiple names in subject alternative name extension:
2594 { ByteString(), DNSName("example.com") + DNSName("example.org"),
2595 GeneralSubtree(DNSName("example.com")),
2596 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2597 },
2598 // Handle a mix of DNSName and DirectoryName:
2599 { RDN(OU("Example Organization")), DNSName("example.com"),
2600 GeneralSubtree(DirectoryName(Name(RDN(OU("Example Organization"))))) +
2601 GeneralSubtree(DNSName("example.com")),
2602 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2603 },
2604 { RDN(OU("Other Example Organization")), DNSName("example.com"),
2605 GeneralSubtree(DirectoryName(Name(RDN(OU("Example Organization"))))) +
2606 GeneralSubtree(DNSName("example.com")),
2607 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2608 },
2609 { RDN(OU("Example Organization")), DNSName("example.org"),
2610 GeneralSubtree(DirectoryName(Name(RDN(OU("Example Organization"))))) +
2611 GeneralSubtree(DNSName("example.com")),
2612 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2613 },
2614 // Handle a certificate with no DirectoryName:
2615 { ByteString(), DNSName("example.com"),
2616 GeneralSubtree(DirectoryName(Name(RDN(OU("Example Organization"))))),
2617 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2618 },
2619 };
2620
2621 class pkixnames_CheckNameConstraints
2622 : public ::testing::Test
2623 , public ::testing::WithParamInterface<NameConstraintParams>
2624 {
2625 public:
2626 DefaultNameMatchingPolicy mNameMatchingPolicy;
2627 };
2628
TEST_P(pkixnames_CheckNameConstraints,NameConstraintsEnforcedForDirectlyIssuedEndEntity)2629 TEST_P(pkixnames_CheckNameConstraints,
2630 NameConstraintsEnforcedForDirectlyIssuedEndEntity)
2631 {
2632 // Test that name constraints are enforced on a certificate directly issued by
2633 // a certificate with the given name constraints.
2634
2635 const NameConstraintParams& param(GetParam());
2636
2637 ByteString certDER(CreateCert(param.subject, param.subjectAltName));
2638 ASSERT_FALSE(ENCODING_FAILED(certDER));
2639 Input certInput;
2640 ASSERT_EQ(Success, certInput.Init(certDER.data(), certDER.length()));
2641 BackCert cert(certInput, EndEntityOrCA::MustBeEndEntity, nullptr);
2642 ASSERT_EQ(Success, cert.Init());
2643
2644 {
2645 ByteString nameConstraintsDER(TLV(der::SEQUENCE,
2646 PermittedSubtrees(param.subtrees)));
2647 Input nameConstraints;
2648 ASSERT_EQ(Success,
2649 nameConstraints.Init(nameConstraintsDER.data(),
2650 nameConstraintsDER.length()));
2651 ASSERT_EQ(param.expectedPermittedSubtreesResult,
2652 CheckNameConstraints(nameConstraints, cert,
2653 KeyPurposeId::id_kp_serverAuth));
2654 }
2655 {
2656 ByteString nameConstraintsDER(TLV(der::SEQUENCE,
2657 ExcludedSubtrees(param.subtrees)));
2658 Input nameConstraints;
2659 ASSERT_EQ(Success,
2660 nameConstraints.Init(nameConstraintsDER.data(),
2661 nameConstraintsDER.length()));
2662 ASSERT_EQ(param.expectedExcludedSubtreesResult,
2663 CheckNameConstraints(nameConstraints, cert,
2664 KeyPurposeId::id_kp_serverAuth));
2665 }
2666 {
2667 ByteString nameConstraintsDER(TLV(der::SEQUENCE,
2668 PermittedSubtrees(param.subtrees) +
2669 ExcludedSubtrees(param.subtrees)));
2670 Input nameConstraints;
2671 ASSERT_EQ(Success,
2672 nameConstraints.Init(nameConstraintsDER.data(),
2673 nameConstraintsDER.length()));
2674 ASSERT_EQ((param.expectedPermittedSubtreesResult ==
2675 param.expectedExcludedSubtreesResult)
2676 ? param.expectedExcludedSubtreesResult
2677 : Result::ERROR_CERT_NOT_IN_NAME_SPACE,
2678 CheckNameConstraints(nameConstraints, cert,
2679 KeyPurposeId::id_kp_serverAuth));
2680 }
2681 }
2682
2683 INSTANTIATE_TEST_SUITE_P(pkixnames_CheckNameConstraints,
2684 pkixnames_CheckNameConstraints,
2685 testing::ValuesIn(NAME_CONSTRAINT_PARAMS));
2686
2687 // The |subjectAltName| param is not used for these test cases (hence the use of
2688 // "NO_SAN").
2689 static const NameConstraintParams NO_FALLBACK_NAME_CONSTRAINT_PARAMS[] =
2690 {
2691 // The only difference between end-entities being verified for serverAuth and
2692 // intermediates or end-entities being verified for other uses is that for
2693 // the latter cases, there is no fallback matching of DNSName entries to the
2694 // subject common name.
2695 { RDN(CN("Not a DNSName")), NO_SAN, GeneralSubtree(DNSName("a.example.com")),
2696 Success, Success
2697 },
2698 { RDN(CN("a.example.com")), NO_SAN, GeneralSubtree(DNSName("a.example.com")),
2699 Success, Success
2700 },
2701 { RDN(CN("b.example.com")), NO_SAN, GeneralSubtree(DNSName("a.example.com")),
2702 Success, Success
2703 },
2704 // Sanity-check that name constraints are in fact enforced in these cases.
2705 { RDN(CN("Example Name")), NO_SAN,
2706 GeneralSubtree(DirectoryName(Name(RDN(CN("Example Name"))))),
2707 Success, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2708 },
2709 // (In this implementation, if a DirectoryName is in excludedSubtrees, nothing
2710 // is considered to be in the name space.)
2711 { RDN(CN("Other Example Name")), NO_SAN,
2712 GeneralSubtree(DirectoryName(Name(RDN(CN("Example Name"))))),
2713 Result::ERROR_CERT_NOT_IN_NAME_SPACE, Result::ERROR_CERT_NOT_IN_NAME_SPACE
2714 },
2715 };
2716
2717 class pkixnames_CheckNameConstraintsOnIntermediate
2718 : public ::testing::Test
2719 , public ::testing::WithParamInterface<NameConstraintParams>
2720 {
2721 };
2722
TEST_P(pkixnames_CheckNameConstraintsOnIntermediate,NameConstraintsEnforcedOnIntermediate)2723 TEST_P(pkixnames_CheckNameConstraintsOnIntermediate,
2724 NameConstraintsEnforcedOnIntermediate)
2725 {
2726 // Test that name constraints are enforced on an intermediate certificate
2727 // directly issued by a certificate with the given name constraints.
2728
2729 const NameConstraintParams& param(GetParam());
2730
2731 ByteString certDER(CreateCert(param.subject, NO_SAN,
2732 EndEntityOrCA::MustBeCA));
2733 ASSERT_FALSE(ENCODING_FAILED(certDER));
2734 Input certInput;
2735 ASSERT_EQ(Success, certInput.Init(certDER.data(), certDER.length()));
2736 BackCert cert(certInput, EndEntityOrCA::MustBeCA, nullptr);
2737 ASSERT_EQ(Success, cert.Init());
2738
2739 {
2740 ByteString nameConstraintsDER(TLV(der::SEQUENCE,
2741 PermittedSubtrees(param.subtrees)));
2742 Input nameConstraints;
2743 ASSERT_EQ(Success,
2744 nameConstraints.Init(nameConstraintsDER.data(),
2745 nameConstraintsDER.length()));
2746 ASSERT_EQ(param.expectedPermittedSubtreesResult,
2747 CheckNameConstraints(nameConstraints, cert,
2748 KeyPurposeId::id_kp_serverAuth));
2749 }
2750 {
2751 ByteString nameConstraintsDER(TLV(der::SEQUENCE,
2752 ExcludedSubtrees(param.subtrees)));
2753 Input nameConstraints;
2754 ASSERT_EQ(Success,
2755 nameConstraints.Init(nameConstraintsDER.data(),
2756 nameConstraintsDER.length()));
2757 ASSERT_EQ(param.expectedExcludedSubtreesResult,
2758 CheckNameConstraints(nameConstraints, cert,
2759 KeyPurposeId::id_kp_serverAuth));
2760 }
2761 {
2762 ByteString nameConstraintsDER(TLV(der::SEQUENCE,
2763 PermittedSubtrees(param.subtrees) +
2764 ExcludedSubtrees(param.subtrees)));
2765 Input nameConstraints;
2766 ASSERT_EQ(Success,
2767 nameConstraints.Init(nameConstraintsDER.data(),
2768 nameConstraintsDER.length()));
2769 ASSERT_EQ(param.expectedExcludedSubtreesResult,
2770 CheckNameConstraints(nameConstraints, cert,
2771 KeyPurposeId::id_kp_serverAuth));
2772 }
2773 }
2774
2775 INSTANTIATE_TEST_SUITE_P(pkixnames_CheckNameConstraintsOnIntermediate,
2776 pkixnames_CheckNameConstraintsOnIntermediate,
2777 testing::ValuesIn(NO_FALLBACK_NAME_CONSTRAINT_PARAMS));
2778
2779 class pkixnames_CheckNameConstraintsForNonServerAuthUsage
2780 : public ::testing::Test
2781 , public ::testing::WithParamInterface<NameConstraintParams>
2782 {
2783 };
2784
TEST_P(pkixnames_CheckNameConstraintsForNonServerAuthUsage,NameConstraintsEnforcedForNonServerAuthUsage)2785 TEST_P(pkixnames_CheckNameConstraintsForNonServerAuthUsage,
2786 NameConstraintsEnforcedForNonServerAuthUsage)
2787 {
2788 // Test that for key purposes other than serverAuth, fallback to the subject
2789 // common name does not occur.
2790
2791 const NameConstraintParams& param(GetParam());
2792
2793 ByteString certDER(CreateCert(param.subject, NO_SAN));
2794 ASSERT_FALSE(ENCODING_FAILED(certDER));
2795 Input certInput;
2796 ASSERT_EQ(Success, certInput.Init(certDER.data(), certDER.length()));
2797 BackCert cert(certInput, EndEntityOrCA::MustBeEndEntity, nullptr);
2798 ASSERT_EQ(Success, cert.Init());
2799
2800 {
2801 ByteString nameConstraintsDER(TLV(der::SEQUENCE,
2802 PermittedSubtrees(param.subtrees)));
2803 Input nameConstraints;
2804 ASSERT_EQ(Success,
2805 nameConstraints.Init(nameConstraintsDER.data(),
2806 nameConstraintsDER.length()));
2807 ASSERT_EQ(param.expectedPermittedSubtreesResult,
2808 CheckNameConstraints(nameConstraints, cert,
2809 KeyPurposeId::id_kp_clientAuth));
2810 }
2811 {
2812 ByteString nameConstraintsDER(TLV(der::SEQUENCE,
2813 ExcludedSubtrees(param.subtrees)));
2814 Input nameConstraints;
2815 ASSERT_EQ(Success,
2816 nameConstraints.Init(nameConstraintsDER.data(),
2817 nameConstraintsDER.length()));
2818 ASSERT_EQ(param.expectedExcludedSubtreesResult,
2819 CheckNameConstraints(nameConstraints, cert,
2820 KeyPurposeId::id_kp_clientAuth));
2821 }
2822 {
2823 ByteString nameConstraintsDER(TLV(der::SEQUENCE,
2824 PermittedSubtrees(param.subtrees) +
2825 ExcludedSubtrees(param.subtrees)));
2826 Input nameConstraints;
2827 ASSERT_EQ(Success,
2828 nameConstraints.Init(nameConstraintsDER.data(),
2829 nameConstraintsDER.length()));
2830 ASSERT_EQ(param.expectedExcludedSubtreesResult,
2831 CheckNameConstraints(nameConstraints, cert,
2832 KeyPurposeId::id_kp_clientAuth));
2833 }
2834 }
2835
2836 INSTANTIATE_TEST_SUITE_P(pkixnames_CheckNameConstraintsForNonServerAuthUsage,
2837 pkixnames_CheckNameConstraintsForNonServerAuthUsage,
2838 testing::ValuesIn(NO_FALLBACK_NAME_CONSTRAINT_PARAMS));
2839