github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/pkg/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 // +build ignore 6 7 // Generate a self-signed X.509 certificate for a TLS server. Outputs to 8 // 'cert.pem' and 'key.pem' and will overwrite existing files. 9 10 package main 11 12 import ( 13 "crypto/rand" 14 "crypto/rsa" 15 "crypto/x509" 16 "crypto/x509/pkix" 17 "encoding/pem" 18 "flag" 19 "fmt" 20 "log" 21 "math/big" 22 "net" 23 "os" 24 "strings" 25 "time" 26 ) 27 28 var ( 29 host = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for") 30 validFrom = flag.String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011") 31 validFor = flag.Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for") 32 isCA = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority") 33 rsaBits = flag.Int("rsa-bits", 2048, "Size of RSA key to generate") 34 ) 35 36 func main() { 37 flag.Parse() 38 39 if len(*host) == 0 { 40 log.Fatalf("Missing required --host parameter") 41 } 42 43 priv, err := rsa.GenerateKey(rand.Reader, *rsaBits) 44 if err != nil { 45 log.Fatalf("failed to generate private key: %s", err) 46 } 47 48 var notBefore time.Time 49 if len(*validFrom) == 0 { 50 notBefore = time.Now() 51 } else { 52 notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom) 53 if err != nil { 54 fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err) 55 os.Exit(1) 56 } 57 } 58 59 notAfter := notBefore.Add(*validFor) 60 61 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 62 serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) 63 if err != nil { 64 log.Fatalf("failed to generate serial number: %s", err) 65 } 66 67 template := x509.Certificate{ 68 SerialNumber: serialNumber, 69 Subject: pkix.Name{ 70 Organization: []string{"Acme Co"}, 71 }, 72 NotBefore: notBefore, 73 NotAfter: notAfter, 74 75 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, 76 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 77 BasicConstraintsValid: true, 78 } 79 80 hosts := strings.Split(*host, ",") 81 for _, h := range hosts { 82 if ip := net.ParseIP(h); ip != nil { 83 template.IPAddresses = append(template.IPAddresses, ip) 84 } else { 85 template.DNSNames = append(template.DNSNames, h) 86 } 87 } 88 89 if *isCA { 90 template.IsCA = true 91 template.KeyUsage |= x509.KeyUsageCertSign 92 } 93 94 derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) 95 if err != nil { 96 log.Fatalf("Failed to create certificate: %s", err) 97 } 98 99 certOut, err := os.Create("cert.pem") 100 if err != nil { 101 log.Fatalf("failed to open cert.pem for writing: %s", err) 102 } 103 pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) 104 certOut.Close() 105 log.Print("written cert.pem\n") 106 107 keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) 108 if err != nil { 109 log.Print("failed to open key.pem for writing:", err) 110 return 111 } 112 pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) 113 keyOut.Close() 114 log.Print("written key.pem\n") 115 }