Home | History | Annotate | Download | only in x509
      1 // Copyright 2017 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package x509
      6 
      7 import (
      8 	"bytes"
      9 	"crypto/ecdsa"
     10 	"crypto/elliptic"
     11 	"crypto/rand"
     12 	"crypto/x509/pkix"
     13 	"encoding/asn1"
     14 	"encoding/pem"
     15 	"fmt"
     16 	"io/ioutil"
     17 	"math/big"
     18 	"net"
     19 	"net/url"
     20 	"os"
     21 	"os/exec"
     22 	"strconv"
     23 	"strings"
     24 	"sync"
     25 	"testing"
     26 	"time"
     27 )
     28 
     29 const (
     30 	// testNameConstraintsAgainstOpenSSL can be set to true to run tests
     31 	// against the system OpenSSL. This is disabled by default because Go
     32 	// cannot depend on having OpenSSL installed at testing time.
     33 	testNameConstraintsAgainstOpenSSL = false
     34 
     35 	// debugOpenSSLFailure can be set to true, when
     36 	// testNameConstraintsAgainstOpenSSL is also true, to cause
     37 	// intermediate files to be preserved for debugging.
     38 	debugOpenSSLFailure = false
     39 )
     40 
     41 type nameConstraintsTest struct {
     42 	roots         []constraintsSpec
     43 	intermediates [][]constraintsSpec
     44 	leaf          leafSpec
     45 	expectedError string
     46 	noOpenSSL     bool
     47 }
     48 
     49 type constraintsSpec struct {
     50 	ok   []string
     51 	bad  []string
     52 	ekus []string
     53 }
     54 
     55 type leafSpec struct {
     56 	sans []string
     57 	ekus []string
     58 }
     59 
     60 var nameConstraintsTests = []nameConstraintsTest{
     61 	// #0: dummy test for the certificate generation process itself.
     62 	nameConstraintsTest{
     63 		roots: []constraintsSpec{
     64 			constraintsSpec{},
     65 		},
     66 		leaf: leafSpec{
     67 			sans: []string{"dns:example.com"},
     68 		},
     69 	},
     70 
     71 	// #1: dummy test for the certificate generation process itself: single
     72 	// level of intermediate.
     73 	nameConstraintsTest{
     74 		roots: []constraintsSpec{
     75 			constraintsSpec{},
     76 		},
     77 		intermediates: [][]constraintsSpec{
     78 			[]constraintsSpec{
     79 				constraintsSpec{},
     80 			},
     81 		},
     82 		leaf: leafSpec{
     83 			sans: []string{"dns:example.com"},
     84 		},
     85 	},
     86 
     87 	// #2: dummy test for the certificate generation process itself: two
     88 	// levels of intermediates.
     89 	nameConstraintsTest{
     90 		roots: []constraintsSpec{
     91 			constraintsSpec{},
     92 		},
     93 		intermediates: [][]constraintsSpec{
     94 			[]constraintsSpec{
     95 				constraintsSpec{},
     96 			},
     97 			[]constraintsSpec{
     98 				constraintsSpec{},
     99 			},
    100 		},
    101 		leaf: leafSpec{
    102 			sans: []string{"dns:example.com"},
    103 		},
    104 	},
    105 
    106 	// #3: matching DNS constraint in root
    107 	nameConstraintsTest{
    108 		roots: []constraintsSpec{
    109 			constraintsSpec{
    110 				ok: []string{"dns:example.com"},
    111 			},
    112 		},
    113 		intermediates: [][]constraintsSpec{
    114 			[]constraintsSpec{
    115 				constraintsSpec{},
    116 			},
    117 		},
    118 		leaf: leafSpec{
    119 			sans: []string{"dns:example.com"},
    120 		},
    121 	},
    122 
    123 	// #4: matching DNS constraint in intermediate.
    124 	nameConstraintsTest{
    125 		roots: []constraintsSpec{
    126 			constraintsSpec{},
    127 		},
    128 		intermediates: [][]constraintsSpec{
    129 			[]constraintsSpec{
    130 				constraintsSpec{
    131 					ok: []string{"dns:example.com"},
    132 				},
    133 			},
    134 		},
    135 		leaf: leafSpec{
    136 			sans: []string{"dns:example.com"},
    137 		},
    138 	},
    139 
    140 	// #5: .example.com only matches subdomains.
    141 	nameConstraintsTest{
    142 		roots: []constraintsSpec{
    143 			constraintsSpec{
    144 				ok: []string{"dns:.example.com"},
    145 			},
    146 		},
    147 		intermediates: [][]constraintsSpec{
    148 			[]constraintsSpec{
    149 				constraintsSpec{},
    150 			},
    151 		},
    152 		leaf: leafSpec{
    153 			sans: []string{"dns:example.com"},
    154 		},
    155 		expectedError: "\"example.com\" is not permitted",
    156 	},
    157 
    158 	// #6: .example.com matches subdomains.
    159 	nameConstraintsTest{
    160 		roots: []constraintsSpec{
    161 			constraintsSpec{},
    162 		},
    163 		intermediates: [][]constraintsSpec{
    164 			[]constraintsSpec{
    165 				constraintsSpec{
    166 					ok: []string{"dns:.example.com"},
    167 				},
    168 			},
    169 		},
    170 		leaf: leafSpec{
    171 			sans: []string{"dns:foo.example.com"},
    172 		},
    173 	},
    174 
    175 	// #7: .example.com matches multiple levels of subdomains
    176 	nameConstraintsTest{
    177 		roots: []constraintsSpec{
    178 			constraintsSpec{
    179 				ok: []string{"dns:.example.com"},
    180 			},
    181 		},
    182 		intermediates: [][]constraintsSpec{
    183 			[]constraintsSpec{
    184 				constraintsSpec{},
    185 			},
    186 		},
    187 		leaf: leafSpec{
    188 			sans: []string{"dns:foo.bar.example.com"},
    189 		},
    190 	},
    191 
    192 	// #8: specifying a permitted list of names does not exclude other name
    193 	// types
    194 	nameConstraintsTest{
    195 		roots: []constraintsSpec{
    196 			constraintsSpec{
    197 				ok: []string{"dns:.example.com"},
    198 			},
    199 		},
    200 		intermediates: [][]constraintsSpec{
    201 			[]constraintsSpec{
    202 				constraintsSpec{},
    203 			},
    204 		},
    205 		leaf: leafSpec{
    206 			sans: []string{"ip:10.1.1.1"},
    207 		},
    208 	},
    209 
    210 	// #9: specifying a permitted list of names does not exclude other name
    211 	// types
    212 	nameConstraintsTest{
    213 		roots: []constraintsSpec{
    214 			constraintsSpec{
    215 				ok: []string{"ip:10.0.0.0/8"},
    216 			},
    217 		},
    218 		intermediates: [][]constraintsSpec{
    219 			[]constraintsSpec{
    220 				constraintsSpec{},
    221 			},
    222 		},
    223 		leaf: leafSpec{
    224 			sans: []string{"dns:example.com"},
    225 		},
    226 	},
    227 
    228 	// #10: intermediates can try to permit other names, which isn't
    229 	// forbidden if the leaf doesn't mention them. I.e. name constraints
    230 	// apply to names, not constraints themselves.
    231 	nameConstraintsTest{
    232 		roots: []constraintsSpec{
    233 			constraintsSpec{
    234 				ok: []string{"dns:example.com"},
    235 			},
    236 		},
    237 		intermediates: [][]constraintsSpec{
    238 			[]constraintsSpec{
    239 				constraintsSpec{
    240 					ok: []string{"dns:example.com", "dns:foo.com"},
    241 				},
    242 			},
    243 		},
    244 		leaf: leafSpec{
    245 			sans: []string{"dns:example.com"},
    246 		},
    247 	},
    248 
    249 	// #11: intermediates cannot add permitted names that the root doesn't
    250 	// grant them.
    251 	nameConstraintsTest{
    252 		roots: []constraintsSpec{
    253 			constraintsSpec{
    254 				ok: []string{"dns:example.com"},
    255 			},
    256 		},
    257 		intermediates: [][]constraintsSpec{
    258 			[]constraintsSpec{
    259 				constraintsSpec{
    260 					ok: []string{"dns:example.com", "dns:foo.com"},
    261 				},
    262 			},
    263 		},
    264 		leaf: leafSpec{
    265 			sans: []string{"dns:foo.com"},
    266 		},
    267 		expectedError: "\"foo.com\" is not permitted",
    268 	},
    269 
    270 	// #12: intermediates can further limit their scope if they wish.
    271 	nameConstraintsTest{
    272 		roots: []constraintsSpec{
    273 			constraintsSpec{
    274 				ok: []string{"dns:.example.com"},
    275 			},
    276 		},
    277 		intermediates: [][]constraintsSpec{
    278 			[]constraintsSpec{
    279 				constraintsSpec{
    280 					ok: []string{"dns:.bar.example.com"},
    281 				},
    282 			},
    283 		},
    284 		leaf: leafSpec{
    285 			sans: []string{"dns:foo.bar.example.com"},
    286 		},
    287 	},
    288 
    289 	// #13: intermediates can further limit their scope and that limitation
    290 	// is effective
    291 	nameConstraintsTest{
    292 		roots: []constraintsSpec{
    293 			constraintsSpec{
    294 				ok: []string{"dns:.example.com"},
    295 			},
    296 		},
    297 		intermediates: [][]constraintsSpec{
    298 			[]constraintsSpec{
    299 				constraintsSpec{
    300 					ok: []string{"dns:.bar.example.com"},
    301 				},
    302 			},
    303 		},
    304 		leaf: leafSpec{
    305 			sans: []string{"dns:foo.notbar.example.com"},
    306 		},
    307 		expectedError: "\"foo.notbar.example.com\" is not permitted",
    308 	},
    309 
    310 	// #14: roots can exclude subtrees and that doesn't affect other names.
    311 	nameConstraintsTest{
    312 		roots: []constraintsSpec{
    313 			constraintsSpec{
    314 				bad: []string{"dns:.example.com"},
    315 			},
    316 		},
    317 		intermediates: [][]constraintsSpec{
    318 			[]constraintsSpec{
    319 				constraintsSpec{},
    320 			},
    321 		},
    322 		leaf: leafSpec{
    323 			sans: []string{"dns:foo.com"},
    324 		},
    325 	},
    326 
    327 	// #15: roots exclusions are effective.
    328 	nameConstraintsTest{
    329 		roots: []constraintsSpec{
    330 			constraintsSpec{
    331 				bad: []string{"dns:.example.com"},
    332 			},
    333 		},
    334 		intermediates: [][]constraintsSpec{
    335 			[]constraintsSpec{
    336 				constraintsSpec{},
    337 			},
    338 		},
    339 		leaf: leafSpec{
    340 			sans: []string{"dns:foo.example.com"},
    341 		},
    342 		expectedError: "\"foo.example.com\" is excluded",
    343 	},
    344 
    345 	// #16: intermediates can also exclude names and that doesn't affect
    346 	// other names.
    347 	nameConstraintsTest{
    348 		roots: []constraintsSpec{
    349 			constraintsSpec{},
    350 		},
    351 		intermediates: [][]constraintsSpec{
    352 			[]constraintsSpec{
    353 				constraintsSpec{
    354 					bad: []string{"dns:.example.com"},
    355 				},
    356 			},
    357 		},
    358 		leaf: leafSpec{
    359 			sans: []string{"dns:foo.com"},
    360 		},
    361 	},
    362 
    363 	// #17: intermediate exclusions are effective.
    364 	nameConstraintsTest{
    365 		roots: []constraintsSpec{
    366 			constraintsSpec{},
    367 		},
    368 		intermediates: [][]constraintsSpec{
    369 			[]constraintsSpec{
    370 				constraintsSpec{
    371 					bad: []string{"dns:.example.com"},
    372 				},
    373 			},
    374 		},
    375 		leaf: leafSpec{
    376 			sans: []string{"dns:foo.example.com"},
    377 		},
    378 		expectedError: "\"foo.example.com\" is excluded",
    379 	},
    380 
    381 	// #18: having an exclusion doesn't prohibit other types of names.
    382 	nameConstraintsTest{
    383 		roots: []constraintsSpec{
    384 			constraintsSpec{
    385 				bad: []string{"dns:.example.com"},
    386 			},
    387 		},
    388 		intermediates: [][]constraintsSpec{
    389 			[]constraintsSpec{
    390 				constraintsSpec{},
    391 			},
    392 		},
    393 		leaf: leafSpec{
    394 			sans: []string{"dns:foo.com", "ip:10.1.1.1"},
    395 		},
    396 	},
    397 
    398 	// #19: IP-based exclusions are permitted and don't affect unrelated IP
    399 	// addresses.
    400 	nameConstraintsTest{
    401 		roots: []constraintsSpec{
    402 			constraintsSpec{
    403 				bad: []string{"ip:10.0.0.0/8"},
    404 			},
    405 		},
    406 		intermediates: [][]constraintsSpec{
    407 			[]constraintsSpec{
    408 				constraintsSpec{},
    409 			},
    410 		},
    411 		leaf: leafSpec{
    412 			sans: []string{"ip:192.168.1.1"},
    413 		},
    414 	},
    415 
    416 	// #20: IP-based exclusions are effective
    417 	nameConstraintsTest{
    418 		roots: []constraintsSpec{
    419 			constraintsSpec{
    420 				bad: []string{"ip:10.0.0.0/8"},
    421 			},
    422 		},
    423 		intermediates: [][]constraintsSpec{
    424 			[]constraintsSpec{
    425 				constraintsSpec{},
    426 			},
    427 		},
    428 		leaf: leafSpec{
    429 			sans: []string{"ip:10.0.0.1"},
    430 		},
    431 		expectedError: "\"10.0.0.1\" is excluded",
    432 	},
    433 
    434 	// #21: intermediates can further constrain IP ranges.
    435 	nameConstraintsTest{
    436 		roots: []constraintsSpec{
    437 			constraintsSpec{
    438 				bad: []string{"ip:0.0.0.0/1"},
    439 			},
    440 		},
    441 		intermediates: [][]constraintsSpec{
    442 			[]constraintsSpec{
    443 				constraintsSpec{
    444 					bad: []string{"ip:11.0.0.0/8"},
    445 				},
    446 			},
    447 		},
    448 		leaf: leafSpec{
    449 			sans: []string{"ip:11.0.0.1"},
    450 		},
    451 		expectedError: "\"11.0.0.1\" is excluded",
    452 	},
    453 
    454 	// #22: when multiple intermediates are present, chain building can
    455 	// avoid intermediates with incompatible constraints.
    456 	nameConstraintsTest{
    457 		roots: []constraintsSpec{
    458 			constraintsSpec{},
    459 		},
    460 		intermediates: [][]constraintsSpec{
    461 			[]constraintsSpec{
    462 				constraintsSpec{
    463 					ok: []string{"dns:.foo.com"},
    464 				},
    465 				constraintsSpec{
    466 					ok: []string{"dns:.example.com"},
    467 				},
    468 			},
    469 		},
    470 		leaf: leafSpec{
    471 			sans: []string{"dns:foo.example.com"},
    472 		},
    473 		noOpenSSL: true, // OpenSSL's chain building is not informed by constraints.
    474 	},
    475 
    476 	// #23: (same as the previous test, but in the other order in ensure
    477 	// that we don't pass it by luck.)
    478 	nameConstraintsTest{
    479 		roots: []constraintsSpec{
    480 			constraintsSpec{},
    481 		},
    482 		intermediates: [][]constraintsSpec{
    483 			[]constraintsSpec{
    484 				constraintsSpec{
    485 					ok: []string{"dns:.example.com"},
    486 				},
    487 				constraintsSpec{
    488 					ok: []string{"dns:.foo.com"},
    489 				},
    490 			},
    491 		},
    492 		leaf: leafSpec{
    493 			sans: []string{"dns:foo.example.com"},
    494 		},
    495 		noOpenSSL: true, // OpenSSL's chain building is not informed by constraints.
    496 	},
    497 
    498 	// #24: when multiple roots are valid, chain building can avoid roots
    499 	// with incompatible constraints.
    500 	nameConstraintsTest{
    501 		roots: []constraintsSpec{
    502 			constraintsSpec{},
    503 			constraintsSpec{
    504 				ok: []string{"dns:foo.com"},
    505 			},
    506 		},
    507 		intermediates: [][]constraintsSpec{
    508 			[]constraintsSpec{
    509 				constraintsSpec{},
    510 			},
    511 		},
    512 		leaf: leafSpec{
    513 			sans: []string{"dns:example.com"},
    514 		},
    515 		noOpenSSL: true, // OpenSSL's chain building is not informed by constraints.
    516 	},
    517 
    518 	// #25: (same as the previous test, but in the other order in ensure
    519 	// that we don't pass it by luck.)
    520 	nameConstraintsTest{
    521 		roots: []constraintsSpec{
    522 			constraintsSpec{
    523 				ok: []string{"dns:foo.com"},
    524 			},
    525 			constraintsSpec{},
    526 		},
    527 		intermediates: [][]constraintsSpec{
    528 			[]constraintsSpec{
    529 				constraintsSpec{},
    530 			},
    531 		},
    532 		leaf: leafSpec{
    533 			sans: []string{"dns:example.com"},
    534 		},
    535 		noOpenSSL: true, // OpenSSL's chain building is not informed by constraints.
    536 	},
    537 
    538 	// #26: chain building can find a valid path even with multiple levels
    539 	// of alternative intermediates and alternative roots.
    540 	nameConstraintsTest{
    541 		roots: []constraintsSpec{
    542 			constraintsSpec{
    543 				ok: []string{"dns:foo.com"},
    544 			},
    545 			constraintsSpec{
    546 				ok: []string{"dns:example.com"},
    547 			},
    548 			constraintsSpec{},
    549 		},
    550 		intermediates: [][]constraintsSpec{
    551 			[]constraintsSpec{
    552 				constraintsSpec{},
    553 				constraintsSpec{
    554 					ok: []string{"dns:foo.com"},
    555 				},
    556 			},
    557 			[]constraintsSpec{
    558 				constraintsSpec{},
    559 				constraintsSpec{
    560 					ok: []string{"dns:foo.com"},
    561 				},
    562 			},
    563 		},
    564 		leaf: leafSpec{
    565 			sans: []string{"dns:bar.com"},
    566 		},
    567 		noOpenSSL: true, // OpenSSL's chain building is not informed by constraints.
    568 	},
    569 
    570 	// #27: chain building doesn't get stuck when there is no valid path.
    571 	nameConstraintsTest{
    572 		roots: []constraintsSpec{
    573 			constraintsSpec{
    574 				ok: []string{"dns:foo.com"},
    575 			},
    576 			constraintsSpec{
    577 				ok: []string{"dns:example.com"},
    578 			},
    579 		},
    580 		intermediates: [][]constraintsSpec{
    581 			[]constraintsSpec{
    582 				constraintsSpec{},
    583 				constraintsSpec{
    584 					ok: []string{"dns:foo.com"},
    585 				},
    586 			},
    587 			[]constraintsSpec{
    588 				constraintsSpec{
    589 					ok: []string{"dns:bar.com"},
    590 				},
    591 				constraintsSpec{
    592 					ok: []string{"dns:foo.com"},
    593 				},
    594 			},
    595 		},
    596 		leaf: leafSpec{
    597 			sans: []string{"dns:bar.com"},
    598 		},
    599 		expectedError: "\"bar.com\" is not permitted",
    600 	},
    601 
    602 	// #28: unknown name types don't cause a problem without constraints.
    603 	nameConstraintsTest{
    604 		roots: []constraintsSpec{
    605 			constraintsSpec{},
    606 		},
    607 		intermediates: [][]constraintsSpec{
    608 			[]constraintsSpec{
    609 				constraintsSpec{},
    610 			},
    611 		},
    612 		leaf: leafSpec{
    613 			sans: []string{"unknown:"},
    614 		},
    615 	},
    616 
    617 	// #29: unknown name types are allowed even in constrained chains.
    618 	nameConstraintsTest{
    619 		roots: []constraintsSpec{
    620 			constraintsSpec{
    621 				ok: []string{"dns:foo.com", "dns:.foo.com"},
    622 			},
    623 		},
    624 		intermediates: [][]constraintsSpec{
    625 			[]constraintsSpec{
    626 				constraintsSpec{},
    627 			},
    628 		},
    629 		leaf: leafSpec{
    630 			sans: []string{"unknown:"},
    631 		},
    632 	},
    633 
    634 	// #30: without SANs, a certificate is rejected in a constrained chain.
    635 	nameConstraintsTest{
    636 		roots: []constraintsSpec{
    637 			constraintsSpec{
    638 				ok: []string{"dns:foo.com", "dns:.foo.com"},
    639 			},
    640 		},
    641 		intermediates: [][]constraintsSpec{
    642 			[]constraintsSpec{
    643 				constraintsSpec{},
    644 			},
    645 		},
    646 		leaf: leafSpec{
    647 			sans: []string{},
    648 		},
    649 		expectedError: "leaf doesn't have a SAN extension",
    650 		noOpenSSL:     true, // OpenSSL doesn't require SANs in this case.
    651 	},
    652 
    653 	// #31: IPv6 addresses work in constraints: roots can permit them as
    654 	// expected.
    655 	nameConstraintsTest{
    656 		roots: []constraintsSpec{
    657 			constraintsSpec{
    658 				ok: []string{"ip:2000:abcd::/32"},
    659 			},
    660 		},
    661 		intermediates: [][]constraintsSpec{
    662 			[]constraintsSpec{
    663 				constraintsSpec{},
    664 			},
    665 		},
    666 		leaf: leafSpec{
    667 			sans: []string{"ip:2000:abcd:1234::"},
    668 		},
    669 	},
    670 
    671 	// #32: IPv6 addresses work in constraints: root restrictions are
    672 	// effective.
    673 	nameConstraintsTest{
    674 		roots: []constraintsSpec{
    675 			constraintsSpec{
    676 				ok: []string{"ip:2000:abcd::/32"},
    677 			},
    678 		},
    679 		intermediates: [][]constraintsSpec{
    680 			[]constraintsSpec{
    681 				constraintsSpec{},
    682 			},
    683 		},
    684 		leaf: leafSpec{
    685 			sans: []string{"ip:2000:1234:abcd::"},
    686 		},
    687 		expectedError: "\"2000:1234:abcd::\" is not permitted",
    688 	},
    689 
    690 	// #33: An IPv6 permitted subtree doesn't affect DNS names.
    691 	nameConstraintsTest{
    692 		roots: []constraintsSpec{
    693 			constraintsSpec{
    694 				ok: []string{"ip:2000:abcd::/32"},
    695 			},
    696 		},
    697 		intermediates: [][]constraintsSpec{
    698 			[]constraintsSpec{
    699 				constraintsSpec{},
    700 			},
    701 		},
    702 		leaf: leafSpec{
    703 			sans: []string{"ip:2000:abcd::", "dns:foo.com"},
    704 		},
    705 	},
    706 
    707 	// #34: IPv6 exclusions don't affect unrelated addresses.
    708 	nameConstraintsTest{
    709 		roots: []constraintsSpec{
    710 			constraintsSpec{
    711 				bad: []string{"ip:2000:abcd::/32"},
    712 			},
    713 		},
    714 		intermediates: [][]constraintsSpec{
    715 			[]constraintsSpec{
    716 				constraintsSpec{},
    717 			},
    718 		},
    719 		leaf: leafSpec{
    720 			sans: []string{"ip:2000:1234::"},
    721 		},
    722 	},
    723 
    724 	// #35: IPv6 exclusions are effective.
    725 	nameConstraintsTest{
    726 		roots: []constraintsSpec{
    727 			constraintsSpec{
    728 				bad: []string{"ip:2000:abcd::/32"},
    729 			},
    730 		},
    731 		intermediates: [][]constraintsSpec{
    732 			[]constraintsSpec{
    733 				constraintsSpec{},
    734 			},
    735 		},
    736 		leaf: leafSpec{
    737 			sans: []string{"ip:2000:abcd::"},
    738 		},
    739 		expectedError: "\"2000:abcd::\" is excluded",
    740 	},
    741 
    742 	// #36: IPv6 constraints do not permit IPv4 addresses.
    743 	nameConstraintsTest{
    744 		roots: []constraintsSpec{
    745 			constraintsSpec{
    746 				ok: []string{"ip:2000:abcd::/32"},
    747 			},
    748 		},
    749 		intermediates: [][]constraintsSpec{
    750 			[]constraintsSpec{
    751 				constraintsSpec{},
    752 			},
    753 		},
    754 		leaf: leafSpec{
    755 			sans: []string{"ip:10.0.0.1"},
    756 		},
    757 		expectedError: "\"10.0.0.1\" is not permitted",
    758 	},
    759 
    760 	// #37: IPv4 constraints do not permit IPv6 addresses.
    761 	nameConstraintsTest{
    762 		roots: []constraintsSpec{
    763 			constraintsSpec{
    764 				ok: []string{"ip:10.0.0.0/8"},
    765 			},
    766 		},
    767 		intermediates: [][]constraintsSpec{
    768 			[]constraintsSpec{
    769 				constraintsSpec{},
    770 			},
    771 		},
    772 		leaf: leafSpec{
    773 			sans: []string{"ip:2000:abcd::"},
    774 		},
    775 		expectedError: "\"2000:abcd::\" is not permitted",
    776 	},
    777 
    778 	// #38: an exclusion of an unknown type doesn't affect other names.
    779 	nameConstraintsTest{
    780 		roots: []constraintsSpec{
    781 			constraintsSpec{
    782 				bad: []string{"unknown:"},
    783 			},
    784 		},
    785 		intermediates: [][]constraintsSpec{
    786 			[]constraintsSpec{
    787 				constraintsSpec{},
    788 			},
    789 		},
    790 		leaf: leafSpec{
    791 			sans: []string{"dns:example.com"},
    792 		},
    793 	},
    794 
    795 	// #39: a permitted subtree of an unknown type doesn't affect other
    796 	// name types.
    797 	nameConstraintsTest{
    798 		roots: []constraintsSpec{
    799 			constraintsSpec{
    800 				ok: []string{"unknown:"},
    801 			},
    802 		},
    803 		intermediates: [][]constraintsSpec{
    804 			[]constraintsSpec{
    805 				constraintsSpec{},
    806 			},
    807 		},
    808 		leaf: leafSpec{
    809 			sans: []string{"dns:example.com"},
    810 		},
    811 	},
    812 
    813 	// #40: exact email constraints work
    814 	nameConstraintsTest{
    815 		roots: []constraintsSpec{
    816 			constraintsSpec{
    817 				ok: []string{"email:foo (a] example.com"},
    818 			},
    819 		},
    820 		intermediates: [][]constraintsSpec{
    821 			[]constraintsSpec{
    822 				constraintsSpec{},
    823 			},
    824 		},
    825 		leaf: leafSpec{
    826 			sans: []string{"email:foo (a] example.com"},
    827 		},
    828 	},
    829 
    830 	// #41: exact email constraints are effective
    831 	nameConstraintsTest{
    832 		roots: []constraintsSpec{
    833 			constraintsSpec{
    834 				ok: []string{"email:foo (a] example.com"},
    835 			},
    836 		},
    837 		intermediates: [][]constraintsSpec{
    838 			[]constraintsSpec{
    839 				constraintsSpec{},
    840 			},
    841 		},
    842 		leaf: leafSpec{
    843 			sans: []string{"email:bar (a] example.com"},
    844 		},
    845 		expectedError: "\"bar (a] example.com\" is not permitted",
    846 	},
    847 
    848 	// #42: email canonicalisation works.
    849 	nameConstraintsTest{
    850 		roots: []constraintsSpec{
    851 			constraintsSpec{
    852 				ok: []string{"email:foo (a] example.com"},
    853 			},
    854 		},
    855 		intermediates: [][]constraintsSpec{
    856 			[]constraintsSpec{
    857 				constraintsSpec{},
    858 			},
    859 		},
    860 		leaf: leafSpec{
    861 			sans: []string{"email:\"\\f\\o\\o\"@example.com"},
    862 		},
    863 		noOpenSSL: true, // OpenSSL doesn't canonicalise email addresses before matching
    864 	},
    865 
    866 	// #43: limiting email addresses to a host works.
    867 	nameConstraintsTest{
    868 		roots: []constraintsSpec{
    869 			constraintsSpec{
    870 				ok: []string{"email:example.com"},
    871 			},
    872 		},
    873 		intermediates: [][]constraintsSpec{
    874 			[]constraintsSpec{
    875 				constraintsSpec{},
    876 			},
    877 		},
    878 		leaf: leafSpec{
    879 			sans: []string{"email:foo (a] example.com"},
    880 		},
    881 	},
    882 
    883 	// #44: a leading dot matches hosts one level deep
    884 	nameConstraintsTest{
    885 		roots: []constraintsSpec{
    886 			constraintsSpec{
    887 				ok: []string{"email:.example.com"},
    888 			},
    889 		},
    890 		intermediates: [][]constraintsSpec{
    891 			[]constraintsSpec{
    892 				constraintsSpec{},
    893 			},
    894 		},
    895 		leaf: leafSpec{
    896 			sans: []string{"email:foo (a] sub.example.com"},
    897 		},
    898 	},
    899 
    900 	// #45: a leading dot does not match the host itself
    901 	nameConstraintsTest{
    902 		roots: []constraintsSpec{
    903 			constraintsSpec{
    904 				ok: []string{"email:.example.com"},
    905 			},
    906 		},
    907 		intermediates: [][]constraintsSpec{
    908 			[]constraintsSpec{
    909 				constraintsSpec{},
    910 			},
    911 		},
    912 		leaf: leafSpec{
    913 			sans: []string{"email:foo (a] example.com"},
    914 		},
    915 		expectedError: "\"foo (a] example.com\" is not permitted",
    916 	},
    917 
    918 	// #46: a leading dot also matches two (or more) levels deep.
    919 	nameConstraintsTest{
    920 		roots: []constraintsSpec{
    921 			constraintsSpec{
    922 				ok: []string{"email:.example.com"},
    923 			},
    924 		},
    925 		intermediates: [][]constraintsSpec{
    926 			[]constraintsSpec{
    927 				constraintsSpec{},
    928 			},
    929 		},
    930 		leaf: leafSpec{
    931 			sans: []string{"email:foo (a] sub.sub.example.com"},
    932 		},
    933 	},
    934 
    935 	// #47: the local part of an email is case-sensitive
    936 	nameConstraintsTest{
    937 		roots: []constraintsSpec{
    938 			constraintsSpec{
    939 				ok: []string{"email:foo (a] example.com"},
    940 			},
    941 		},
    942 		intermediates: [][]constraintsSpec{
    943 			[]constraintsSpec{
    944 				constraintsSpec{},
    945 			},
    946 		},
    947 		leaf: leafSpec{
    948 			sans: []string{"email:Foo (a] example.com"},
    949 		},
    950 		expectedError: "\"Foo (a] example.com\" is not permitted",
    951 	},
    952 
    953 	// #48: the domain part of an email is not case-sensitive
    954 	nameConstraintsTest{
    955 		roots: []constraintsSpec{
    956 			constraintsSpec{
    957 				ok: []string{"email:foo (a] EXAMPLE.com"},
    958 			},
    959 		},
    960 		intermediates: [][]constraintsSpec{
    961 			[]constraintsSpec{
    962 				constraintsSpec{},
    963 			},
    964 		},
    965 		leaf: leafSpec{
    966 			sans: []string{"email:foo (a] example.com"},
    967 		},
    968 	},
    969 
    970 	// #49: the domain part of a DNS constraint is also not case-sensitive.
    971 	nameConstraintsTest{
    972 		roots: []constraintsSpec{
    973 			constraintsSpec{
    974 				ok: []string{"dns:EXAMPLE.com"},
    975 			},
    976 		},
    977 		intermediates: [][]constraintsSpec{
    978 			[]constraintsSpec{
    979 				constraintsSpec{},
    980 			},
    981 		},
    982 		leaf: leafSpec{
    983 			sans: []string{"dns:example.com"},
    984 		},
    985 	},
    986 
    987 	// #50: URI constraints only cover the host part of the URI
    988 	nameConstraintsTest{
    989 		roots: []constraintsSpec{
    990 			constraintsSpec{
    991 				ok: []string{"uri:example.com"},
    992 			},
    993 		},
    994 		intermediates: [][]constraintsSpec{
    995 			[]constraintsSpec{
    996 				constraintsSpec{},
    997 			},
    998 		},
    999 		leaf: leafSpec{
   1000 			sans: []string{
   1001 				"uri:http://example.com/bar",
   1002 				"uri:http://example.com:8080/",
   1003 				"uri:https://example.com/wibble#bar",
   1004 			},
   1005 		},
   1006 	},
   1007 
   1008 	// #51: URIs with IPs are rejected
   1009 	nameConstraintsTest{
   1010 		roots: []constraintsSpec{
   1011 			constraintsSpec{
   1012 				ok: []string{"uri:example.com"},
   1013 			},
   1014 		},
   1015 		intermediates: [][]constraintsSpec{
   1016 			[]constraintsSpec{
   1017 				constraintsSpec{},
   1018 			},
   1019 		},
   1020 		leaf: leafSpec{
   1021 			sans: []string{"uri:http://1.2.3.4/"},
   1022 		},
   1023 		expectedError: "URI with IP",
   1024 	},
   1025 
   1026 	// #52: URIs with IPs and ports are rejected
   1027 	nameConstraintsTest{
   1028 		roots: []constraintsSpec{
   1029 			constraintsSpec{
   1030 				ok: []string{"uri:example.com"},
   1031 			},
   1032 		},
   1033 		intermediates: [][]constraintsSpec{
   1034 			[]constraintsSpec{
   1035 				constraintsSpec{},
   1036 			},
   1037 		},
   1038 		leaf: leafSpec{
   1039 			sans: []string{"uri:http://1.2.3.4:43/"},
   1040 		},
   1041 		expectedError: "URI with IP",
   1042 	},
   1043 
   1044 	// #53: URIs with IPv6 addresses are also rejected
   1045 	nameConstraintsTest{
   1046 		roots: []constraintsSpec{
   1047 			constraintsSpec{
   1048 				ok: []string{"uri:example.com"},
   1049 			},
   1050 		},
   1051 		intermediates: [][]constraintsSpec{
   1052 			[]constraintsSpec{
   1053 				constraintsSpec{},
   1054 			},
   1055 		},
   1056 		leaf: leafSpec{
   1057 			sans: []string{"uri:http://[2006:abcd::1]/"},
   1058 		},
   1059 		expectedError: "URI with IP",
   1060 	},
   1061 
   1062 	// #54: URIs with IPv6 addresses with ports are also rejected
   1063 	nameConstraintsTest{
   1064 		roots: []constraintsSpec{
   1065 			constraintsSpec{
   1066 				ok: []string{"uri:example.com"},
   1067 			},
   1068 		},
   1069 		intermediates: [][]constraintsSpec{
   1070 			[]constraintsSpec{
   1071 				constraintsSpec{},
   1072 			},
   1073 		},
   1074 		leaf: leafSpec{
   1075 			sans: []string{"uri:http://[2006:abcd::1]:16/"},
   1076 		},
   1077 		expectedError: "URI with IP",
   1078 	},
   1079 
   1080 	// #55: URI constraints are effective
   1081 	nameConstraintsTest{
   1082 		roots: []constraintsSpec{
   1083 			constraintsSpec{
   1084 				ok: []string{"uri:example.com"},
   1085 			},
   1086 		},
   1087 		intermediates: [][]constraintsSpec{
   1088 			[]constraintsSpec{
   1089 				constraintsSpec{},
   1090 			},
   1091 		},
   1092 		leaf: leafSpec{
   1093 			sans: []string{"uri:http://bar.com/"},
   1094 		},
   1095 		expectedError: "\"http://bar.com/\" is not permitted",
   1096 	},
   1097 
   1098 	// #56: URI constraints are effective
   1099 	nameConstraintsTest{
   1100 		roots: []constraintsSpec{
   1101 			constraintsSpec{
   1102 				bad: []string{"uri:foo.com"},
   1103 			},
   1104 		},
   1105 		intermediates: [][]constraintsSpec{
   1106 			[]constraintsSpec{
   1107 				constraintsSpec{},
   1108 			},
   1109 		},
   1110 		leaf: leafSpec{
   1111 			sans: []string{"uri:http://foo.com/"},
   1112 		},
   1113 		expectedError: "\"http://foo.com/\" is excluded",
   1114 	},
   1115 
   1116 	// #57: URI constraints can allow subdomains
   1117 	nameConstraintsTest{
   1118 		roots: []constraintsSpec{
   1119 			constraintsSpec{
   1120 				ok: []string{"uri:.foo.com"},
   1121 			},
   1122 		},
   1123 		intermediates: [][]constraintsSpec{
   1124 			[]constraintsSpec{
   1125 				constraintsSpec{},
   1126 			},
   1127 		},
   1128 		leaf: leafSpec{
   1129 			sans: []string{"uri:http://www.foo.com/"},
   1130 		},
   1131 	},
   1132 
   1133 	// #58: excluding an IPv4-mapped-IPv6 address doesn't affect the IPv4
   1134 	// version of that address.
   1135 	nameConstraintsTest{
   1136 		roots: []constraintsSpec{
   1137 			constraintsSpec{
   1138 				bad: []string{"ip:::ffff:1.2.3.4/128"},
   1139 			},
   1140 		},
   1141 		intermediates: [][]constraintsSpec{
   1142 			[]constraintsSpec{
   1143 				constraintsSpec{},
   1144 			},
   1145 		},
   1146 		leaf: leafSpec{
   1147 			sans: []string{"ip:1.2.3.4"},
   1148 		},
   1149 	},
   1150 
   1151 	// #59: a URI constraint isn't matched by a URN.
   1152 	nameConstraintsTest{
   1153 		roots: []constraintsSpec{
   1154 			constraintsSpec{
   1155 				ok: []string{"uri:example.com"},
   1156 			},
   1157 		},
   1158 		intermediates: [][]constraintsSpec{
   1159 			[]constraintsSpec{
   1160 				constraintsSpec{},
   1161 			},
   1162 		},
   1163 		leaf: leafSpec{
   1164 			sans: []string{"uri:urn:example"},
   1165 		},
   1166 		expectedError: "URI with empty host",
   1167 	},
   1168 
   1169 	// #60: excluding all IPv6 addresses doesn't exclude all IPv4 addresses
   1170 	// too, even though IPv4 is mapped into the IPv6 range.
   1171 	nameConstraintsTest{
   1172 		roots: []constraintsSpec{
   1173 			constraintsSpec{
   1174 				ok:  []string{"ip:1.2.3.0/24"},
   1175 				bad: []string{"ip:::0/0"},
   1176 			},
   1177 		},
   1178 		intermediates: [][]constraintsSpec{
   1179 			[]constraintsSpec{
   1180 				constraintsSpec{},
   1181 			},
   1182 		},
   1183 		leaf: leafSpec{
   1184 			sans: []string{"ip:1.2.3.4"},
   1185 		},
   1186 	},
   1187 
   1188 	// #61: omitting extended key usage in a CA certificate implies that
   1189 	// any usage is ok.
   1190 	nameConstraintsTest{
   1191 		roots: []constraintsSpec{
   1192 			constraintsSpec{},
   1193 		},
   1194 		intermediates: [][]constraintsSpec{
   1195 			[]constraintsSpec{
   1196 				constraintsSpec{},
   1197 			},
   1198 		},
   1199 		leaf: leafSpec{
   1200 			sans: []string{"dns:example.com"},
   1201 			ekus: []string{"serverAuth", "other"},
   1202 		},
   1203 	},
   1204 
   1205 	// #62: The any EKU also means that any usage is ok.
   1206 	nameConstraintsTest{
   1207 		roots: []constraintsSpec{
   1208 			constraintsSpec{},
   1209 		},
   1210 		intermediates: [][]constraintsSpec{
   1211 			[]constraintsSpec{
   1212 				constraintsSpec{
   1213 					ekus: []string{"any"},
   1214 				},
   1215 			},
   1216 		},
   1217 		leaf: leafSpec{
   1218 			sans: []string{"dns:example.com"},
   1219 			ekus: []string{"serverAuth", "other"},
   1220 		},
   1221 	},
   1222 
   1223 	// #63: A specified key usage in an intermediate forbids other usages
   1224 	// in the leaf.
   1225 	nameConstraintsTest{
   1226 		roots: []constraintsSpec{
   1227 			constraintsSpec{},
   1228 		},
   1229 		intermediates: [][]constraintsSpec{
   1230 			[]constraintsSpec{
   1231 				constraintsSpec{
   1232 					ekus: []string{"email"},
   1233 				},
   1234 			},
   1235 		},
   1236 		leaf: leafSpec{
   1237 			sans: []string{"dns:example.com"},
   1238 			ekus: []string{"serverAuth"},
   1239 		},
   1240 		expectedError: "EKU not permitted",
   1241 	},
   1242 
   1243 	// #64: A specified key usage in an intermediate forbids other usages
   1244 	// in the leaf, even if we don't recognise them.
   1245 	nameConstraintsTest{
   1246 		roots: []constraintsSpec{
   1247 			constraintsSpec{},
   1248 		},
   1249 		intermediates: [][]constraintsSpec{
   1250 			[]constraintsSpec{
   1251 				constraintsSpec{
   1252 					ekus: []string{"email"},
   1253 				},
   1254 			},
   1255 		},
   1256 		leaf: leafSpec{
   1257 			sans: []string{"dns:example.com"},
   1258 			ekus: []string{"other"},
   1259 		},
   1260 		expectedError: "EKU not permitted",
   1261 	},
   1262 
   1263 	// #65: trying to add extra permitted key usages in an intermediate
   1264 	// (after a limitation in the root) is acceptable so long as the leaf
   1265 	// certificate doesn't use them.
   1266 	nameConstraintsTest{
   1267 		roots: []constraintsSpec{
   1268 			constraintsSpec{
   1269 				ekus: []string{"serverAuth"},
   1270 			},
   1271 		},
   1272 		intermediates: [][]constraintsSpec{
   1273 			[]constraintsSpec{
   1274 				constraintsSpec{
   1275 					ekus: []string{"serverAuth", "email"},
   1276 				},
   1277 			},
   1278 		},
   1279 		leaf: leafSpec{
   1280 			sans: []string{"dns:example.com"},
   1281 			ekus: []string{"serverAuth"},
   1282 		},
   1283 	},
   1284 
   1285 	// #66: EKUs in roots are ignored.
   1286 	nameConstraintsTest{
   1287 		roots: []constraintsSpec{
   1288 			constraintsSpec{
   1289 				ekus: []string{"serverAuth"},
   1290 			},
   1291 		},
   1292 		intermediates: [][]constraintsSpec{
   1293 			[]constraintsSpec{
   1294 				constraintsSpec{
   1295 					ekus: []string{"serverAuth", "email"},
   1296 				},
   1297 			},
   1298 		},
   1299 		leaf: leafSpec{
   1300 			sans: []string{"dns:example.com"},
   1301 			ekus: []string{"serverAuth", "email"},
   1302 		},
   1303 	},
   1304 
   1305 	// #67: in order to support COMODO chains, SGC key usages permit
   1306 	// serverAuth and clientAuth.
   1307 	nameConstraintsTest{
   1308 		roots: []constraintsSpec{
   1309 			constraintsSpec{},
   1310 		},
   1311 		intermediates: [][]constraintsSpec{
   1312 			[]constraintsSpec{
   1313 				constraintsSpec{
   1314 					ekus: []string{"netscapeSGC"},
   1315 				},
   1316 			},
   1317 		},
   1318 		leaf: leafSpec{
   1319 			sans: []string{"dns:example.com"},
   1320 			ekus: []string{"serverAuth", "clientAuth"},
   1321 		},
   1322 	},
   1323 
   1324 	// #68: in order to support COMODO chains, SGC key usages permit
   1325 	// serverAuth and clientAuth.
   1326 	nameConstraintsTest{
   1327 		roots: []constraintsSpec{
   1328 			constraintsSpec{},
   1329 		},
   1330 		intermediates: [][]constraintsSpec{
   1331 			[]constraintsSpec{
   1332 				constraintsSpec{
   1333 					ekus: []string{"msSGC"},
   1334 				},
   1335 			},
   1336 		},
   1337 		leaf: leafSpec{
   1338 			sans: []string{"dns:example.com"},
   1339 			ekus: []string{"serverAuth", "clientAuth"},
   1340 		},
   1341 	},
   1342 
   1343 	// #69: an empty DNS constraint should allow anything.
   1344 	nameConstraintsTest{
   1345 		roots: []constraintsSpec{
   1346 			constraintsSpec{
   1347 				ok: []string{"dns:"},
   1348 			},
   1349 		},
   1350 		intermediates: [][]constraintsSpec{
   1351 			[]constraintsSpec{
   1352 				constraintsSpec{},
   1353 			},
   1354 		},
   1355 		leaf: leafSpec{
   1356 			sans: []string{"dns:example.com"},
   1357 		},
   1358 	},
   1359 
   1360 	// #70: an empty DNS constraint should also reject everything.
   1361 	nameConstraintsTest{
   1362 		roots: []constraintsSpec{
   1363 			constraintsSpec{
   1364 				bad: []string{"dns:"},
   1365 			},
   1366 		},
   1367 		intermediates: [][]constraintsSpec{
   1368 			[]constraintsSpec{
   1369 				constraintsSpec{},
   1370 			},
   1371 		},
   1372 		leaf: leafSpec{
   1373 			sans: []string{"dns:example.com"},
   1374 		},
   1375 		expectedError: "\"example.com\" is excluded",
   1376 	},
   1377 
   1378 	// #71: an empty email constraint should allow anything
   1379 	nameConstraintsTest{
   1380 		roots: []constraintsSpec{
   1381 			constraintsSpec{
   1382 				ok: []string{"email:"},
   1383 			},
   1384 		},
   1385 		intermediates: [][]constraintsSpec{
   1386 			[]constraintsSpec{
   1387 				constraintsSpec{},
   1388 			},
   1389 		},
   1390 		leaf: leafSpec{
   1391 			sans: []string{"email:foo (a] example.com"},
   1392 		},
   1393 	},
   1394 
   1395 	// #72: an empty email constraint should also reject everything.
   1396 	nameConstraintsTest{
   1397 		roots: []constraintsSpec{
   1398 			constraintsSpec{
   1399 				bad: []string{"email:"},
   1400 			},
   1401 		},
   1402 		intermediates: [][]constraintsSpec{
   1403 			[]constraintsSpec{
   1404 				constraintsSpec{},
   1405 			},
   1406 		},
   1407 		leaf: leafSpec{
   1408 			sans: []string{"email:foo (a] example.com"},
   1409 		},
   1410 		expectedError: "\"foo (a] example.com\" is excluded",
   1411 	},
   1412 
   1413 	// #73: an empty URI constraint should allow anything
   1414 	nameConstraintsTest{
   1415 		roots: []constraintsSpec{
   1416 			constraintsSpec{
   1417 				ok: []string{"uri:"},
   1418 			},
   1419 		},
   1420 		intermediates: [][]constraintsSpec{
   1421 			[]constraintsSpec{
   1422 				constraintsSpec{},
   1423 			},
   1424 		},
   1425 		leaf: leafSpec{
   1426 			sans: []string{"uri:https://example.com/test"},
   1427 		},
   1428 	},
   1429 
   1430 	// #74: an empty URI constraint should also reject everything.
   1431 	nameConstraintsTest{
   1432 		roots: []constraintsSpec{
   1433 			constraintsSpec{
   1434 				bad: []string{"uri:"},
   1435 			},
   1436 		},
   1437 		intermediates: [][]constraintsSpec{
   1438 			[]constraintsSpec{
   1439 				constraintsSpec{},
   1440 			},
   1441 		},
   1442 		leaf: leafSpec{
   1443 			sans: []string{"uri:https://example.com/test"},
   1444 		},
   1445 		expectedError: "\"https://example.com/test\" is excluded",
   1446 	},
   1447 }
   1448 
   1449 func makeConstraintsCACert(constraints constraintsSpec, name string, key *ecdsa.PrivateKey, parent *Certificate, parentKey *ecdsa.PrivateKey) (*Certificate, error) {
   1450 	var serialBytes [16]byte
   1451 	rand.Read(serialBytes[:])
   1452 
   1453 	template := &Certificate{
   1454 		SerialNumber: new(big.Int).SetBytes(serialBytes[:]),
   1455 		Subject: pkix.Name{
   1456 			CommonName: name,
   1457 		},
   1458 		NotBefore:             time.Unix(1000, 0),
   1459 		NotAfter:              time.Unix(2000, 0),
   1460 		KeyUsage:              KeyUsageCertSign,
   1461 		BasicConstraintsValid: true,
   1462 		IsCA: true,
   1463 	}
   1464 
   1465 	if err := addConstraintsToTemplate(constraints, template); err != nil {
   1466 		return nil, err
   1467 	}
   1468 
   1469 	if parent == nil {
   1470 		parent = template
   1471 	}
   1472 	derBytes, err := CreateCertificate(rand.Reader, template, parent, &key.PublicKey, parentKey)
   1473 	if err != nil {
   1474 		return nil, err
   1475 	}
   1476 
   1477 	caCert, err := ParseCertificate(derBytes)
   1478 	if err != nil {
   1479 		return nil, err
   1480 	}
   1481 
   1482 	return caCert, nil
   1483 }
   1484 
   1485 func makeConstraintsLeafCert(leaf leafSpec, key *ecdsa.PrivateKey, parent *Certificate, parentKey *ecdsa.PrivateKey) (*Certificate, error) {
   1486 	var serialBytes [16]byte
   1487 	rand.Read(serialBytes[:])
   1488 
   1489 	template := &Certificate{
   1490 		SerialNumber: new(big.Int).SetBytes(serialBytes[:]),
   1491 		Subject: pkix.Name{
   1492 			// Don't set a CommonName because OpenSSL (at least) will try to
   1493 			// match it against name constraints.
   1494 			OrganizationalUnit: []string{"Leaf"},
   1495 		},
   1496 		NotBefore:             time.Unix(1000, 0),
   1497 		NotAfter:              time.Unix(2000, 0),
   1498 		KeyUsage:              KeyUsageDigitalSignature,
   1499 		BasicConstraintsValid: true,
   1500 		IsCA: false,
   1501 	}
   1502 
   1503 	for _, name := range leaf.sans {
   1504 		switch {
   1505 		case strings.HasPrefix(name, "dns:"):
   1506 			template.DNSNames = append(template.DNSNames, name[4:])
   1507 
   1508 		case strings.HasPrefix(name, "ip:"):
   1509 			ip := net.ParseIP(name[3:])
   1510 			if ip == nil {
   1511 				return nil, fmt.Errorf("cannot parse IP %q", name[3:])
   1512 			}
   1513 			template.IPAddresses = append(template.IPAddresses, ip)
   1514 
   1515 		case strings.HasPrefix(name, "email:"):
   1516 			template.EmailAddresses = append(template.EmailAddresses, name[6:])
   1517 
   1518 		case strings.HasPrefix(name, "uri:"):
   1519 			uri, err := url.Parse(name[4:])
   1520 			if err != nil {
   1521 				return nil, fmt.Errorf("cannot parse URI %q: %s", name[4:], err)
   1522 			}
   1523 			template.URIs = append(template.URIs, uri)
   1524 
   1525 		case strings.HasPrefix(name, "unknown:"):
   1526 			// This is a special case for testing unknown
   1527 			// name types. A custom SAN extension is
   1528 			// injected into the certificate.
   1529 			if len(leaf.sans) != 1 {
   1530 				panic("when using unknown name types, it must be the sole name")
   1531 			}
   1532 
   1533 			template.ExtraExtensions = append(template.ExtraExtensions, pkix.Extension{
   1534 				Id: []int{2, 5, 29, 17},
   1535 				Value: []byte{
   1536 					0x30, // SEQUENCE
   1537 					3,    // three bytes
   1538 					9,    // undefined GeneralName type 9
   1539 					1,
   1540 					1,
   1541 				},
   1542 			})
   1543 
   1544 		default:
   1545 			return nil, fmt.Errorf("unknown name type %q", name)
   1546 		}
   1547 	}
   1548 
   1549 	var err error
   1550 	if template.ExtKeyUsage, template.UnknownExtKeyUsage, err = parseEKUs(leaf.ekus); err != nil {
   1551 		return nil, err
   1552 	}
   1553 
   1554 	if parent == nil {
   1555 		parent = template
   1556 	}
   1557 
   1558 	derBytes, err := CreateCertificate(rand.Reader, template, parent, &key.PublicKey, parentKey)
   1559 	if err != nil {
   1560 		return nil, err
   1561 	}
   1562 
   1563 	return ParseCertificate(derBytes)
   1564 }
   1565 
   1566 func customConstraintsExtension(typeNum int, constraint []byte, isExcluded bool) pkix.Extension {
   1567 	appendConstraint := func(contents []byte, tag uint8) []byte {
   1568 		contents = append(contents, tag|32 /* constructed */ |0x80 /* context-specific */)
   1569 		contents = append(contents, byte(4+len(constraint)) /* length */)
   1570 		contents = append(contents, 0x30 /* SEQUENCE */)
   1571 		contents = append(contents, byte(2+len(constraint)) /* length */)
   1572 		contents = append(contents, byte(typeNum) /* GeneralName type */)
   1573 		contents = append(contents, byte(len(constraint)))
   1574 		return append(contents, constraint...)
   1575 	}
   1576 
   1577 	var contents []byte
   1578 	if !isExcluded {
   1579 		contents = appendConstraint(contents, 0 /* tag 0 for permitted */)
   1580 	} else {
   1581 		contents = appendConstraint(contents, 1 /* tag 1 for excluded */)
   1582 	}
   1583 
   1584 	var value []byte
   1585 	value = append(value, 0x30 /* SEQUENCE */)
   1586 	value = append(value, byte(len(contents)))
   1587 	value = append(value, contents...)
   1588 
   1589 	return pkix.Extension{
   1590 		Id:    []int{2, 5, 29, 30},
   1591 		Value: value,
   1592 	}
   1593 }
   1594 
   1595 func addConstraintsToTemplate(constraints constraintsSpec, template *Certificate) error {
   1596 	parse := func(constraints []string) (dnsNames []string, ips []*net.IPNet, emailAddrs []string, uriDomains []string, err error) {
   1597 		for _, constraint := range constraints {
   1598 			switch {
   1599 			case strings.HasPrefix(constraint, "dns:"):
   1600 				dnsNames = append(dnsNames, constraint[4:])
   1601 
   1602 			case strings.HasPrefix(constraint, "ip:"):
   1603 				_, ipNet, err := net.ParseCIDR(constraint[3:])
   1604 				if err != nil {
   1605 					return nil, nil, nil, nil, err
   1606 				}
   1607 				ips = append(ips, ipNet)
   1608 
   1609 			case strings.HasPrefix(constraint, "email:"):
   1610 				emailAddrs = append(emailAddrs, constraint[6:])
   1611 
   1612 			case strings.HasPrefix(constraint, "uri:"):
   1613 				uriDomains = append(uriDomains, constraint[4:])
   1614 
   1615 			default:
   1616 				return nil, nil, nil, nil, fmt.Errorf("unknown constraint %q", constraint)
   1617 			}
   1618 		}
   1619 
   1620 		return dnsNames, ips, emailAddrs, uriDomains, err
   1621 	}
   1622 
   1623 	handleSpecialConstraint := func(constraint string, isExcluded bool) bool {
   1624 		switch {
   1625 		case constraint == "unknown:":
   1626 			template.ExtraExtensions = append(template.ExtraExtensions, customConstraintsExtension(9 /* undefined GeneralName type */, []byte{1}, isExcluded))
   1627 
   1628 		default:
   1629 			return false
   1630 		}
   1631 
   1632 		return true
   1633 	}
   1634 
   1635 	if len(constraints.ok) == 1 && len(constraints.bad) == 0 {
   1636 		if handleSpecialConstraint(constraints.ok[0], false) {
   1637 			return nil
   1638 		}
   1639 	}
   1640 
   1641 	if len(constraints.bad) == 1 && len(constraints.ok) == 0 {
   1642 		if handleSpecialConstraint(constraints.bad[0], true) {
   1643 			return nil
   1644 		}
   1645 	}
   1646 
   1647 	var err error
   1648 	template.PermittedDNSDomains, template.PermittedIPRanges, template.PermittedEmailAddresses, template.PermittedURIDomains, err = parse(constraints.ok)
   1649 	if err != nil {
   1650 		return err
   1651 	}
   1652 
   1653 	template.ExcludedDNSDomains, template.ExcludedIPRanges, template.ExcludedEmailAddresses, template.ExcludedURIDomains, err = parse(constraints.bad)
   1654 	if err != nil {
   1655 		return err
   1656 	}
   1657 
   1658 	if template.ExtKeyUsage, template.UnknownExtKeyUsage, err = parseEKUs(constraints.ekus); err != nil {
   1659 		return err
   1660 	}
   1661 
   1662 	return nil
   1663 }
   1664 
   1665 func parseEKUs(ekuStrs []string) (ekus []ExtKeyUsage, unknowns []asn1.ObjectIdentifier, err error) {
   1666 	for _, s := range ekuStrs {
   1667 		switch s {
   1668 		case "serverAuth":
   1669 			ekus = append(ekus, ExtKeyUsageServerAuth)
   1670 		case "clientAuth":
   1671 			ekus = append(ekus, ExtKeyUsageClientAuth)
   1672 		case "email":
   1673 			ekus = append(ekus, ExtKeyUsageEmailProtection)
   1674 		case "netscapeSGC":
   1675 			ekus = append(ekus, ExtKeyUsageNetscapeServerGatedCrypto)
   1676 		case "msSGC":
   1677 			ekus = append(ekus, ExtKeyUsageMicrosoftServerGatedCrypto)
   1678 		case "any":
   1679 			ekus = append(ekus, ExtKeyUsageAny)
   1680 		case "other":
   1681 			unknowns = append(unknowns, asn1.ObjectIdentifier{2, 4, 1, 2, 3})
   1682 		default:
   1683 			return nil, nil, fmt.Errorf("unknown EKU %q", s)
   1684 		}
   1685 	}
   1686 
   1687 	return
   1688 }
   1689 
   1690 func TestConstraintCases(t *testing.T) {
   1691 	privateKeys := sync.Pool{
   1692 		New: func() interface{} {
   1693 			priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   1694 			if err != nil {
   1695 				panic(err)
   1696 			}
   1697 			return priv
   1698 		},
   1699 	}
   1700 
   1701 	for i, test := range nameConstraintsTests {
   1702 		rootPool := NewCertPool()
   1703 		rootKey := privateKeys.Get().(*ecdsa.PrivateKey)
   1704 		rootName := "Root " + strconv.Itoa(i)
   1705 
   1706 		// keys keeps track of all the private keys used in a given
   1707 		// test and puts them back in the privateKeys pool at the end.
   1708 		keys := []*ecdsa.PrivateKey{rootKey}
   1709 
   1710 		// At each level (root, intermediate(s), leaf), parent points to
   1711 		// an example parent certificate and parentKey the key for the
   1712 		// parent level. Since all certificates at a given level have
   1713 		// the same name and public key, any parent certificate is
   1714 		// sufficient to get the correct issuer name and authority
   1715 		// key ID.
   1716 		var parent *Certificate
   1717 		parentKey := rootKey
   1718 
   1719 		for _, root := range test.roots {
   1720 			rootCert, err := makeConstraintsCACert(root, rootName, rootKey, nil, rootKey)
   1721 			if err != nil {
   1722 				t.Fatalf("#%d: failed to create root: %s", i, err)
   1723 			}
   1724 
   1725 			parent = rootCert
   1726 			rootPool.AddCert(rootCert)
   1727 		}
   1728 
   1729 		intermediatePool := NewCertPool()
   1730 
   1731 		for level, intermediates := range test.intermediates {
   1732 			levelKey := privateKeys.Get().(*ecdsa.PrivateKey)
   1733 			keys = append(keys, levelKey)
   1734 			levelName := "Intermediate level " + strconv.Itoa(level)
   1735 			var last *Certificate
   1736 
   1737 			for _, intermediate := range intermediates {
   1738 				caCert, err := makeConstraintsCACert(intermediate, levelName, levelKey, parent, parentKey)
   1739 				if err != nil {
   1740 					t.Fatalf("#%d: failed to create %q: %s", i, levelName, err)
   1741 				}
   1742 
   1743 				last = caCert
   1744 				intermediatePool.AddCert(caCert)
   1745 			}
   1746 
   1747 			parent = last
   1748 			parentKey = levelKey
   1749 		}
   1750 
   1751 		leafKey := privateKeys.Get().(*ecdsa.PrivateKey)
   1752 		keys = append(keys, leafKey)
   1753 
   1754 		leafCert, err := makeConstraintsLeafCert(test.leaf, leafKey, parent, parentKey)
   1755 		if err != nil {
   1756 			t.Fatalf("#%d: cannot create leaf: %s", i, err)
   1757 		}
   1758 
   1759 		if !test.noOpenSSL && testNameConstraintsAgainstOpenSSL {
   1760 			output, err := testChainAgainstOpenSSL(leafCert, intermediatePool, rootPool)
   1761 			if err == nil && len(test.expectedError) > 0 {
   1762 				t.Errorf("#%d: unexpectedly succeeded against OpenSSL", i)
   1763 				if debugOpenSSLFailure {
   1764 					return
   1765 				}
   1766 			}
   1767 
   1768 			if err != nil {
   1769 				if _, ok := err.(*exec.ExitError); !ok {
   1770 					t.Errorf("#%d: OpenSSL failed to run: %s", i, err)
   1771 				} else if len(test.expectedError) == 0 {
   1772 					t.Errorf("#%d: OpenSSL unexpectedly failed: %q", i, output)
   1773 					if debugOpenSSLFailure {
   1774 						return
   1775 					}
   1776 				}
   1777 			}
   1778 		}
   1779 
   1780 		verifyOpts := VerifyOptions{
   1781 			Roots:         rootPool,
   1782 			Intermediates: intermediatePool,
   1783 			CurrentTime:   time.Unix(1500, 0),
   1784 		}
   1785 		_, err = leafCert.Verify(verifyOpts)
   1786 
   1787 		logInfo := true
   1788 		if len(test.expectedError) == 0 {
   1789 			if err != nil {
   1790 				t.Errorf("#%d: unexpected failure: %s", i, err)
   1791 			} else {
   1792 				logInfo = false
   1793 			}
   1794 		} else {
   1795 			if err == nil {
   1796 				t.Errorf("#%d: unexpected success", i)
   1797 			} else if !strings.Contains(err.Error(), test.expectedError) {
   1798 				t.Errorf("#%d: expected error containing %q, but got: %s", i, test.expectedError, err)
   1799 			} else {
   1800 				logInfo = false
   1801 			}
   1802 		}
   1803 
   1804 		if logInfo {
   1805 			certAsPEM := func(cert *Certificate) string {
   1806 				var buf bytes.Buffer
   1807 				pem.Encode(&buf, &pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})
   1808 				return string(buf.Bytes())
   1809 			}
   1810 			t.Errorf("#%d: root:\n%s", i, certAsPEM(rootPool.certs[0]))
   1811 			t.Errorf("#%d: leaf:\n%s", i, certAsPEM(leafCert))
   1812 		}
   1813 
   1814 		for _, key := range keys {
   1815 			privateKeys.Put(key)
   1816 		}
   1817 		keys = keys[:0]
   1818 	}
   1819 }
   1820 
   1821 func writePEMsToTempFile(certs []*Certificate) *os.File {
   1822 	file, err := ioutil.TempFile("", "name_constraints_test")
   1823 	if err != nil {
   1824 		panic("cannot create tempfile")
   1825 	}
   1826 
   1827 	pemBlock := &pem.Block{Type: "CERTIFICATE"}
   1828 	for _, cert := range certs {
   1829 		pemBlock.Bytes = cert.Raw
   1830 		pem.Encode(file, pemBlock)
   1831 	}
   1832 
   1833 	return file
   1834 }
   1835 
   1836 func testChainAgainstOpenSSL(leaf *Certificate, intermediates, roots *CertPool) (string, error) {
   1837 	args := []string{"verify", "-no_check_time"}
   1838 
   1839 	rootsFile := writePEMsToTempFile(roots.certs)
   1840 	if debugOpenSSLFailure {
   1841 		println("roots file:", rootsFile.Name())
   1842 	} else {
   1843 		defer os.Remove(rootsFile.Name())
   1844 	}
   1845 	args = append(args, "-CAfile", rootsFile.Name())
   1846 
   1847 	if len(intermediates.certs) > 0 {
   1848 		intermediatesFile := writePEMsToTempFile(intermediates.certs)
   1849 		if debugOpenSSLFailure {
   1850 			println("intermediates file:", intermediatesFile.Name())
   1851 		} else {
   1852 			defer os.Remove(intermediatesFile.Name())
   1853 		}
   1854 		args = append(args, "-untrusted", intermediatesFile.Name())
   1855 	}
   1856 
   1857 	leafFile := writePEMsToTempFile([]*Certificate{leaf})
   1858 	if debugOpenSSLFailure {
   1859 		println("leaf file:", leafFile.Name())
   1860 	} else {
   1861 		defer os.Remove(leafFile.Name())
   1862 	}
   1863 	args = append(args, leafFile.Name())
   1864 
   1865 	var output bytes.Buffer
   1866 	cmd := exec.Command("openssl", args...)
   1867 	cmd.Stdout = &output
   1868 	cmd.Stderr = &output
   1869 
   1870 	err := cmd.Run()
   1871 	return string(output.Bytes()), err
   1872 }
   1873 
   1874 var rfc2821Tests = []struct {
   1875 	in                string
   1876 	localPart, domain string
   1877 }{
   1878 	{"foo (a] example.com", "foo", "example.com"},
   1879 	{"@example.com", "", ""},
   1880 	{"\"@example.com", "", ""},
   1881 	{"\"\"@example.com", "", "example.com"},
   1882 	{"\"a\"@example.com", "a", "example.com"},
   1883 	{"\"\\a\"@example.com", "a", "example.com"},
   1884 	{"a\"@example.com", "", ""},
   1885 	{"foo..bar (a] example.com", "", ""},
   1886 	{".foo.bar (a] example.com", "", ""},
   1887 	{"foo.bar. (a] example.com", "", ""},
   1888 	{"|{}?'@example.com", "|{}?'", "example.com"},
   1889 
   1890 	// Examples from RFC 3696
   1891 	{"Abc\\@def (a] example.com", "Abc@def", "example.com"},
   1892 	{"Fred\\ Bloggs (a] example.com", "Fred Bloggs", "example.com"},
   1893 	{"Joe.\\\\Blow (a] example.com", "Joe.\\Blow", "example.com"},
   1894 	{"\"Abc@def\"@example.com", "Abc@def", "example.com"},
   1895 	{"\"Fred Bloggs\"@example.com", "Fred Bloggs", "example.com"},
   1896 	{"customer/department=shipping (a] example.com", "customer/department=shipping", "example.com"},
   1897 	{"$A12345 (a] example.com", "$A12345", "example.com"},
   1898 	{"!def!xyz%abc (a] example.com", "!def!xyz%abc", "example.com"},
   1899 	{"_somename (a] example.com", "_somename", "example.com"},
   1900 }
   1901 
   1902 func TestRFC2821Parsing(t *testing.T) {
   1903 	for i, test := range rfc2821Tests {
   1904 		mailbox, ok := parseRFC2821Mailbox(test.in)
   1905 		expectedFailure := len(test.localPart) == 0 && len(test.domain) == 0
   1906 
   1907 		if ok && expectedFailure {
   1908 			t.Errorf("#%d: %q unexpectedly parsed as (%q, %q)", i, test.in, mailbox.local, mailbox.domain)
   1909 			continue
   1910 		}
   1911 
   1912 		if !ok && !expectedFailure {
   1913 			t.Errorf("#%d: unexpected failure for %q", i, test.in)
   1914 			continue
   1915 		}
   1916 
   1917 		if !ok {
   1918 			continue
   1919 		}
   1920 
   1921 		if mailbox.local != test.localPart || mailbox.domain != test.domain {
   1922 			t.Errorf("#%d: %q parsed as (%q, %q), but wanted (%q, %q)", i, test.in, mailbox.local, mailbox.domain, test.localPart, test.domain)
   1923 		}
   1924 	}
   1925 }
   1926 
   1927 func TestBadNamesInConstraints(t *testing.T) {
   1928 	constraintParseError := func(err error) bool {
   1929 		str := err.Error()
   1930 		return strings.Contains(str, "failed to parse ") && strings.Contains(str, "constraint")
   1931 	}
   1932 
   1933 	encodingError := func(err error) bool {
   1934 		return strings.Contains(err.Error(), "cannot be encoded as an IA5String")
   1935 	}
   1936 
   1937 	// Bad names in constraints should not parse.
   1938 	badNames := []struct {
   1939 		name    string
   1940 		matcher func(error) bool
   1941 	}{
   1942 		{"dns:foo.com.", constraintParseError},
   1943 		{"email:abc (a] foo.com.", constraintParseError},
   1944 		{"email:foo.com.", constraintParseError},
   1945 		{"uri:example.com.", constraintParseError},
   1946 		{"uri:1.2.3.4", constraintParseError},
   1947 		{"uri:ffff::1", constraintParseError},
   1948 		{"dns:nothyphen.com", encodingError},
   1949 		{"email:foo@nothyphen.com", encodingError},
   1950 		{"uri:nothyphen.com", encodingError},
   1951 	}
   1952 
   1953 	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   1954 	if err != nil {
   1955 		panic(err)
   1956 	}
   1957 
   1958 	for _, test := range badNames {
   1959 		_, err := makeConstraintsCACert(constraintsSpec{
   1960 			ok: []string{test.name},
   1961 		}, "TestAbsoluteNamesInConstraints", priv, nil, priv)
   1962 
   1963 		if err == nil {
   1964 			t.Errorf("bad name %q unexpectedly accepted in name constraint", test.name)
   1965 			continue
   1966 		} else {
   1967 			if !test.matcher(err) {
   1968 				t.Errorf("bad name %q triggered unrecognised error: %s", test.name, err)
   1969 			}
   1970 		}
   1971 	}
   1972 }
   1973 
   1974 func TestBadNamesInSANs(t *testing.T) {
   1975 	// Bad names in SANs should not parse.
   1976 	badNames := []string{
   1977 		"dns:foo.com.",
   1978 		"email:abc (a] foo.com.",
   1979 		"email:foo.com.",
   1980 		"uri:https://example.com./dsf",
   1981 	}
   1982 
   1983 	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   1984 	if err != nil {
   1985 		panic(err)
   1986 	}
   1987 
   1988 	for _, badName := range badNames {
   1989 		_, err := makeConstraintsLeafCert(leafSpec{sans: []string{badName}}, priv, nil, priv)
   1990 
   1991 		if err == nil {
   1992 			t.Errorf("bad name %q unexpectedly accepted in SAN", badName)
   1993 			continue
   1994 		}
   1995 
   1996 		if err != nil {
   1997 			if str := err.Error(); !strings.Contains(str, "cannot parse ") {
   1998 				t.Errorf("bad name %q triggered unrecognised error: %s", badName, str)
   1999 			}
   2000 		}
   2001 	}
   2002 }
   2003