Last active
September 18, 2019 16:06
-
-
Save jredl-va/d5df26877fc85095115731d98ea5ff33 to your computer and use it in GitHub Desktop.
Certificate Generation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func GenCA(name string) (certPEM, keyPEM []byte, err error) { | |
now := time.Now().UTC() | |
tmpl := &x509.Certificate{ | |
SerialNumber: big.NewInt(1), | |
Subject: pkix.Name{CommonName: name}, | |
NotBefore: now, | |
NotAfter: now.Add(caMaxAge), | |
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, | |
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, | |
IsCA: true, | |
BasicConstraintsValid: true, | |
} | |
key, err := genKeyPair() | |
if err != nil { | |
return | |
} | |
certDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, key.Public(), key) | |
if err != nil { | |
return | |
} | |
certPEM = pem.EncodeToMemory(&pem.Block{ | |
Type: "CERTIFICATE", | |
Bytes: certDER, | |
}) | |
keyPEM = pem.EncodeToMemory(&pem.Block{ | |
Type: "RSA PRIVATE KEY", | |
Bytes: x509.MarshalPKCS1PrivateKey(key), | |
}) | |
return | |
} | |
// GenerateCert generates a leaf cert from ca. | |
func GenerateCert(ca *tls.Certificate, hosts ...string) (*tls.Certificate, error) { | |
now := time.Now().Add(-1 * time.Hour).UTC() | |
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) | |
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) | |
if err != nil { | |
return nil, fmt.Errorf("failed to generate serial number: %s", err) | |
} | |
template := &x509.Certificate{ | |
SerialNumber: serialNumber, | |
Subject: pkix.Name{CommonName: hosts[0]}, | |
NotBefore: now, | |
NotAfter: now.Add(leafMaxAge), | |
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, | |
KeyUsage: x509.KeyUsageDigitalSignature, | |
} | |
for _, h := range hosts { | |
if ip := net.ParseIP(h); ip != nil { | |
template.IPAddresses = append(template.IPAddresses, ip) | |
} else { | |
template.DNSNames = append(template.DNSNames, h) | |
} | |
} | |
key, err := genKeyPair() | |
if err != nil { | |
return nil, err | |
} | |
x, err := x509.CreateCertificate(rand.Reader, template, ca.Leaf, key.Public(), ca.PrivateKey) | |
if err != nil { | |
return nil, err | |
} | |
cert := new(tls.Certificate) | |
cert.Certificate = append(cert.Certificate, x) | |
cert.PrivateKey = key | |
cert.Leaf, _ = x509.ParseCertificate(x) | |
return cert, nil | |
} | |
func genKeyPair() (*rsa.PrivateKey, error) { | |
return rsa.GenerateKey(rand.Reader, 2048) | |
} | |
func buildBoolFromCA(ca *tls.Certificate) *x509.CertPool { | |
pool := x509.NewCertPool() | |
pool.AddCert(ca.Leaf) | |
return pool | |
} | |
func getCert(ca *tls.Certificate, host string) (*tls.Certificate, error) { | |
cert, err := GenerateCert(ca, host) | |
if err != nil { | |
return nil, err | |
} | |
return cert, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment