| /* Copyright (c) 2017, Google Inc. |
| * |
| * Permission to use, copy, modify, and/or distribute this software for any |
| * purpose with or without fee is hereby granted, provided that the above |
| * copyright notice and this permission notice appear in all copies. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
| * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
| * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ |
| |
| // make_many_constraints.go generates test certificates many_constraints.pem, |
| // many_names*.pem, and some_names*.pem for x509_test.cc |
| package main |
| |
| import ( |
| "crypto/rand" |
| "crypto/rsa" |
| "crypto/x509" |
| "crypto/x509/pkix" |
| "encoding/asn1" |
| "encoding/pem" |
| "fmt" |
| "math/big" |
| "os" |
| "time" |
| ) |
| |
| const privateKeyPEM = `-----BEGIN PRIVATE KEY----- |
| MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC6C9qEGRIBQXV8 |
| Lj29vVu+U+tyXzSSinWIumK5ijPhCm3DLnv4RayxkFwemtnkGRZ/o94ZnsXkBfU/ |
| IlsYdkuq8wK9WI/ql3gwWjH+KARIhIQcSLGiJcLN6kGuG2nlRBKMcPgPiEq2B0yB |
| XFf4tG3CBbeae7+8G7uvOmv8NLyKj32neWpnUCTL5o2VwyPoxjLxT5gUR69v9XSV |
| Fj2irCZbsEedeKSb++LqyMhLfnRTzNv+ZHNh4izZHrktR25MvnT5QyBq32hx7AjZ |
| 2/xo70OmH7w10a2DwsVjJNMdxTEmgyvU9M6CeYRPX1Ykfg+sXCTtkTVAlBDUviIq |
| Y95CKy25AgMBAAECggEAHPvvxRiqx2tNRFVn5QF1I4erbJwMcrADc5OmAcXYIz0e |
| sIOzaJBiQR9+Wn5BZ9nIuYXr+g3UQpvzAyz1CDCVxUIqsRj1AtUqMk4675+IW0vZ |
| 0RY6Jkq/uJjANsGqk78xLJQE8VaIXSdx8c1THznsx4dgfT6+Ni4T5U6yuA33OZaw |
| 4NdYZYtEkqNiqK6VYe4mAxxVh5qscihVVMGkBVqJNiiEotctm1lph8ow+7o8ggXO |
| W9xm+RHHPcH7Epx7hjkb/helANcYOK950W5/R+2zWV9R6kxo6R+/hfGFFmCvl4k5 |
| +i8Y0IlEv3fze1E0Lwyf379i3C/cKcuaE5gwR54BAQKBgQDxlsNy9M37HgguglHt |
| 8W+cuPNtxNjFCWIjNR9dSvdr1Oi28Z1AY+BBPSv6UBKnT5PpOFjqxfMY/j/zoKdI |
| aYX1phgeQHXcHrB1pS8yoaF/pTJSN2Yb8v9kl/Ch1yeYXaNVGmeBLkH9H6wIcUxD |
| Mas1i8VUzshzhcluCNGoJj9wUQKBgQDFJOoWncssfWCrsuDWEoeU71Zh3+bD96GF |
| s29CdIbHpcbxhWYjA9RM8yxbGPopexzoGcV1HX6j8E1s0xfYZJV23rxoM9Zj9l5D |
| mZAJQPxYXIdu3h4PslhZLd3p+DEHjbsLC/avk3M4iZim1FMPBJMswKSL23ysqXoY |
| /ynor+W06QKBgHYeu6M6NHgCYAe1ai+Hq4WaHFNgOohkJRqHv7USkVSkvb+s9LDl |
| 5GChcx4pBmXNj8ko5rirXkerEEOjGgdaqMfJlOM9qyKb0rVCtYfw5RCPCcKPGZqy |
| vdJGQ74tf0uNBO34QgE0R8lmMevS0XHNGCPPGgV0MSfikvD82N15De1xAoGAbsZM |
| RsMJfAlDPZc4oPEuf/BwMHTYPTsy5map2MSTSzGKdQHJH1myfD6TqOiDALXtyzlX |
| 63PUShfn2YNPvcbe+Tk00rR1/htcYk2yUpDSenAbpZ9ncth6rjmInURZgG4SMKXb |
| SlLnBljCjtN1jFW8wQPKMc/14SslsVAHY3ka8KkCgYB58QNT1YfH3jS62+mT2pXq |
| qLjLqvsD742VYnFoHR+HBOnN8ry0dda4lgwM106L5FgSg9DOZvASZ+QGFk+QVQv+ |
| c77ASWpuhmBmamZCrwZXrq9Xc92RDPkKFqnP9MVv06hYKNp0moSdM8dIaM6uSows |
| /r/aDs4oudubz26o5GDKmA== |
| -----END PRIVATE KEY-----` |
| |
| var privateKey *rsa.PrivateKey |
| |
| func init() { |
| in := []byte(privateKeyPEM) |
| keyBlock, in := pem.Decode(in) |
| if keyBlock == nil || keyBlock.Type != "PRIVATE KEY" { |
| panic("could not decode private key") |
| } |
| key, err := x509.ParsePKCS8PrivateKey(keyBlock.Bytes) |
| if err != nil { |
| panic(err) |
| } |
| privateKey = key.(*rsa.PrivateKey) |
| } |
| |
| func randOrDie(out []byte) { |
| if _, err := rand.Reader.Read(out); err != nil { |
| panic(err) |
| } |
| } |
| |
| func writePEM(path string, in []byte) { |
| file, err := os.Create(path) |
| if err != nil { |
| panic(err) |
| } |
| defer file.Close() |
| err = pem.Encode(file, &pem.Block{Type: "CERTIFICATE", Bytes: in}) |
| if err != nil { |
| panic(err) |
| } |
| } |
| |
| func main() { |
| notBefore, err := time.Parse(time.RFC3339, "2000-01-01T00:00:00Z") |
| if err != nil { |
| panic(err) |
| } |
| notAfter, err := time.Parse(time.RFC3339, "2100-01-01T00:00:00Z") |
| if err != nil { |
| panic(err) |
| } |
| |
| caTemplate := x509.Certificate{ |
| SerialNumber: new(big.Int).SetInt64(1), |
| Subject: pkix.Name{CommonName: "CA"}, |
| NotBefore: notBefore, |
| NotAfter: notAfter, |
| BasicConstraintsValid: true, |
| IsCA: true, |
| ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, |
| KeyUsage: x509.KeyUsageCertSign, |
| SignatureAlgorithm: x509.SHA256WithRSA, |
| } |
| for i := 0; i < 513; i++ { |
| caTemplate.ExcludedDNSDomains = append(caTemplate.ExcludedDNSDomains, fmt.Sprintf("x%d.test", i)) |
| } |
| for i := 0; i < 513; i++ { |
| caTemplate.PermittedDNSDomains = append(caTemplate.PermittedDNSDomains, fmt.Sprintf("t%d.test", i)) |
| } |
| caTemplate.PermittedDNSDomains = append(caTemplate.PermittedDNSDomains, ".test") |
| caBytes, err := x509.CreateCertificate(rand.Reader, &caTemplate, &caTemplate, &privateKey.PublicKey, privateKey) |
| if err != nil { |
| panic(err) |
| } |
| writePEM("many_constraints.pem", caBytes) |
| |
| ca, err := x509.ParseCertificate(caBytes) |
| if err != nil { |
| panic(err) |
| } |
| |
| leaves := []struct { |
| path string |
| names int |
| emails int |
| }{ |
| {"many_names1.pem", 513, 513}, |
| {"many_names2.pem", 1025, 0}, |
| {"many_names3.pem", 1, 1025}, |
| {"some_names1.pem", 256, 256}, |
| {"some_names2.pem", 513, 0}, |
| {"some_names3.pem", 1, 513}, |
| } |
| for i, leaf := range leaves { |
| leafTemplate := x509.Certificate{ |
| SerialNumber: new(big.Int).SetInt64(int64(i + 2)), |
| Subject: pkix.Name{CommonName: "t0.test"}, |
| NotBefore: notBefore, |
| NotAfter: notAfter, |
| BasicConstraintsValid: true, |
| IsCA: false, |
| ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, |
| KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, |
| SignatureAlgorithm: x509.SHA256WithRSA, |
| } |
| for i := 0; i < leaf.names; i++ { |
| leafTemplate.DNSNames = append(leafTemplate.DNSNames, fmt.Sprintf("t%d.test", i)) |
| } |
| for i := 0; i < leaf.emails; i++ { |
| leafTemplate.Subject.ExtraNames = append(leafTemplate.Subject.ExtraNames, pkix.AttributeTypeAndValue{ |
| Type: []int{1, 2, 840, 113549, 1, 9, 1}, |
| Value: asn1.RawValue{ |
| Class: asn1.ClassUniversal, |
| Tag: asn1.TagIA5String, |
| IsCompound: false, |
| Bytes: []byte(fmt.Sprintf("t%d@test", i)), |
| }, |
| }) |
| } |
| leafBytes, err := x509.CreateCertificate(rand.Reader, &leafTemplate, ca, &privateKey.PublicKey, privateKey) |
| if err != nil { |
| panic(err) |
| } |
| |
| writePEM(leaf.path, leafBytes) |
| } |
| } |