github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/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 return 47 } 48 49 var notBefore time.Time 50 if len(*validFrom) == 0 { 51 notBefore = time.Now() 52 } else { 53 notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom) 54 if err != nil { 55 fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err) 56 os.Exit(1) 57 } 58 } 59 60 notAfter := notBefore.Add(*validFor) 61 62 // end of ASN.1 time 63 endOfTime := time.Date(2049, 12, 31, 23, 59, 59, 0, time.UTC) 64 if notAfter.After(endOfTime) { 65 notAfter = endOfTime 66 } 67 68 template := x509.Certificate{ 69 SerialNumber: new(big.Int).SetInt64(0), 70 Subject: pkix.Name{ 71 Organization: []string{"Acme Co"}, 72 }, 73 NotBefore: notBefore, 74 NotAfter: notAfter, 75 76 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, 77 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 78 BasicConstraintsValid: true, 79 } 80 81 hosts := strings.Split(*host, ",") 82 for _, h := range hosts { 83 if ip := net.ParseIP(h); ip != nil { 84 template.IPAddresses = append(template.IPAddresses, ip) 85 } else { 86 template.DNSNames = append(template.DNSNames, h) 87 } 88 } 89 90 if *isCA { 91 template.IsCA = true 92 template.KeyUsage |= x509.KeyUsageCertSign 93 } 94 95 derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) 96 if err != nil { 97 log.Fatalf("Failed to create certificate: %s", err) 98 return 99 } 100 101 certOut, err := os.Create("cert.pem") 102 if err != nil { 103 log.Fatalf("failed to open cert.pem for writing: %s", err) 104 return 105 } 106 pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) 107 certOut.Close() 108 log.Print("written cert.pem\n") 109 110 keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) 111 if err != nil { 112 log.Print("failed to open key.pem for writing:", err) 113 return 114 } 115 pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) 116 keyOut.Close() 117 log.Print("written key.pem\n") 118 }