Home | History | Annotate | Download | only in x509
      1 /* Copyright (c) 2017, Google Inc.
      2  *
      3  * Permission to use, copy, modify, and/or distribute this software for any
      4  * purpose with or without fee is hereby granted, provided that the above
      5  * copyright notice and this permission notice appear in all copies.
      6  *
      7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
     10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
     12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
     13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
     14 
     15 // make_many_constraints.go generates test certificates many_constraints.pem,
     16 // many_names*.pem, and some_names*.pem for x509_test.cc
     17 package main
     18 
     19 import (
     20 	"crypto/rand"
     21 	"crypto/rsa"
     22 	"crypto/x509"
     23 	"crypto/x509/pkix"
     24 	"encoding/asn1"
     25 	"encoding/pem"
     26 	"fmt"
     27 	"math/big"
     28 	"os"
     29 	"time"
     30 )
     31 
     32 const privateKeyPEM = `-----BEGIN PRIVATE KEY-----
     33 MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC6C9qEGRIBQXV8
     34 Lj29vVu+U+tyXzSSinWIumK5ijPhCm3DLnv4RayxkFwemtnkGRZ/o94ZnsXkBfU/
     35 IlsYdkuq8wK9WI/ql3gwWjH+KARIhIQcSLGiJcLN6kGuG2nlRBKMcPgPiEq2B0yB
     36 XFf4tG3CBbeae7+8G7uvOmv8NLyKj32neWpnUCTL5o2VwyPoxjLxT5gUR69v9XSV
     37 Fj2irCZbsEedeKSb++LqyMhLfnRTzNv+ZHNh4izZHrktR25MvnT5QyBq32hx7AjZ
     38 2/xo70OmH7w10a2DwsVjJNMdxTEmgyvU9M6CeYRPX1Ykfg+sXCTtkTVAlBDUviIq
     39 Y95CKy25AgMBAAECggEAHPvvxRiqx2tNRFVn5QF1I4erbJwMcrADc5OmAcXYIz0e
     40 sIOzaJBiQR9+Wn5BZ9nIuYXr+g3UQpvzAyz1CDCVxUIqsRj1AtUqMk4675+IW0vZ
     41 0RY6Jkq/uJjANsGqk78xLJQE8VaIXSdx8c1THznsx4dgfT6+Ni4T5U6yuA33OZaw
     42 4NdYZYtEkqNiqK6VYe4mAxxVh5qscihVVMGkBVqJNiiEotctm1lph8ow+7o8ggXO
     43 W9xm+RHHPcH7Epx7hjkb/helANcYOK950W5/R+2zWV9R6kxo6R+/hfGFFmCvl4k5
     44 +i8Y0IlEv3fze1E0Lwyf379i3C/cKcuaE5gwR54BAQKBgQDxlsNy9M37HgguglHt
     45 8W+cuPNtxNjFCWIjNR9dSvdr1Oi28Z1AY+BBPSv6UBKnT5PpOFjqxfMY/j/zoKdI
     46 aYX1phgeQHXcHrB1pS8yoaF/pTJSN2Yb8v9kl/Ch1yeYXaNVGmeBLkH9H6wIcUxD
     47 Mas1i8VUzshzhcluCNGoJj9wUQKBgQDFJOoWncssfWCrsuDWEoeU71Zh3+bD96GF
     48 s29CdIbHpcbxhWYjA9RM8yxbGPopexzoGcV1HX6j8E1s0xfYZJV23rxoM9Zj9l5D
     49 mZAJQPxYXIdu3h4PslhZLd3p+DEHjbsLC/avk3M4iZim1FMPBJMswKSL23ysqXoY
     50 /ynor+W06QKBgHYeu6M6NHgCYAe1ai+Hq4WaHFNgOohkJRqHv7USkVSkvb+s9LDl
     51 5GChcx4pBmXNj8ko5rirXkerEEOjGgdaqMfJlOM9qyKb0rVCtYfw5RCPCcKPGZqy
     52 vdJGQ74tf0uNBO34QgE0R8lmMevS0XHNGCPPGgV0MSfikvD82N15De1xAoGAbsZM
     53 RsMJfAlDPZc4oPEuf/BwMHTYPTsy5map2MSTSzGKdQHJH1myfD6TqOiDALXtyzlX
     54 63PUShfn2YNPvcbe+Tk00rR1/htcYk2yUpDSenAbpZ9ncth6rjmInURZgG4SMKXb
     55 SlLnBljCjtN1jFW8wQPKMc/14SslsVAHY3ka8KkCgYB58QNT1YfH3jS62+mT2pXq
     56 qLjLqvsD742VYnFoHR+HBOnN8ry0dda4lgwM106L5FgSg9DOZvASZ+QGFk+QVQv+
     57 c77ASWpuhmBmamZCrwZXrq9Xc92RDPkKFqnP9MVv06hYKNp0moSdM8dIaM6uSows
     58 /r/aDs4oudubz26o5GDKmA==
     59 -----END PRIVATE KEY-----`
     60 
     61 var privateKey *rsa.PrivateKey
     62 
     63 func init() {
     64 	in := []byte(privateKeyPEM)
     65 	keyBlock, in := pem.Decode(in)
     66 	if keyBlock == nil || keyBlock.Type != "PRIVATE KEY" {
     67 		panic("could not decode private key")
     68 	}
     69 	key, err := x509.ParsePKCS8PrivateKey(keyBlock.Bytes)
     70 	if err != nil {
     71 		panic(err)
     72 	}
     73 	privateKey = key.(*rsa.PrivateKey)
     74 }
     75 
     76 func randOrDie(out []byte) {
     77 	if _, err := rand.Reader.Read(out); err != nil {
     78 		panic(err)
     79 	}
     80 }
     81 
     82 func writePEM(path string, in []byte) {
     83 	file, err := os.Create(path)
     84 	if err != nil {
     85 		panic(err)
     86 	}
     87 	defer file.Close()
     88 	err = pem.Encode(file, &pem.Block{Type: "CERTIFICATE", Bytes: in})
     89 	if err != nil {
     90 		panic(err)
     91 	}
     92 }
     93 
     94 func main() {
     95 	notBefore, err := time.Parse(time.RFC3339, "2000-01-01T00:00:00Z")
     96 	if err != nil {
     97 		panic(err)
     98 	}
     99 	notAfter, err := time.Parse(time.RFC3339, "2100-01-01T00:00:00Z")
    100 	if err != nil {
    101 		panic(err)
    102 	}
    103 
    104 	caTemplate := x509.Certificate{
    105 		SerialNumber:          new(big.Int).SetInt64(1),
    106 		Subject:               pkix.Name{CommonName: "CA"},
    107 		NotBefore:             notBefore,
    108 		NotAfter:              notAfter,
    109 		BasicConstraintsValid: true,
    110 		IsCA:               true,
    111 		ExtKeyUsage:        []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
    112 		KeyUsage:           x509.KeyUsageCertSign,
    113 		SignatureAlgorithm: x509.SHA256WithRSA,
    114 	}
    115 	for i := 0; i < 513; i++ {
    116 		caTemplate.ExcludedDNSDomains = append(caTemplate.ExcludedDNSDomains, fmt.Sprintf("x%d.test", i))
    117 	}
    118 	for i := 0; i < 513; i++ {
    119 		caTemplate.PermittedDNSDomains = append(caTemplate.PermittedDNSDomains, fmt.Sprintf("t%d.test", i))
    120 	}
    121 	caTemplate.PermittedDNSDomains = append(caTemplate.PermittedDNSDomains, ".test")
    122 	caBytes, err := x509.CreateCertificate(rand.Reader, &caTemplate, &caTemplate, &privateKey.PublicKey, privateKey)
    123 	if err != nil {
    124 		panic(err)
    125 	}
    126 	writePEM("many_constraints.pem", caBytes)
    127 
    128 	ca, err := x509.ParseCertificate(caBytes)
    129 	if err != nil {
    130 		panic(err)
    131 	}
    132 
    133 	leaves := []struct {
    134 		path   string
    135 		names  int
    136 		emails int
    137 	}{
    138 		{"many_names1.pem", 513, 513},
    139 		{"many_names2.pem", 1025, 0},
    140 		{"many_names3.pem", 0, 1025},
    141 		{"some_names1.pem", 256, 256},
    142 		{"some_names2.pem", 513, 0},
    143 		{"some_names3.pem", 0, 513},
    144 	}
    145 	for i, leaf := range leaves {
    146 		leafTemplate := x509.Certificate{
    147 			SerialNumber:          new(big.Int).SetInt64(int64(i + 2)),
    148 			Subject:               pkix.Name{CommonName: "t0.test"},
    149 			NotBefore:             notBefore,
    150 			NotAfter:              notAfter,
    151 			BasicConstraintsValid: true,
    152 			IsCA:               false,
    153 			ExtKeyUsage:        []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
    154 			KeyUsage:           x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
    155 			SignatureAlgorithm: x509.SHA256WithRSA,
    156 		}
    157 		for i := 0; i < leaf.names; i++ {
    158 			leafTemplate.DNSNames = append(leafTemplate.DNSNames, fmt.Sprintf("t%d.test", i))
    159 		}
    160 		for i := 0; i < leaf.emails; i++ {
    161 			leafTemplate.Subject.ExtraNames = append(leafTemplate.Subject.ExtraNames, pkix.AttributeTypeAndValue{
    162 				Type: []int{1, 2, 840, 113549, 1, 9, 1},
    163 				Value: asn1.RawValue{
    164 					Class:      asn1.ClassUniversal,
    165 					Tag:        asn1.TagIA5String,
    166 					IsCompound: false,
    167 					Bytes:      []byte(fmt.Sprintf("t%d@test", i)),
    168 				},
    169 			})
    170 		}
    171 		leafBytes, err := x509.CreateCertificate(rand.Reader, &leafTemplate, ca, &privateKey.PublicKey, privateKey)
    172 		if err != nil {
    173 			panic(err)
    174 		}
    175 
    176 		writePEM(leaf.path, leafBytes)
    177 	}
    178 }
    179