github.com/likebike/go--@v0.0.0-20190911215757-0bd925d16e96/go/src/crypto/x509/name_constraints_test.go (about)

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