diff options
author | Steve <nilslice@gmail.com> | 2016-12-28 16:23:44 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-28 16:23:44 -0800 |
commit | 806fdbe1e8839feb1bcc4e5e07aa7c144a429901 (patch) | |
tree | dacaed91abb57bc6891c1b2cb58a82fc0c9610fc /system/tls/devcerts.go | |
parent | 1f7a5b46b906da00ceccb03e7ff26627bb29a3dd (diff) | |
parent | 5c340ca57e876a556a5b57e5a7dd32b0ae288440 (diff) |
Merge pull request #26 from ponzu-cms/ponzu-dev
[tooling] Add Go command flag, auto-generate self-signed SSL for development
Diffstat (limited to 'system/tls/devcerts.go')
-rw-r--r-- | system/tls/devcerts.go | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/system/tls/devcerts.go b/system/tls/devcerts.go new file mode 100644 index 0000000..b41f099 --- /dev/null +++ b/system/tls/devcerts.go @@ -0,0 +1,148 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Modified 2016 by Steve Manuel, Boss Sauce Creative, LLC +// All modifications are relicensed under the same BSD license +// found in the LICENSE file. + +// Generate a self-signed X.509 certificate for a TLS server. Outputs to +// 'devcerts/cert.pem' and 'devcerts/key.pem' and will overwrite existing files. + +package tls + +import ( + "crypto/ecdsa" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "fmt" + "log" + "math/big" + "net" + "os" + "path/filepath" + "time" + + "github.com/ponzu-cms/ponzu/system/db" +) + +func publicKey(priv interface{}) interface{} { + switch k := priv.(type) { + case *rsa.PrivateKey: + return &k.PublicKey + case *ecdsa.PrivateKey: + return &k.PublicKey + default: + return nil + } +} + +func pemBlockForKey(priv interface{}) *pem.Block { + switch k := priv.(type) { + case *rsa.PrivateKey: + return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)} + case *ecdsa.PrivateKey: + b, err := x509.MarshalECPrivateKey(k) + if err != nil { + fmt.Fprintf(os.Stderr, "Unable to marshal ECDSA private key: %v", err) + os.Exit(2) + } + return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b} + default: + return nil + } +} + +func setupDev() { + var priv interface{} + var err error + + priv, err = rsa.GenerateKey(rand.Reader, 2048) + + if err != nil { + log.Fatalf("failed to generate private key: %s", err) + } + + notBefore := time.Now() + notAfter := notBefore.Add(time.Hour * 24 * 30) // valid for 30 days + + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + log.Fatalf("failed to generate serial number: %s", err) + } + + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + Organization: []string{"Ponzu Dev Server"}, + }, + NotBefore: notBefore, + NotAfter: notAfter, + + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + } + + hosts := []string{"localhost", "0.0.0.0"} + domain := db.ConfigCache("domain") + if domain != "" { + hosts = append(hosts, domain) + } + + for _, h := range hosts { + if ip := net.ParseIP(h); ip != nil { + template.IPAddresses = append(template.IPAddresses, ip) + } else { + template.DNSNames = append(template.DNSNames, h) + } + } + + // make all certs CA + template.IsCA = true + template.KeyUsage |= x509.KeyUsageCertSign + + derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) + if err != nil { + log.Fatalln("Failed to create certificate:", err) + } + + // overwrite/create directory for devcerts + pwd, err := os.Getwd() + if err != nil { + log.Fatalln("Couldn't find working directory to locate or save dev certificates:", err) + } + + vendorTLSPath := filepath.Join(pwd, "cmd", "ponzu", "vendor", "github.com", "ponzu-cms", "ponzu", "system", "tls") + devcertsPath := filepath.Join(vendorTLSPath, "devcerts") + + // clear all old certs if found + err = os.RemoveAll(devcertsPath) + if err != nil { + log.Fatalln("Failed to remove old files from dev certificate directory:", err) + } + + err = os.Mkdir(devcertsPath, os.ModePerm|os.ModePerm) + if err != nil { + log.Fatalln("Failed to create directory to locate or save dev certificates:", err) + } + + certOut, err := os.Create(filepath.Join(devcertsPath, "cert.pem")) + if err != nil { + log.Fatalln("Failed to open devcerts/cert.pem for writing:", err) + } + pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) + certOut.Close() + + keyOut, err := os.OpenFile(filepath.Join(devcertsPath, "key.pem"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + log.Fatalln("Failed to open devcerts/key.pem for writing:", err) + return + } + pem.Encode(keyOut, pemBlockForKey(priv)) + keyOut.Close() +} |