github.com/rpdict/ponzu@v0.10.1-0.20190226054626-477f29d6bf5e/system/tls/devcerts.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 // Modified 2016 by Steve Manuel, Boss Sauce Creative, LLC 6 // All modifications are relicensed under the same BSD license 7 // found in the LICENSE file. 8 9 // Generate a self-signed X.509 certificate for a TLS server. Outputs to 10 // 'devcerts/cert.pem' and 'devcerts/key.pem' and will overwrite existing files. 11 12 package tls 13 14 import ( 15 "crypto/ecdsa" 16 "crypto/rand" 17 "crypto/rsa" 18 "crypto/x509" 19 "crypto/x509/pkix" 20 "encoding/pem" 21 "fmt" 22 "log" 23 "math/big" 24 "net" 25 "os" 26 "path/filepath" 27 "time" 28 29 "github.com/rpdict/ponzu/system/db" 30 ) 31 32 func publicKey(priv interface{}) interface{} { 33 switch k := priv.(type) { 34 case *rsa.PrivateKey: 35 return &k.PublicKey 36 case *ecdsa.PrivateKey: 37 return &k.PublicKey 38 default: 39 return nil 40 } 41 } 42 43 func pemBlockForKey(priv interface{}) *pem.Block { 44 switch k := priv.(type) { 45 case *rsa.PrivateKey: 46 return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)} 47 case *ecdsa.PrivateKey: 48 b, err := x509.MarshalECPrivateKey(k) 49 if err != nil { 50 fmt.Fprintf(os.Stderr, "Unable to marshal ECDSA private key: %v", err) 51 os.Exit(2) 52 } 53 return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b} 54 default: 55 return nil 56 } 57 } 58 59 func setupDev() { 60 var priv interface{} 61 var err error 62 63 priv, err = rsa.GenerateKey(rand.Reader, 2048) 64 65 if err != nil { 66 log.Fatalf("failed to generate private key: %s", err) 67 } 68 69 notBefore := time.Now() 70 notAfter := notBefore.Add(time.Hour * 24 * 30) // valid for 30 days 71 72 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 73 serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) 74 if err != nil { 75 log.Fatalf("failed to generate serial number: %s", err) 76 } 77 78 template := x509.Certificate{ 79 SerialNumber: serialNumber, 80 Subject: pkix.Name{ 81 Organization: []string{"Ponzu Dev Server"}, 82 }, 83 NotBefore: notBefore, 84 NotAfter: notAfter, 85 86 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, 87 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 88 BasicConstraintsValid: true, 89 } 90 91 hosts := []string{"localhost", "0.0.0.0"} 92 domain := db.ConfigCache("domain").(string) 93 if domain != "" { 94 hosts = append(hosts, domain) 95 } 96 97 for _, h := range hosts { 98 if ip := net.ParseIP(h); ip != nil { 99 template.IPAddresses = append(template.IPAddresses, ip) 100 } else { 101 template.DNSNames = append(template.DNSNames, h) 102 } 103 } 104 105 // make all certs CA 106 template.IsCA = true 107 template.KeyUsage |= x509.KeyUsageCertSign 108 109 derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) 110 if err != nil { 111 log.Fatalln("Failed to create certificate:", err) 112 } 113 114 // overwrite/create directory for devcerts 115 pwd, err := os.Getwd() 116 if err != nil { 117 log.Fatalln("Couldn't find working directory to locate or save dev certificates:", err) 118 } 119 120 vendorTLSPath := filepath.Join(pwd, "cmd", "ponzu", "vendor", "github.com", "rpdict", "ponzu", "system", "tls") 121 devcertsPath := filepath.Join(vendorTLSPath, "devcerts") 122 123 // clear all old certs if found 124 err = os.RemoveAll(devcertsPath) 125 if err != nil { 126 log.Fatalln("Failed to remove old files from dev certificate directory:", err) 127 } 128 129 err = os.Mkdir(devcertsPath, os.ModeDir|os.ModePerm) 130 if err != nil { 131 log.Fatalln("Failed to create directory to locate or save dev certificates:", err) 132 } 133 134 certOut, err := os.Create(filepath.Join(devcertsPath, "cert.pem")) 135 if err != nil { 136 log.Fatalln("Failed to open devcerts/cert.pem for writing:", err) 137 } 138 pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) 139 certOut.Close() 140 141 keyOut, err := os.OpenFile(filepath.Join(devcertsPath, "key.pem"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) 142 if err != nil { 143 log.Fatalln("Failed to open devcerts/key.pem for writing:", err) 144 return 145 } 146 pem.Encode(keyOut, pemBlockForKey(priv)) 147 keyOut.Close() 148 }