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