github.com/smoorpal/witchcraft-go-server@v1.12.0/integration/testdata/generator.go (about) 1 // Copyright (c) 2018 Palantir Technologies. All rights reserved. 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 // http://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:generate go run $GOFILE 16 17 // package main writes the crypto material used by unit tests. Run using "go generate". 18 package main 19 20 import ( 21 "bytes" 22 "crypto/rand" 23 "crypto/rsa" 24 "crypto/x509" 25 "crypto/x509/pkix" 26 "encoding/pem" 27 "io/ioutil" 28 "math/big" 29 "net" 30 "os" 31 "time" 32 ) 33 34 const ( 35 caCertFile = "ca-cert.pem" 36 caKeyFile = "ca-key.pem" 37 serverCertFile = "server-cert.pem" 38 serverKeyFile = "server-key.pem" 39 clientCertFile = "client-cert.pem" 40 clientKeyFile = "client-key.pem" 41 ) 42 43 var ( 44 serverTemplate = x509.Certificate{ 45 NotBefore: time.Now(), 46 NotAfter: time.Now().Add(10 * 365 * 24 * time.Hour), 47 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, 48 BasicConstraintsValid: true, 49 DNSNames: []string{"localhost"}, 50 IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1)}, 51 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 52 } 53 clientTemplate = x509.Certificate{ 54 NotBefore: time.Now(), 55 NotAfter: time.Now().Add(10 * 365 * 24 * time.Hour), 56 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, 57 BasicConstraintsValid: true, 58 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, 59 } 60 ) 61 62 func main() { 63 caCertStr, caKeyStr := newCAKeyPair(1, "Root CA") 64 block, _ := pem.Decode([]byte(caCertStr)) 65 if block == nil { 66 panic("failed to parse certificate PEM") 67 } 68 caCert, err := x509.ParseCertificate(block.Bytes) 69 if err != nil { 70 panic(err) 71 } 72 73 serverCertStr, serverKeyStr := newSignedKeyPair(2, "Test Org", "localhost", &serverTemplate, caCert, caKeyStr) 74 clientCertStr, clientKeyStr := newSignedKeyPair(3, "Test Org", "client", &clientTemplate, caCert, caKeyStr) 75 76 mustWriteFile(caCertFile, []byte(caCertStr), 0644) 77 mustWriteFile(caKeyFile, []byte(caKeyStr), 0644) 78 79 mustWriteFile(serverCertFile, []byte(serverCertStr), 0644) 80 mustWriteFile(serverKeyFile, []byte(serverKeyStr), 0644) 81 82 mustWriteFile(clientCertFile, []byte(clientCertStr), 0644) 83 mustWriteFile(clientKeyFile, []byte(clientKeyStr), 0644) 84 } 85 86 func mustWriteFile(filename string, data []byte, perm os.FileMode) { 87 if err := ioutil.WriteFile(filename, data, perm); err != nil { 88 panic(err) 89 } 90 } 91 92 func newCAKeyPair(serial int64, org string) (string, string) { 93 caTemplate := &x509.Certificate{ 94 SerialNumber: big.NewInt(serial), 95 Subject: pkix.Name{ 96 Organization: []string{org}, 97 }, 98 NotBefore: time.Now(), 99 NotAfter: time.Now().Add(10 * 365 * 24 * time.Hour), 100 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, 101 BasicConstraintsValid: true, 102 IsCA: true, 103 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageAny}, 104 } 105 privKey, err := rsa.GenerateKey(rand.Reader, 2048) 106 if err != nil { 107 panic(err) 108 } 109 certDERBytes, err := x509.CreateCertificate(rand.Reader, caTemplate, caTemplate, &privKey.PublicKey, privKey) 110 if err != nil { 111 panic(err) 112 } 113 keyDERBytes := x509.MarshalPKCS1PrivateKey(privKey) 114 return derBytesToStrings(certDERBytes, keyDERBytes) 115 } 116 117 func newSignedKeyPair(serial int64, org, cn string, template, caCert *x509.Certificate, caPrivKey string) (string, string) { 118 block, _ := pem.Decode([]byte(caPrivKey)) 119 if block == nil { 120 panic("failed to parse certificate PEM") 121 } 122 signingPrivKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) 123 if err != nil { 124 panic(err) 125 } 126 127 privKey, err := rsa.GenerateKey(rand.Reader, 2048) 128 if err != nil { 129 panic(err) 130 } 131 132 tmplCopy := *template 133 tmplCopy.SerialNumber = big.NewInt(serial) 134 tmplCopy.Subject = pkix.Name{ 135 Organization: []string{org}, 136 CommonName: cn, 137 } 138 139 certDERBytes, err := x509.CreateCertificate(rand.Reader, &tmplCopy, caCert, &privKey.PublicKey, signingPrivKey) 140 if err != nil { 141 panic(err) 142 } 143 144 return derBytesToStrings(certDERBytes, x509.MarshalPKCS1PrivateKey(privKey)) 145 } 146 147 func derBytesToStrings(certDERBytes, keyDERBytes []byte) (string, string) { 148 var certBuf bytes.Buffer 149 if err := pem.Encode(&certBuf, &pem.Block{Type: "CERTIFICATE", Bytes: certDERBytes}); err != nil { 150 panic(err) 151 } 152 var keyBuf bytes.Buffer 153 if err := pem.Encode(&keyBuf, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: keyDERBytes}); err != nil { 154 panic(err) 155 } 156 return certBuf.String(), keyBuf.String() 157 }