Skip to content

Commit

Permalink
Refactor output path flags
Browse files Browse the repository at this point in the history
  • Loading branch information
FiloSottile committed Jan 7, 2019
1 parent 5ea72c3 commit da4da8a
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 127 deletions.
78 changes: 34 additions & 44 deletions cert.go
Expand Up @@ -12,7 +12,6 @@ import (
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"errors"
"io/ioutil"
"log"
"math/big"
Expand Down Expand Up @@ -40,34 +39,6 @@ func init() {
userAndHostname += strings.TrimSpace(string(out))
}

// getFileName generate file name according to flags
func (m *mkcert) getFileName(w string, args []string) (name string, err error) {
filename := strings.Replace(args[0], ":", "_", -1)
filename = strings.Replace(filename, "*", "_wildcard", -1)
if len(args) > 1 {
filename += "+" + strconv.Itoa(len(args)-1)
}
switch w {
case "key":
if m.keyFileFlag != "" {
return m.keyFileFlag, nil
}
return filename + "-key.pem", nil
case "cert":
if m.certFileFlag != "" {
return m.certFileFlag, nil
}
return filename + ".pem", nil
case "p12":
if m.p12FileFlag != "" {
return m.p12FileFlag, nil
}
return filename + ".p12", nil
default:
return "", errors.New("failed to generate file name")
}
}

func (m *mkcert) makeCert(hosts []string) {
if m.caKey == nil {
log.Fatalln("ERROR: can't create new certificates because the CA key (rootCA-key.pem) is missing")
Expand Down Expand Up @@ -105,28 +76,24 @@ func (m *mkcert) makeCert(hosts []string) {
pub := priv.PublicKey
cert, err := x509.CreateCertificate(rand.Reader, tpl, m.caCert, &pub, m.caKey)
fatalIfErr(err, "failed to generate certificate")
var keyname, certname, p12name string

certFile, keyFile, p12File := m.fileNames(hosts)

if !m.pkcs12 {
privDER, err := x509.MarshalPKCS8PrivateKey(priv)
fatalIfErr(err, "failed to encode certificate key")
keyname, err = m.getFileName("key", hosts)
fatalIfErr(err, "failed to generate key file name")
err = ioutil.WriteFile(keyname, pem.EncodeToMemory(
err = ioutil.WriteFile(keyFile, pem.EncodeToMemory(
&pem.Block{Type: "PRIVATE KEY", Bytes: privDER}), 0600)
fatalIfErr(err, "failed to save certificate key")

certname, err = m.getFileName("cert", hosts)
fatalIfErr(err, "failed to generate cert file name")
err = ioutil.WriteFile(certname, pem.EncodeToMemory(
err = ioutil.WriteFile(certFile, pem.EncodeToMemory(
&pem.Block{Type: "CERTIFICATE", Bytes: cert}), 0644)
fatalIfErr(err, "failed to save certificate key")
} else {
domainCert, _ := x509.ParseCertificate(cert)
pfxData, err := pkcs12.Encode(rand.Reader, priv, domainCert, []*x509.Certificate{m.caCert}, "changeit")
fatalIfErr(err, "failed to generate PKCS#12")
p12name, err = m.getFileName("p12", hosts)
fatalIfErr(err, "failed to generate cert PKCS#12 file name")
err = ioutil.WriteFile(p12name, pfxData, 0644)
err = ioutil.WriteFile(p12File, pfxData, 0644)
fatalIfErr(err, "failed to save PKCS#12")
}

Expand All @@ -147,13 +114,36 @@ func (m *mkcert) makeCert(hosts []string) {
}

if !m.pkcs12 {
log.Printf("\nThe certificate is at \"./%s\" and the key at \"./%s\"\n\n", certname, keyname)
log.Printf("\nThe certificate is at \"%s\" and the key at \"%s\"\n\n", certFile, keyFile)
} else {
log.Printf("\nThe PKCS#12 bundle is at \"./%s\"\n", p12name)
log.Printf("\nThe PKCS#12 bundle is at \"%s\"\n", p12File)
log.Printf("\nThe legacy PKCS#12 encryption password is the often hardcoded default \"changeit\" ℹ️\n\n")
}
}

func (m *mkcert) fileNames(hosts []string) (certFile, keyFile, p12File string) {
defaultName := strings.Replace(hosts[0], ":", "_", -1)
defaultName = strings.Replace(defaultName, "*", "_wildcard", -1)
if len(hosts) > 1 {
defaultName += "+" + strconv.Itoa(len(hosts)-1)
}

certFile = "./" + defaultName + ".pem"
if m.certFile != "" {
certFile = m.certFile
}
keyFile = "./" + defaultName + "-key.pem"
if m.keyFile != "" {
keyFile = m.keyFile
}
p12File = "./" + defaultName + ".p12"
if m.p12File != "" {
p12File = m.p12File
}

return
}

// loadCA will load or create the CA at CAROOT.
func (m *mkcert) loadCA() {
if _, err := os.Stat(filepath.Join(m.CAROOT, rootName)); os.IsNotExist(err) {
Expand All @@ -171,11 +161,11 @@ func (m *mkcert) loadCA() {
m.caCert, err = x509.ParseCertificate(certDERBlock.Bytes)
fatalIfErr(err, "failed to parse the CA certificate")

if _, err := os.Stat(filepath.Join(m.CAROOT, keyName)); os.IsNotExist(err) {
if _, err := os.Stat(filepath.Join(m.CAROOT, rootKeyName)); os.IsNotExist(err) {
return // keyless mode, where only -install works
}

keyPEMBlock, err := ioutil.ReadFile(filepath.Join(m.CAROOT, keyName))
keyPEMBlock, err := ioutil.ReadFile(filepath.Join(m.CAROOT, rootKeyName))
fatalIfErr(err, "failed to read the CA key")
keyDERBlock, _ := pem.Decode(keyPEMBlock)
if keyDERBlock == nil || keyDERBlock.Type != "PRIVATE KEY" {
Expand Down Expand Up @@ -234,7 +224,7 @@ func (m *mkcert) newCA() {

privDER, err := x509.MarshalPKCS8PrivateKey(priv)
fatalIfErr(err, "failed to encode CA key")
err = ioutil.WriteFile(filepath.Join(m.CAROOT, keyName), pem.EncodeToMemory(
err = ioutil.WriteFile(filepath.Join(m.CAROOT, rootKeyName), pem.EncodeToMemory(
&pem.Block{Type: "PRIVATE KEY", Bytes: privDER}), 0400)
fatalIfErr(err, "failed to save CA key")

Expand Down
72 changes: 0 additions & 72 deletions cert_test.go

This file was deleted.

21 changes: 10 additions & 11 deletions main.go
Expand Up @@ -40,6 +40,8 @@ const usage = `Usage of mkcert:
$ mkcert -uninstall
Uninstall the local CA (but do not delete it).
Use -cert-file, -key-file and -p12-file to customize the output paths.
Change the CA certificate and key storage location by setting $CAROOT,
print it with "mkcert -CAROOT".
`
Expand All @@ -50,10 +52,9 @@ func main() {
var uninstallFlag = flag.Bool("uninstall", false, "uninstall the local root CA from the system trust store")
var pkcs12Flag = flag.Bool("pkcs12", false, "generate PKCS#12 instead of PEM")
var carootFlag = flag.Bool("CAROOT", false, "print the CAROOT path")
// customize file name according to issue#72
var keyFileFlag = flag.String("key-file", "", "customlize your key file name")
var certFileFlag = flag.String("cert-file", "", "customlize your cert file name")
var p12FileFlag = flag.String("p12-file", "", "customlize your p12 file name")
var certFileFlag = flag.String("cert-file", "", "output certificate file path")
var keyFileFlag = flag.String("key-file", "", "output key file path")
var p12FileFlag = flag.String("p12-file", "", "output PKCS#12 file path")
flag.Usage = func() { fmt.Fprintf(flag.CommandLine.Output(), usage) }
flag.Parse()
if *carootFlag {
Expand All @@ -68,19 +69,17 @@ func main() {
}
(&mkcert{
installMode: *installFlag, uninstallMode: *uninstallFlag, pkcs12: *pkcs12Flag,
keyFileFlag: *keyFileFlag,
certFileFlag: *certFileFlag,
p12FileFlag: *p12FileFlag,
certFile: *certFileFlag, keyFile: *keyFileFlag, p12File: *p12FileFlag,
}).Run(flag.Args())
}

const rootName = "rootCA.pem"
const keyName = "rootCA-key.pem"
const rootKeyName = "rootCA-key.pem"

type mkcert struct {
installMode, uninstallMode bool
pkcs12 bool
keyFileFlag, certFileFlag, p12FileFlag string
installMode, uninstallMode bool
pkcs12 bool
keyFile, certFile, p12File string

CAROOT string
caCert *x509.Certificate
Expand Down

0 comments on commit da4da8a

Please sign in to comment.