1// Copyright 2017 The BoringSSL Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//go:build ignore
16
17// make_many_constraints.go generates test certificates many_constraints.pem,
18// many_names*.pem, and some_names*.pem for x509_test.cc
19package main
20
21import (
22	"crypto/rand"
23	"crypto/rsa"
24	"crypto/x509"
25	"crypto/x509/pkix"
26	"encoding/asn1"
27	"encoding/pem"
28	"fmt"
29	"math/big"
30	"os"
31	"time"
32)
33
34const privateKeyPEM = `-----BEGIN PRIVATE KEY-----
35MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC6C9qEGRIBQXV8
36Lj29vVu+U+tyXzSSinWIumK5ijPhCm3DLnv4RayxkFwemtnkGRZ/o94ZnsXkBfU/
37IlsYdkuq8wK9WI/ql3gwWjH+KARIhIQcSLGiJcLN6kGuG2nlRBKMcPgPiEq2B0yB
38XFf4tG3CBbeae7+8G7uvOmv8NLyKj32neWpnUCTL5o2VwyPoxjLxT5gUR69v9XSV
39Fj2irCZbsEedeKSb++LqyMhLfnRTzNv+ZHNh4izZHrktR25MvnT5QyBq32hx7AjZ
402/xo70OmH7w10a2DwsVjJNMdxTEmgyvU9M6CeYRPX1Ykfg+sXCTtkTVAlBDUviIq
41Y95CKy25AgMBAAECggEAHPvvxRiqx2tNRFVn5QF1I4erbJwMcrADc5OmAcXYIz0e
42sIOzaJBiQR9+Wn5BZ9nIuYXr+g3UQpvzAyz1CDCVxUIqsRj1AtUqMk4675+IW0vZ
430RY6Jkq/uJjANsGqk78xLJQE8VaIXSdx8c1THznsx4dgfT6+Ni4T5U6yuA33OZaw
444NdYZYtEkqNiqK6VYe4mAxxVh5qscihVVMGkBVqJNiiEotctm1lph8ow+7o8ggXO
45W9xm+RHHPcH7Epx7hjkb/helANcYOK950W5/R+2zWV9R6kxo6R+/hfGFFmCvl4k5
46+i8Y0IlEv3fze1E0Lwyf379i3C/cKcuaE5gwR54BAQKBgQDxlsNy9M37HgguglHt
478W+cuPNtxNjFCWIjNR9dSvdr1Oi28Z1AY+BBPSv6UBKnT5PpOFjqxfMY/j/zoKdI
48aYX1phgeQHXcHrB1pS8yoaF/pTJSN2Yb8v9kl/Ch1yeYXaNVGmeBLkH9H6wIcUxD
49Mas1i8VUzshzhcluCNGoJj9wUQKBgQDFJOoWncssfWCrsuDWEoeU71Zh3+bD96GF
50s29CdIbHpcbxhWYjA9RM8yxbGPopexzoGcV1HX6j8E1s0xfYZJV23rxoM9Zj9l5D
51mZAJQPxYXIdu3h4PslhZLd3p+DEHjbsLC/avk3M4iZim1FMPBJMswKSL23ysqXoY
52/ynor+W06QKBgHYeu6M6NHgCYAe1ai+Hq4WaHFNgOohkJRqHv7USkVSkvb+s9LDl
535GChcx4pBmXNj8ko5rirXkerEEOjGgdaqMfJlOM9qyKb0rVCtYfw5RCPCcKPGZqy
54vdJGQ74tf0uNBO34QgE0R8lmMevS0XHNGCPPGgV0MSfikvD82N15De1xAoGAbsZM
55RsMJfAlDPZc4oPEuf/BwMHTYPTsy5map2MSTSzGKdQHJH1myfD6TqOiDALXtyzlX
5663PUShfn2YNPvcbe+Tk00rR1/htcYk2yUpDSenAbpZ9ncth6rjmInURZgG4SMKXb
57SlLnBljCjtN1jFW8wQPKMc/14SslsVAHY3ka8KkCgYB58QNT1YfH3jS62+mT2pXq
58qLjLqvsD742VYnFoHR+HBOnN8ry0dda4lgwM106L5FgSg9DOZvASZ+QGFk+QVQv+
59c77ASWpuhmBmamZCrwZXrq9Xc92RDPkKFqnP9MVv06hYKNp0moSdM8dIaM6uSows
60/r/aDs4oudubz26o5GDKmA==
61-----END PRIVATE KEY-----`
62
63var privateKey *rsa.PrivateKey
64
65func init() {
66	in := []byte(privateKeyPEM)
67	keyBlock, in := pem.Decode(in)
68	if keyBlock == nil || keyBlock.Type != "PRIVATE KEY" {
69		panic("could not decode private key")
70	}
71	key, err := x509.ParsePKCS8PrivateKey(keyBlock.Bytes)
72	if err != nil {
73		panic(err)
74	}
75	privateKey = key.(*rsa.PrivateKey)
76}
77
78func randOrDie(out []byte) {
79	if _, err := rand.Reader.Read(out); err != nil {
80		panic(err)
81	}
82}
83
84func writePEM(path string, in []byte) {
85	file, err := os.Create(path)
86	if err != nil {
87		panic(err)
88	}
89	defer file.Close()
90	err = pem.Encode(file, &pem.Block{Type: "CERTIFICATE", Bytes: in})
91	if err != nil {
92		panic(err)
93	}
94}
95
96func main() {
97	notBefore, err := time.Parse(time.RFC3339, "2000-01-01T00:00:00Z")
98	if err != nil {
99		panic(err)
100	}
101	notAfter, err := time.Parse(time.RFC3339, "2100-01-01T00:00:00Z")
102	if err != nil {
103		panic(err)
104	}
105
106	caTemplate := x509.Certificate{
107		SerialNumber:          new(big.Int).SetInt64(1),
108		Subject:               pkix.Name{CommonName: "CA"},
109		NotBefore:             notBefore,
110		NotAfter:              notAfter,
111		BasicConstraintsValid: true,
112		IsCA:                  true,
113		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
114		KeyUsage:              x509.KeyUsageCertSign,
115		SignatureAlgorithm:    x509.SHA256WithRSA,
116	}
117	for i := 0; i < 513; i++ {
118		caTemplate.ExcludedDNSDomains = append(caTemplate.ExcludedDNSDomains, fmt.Sprintf("x%d.test", i))
119	}
120	for i := 0; i < 513; i++ {
121		caTemplate.PermittedDNSDomains = append(caTemplate.PermittedDNSDomains, fmt.Sprintf("t%d.test", i))
122	}
123	caTemplate.PermittedDNSDomains = append(caTemplate.PermittedDNSDomains, ".test")
124	caBytes, err := x509.CreateCertificate(rand.Reader, &caTemplate, &caTemplate, &privateKey.PublicKey, privateKey)
125	if err != nil {
126		panic(err)
127	}
128	writePEM("many_constraints.pem", caBytes)
129
130	ca, err := x509.ParseCertificate(caBytes)
131	if err != nil {
132		panic(err)
133	}
134
135	leaves := []struct {
136		path   string
137		names  int
138		emails int
139	}{
140		{"many_names1.pem", 513, 513},
141		{"many_names2.pem", 1025, 0},
142		{"many_names3.pem", 1, 1025},
143		{"some_names1.pem", 256, 256},
144		{"some_names2.pem", 513, 0},
145		{"some_names3.pem", 1, 513},
146	}
147	for i, leaf := range leaves {
148		leafTemplate := x509.Certificate{
149			SerialNumber:          new(big.Int).SetInt64(int64(i + 2)),
150			Subject:               pkix.Name{CommonName: "t0.test"},
151			NotBefore:             notBefore,
152			NotAfter:              notAfter,
153			BasicConstraintsValid: true,
154			IsCA:                  false,
155			ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
156			KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
157			SignatureAlgorithm:    x509.SHA256WithRSA,
158		}
159		for i := 0; i < leaf.names; i++ {
160			leafTemplate.DNSNames = append(leafTemplate.DNSNames, fmt.Sprintf("t%d.test", i))
161		}
162		for i := 0; i < leaf.emails; i++ {
163			leafTemplate.Subject.ExtraNames = append(leafTemplate.Subject.ExtraNames, pkix.AttributeTypeAndValue{
164				Type: []int{1, 2, 840, 113549, 1, 9, 1},
165				Value: asn1.RawValue{
166					Class:      asn1.ClassUniversal,
167					Tag:        asn1.TagIA5String,
168					IsCompound: false,
169					Bytes:      []byte(fmt.Sprintf("t%d@test", i)),
170				},
171			})
172		}
173		leafBytes, err := x509.CreateCertificate(rand.Reader, &leafTemplate, ca, &privateKey.PublicKey, privateKey)
174		if err != nil {
175			panic(err)
176		}
177
178		writePEM(leaf.path, leafBytes)
179	}
180}
181