github.com/gidoBOSSftw5731/go/src@v0.0.0-20210226122457-d24b0edbf019/crypto/tls/generate_cert.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build ignore 6 // +build ignore 7 8 // Generate a self-signed X.509 certificate for a TLS server. Outputs to 9 // 'cert.pem' and 'key.pem' and will overwrite existing files. 10 11 package main 12 13 import ( 14 "crypto/ecdsa" 15 "crypto/ed25519" 16 "crypto/elliptic" 17 "crypto/rand" 18 "crypto/rsa" 19 "crypto/x509" 20 "crypto/x509/pkix" 21 "encoding/pem" 22 "flag" 23 "log" 24 "math/big" 25 "net" 26 "os" 27 "strings" 28 "time" 29 ) 30 31 var ( 32 host = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for") 33 validFrom = flag.String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011") 34 validFor = flag.Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for") 35 isCA = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority") 36 rsaBits = flag.Int("rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set") 37 ecdsaCurve = flag.String("ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256 (recommended), P384, P521") 38 ed25519Key = flag.Bool("ed25519", false, "Generate an Ed25519 key") 39 ) 40 41 func publicKey(priv interface{}) interface{} { 42 switch k := priv.(type) { 43 case *rsa.PrivateKey: 44 return &k.PublicKey 45 case *ecdsa.PrivateKey: 46 return &k.PublicKey 47 case ed25519.PrivateKey: 48 return k.Public().(ed25519.PublicKey) 49 default: 50 return nil 51 } 52 } 53 54 func main() { 55 flag.Parse() 56 57 if len(*host) == 0 { 58 log.Fatalf("Missing required --host parameter") 59 } 60 61 var priv interface{} 62 var err error 63 switch *ecdsaCurve { 64 case "": 65 if *ed25519Key { 66 _, priv, err = ed25519.GenerateKey(rand.Reader) 67 } else { 68 priv, err = rsa.GenerateKey(rand.Reader, *rsaBits) 69 } 70 case "P224": 71 priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader) 72 case "P256": 73 priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 74 case "P384": 75 priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) 76 case "P521": 77 priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) 78 default: 79 log.Fatalf("Unrecognized elliptic curve: %q", *ecdsaCurve) 80 } 81 if err != nil { 82 log.Fatalf("Failed to generate private key: %v", err) 83 } 84 85 // ECDSA, ED25519 and RSA subject keys should have the DigitalSignature 86 // KeyUsage bits set in the x509.Certificate template 87 keyUsage := x509.KeyUsageDigitalSignature 88 // Only RSA subject keys should have the KeyEncipherment KeyUsage bits set. In 89 // the context of TLS this KeyUsage is particular to RSA key exchange and 90 // authentication. 91 if _, isRSA := priv.(*rsa.PrivateKey); isRSA { 92 keyUsage |= x509.KeyUsageKeyEncipherment 93 } 94 95 var notBefore time.Time 96 if len(*validFrom) == 0 { 97 notBefore = time.Now() 98 } else { 99 notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom) 100 if err != nil { 101 log.Fatalf("Failed to parse creation date: %v", err) 102 } 103 } 104 105 notAfter := notBefore.Add(*validFor) 106 107 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 108 serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) 109 if err != nil { 110 log.Fatalf("Failed to generate serial number: %v", err) 111 } 112 113 template := x509.Certificate{ 114 SerialNumber: serialNumber, 115 Subject: pkix.Name{ 116 Organization: []string{"Acme Co"}, 117 }, 118 NotBefore: notBefore, 119 NotAfter: notAfter, 120 121 KeyUsage: keyUsage, 122 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 123 BasicConstraintsValid: true, 124 } 125 126 hosts := strings.Split(*host, ",") 127 for _, h := range hosts { 128 if ip := net.ParseIP(h); ip != nil { 129 template.IPAddresses = append(template.IPAddresses, ip) 130 } else { 131 template.DNSNames = append(template.DNSNames, h) 132 } 133 } 134 135 if *isCA { 136 template.IsCA = true 137 template.KeyUsage |= x509.KeyUsageCertSign 138 } 139 140 derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) 141 if err != nil { 142 log.Fatalf("Failed to create certificate: %v", err) 143 } 144 145 certOut, err := os.Create("cert.pem") 146 if err != nil { 147 log.Fatalf("Failed to open cert.pem for writing: %v", err) 148 } 149 if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil { 150 log.Fatalf("Failed to write data to cert.pem: %v", err) 151 } 152 if err := certOut.Close(); err != nil { 153 log.Fatalf("Error closing cert.pem: %v", err) 154 } 155 log.Print("wrote cert.pem\n") 156 157 keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) 158 if err != nil { 159 log.Fatalf("Failed to open key.pem for writing: %v", err) 160 return 161 } 162 privBytes, err := x509.MarshalPKCS8PrivateKey(priv) 163 if err != nil { 164 log.Fatalf("Unable to marshal private key: %v", err) 165 } 166 if err := pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil { 167 log.Fatalf("Failed to write data to key.pem: %v", err) 168 } 169 if err := keyOut.Close(); err != nil { 170 log.Fatalf("Error closing key.pem: %v", err) 171 } 172 log.Print("wrote key.pem\n") 173 }