2022-03-13 01:45:20 +00:00
|
|
|
package certgen
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/rand"
|
|
|
|
"crypto/rsa"
|
|
|
|
"crypto/tls"
|
|
|
|
"crypto/x509"
|
|
|
|
"crypto/x509/pkix"
|
2023-06-19 16:12:47 +01:00
|
|
|
"fmt"
|
2022-03-13 01:45:20 +00:00
|
|
|
"math/big"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2023-06-19 16:12:47 +01:00
|
|
|
// MakeCaTls generates a CA TLS certificate
|
|
|
|
func MakeCaTls(bits int, name pkix.Name, serialNumber *big.Int, future Future) (*CertGen, error) {
|
|
|
|
// base certificate data
|
|
|
|
now := time.Now()
|
2022-03-13 01:45:20 +00:00
|
|
|
ca := &x509.Certificate{
|
2022-03-13 10:22:53 +00:00
|
|
|
SerialNumber: serialNumber,
|
|
|
|
Subject: name,
|
2023-06-19 16:12:47 +01:00
|
|
|
NotBefore: now,
|
|
|
|
NotAfter: future(now),
|
2022-03-13 01:45:20 +00:00
|
|
|
IsCA: true,
|
|
|
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
|
|
|
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
|
|
|
BasicConstraintsValid: true,
|
|
|
|
}
|
|
|
|
|
2023-06-19 16:12:47 +01:00
|
|
|
// generate rsa private key
|
|
|
|
caPrivKey, err := rsa.GenerateKey(rand.Reader, bits)
|
2022-03-13 01:45:20 +00:00
|
|
|
if err != nil {
|
2023-06-19 16:12:47 +01:00
|
|
|
return nil, fmt.Errorf("Failed to generate CA private key: %w", err)
|
2022-03-13 01:45:20 +00:00
|
|
|
}
|
|
|
|
|
2023-06-19 16:12:47 +01:00
|
|
|
// create certificate bytes
|
2022-03-13 01:45:20 +00:00
|
|
|
caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, caPrivKey.Public(), caPrivKey)
|
|
|
|
if err != nil {
|
2023-06-19 16:12:47 +01:00
|
|
|
return nil, fmt.Errorf("Failed to generate CA certificate bytes: %w", err)
|
2022-03-13 01:45:20 +00:00
|
|
|
}
|
2023-06-19 16:12:47 +01:00
|
|
|
|
|
|
|
// add the raw certificate bytes so `*x509.Certificate.Equal(*x509.Certificate)` is valid
|
|
|
|
ca.Raw = caBytes
|
|
|
|
|
|
|
|
// get private key bytes
|
2022-03-13 01:45:20 +00:00
|
|
|
privKeyBytes := x509.MarshalPKCS1PrivateKey(caPrivKey)
|
|
|
|
gen := &CertGen{cert: ca, certBytes: caBytes, key: caPrivKey, keyBytes: privKeyBytes}
|
2023-06-19 16:12:47 +01:00
|
|
|
|
|
|
|
// generate pem blocks
|
2022-03-13 01:45:20 +00:00
|
|
|
err = gen.generatePem()
|
|
|
|
if err != nil {
|
2023-06-19 16:12:47 +01:00
|
|
|
return nil, fmt.Errorf("Failed to generate PEM encoding: %w", err)
|
2022-03-13 01:45:20 +00:00
|
|
|
}
|
2023-06-19 16:12:47 +01:00
|
|
|
|
|
|
|
// generate key pair
|
2022-03-13 01:45:20 +00:00
|
|
|
caKeyPair, err := tls.X509KeyPair(gen.certPem, gen.keyPem)
|
|
|
|
if err != nil {
|
2023-06-19 16:12:47 +01:00
|
|
|
return nil, fmt.Errorf("Failed to generate CA key pair: %w", err)
|
2022-03-13 01:45:20 +00:00
|
|
|
}
|
2023-06-19 16:12:47 +01:00
|
|
|
|
2022-03-13 01:45:20 +00:00
|
|
|
gen.tlsCert = caKeyPair
|
|
|
|
return gen, nil
|
|
|
|
}
|