Skip to content

Instantly share code, notes, and snippets.

@jredl-va
Last active September 18, 2019 16:06
Show Gist options
  • Save jredl-va/d5df26877fc85095115731d98ea5ff33 to your computer and use it in GitHub Desktop.
Save jredl-va/d5df26877fc85095115731d98ea5ff33 to your computer and use it in GitHub Desktop.
Certificate Generation
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