• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
17package main
18
19import (
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
32const privateKeyPEM = `-----BEGIN PRIVATE KEY-----
33MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC6C9qEGRIBQXV8
34Lj29vVu+U+tyXzSSinWIumK5ijPhCm3DLnv4RayxkFwemtnkGRZ/o94ZnsXkBfU/
35IlsYdkuq8wK9WI/ql3gwWjH+KARIhIQcSLGiJcLN6kGuG2nlRBKMcPgPiEq2B0yB
36XFf4tG3CBbeae7+8G7uvOmv8NLyKj32neWpnUCTL5o2VwyPoxjLxT5gUR69v9XSV
37Fj2irCZbsEedeKSb++LqyMhLfnRTzNv+ZHNh4izZHrktR25MvnT5QyBq32hx7AjZ
382/xo70OmH7w10a2DwsVjJNMdxTEmgyvU9M6CeYRPX1Ykfg+sXCTtkTVAlBDUviIq
39Y95CKy25AgMBAAECggEAHPvvxRiqx2tNRFVn5QF1I4erbJwMcrADc5OmAcXYIz0e
40sIOzaJBiQR9+Wn5BZ9nIuYXr+g3UQpvzAyz1CDCVxUIqsRj1AtUqMk4675+IW0vZ
410RY6Jkq/uJjANsGqk78xLJQE8VaIXSdx8c1THznsx4dgfT6+Ni4T5U6yuA33OZaw
424NdYZYtEkqNiqK6VYe4mAxxVh5qscihVVMGkBVqJNiiEotctm1lph8ow+7o8ggXO
43W9xm+RHHPcH7Epx7hjkb/helANcYOK950W5/R+2zWV9R6kxo6R+/hfGFFmCvl4k5
44+i8Y0IlEv3fze1E0Lwyf379i3C/cKcuaE5gwR54BAQKBgQDxlsNy9M37HgguglHt
458W+cuPNtxNjFCWIjNR9dSvdr1Oi28Z1AY+BBPSv6UBKnT5PpOFjqxfMY/j/zoKdI
46aYX1phgeQHXcHrB1pS8yoaF/pTJSN2Yb8v9kl/Ch1yeYXaNVGmeBLkH9H6wIcUxD
47Mas1i8VUzshzhcluCNGoJj9wUQKBgQDFJOoWncssfWCrsuDWEoeU71Zh3+bD96GF
48s29CdIbHpcbxhWYjA9RM8yxbGPopexzoGcV1HX6j8E1s0xfYZJV23rxoM9Zj9l5D
49mZAJQPxYXIdu3h4PslhZLd3p+DEHjbsLC/avk3M4iZim1FMPBJMswKSL23ysqXoY
50/ynor+W06QKBgHYeu6M6NHgCYAe1ai+Hq4WaHFNgOohkJRqHv7USkVSkvb+s9LDl
515GChcx4pBmXNj8ko5rirXkerEEOjGgdaqMfJlOM9qyKb0rVCtYfw5RCPCcKPGZqy
52vdJGQ74tf0uNBO34QgE0R8lmMevS0XHNGCPPGgV0MSfikvD82N15De1xAoGAbsZM
53RsMJfAlDPZc4oPEuf/BwMHTYPTsy5map2MSTSzGKdQHJH1myfD6TqOiDALXtyzlX
5463PUShfn2YNPvcbe+Tk00rR1/htcYk2yUpDSenAbpZ9ncth6rjmInURZgG4SMKXb
55SlLnBljCjtN1jFW8wQPKMc/14SslsVAHY3ka8KkCgYB58QNT1YfH3jS62+mT2pXq
56qLjLqvsD742VYnFoHR+HBOnN8ry0dda4lgwM106L5FgSg9DOZvASZ+QGFk+QVQv+
57c77ASWpuhmBmamZCrwZXrq9Xc92RDPkKFqnP9MVv06hYKNp0moSdM8dIaM6uSows
58/r/aDs4oudubz26o5GDKmA==
59-----END PRIVATE KEY-----`
60
61var privateKey *rsa.PrivateKey
62
63func 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
76func randOrDie(out []byte) {
77	if _, err := rand.Reader.Read(out); err != nil {
78		panic(err)
79	}
80}
81
82func 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
94func 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", 1, 1025},
141		{"some_names1.pem", 256, 256},
142		{"some_names2.pem", 513, 0},
143		{"some_names3.pem", 1, 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