certificate overhaul

This commit is contained in:
2023-03-25 15:06:58 -05:00
parent c7fef651b2
commit 42e154c6ab
18 changed files with 406 additions and 166 deletions

View File

@@ -2,18 +2,19 @@ package certificate
import (
"bytes"
"fmt"
"log"
"strconv"
"time"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
)
func CreateCA() ([]byte, []byte, []byte, error) {
func CreateCA(privateKey string) (string, error) {
serial, _ := strconv.ParseInt(time.Now().Format("20060102150405"), 10, 64)
ca := &x509.Certificate{
SerialNumber: big.NewInt(serial),
@@ -37,14 +38,18 @@ func CreateCA() ([]byte, []byte, []byte, error) {
SignatureAlgorithm: x509.SHA384WithRSA,
}
keyPair, err := rsa.GenerateKey(rand.Reader, 4096)
pemKey, _ := pem.Decode([]byte(privateKey))
if pemKey == nil || pemKey.Type != "RSA PRIVATE KEY" {
return "", fmt.Errorf("failed to decode PEM block containing private key")
}
keyPair, err := x509.ParsePKCS1PrivateKey(pemKey.Bytes)
if err != nil {
return []byte(""), []byte(""), []byte(""), err
return "", err
}
certBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &keyPair.PublicKey, keyPair)
if err != nil {
return []byte(""), []byte(""), []byte(""), err
return "", err
}
c := new(bytes.Buffer)
@@ -53,17 +58,6 @@ func CreateCA() ([]byte, []byte, []byte, error) {
Bytes: certBytes,
})
k := new(bytes.Buffer)
pem.Encode(k, &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(keyPair),
})
p := new(bytes.Buffer)
pem.Encode(p, &pem.Block{
Type: "PUBLIC KEY",
Bytes: x509.MarshalPKCS1PublicKey(&keyPair.PublicKey),
})
return c.Bytes(), k.Bytes(), p.Bytes(), nil
log.Printf("[DEBUG] Generated Certificate Authority Certificate:\n%s", c)
return c.String(), nil
}

View File

@@ -1,72 +0,0 @@
package certificate
import (
"bytes"
"strconv"
"time"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
)
func CreateCert() ([]byte, []byte, []byte, error) {
serial, _ := strconv.ParseInt(time.Now().Format("20060102150405"), 10, 64)
ca := &x509.Certificate{
SerialNumber: big.NewInt(serial + 1),
Subject: pkix.Name{
Organization: []string{"Kubernetes Mutating Webserver"},
Country: []string{"K8S"},
Province: []string{"Cluster Service"},
Locality: []string{"Cluster Local"},
//StreetAddress: []string{""},
//PostalCode: []string{""},
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(1, 6, 0),
ExtKeyUsage: []x509.ExtKeyUsage{
x509.ExtKeyUsageClientAuth,
x509.ExtKeyUsageServerAuth,
},
DNSNames: []string{
"svc.cluster.local",
"*.svc.cluster.local",
},
SubjectKeyId: []byte{1, 2, 3, 4, 6},
KeyUsage: x509.KeyUsageDigitalSignature,
SignatureAlgorithm: x509.SHA384WithRSA,
}
keyPair, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
return []byte(""), []byte(""), []byte(""), err
}
certBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &keyPair.PublicKey, keyPair)
if err != nil {
return []byte(""), []byte(""), []byte(""), err
}
c := new(bytes.Buffer)
pem.Encode(c, &pem.Block{
Type: "CERTIFICATE",
Bytes: certBytes,
})
k := new(bytes.Buffer)
pem.Encode(k, &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(keyPair),
})
p := new(bytes.Buffer)
pem.Encode(p, &pem.Block{
Type: "PUBLIC KEY",
Bytes: x509.MarshalPKCS1PublicKey(&keyPair.PublicKey),
})
return c.Bytes(), k.Bytes(), p.Bytes(), nil
}

View File

@@ -0,0 +1,53 @@
package certificate
import (
"bytes"
"fmt"
"log"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
)
func CreateCSR(privateKey string) (string, error) {
csr := x509.CertificateRequest{
Subject: pkix.Name{
Organization: []string{"Kubernetes Mutating Webserver"},
Country: []string{"K8S"},
Province: []string{"Cluster Service"},
Locality: []string{"Cluster Local"},
//StreetAddress: []string{""},
//PostalCode: []string{""},
},
DNSNames: []string{
"svc.cluster.local",
"*.svc.cluster.local",
},
SignatureAlgorithm: x509.SHA384WithRSA,
}
pemKey, _ := pem.Decode([]byte(privateKey))
if pemKey == nil || pemKey.Type != "RSA PRIVATE KEY" {
return "", fmt.Errorf("failed to decode PEM block containing private key")
}
keyPair, err := x509.ParsePKCS1PrivateKey(pemKey.Bytes)
if err != nil {
return "", err
}
csrData, err := x509.CreateCertificateRequest(rand.Reader, &csr, keyPair)
if err != nil {
return "", err
}
c := new(bytes.Buffer)
pem.Encode(c, &pem.Block{
Type: "CERTIFICATE REQUEST",
Bytes: csrData,
})
log.Printf("[TRACE] Generated Host CSR:\n%s", c.String())
return c.String(), nil
}

View File

@@ -0,0 +1,15 @@
package certificate
import (
"crypto/rand"
"crypto/rsa"
)
func CreateRSAKeyPair(bytes int) (*rsa.PrivateKey, error) {
keyPair, err := rsa.GenerateKey(rand.Reader, bytes)
if err != nil {
return &rsa.PrivateKey{}, err
}
return keyPair, nil
}

View File

@@ -1,43 +0,0 @@
package certificate
import (
"bytes"
"log"
"crypto/rand"
"crypto/tls"
"crypto/x509"
"encoding/pem"
)
func CreateServerCert() tls.Certificate {
caCertPem, caPrivKeyPem, _, _ := CreateCA()
certCertPem, certPrivKeyPem, certPublicKeyPem, _ := CreateCert()
caCertBlob, _ := pem.Decode(caCertPem)
caCert, _ := x509.ParseCertificate(caCertBlob.Bytes)
caPrivKeyBlob, _ := pem.Decode(caPrivKeyPem)
caPrivKey, _ := x509.ParsePKCS1PrivateKey(caPrivKeyBlob.Bytes)
certCertBlob, _ := pem.Decode(certCertPem)
certCert, _ := x509.ParseCertificate(certCertBlob.Bytes)
certPublicKeyBlob, _ := pem.Decode(certPublicKeyPem)
certPublicKey, _ := x509.ParsePKCS1PublicKey(certPublicKeyBlob.Bytes)
signedCert, err := x509.CreateCertificate(rand.Reader, certCert, caCert, certPublicKey, caPrivKey)
if err != nil {
log.Fatalf("[FATAL] CreateCertificate: %v", err)
}
serverCertPem := new(bytes.Buffer)
pem.Encode(serverCertPem, &pem.Block{
Type: "CERTIFICATE",
Bytes: signedCert,
})
serverCert, err := tls.X509KeyPair(append(serverCertPem.Bytes(), caCertPem...), certPrivKeyPem)
if err != nil {
log.Fatalf("[FATAL] x509KeyPair: %v", err)
}
return serverCert
}

View File

@@ -0,0 +1,74 @@
package certificate
import (
"bytes"
"fmt"
"strconv"
"time"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
)
func SignCert(caCertPem, caPrivKeyPem, csrPem string) (string, error) {
caCertData, _ := pem.Decode([]byte(caCertPem))
caCert, err := x509.ParseCertificate(caCertData.Bytes)
if err != nil {
return "", fmt.Errorf("parse cert %v", err)
}
pemKey, _ := pem.Decode([]byte(caPrivKeyPem))
if pemKey == nil || pemKey.Type != "RSA PRIVATE KEY" {
return "", fmt.Errorf("failed to decode PEM block containing private key")
}
keyPair, err := x509.ParsePKCS1PrivateKey(pemKey.Bytes)
if err != nil {
return "", fmt.Errorf("private key %v", err)
}
csrData, _ := pem.Decode([]byte(csrPem))
csr, err := x509.ParseCertificateRequest(csrData.Bytes)
if err != nil {
return "", fmt.Errorf("parse csr %v", err)
}
serial, _ := strconv.ParseInt(time.Now().Format("20060102150405"), 10, 64)
certTemplate := x509.Certificate{
SerialNumber: big.NewInt(serial + 1),
Issuer: caCert.Issuer,
Subject: pkix.Name{
Organization: []string{"Kubernetes Mutating Webserver"},
Country: csr.Subject.Country,
Province: []string{"Cluster Service"},
Locality: []string{"Cluster Local"},
StreetAddress: csr.Subject.StreetAddress,
PostalCode: csr.Subject.PostalCode,
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(1, 6, 0),
KeyUsage: x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{
x509.ExtKeyUsageClientAuth,
x509.ExtKeyUsageServerAuth,
},
DNSNames: csr.DNSNames,
Signature: csr.Signature,
SignatureAlgorithm: csr.SignatureAlgorithm,
PublicKey: csr.PublicKey,
PublicKeyAlgorithm: csr.PublicKeyAlgorithm,
}
certBytes, err := x509.CreateCertificate(rand.Reader, &certTemplate, caCert, csr.PublicKey, keyPair)
if err != nil {
return "", fmt.Errorf("sign %v", err)
}
c := new(bytes.Buffer)
pem.Encode(c, &pem.Block{
Type: "CERTIFICATE",
Bytes: certBytes,
})
return c.String(), nil
}