2022-05-11 08:05:13 +00:00
|
|
|
package tls
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/rand"
|
|
|
|
"crypto/rsa"
|
|
|
|
"crypto/x509"
|
|
|
|
"crypto/x509/pkix"
|
2023-08-29 10:31:56 +00:00
|
|
|
"fmt"
|
2022-05-11 08:05:13 +00:00
|
|
|
"math/big"
|
|
|
|
"net"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2022-05-11 14:58:14 +00:00
|
|
|
// generateCA creates the self-signed CA cert and private key
|
2022-05-11 08:05:13 +00:00
|
|
|
// it will be used to sign the webhook server certificate
|
2022-05-12 14:07:25 +00:00
|
|
|
func generateCA(key *rsa.PrivateKey, certValidityDuration time.Duration) (*rsa.PrivateKey, *x509.Certificate, error) {
|
2022-05-11 08:05:13 +00:00
|
|
|
now := time.Now()
|
|
|
|
begin, end := now.Add(-1*time.Hour), now.Add(certValidityDuration)
|
2022-05-12 14:07:25 +00:00
|
|
|
if key == nil {
|
|
|
|
newKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
key = newKey
|
2022-05-11 08:05:13 +00:00
|
|
|
}
|
|
|
|
templ := &x509.Certificate{
|
|
|
|
SerialNumber: big.NewInt(0),
|
|
|
|
Subject: pkix.Name{
|
|
|
|
CommonName: "*.kyverno.svc",
|
|
|
|
},
|
|
|
|
NotBefore: begin,
|
|
|
|
NotAfter: end,
|
|
|
|
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign,
|
|
|
|
BasicConstraintsValid: true,
|
|
|
|
IsCA: true,
|
|
|
|
}
|
|
|
|
der, err := x509.CreateCertificate(rand.Reader, templ, templ, key.Public(), key)
|
|
|
|
if err != nil {
|
2022-05-12 14:07:25 +00:00
|
|
|
return nil, nil, err
|
2022-05-11 08:05:13 +00:00
|
|
|
}
|
|
|
|
cert, err := x509.ParseCertificate(der)
|
|
|
|
if err != nil {
|
2022-05-12 14:07:25 +00:00
|
|
|
return nil, nil, err
|
2022-05-11 08:05:13 +00:00
|
|
|
}
|
2022-05-12 14:07:25 +00:00
|
|
|
return key, cert, nil
|
2022-05-11 08:05:13 +00:00
|
|
|
}
|
|
|
|
|
2022-05-12 14:07:25 +00:00
|
|
|
// generateTLS takes the results of GenerateCACert and uses it to create the
|
2022-05-11 08:05:13 +00:00
|
|
|
// PEM-encoded public certificate and private key, respectively
|
2023-08-25 11:24:52 +00:00
|
|
|
func generateTLS(server string, caCert *x509.Certificate, caKey *rsa.PrivateKey, certValidityDuration time.Duration, commonName string, dnsNames []string) (*rsa.PrivateKey, *x509.Certificate, error) {
|
2022-05-11 08:05:13 +00:00
|
|
|
now := time.Now()
|
|
|
|
begin, end := now.Add(-1*time.Hour), now.Add(certValidityDuration)
|
|
|
|
var ips []net.IP
|
2022-10-13 09:46:05 +00:00
|
|
|
if server != "" {
|
2023-08-17 13:05:00 +00:00
|
|
|
serverHost := server
|
|
|
|
if strings.Contains(serverHost, ":") {
|
|
|
|
host, _, err := net.SplitHostPort(serverHost)
|
2022-10-13 09:46:05 +00:00
|
|
|
if err != nil {
|
2023-08-29 10:31:56 +00:00
|
|
|
return nil, nil, fmt.Errorf("failed to split server host/port (%w)", err)
|
2022-10-13 09:46:05 +00:00
|
|
|
}
|
|
|
|
serverHost = host
|
|
|
|
}
|
2023-08-17 13:05:00 +00:00
|
|
|
ip := net.ParseIP(serverHost)
|
|
|
|
if ip == nil || ip.IsUnspecified() {
|
|
|
|
dnsNames = append(dnsNames, serverHost)
|
|
|
|
} else {
|
|
|
|
ips = append(ips, ip)
|
2022-05-11 08:05:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
templ := &x509.Certificate{
|
|
|
|
SerialNumber: big.NewInt(1),
|
|
|
|
Subject: pkix.Name{
|
2023-08-25 11:24:52 +00:00
|
|
|
CommonName: commonName,
|
2022-05-11 08:05:13 +00:00
|
|
|
},
|
|
|
|
DNSNames: dnsNames,
|
|
|
|
IPAddresses: ips,
|
|
|
|
NotBefore: begin,
|
|
|
|
NotAfter: end,
|
|
|
|
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
|
|
|
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
|
|
|
BasicConstraintsValid: true,
|
|
|
|
}
|
|
|
|
key, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
|
|
if err != nil {
|
2022-05-12 14:07:25 +00:00
|
|
|
return nil, nil, err
|
2022-05-11 08:05:13 +00:00
|
|
|
}
|
2022-05-12 14:07:25 +00:00
|
|
|
der, err := x509.CreateCertificate(rand.Reader, templ, caCert, key.Public(), caKey)
|
2022-05-11 08:05:13 +00:00
|
|
|
if err != nil {
|
2022-05-12 14:07:25 +00:00
|
|
|
return nil, nil, err
|
2022-05-11 08:05:13 +00:00
|
|
|
}
|
|
|
|
cert, err := x509.ParseCertificate(der)
|
|
|
|
if err != nil {
|
2022-05-12 14:07:25 +00:00
|
|
|
return nil, nil, err
|
2022-05-11 08:05:13 +00:00
|
|
|
}
|
2022-05-12 14:07:25 +00:00
|
|
|
return key, cert, nil
|
2022-05-11 08:05:13 +00:00
|
|
|
}
|