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