From 41eddc04627cd5f4932166bebb0b4d527e2ae73d Mon Sep 17 00:00:00 2001 From: Dario Tranchitella Date: Fri, 9 Sep 2022 18:00:46 +0200 Subject: [PATCH] refactor(crypto): eliminating bloated certs functions --- internal/crypto/crypto.go | 260 +++++++++++------- internal/kubeadm/addon.go | 1 + internal/kubeadm/certificates.go | 26 +- internal/resources/api_server_certificate.go | 3 +- .../api_server_kubelet_client_certificate.go | 3 +- internal/resources/ca_certificate.go | 3 +- .../datastore/datastore_certificate.go | 29 +- .../front-proxy-client-certificate.go | 3 +- .../resources/front_proxy_ca_certificate.go | 3 +- .../konnectivity/certificate_resource.go | 50 +--- internal/resources/konnectivity/constants.go | 2 - .../konnectivity/deployment_resource.go | 2 +- internal/resources/sa_certificate.go | 6 +- 13 files changed, 181 insertions(+), 210 deletions(-) diff --git a/internal/crypto/crypto.go b/internal/crypto/crypto.go index 1320f48..ffa452e 100644 --- a/internal/crypto/crypto.go +++ b/internal/crypto/crypto.go @@ -5,103 +5,31 @@ package crypto import ( "bytes" - "crypto/rand" + cryptorand "crypto/rand" "crypto/rsa" "crypto/x509" + "crypto/x509/pkix" "encoding/pem" "fmt" + "math/big" + mathrand "math/rand" "time" + + "github.com/pkg/errors" ) -const ( - certBitSize = 2048 -) - -func GetCertificateAndKeyPair(template *x509.Certificate, caCert []byte, caPrivKey []byte) (*bytes.Buffer, *bytes.Buffer, error) { - caCertBytes, err := GetCertificate(caCert) - if err != nil { - return nil, nil, err +// CheckPublicAndPrivateKeyValidity checks if the given bytes for the private and public keys are valid. +func CheckPublicAndPrivateKeyValidity(publicKey []byte, privateKey []byte) (bool, error) { + if len(publicKey) == 0 || len(privateKey) == 0 { + return false, nil } - caPrivKeyBytes, err := GetPrivateKey(caPrivKey) - if err != nil { - return nil, nil, err - } - - return GenerateCertificateKeyPairBytes(template, certBitSize, caCertBytes, caPrivKeyBytes) -} - -func GetCertificate(cert []byte) (*x509.Certificate, error) { - pemContent, _ := pem.Decode(cert) - if pemContent == nil { - return nil, fmt.Errorf("no right PEM block") - } - - return x509.ParseCertificate(pemContent.Bytes) -} - -func GetPrivateKey(privKey []byte) (*rsa.PrivateKey, error) { - pemContent, _ := pem.Decode(privKey) - if pemContent == nil { - return nil, fmt.Errorf("no right PEM block") - } - - return x509.ParsePKCS1PrivateKey(pemContent.Bytes) -} - -func GetPublickKey(pubKey []byte) (*rsa.PublicKey, error) { - pemContent, _ := pem.Decode(pubKey) - if pemContent == nil { - return nil, fmt.Errorf("no right PEM block") - } - - pub, err := x509.ParsePKIXPublicKey(pemContent.Bytes) - if err != nil { - return nil, err - } - - return pub.(*rsa.PublicKey), nil //nolint:forcetypeassert -} - -func GenerateCertificateKeyPairBytes(template *x509.Certificate, bitSize int, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*bytes.Buffer, *bytes.Buffer, error) { - certPrivKey, err := rsa.GenerateKey(rand.Reader, bitSize) - if err != nil { - return nil, nil, err - } - - certBytes, err := x509.CreateCertificate(rand.Reader, template, caCert, &certPrivKey.PublicKey, caKey) - if err != nil { - return nil, nil, err - } - - certPEM := &bytes.Buffer{} - if err := pem.Encode(certPEM, &pem.Block{ - Type: "CERTIFICATE", - Headers: nil, - Bytes: certBytes, - }); err != nil { - return nil, nil, err - } - - certPrivKeyPEM := &bytes.Buffer{} - if err := pem.Encode(certPrivKeyPEM, &pem.Block{ - Type: "RSA PRIVATE KEY", - Headers: nil, - Bytes: x509.MarshalPKCS1PrivateKey(certPrivKey), - }); err != nil { - return nil, nil, err - } - - return certPEM, certPrivKeyPEM, nil -} - -func IsValidKeyPairBytes(pubKeyBytes []byte, privKeyBytes []byte) (bool, error) { - privKey, err := GetPrivateKey(privKeyBytes) + pubKey, err := ParsePublicKeyBytes(publicKey) if err != nil { return false, err } - pubKey, err := GetPublickKey(pubKeyBytes) + privKey, err := ParsePrivateKeyBytes(privateKey) if err != nil { return false, err } @@ -109,22 +37,134 @@ func IsValidKeyPairBytes(pubKeyBytes []byte, privKeyBytes []byte) (bool, error) return checkPublicKeys(privKey.PublicKey, *pubKey), nil } -func IsValidCertificateKeyPairBytes(certBytes []byte, privKeyBytes []byte) (bool, error) { - cert, err := GetCertificate(certBytes) - if err != nil { - return false, err +// CheckCertificateAndPrivateKeyPairValidity checks if the certificate and private key pair are valid. +func CheckCertificateAndPrivateKeyPairValidity(certificate []byte, privateKey []byte) (bool, error) { + switch { + case len(certificate) == 0, len(privateKey) == 0: + return false, nil + default: + return IsValidCertificateKeyPairBytes(certificate, privateKey) } - - privKey, err := GetPrivateKey(privKeyBytes) - if err != nil { - return false, err - } - - return isValidCertificateKeyPairBytes(*cert, *privKey), nil } -func isValidCertificateKeyPairBytes(cert x509.Certificate, privKey rsa.PrivateKey) bool { - return checkCertificateValidity(cert) && checkCertificateKeyPair(cert, privKey) +// GenerateCertificatePrivateKeyPair starts from the Certificate Authority bytes a certificate using the provided +// template, returning the bytes both for the certificate and its key. +func GenerateCertificatePrivateKeyPair(template *x509.Certificate, caCertificate []byte, caPrivateKey []byte) (*bytes.Buffer, *bytes.Buffer, error) { + caCertBytes, err := ParseCertificateBytes(caCertificate) + if err != nil { + return nil, nil, err + } + + caPrivKeyBytes, err := ParsePrivateKeyBytes(caPrivateKey) + if err != nil { + return nil, nil, errors.Wrap(err, "provided CA private key for certificate generation cannot be parsed") + } + + return generateCertificateKeyPairBytes(template, caCertBytes, caPrivKeyBytes) +} + +// ParseCertificateBytes takes the certificate bytes returning a x509 certificate by parsing it. +func ParseCertificateBytes(content []byte) (*x509.Certificate, error) { + pemContent, _ := pem.Decode(content) + if pemContent == nil { + return nil, fmt.Errorf("no right PEM block") + } + + crt, err := x509.ParseCertificate(pemContent.Bytes) + if err != nil { + return nil, errors.Wrap(err, "cannot parse x509 Certificate") + } + + return crt, nil +} + +// ParsePrivateKeyBytes takes the private key bytes returning an RSA private key by parsing it. +func ParsePrivateKeyBytes(content []byte) (*rsa.PrivateKey, error) { + pemContent, _ := pem.Decode(content) + if pemContent == nil { + return nil, fmt.Errorf("no right PEM block") + } + + privateKey, err := x509.ParsePKCS1PrivateKey(pemContent.Bytes) + if err != nil { + return nil, errors.Wrap(err, "cannot parse PKCS1 Private Key") + } + + return privateKey, nil +} + +// ParsePublicKeyBytes takes the public key bytes returning an RSA public key by parsing it. +func ParsePublicKeyBytes(content []byte) (*rsa.PublicKey, error) { + pemContent, _ := pem.Decode(content) + if pemContent == nil { + return nil, fmt.Errorf("no right PEM block") + } + + publicKey, err := x509.ParsePKIXPublicKey(pemContent.Bytes) + if err != nil { + return nil, err + } + + rsaPublicKey, ok := publicKey.(*rsa.PublicKey) + if !ok { + return nil, fmt.Errorf("expected *rsa.PublicKey, got %T", rsaPublicKey) + } + + return rsaPublicKey, nil +} + +// IsValidCertificateKeyPairBytes checks if the certificate matches the private key bounded to it. +func IsValidCertificateKeyPairBytes(certificateBytes []byte, privateKeyBytes []byte) (bool, error) { + crt, err := ParseCertificateBytes(certificateBytes) + if err != nil { + return false, err + } + + key, err := ParsePrivateKeyBytes(privateKeyBytes) + if err != nil { + return false, err + } + + switch { + case !checkCertificateValidity(*crt): + return false, nil + case !checkPublicKeys(*crt.PublicKey.(*rsa.PublicKey), key.PublicKey): //nolint:forcetypeassert + return false, nil + default: + return true, nil + } +} + +func generateCertificateKeyPairBytes(template *x509.Certificate, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*bytes.Buffer, *bytes.Buffer, error) { + certPrivKey, err := rsa.GenerateKey(cryptorand.Reader, 2048) + if err != nil { + return nil, nil, errors.Wrap(err, "cannot generate an RSA key") + } + + certBytes, err := x509.CreateCertificate(cryptorand.Reader, template, caCert, &certPrivKey.PublicKey, caKey) + if err != nil { + return nil, nil, errors.Wrap(err, "cannot create the certificate") + } + + certPEM := &bytes.Buffer{} + if err = pem.Encode(certPEM, &pem.Block{ + Type: "CERTIFICATE", + Headers: nil, + Bytes: certBytes, + }); err != nil { + return nil, nil, errors.Wrap(err, "cannot encode the generate certificate bytes") + } + + certPrivKeyPEM := &bytes.Buffer{} + if err = pem.Encode(certPrivKeyPEM, &pem.Block{ + Type: "RSA PRIVATE KEY", + Headers: nil, + Bytes: x509.MarshalPKCS1PrivateKey(certPrivKey), + }); err != nil { + return nil, nil, errors.Wrap(err, "cannot encode private key") + } + + return certPEM, certPrivKeyPEM, nil } func checkCertificateValidity(cert x509.Certificate) bool { @@ -133,13 +173,31 @@ func checkCertificateValidity(cert x509.Certificate) bool { return now.Before(cert.NotAfter) && now.After(cert.NotBefore) } -func checkCertificateKeyPair(cert x509.Certificate, privKey rsa.PrivateKey) bool { - return checkPublicKeys(*cert.PublicKey.(*rsa.PublicKey), privKey.PublicKey) //nolint:forcetypeassert -} - func checkPublicKeys(a rsa.PublicKey, b rsa.PublicKey) bool { isN := a.N.Cmp(b.N) == 0 isE := a.E == b.E return isN && isE } + +// NewCertificateTemplate returns the template that must be used to generate a certificate, +// used to perform the authentication against the DataStore. +func NewCertificateTemplate(commonName string) *x509.Certificate { + return &x509.Certificate{ + PublicKeyAlgorithm: x509.RSA, + SerialNumber: big.NewInt(mathrand.Int63()), + Subject: pkix.Name{ + CommonName: commonName, + Organization: []string{"system:masters"}, + }, + NotBefore: time.Now(), + NotAfter: time.Now().AddDate(10, 0, 0), + SubjectKeyId: []byte{1, 2, 3, 4, 6}, + ExtKeyUsage: []x509.ExtKeyUsage{ + x509.ExtKeyUsageClientAuth, + x509.ExtKeyUsageServerAuth, + x509.ExtKeyUsageCodeSigning, + }, + KeyUsage: x509.KeyUsageDigitalSignature, + } +} diff --git a/internal/kubeadm/addon.go b/internal/kubeadm/addon.go index 879a523..9be14bb 100644 --- a/internal/kubeadm/addon.go +++ b/internal/kubeadm/addon.go @@ -6,6 +6,7 @@ package kubeadm import ( "context" "io" + k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" diff --git a/internal/kubeadm/certificates.go b/internal/kubeadm/certificates.go index f7bbf40..00c207e 100644 --- a/internal/kubeadm/certificates.go +++ b/internal/kubeadm/certificates.go @@ -44,8 +44,8 @@ func GenerateCACertificatePrivateKeyPair(baseName string, config *Configuration) func GenerateCertificatePrivateKeyPair(baseName string, config *Configuration, ca CertificatePrivateKeyPair) (*CertificatePrivateKeyPair, error) { defer deleteCertificateDirectory(config.InitConfiguration.CertificatesDir) - certificate, _ := cryptoKamaji.GetCertificate(ca.Certificate) - signer, _ := cryptoKamaji.GetPrivateKey(ca.PrivateKey) + certificate, _ := cryptoKamaji.ParseCertificateBytes(ca.Certificate) + signer, _ := cryptoKamaji.ParsePrivateKeyBytes(ca.PrivateKey) kubeadmCert, err := getKubeadmCert(baseName) if err != nil { @@ -106,28 +106,6 @@ func GeneratePublicKeyPrivateKeyPair(baseName string, config *Configuration) (*P return publicKeyPrivateKeyPair, err } -func IsCertificatePrivateKeyPairValid(certificate []byte, privKey []byte) (bool, error) { - if len(certificate) == 0 { - return false, nil - } - if len(privKey) == 0 { - return false, nil - } - - return cryptoKamaji.IsValidCertificateKeyPairBytes(certificate, privKey) -} - -func IsPublicKeyPrivateKeyPairValid(pubKey []byte, privKey []byte) (bool, error) { - if len(pubKey) == 0 { - return false, nil - } - if len(privKey) == 0 { - return false, nil - } - - return cryptoKamaji.IsValidKeyPairBytes(pubKey, privKey) -} - func initPhaseCertsSA(config *Configuration) error { return certs.CreateServiceAccountKeyAndPublicKeyFiles(config.InitConfiguration.CertificatesDir, config.InitConfiguration.PublicKeyAlgorithm()) } diff --git a/internal/resources/api_server_certificate.go b/internal/resources/api_server_certificate.go index 0aaa75b..d8d9b4c 100644 --- a/internal/resources/api_server_certificate.go +++ b/internal/resources/api_server_certificate.go @@ -17,6 +17,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1" + "github.com/clastix/kamaji/internal/crypto" "github.com/clastix/kamaji/internal/kubeadm" "github.com/clastix/kamaji/internal/utilities" ) @@ -83,7 +84,7 @@ func (r *APIServerCertificate) mutate(ctx context.Context, tenantControlPlane *k logger := log.FromContext(ctx, "resource", r.GetName()) if checksum := tenantControlPlane.Status.Certificates.APIServer.Checksum; len(checksum) > 0 && checksum == r.resource.GetAnnotations()["checksum"] { - isValid, err := kubeadm.IsCertificatePrivateKeyPairValid( + isValid, err := crypto.CheckCertificateAndPrivateKeyPairValidity( r.resource.Data[kubeadmconstants.APIServerCertName], r.resource.Data[kubeadmconstants.APIServerKeyName], ) diff --git a/internal/resources/api_server_kubelet_client_certificate.go b/internal/resources/api_server_kubelet_client_certificate.go index cfc6ec8..1dbe7dc 100644 --- a/internal/resources/api_server_kubelet_client_certificate.go +++ b/internal/resources/api_server_kubelet_client_certificate.go @@ -17,6 +17,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1" + "github.com/clastix/kamaji/internal/crypto" "github.com/clastix/kamaji/internal/kubeadm" "github.com/clastix/kamaji/internal/utilities" ) @@ -83,7 +84,7 @@ func (r *APIServerKubeletClientCertificate) mutate(ctx context.Context, tenantCo logger := log.FromContext(ctx, "resource", r.GetName()) if checksum := tenantControlPlane.Status.Certificates.APIServerKubeletClient.Checksum; len(checksum) > 0 && checksum == r.resource.GetAnnotations()["checksum"] { - isValid, err := kubeadm.IsCertificatePrivateKeyPairValid( + isValid, err := crypto.CheckCertificateAndPrivateKeyPairValidity( r.resource.Data[kubeadmconstants.APIServerKubeletClientCertName], r.resource.Data[kubeadmconstants.APIServerKubeletClientKeyName], ) diff --git a/internal/resources/ca_certificate.go b/internal/resources/ca_certificate.go index 6e85f8e..531055d 100644 --- a/internal/resources/ca_certificate.go +++ b/internal/resources/ca_certificate.go @@ -16,6 +16,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1" + "github.com/clastix/kamaji/internal/crypto" "github.com/clastix/kamaji/internal/kubeadm" "github.com/clastix/kamaji/internal/utilities" ) @@ -83,7 +84,7 @@ func (r *CACertificate) mutate(ctx context.Context, tenantControlPlane *kamajiv1 logger := log.FromContext(ctx, "resource", r.GetName()) if checksum := tenantControlPlane.Status.Certificates.CA.Checksum; len(checksum) > 0 && checksum == r.resource.GetAnnotations()["checksum"] { - isValid, err := kubeadm.IsCertificatePrivateKeyPairValid( + isValid, err := crypto.CheckCertificateAndPrivateKeyPairValidity( r.resource.Data[kubeadmconstants.CACertName], r.resource.Data[kubeadmconstants.CAKeyName], ) diff --git a/internal/resources/datastore/datastore_certificate.go b/internal/resources/datastore/datastore_certificate.go index 1c9f45b..eab0b7d 100644 --- a/internal/resources/datastore/datastore_certificate.go +++ b/internal/resources/datastore/datastore_certificate.go @@ -6,12 +6,7 @@ package datastore import ( "bytes" "context" - "crypto/x509" - "crypto/x509/pkix" "fmt" - "math/big" - "math/rand" - "time" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -114,7 +109,7 @@ func (r *Certificate) mutate(ctx context.Context, tenantControlPlane *kamajiv1al return err } - crt, key, err = crypto.GetCertificateAndKeyPair(r.getCertificateTemplate(tenantControlPlane), ca, privateKey) + crt, key, err = crypto.GenerateCertificatePrivateKeyPair(crypto.NewCertificateTemplate(tenantControlPlane.GetName()), ca, privateKey) if err != nil { logger.Error(err, "unable to generate certificate and private key") @@ -164,25 +159,3 @@ func (r *Certificate) mutate(ctx context.Context, tenantControlPlane *kamajiv1al return ctrl.SetControllerReference(tenantControlPlane, r.resource, r.Client.Scheme()) } } - -// getCertificateTemplate returns the template that must be used to generate a certificate, -// used to perform the authentication against the DataStore. -func (r *Certificate) getCertificateTemplate(tenant *kamajiv1alpha1.TenantControlPlane) *x509.Certificate { - return &x509.Certificate{ - PublicKeyAlgorithm: x509.RSA, - SerialNumber: big.NewInt(rand.Int63()), - Subject: pkix.Name{ - CommonName: tenant.GetName(), - Organization: []string{"system:masters"}, - }, - NotBefore: time.Now(), - NotAfter: time.Now().AddDate(10, 0, 0), - SubjectKeyId: []byte{1, 2, 3, 4, 6}, - ExtKeyUsage: []x509.ExtKeyUsage{ - x509.ExtKeyUsageClientAuth, - x509.ExtKeyUsageServerAuth, - x509.ExtKeyUsageCodeSigning, - }, - KeyUsage: x509.KeyUsageDigitalSignature, - } -} diff --git a/internal/resources/front-proxy-client-certificate.go b/internal/resources/front-proxy-client-certificate.go index 361c908..5e89cdc 100644 --- a/internal/resources/front-proxy-client-certificate.go +++ b/internal/resources/front-proxy-client-certificate.go @@ -17,6 +17,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1" + "github.com/clastix/kamaji/internal/crypto" "github.com/clastix/kamaji/internal/kubeadm" "github.com/clastix/kamaji/internal/utilities" ) @@ -83,7 +84,7 @@ func (r *FrontProxyClientCertificate) mutate(ctx context.Context, tenantControlP logger := log.FromContext(ctx, "resource", r.GetName()) if checksum := tenantControlPlane.Status.Certificates.FrontProxyClient.Checksum; len(checksum) > 0 && checksum == r.resource.GetAnnotations()["checksum"] { - isValid, err := kubeadm.IsCertificatePrivateKeyPairValid( + isValid, err := crypto.CheckCertificateAndPrivateKeyPairValidity( r.resource.Data[kubeadmconstants.FrontProxyClientCertName], r.resource.Data[kubeadmconstants.FrontProxyClientKeyName], ) diff --git a/internal/resources/front_proxy_ca_certificate.go b/internal/resources/front_proxy_ca_certificate.go index ccce416..a7e27ac 100644 --- a/internal/resources/front_proxy_ca_certificate.go +++ b/internal/resources/front_proxy_ca_certificate.go @@ -16,6 +16,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1" + "github.com/clastix/kamaji/internal/crypto" "github.com/clastix/kamaji/internal/kubeadm" "github.com/clastix/kamaji/internal/utilities" ) @@ -82,7 +83,7 @@ func (r *FrontProxyCACertificate) mutate(ctx context.Context, tenantControlPlane logger := log.FromContext(ctx, "resource", r.GetName()) if checksum := tenantControlPlane.Status.Certificates.FrontProxyCA.Checksum; len(checksum) > 0 && checksum == r.resource.GetAnnotations()["checksum"] { - isValid, err := kubeadm.IsCertificatePrivateKeyPairValid( + isValid, err := crypto.CheckCertificateAndPrivateKeyPairValidity( r.resource.Data[kubeadmconstants.FrontProxyCACertName], r.resource.Data[kubeadmconstants.FrontProxyCAKeyName], ) diff --git a/internal/resources/konnectivity/certificate_resource.go b/internal/resources/konnectivity/certificate_resource.go index b22fa9f..8b65b55 100644 --- a/internal/resources/konnectivity/certificate_resource.go +++ b/internal/resources/konnectivity/certificate_resource.go @@ -4,14 +4,8 @@ package konnectivity import ( - "bytes" "context" - "crypto/x509" - "crypto/x509/pkix" "fmt" - "math/big" - "math/rand" - "time" corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -102,11 +96,8 @@ func (r *CertificateResource) mutate(ctx context.Context, tenantControlPlane *ka return func() error { logger := log.FromContext(ctx, "resource", r.GetName()) - if checksum := tenantControlPlane.Status.Certificates.CA.Checksum; len(checksum) > 0 && checksum == utilities.CalculateConfigMapChecksum(r.resource.StringData) { - isValid, err := isCertificateAndKeyPairValid( - r.resource.Data[corev1.TLSCertKey], - r.resource.Data[corev1.TLSPrivateKeyKey], - ) + if checksum := tenantControlPlane.Status.Addons.Konnectivity.Certificate.Checksum; len(checksum) > 0 && checksum == utilities.CalculateConfigMapChecksum(r.resource.StringData) { + isValid, err := crypto.IsValidCertificateKeyPairBytes(r.resource.Data[corev1.TLSCertKey], r.resource.Data[corev1.TLSPrivateKeyKey]) if err != nil { logger.Info(fmt.Sprintf("%s certificate-private_key pair is not valid: %s", konnectivityCertAndKeyBaseName, err.Error())) } @@ -128,9 +119,10 @@ func (r *CertificateResource) mutate(ctx context.Context, tenantControlPlane *ka Certificate: secretCA.Data[kubeadmconstants.CACertName], PrivateKey: secretCA.Data[kubeadmconstants.CAKeyName], } - cert, privKey, err := getCertificateAndKeyPair(ca.Certificate, ca.PrivateKey) + + cert, privKey, err := crypto.GenerateCertificatePrivateKeyPair(crypto.NewCertificateTemplate(CertCommonName), ca.Certificate, ca.PrivateKey) if err != nil { - logger.Error(err, "cannot generate certificate and key pair") + logger.Error(err, "unable to generate certificate and private key") return err } @@ -159,35 +151,3 @@ func (r *CertificateResource) mutate(ctx context.Context, tenantControlPlane *ka return ctrl.SetControllerReference(tenantControlPlane, r.resource, r.Client.Scheme()) } } - -func getCertificateAndKeyPair(caCert []byte, caPrivKey []byte) (*bytes.Buffer, *bytes.Buffer, error) { - template := getCertTemplate() - - return crypto.GetCertificateAndKeyPair(template, caCert, caPrivKey) -} - -func isCertificateAndKeyPairValid(cert []byte, privKey []byte) (bool, error) { - return crypto.IsValidCertificateKeyPairBytes(cert, privKey) -} - -func getCertTemplate() *x509.Certificate { - serialNumber := big.NewInt(rand.Int63()) - - return &x509.Certificate{ - PublicKeyAlgorithm: x509.RSA, - SerialNumber: serialNumber, - Subject: pkix.Name{ - CommonName: CertCommonName, - Organization: []string{certOrganization}, - }, - NotBefore: time.Now(), - NotAfter: time.Now().AddDate(certExpirationDelayYears, 0, 0), - SubjectKeyId: []byte{1, 2, 3, 4, 6}, - ExtKeyUsage: []x509.ExtKeyUsage{ - x509.ExtKeyUsageClientAuth, - x509.ExtKeyUsageServerAuth, - x509.ExtKeyUsageCodeSigning, - }, - KeyUsage: x509.KeyUsageDigitalSignature, - } -} diff --git a/internal/resources/konnectivity/constants.go b/internal/resources/konnectivity/constants.go index 456926e..33ee186 100644 --- a/internal/resources/konnectivity/constants.go +++ b/internal/resources/konnectivity/constants.go @@ -9,8 +9,6 @@ const ( agentTokenName = "konnectivity-agent-token" apiServerAPIVersion = "apiserver.k8s.io/v1beta1" - certExpirationDelayYears = 10 - certOrganization = "system:master" defaultClusterName = "kubernetes" defaultUDSName = "/run/konnectivity/konnectivity-server.socket" egressSelectorConfigurationKind = "EgressSelectorConfiguration" diff --git a/internal/resources/konnectivity/deployment_resource.go b/internal/resources/konnectivity/deployment_resource.go index 157a753..69e2165 100644 --- a/internal/resources/konnectivity/deployment_resource.go +++ b/internal/resources/konnectivity/deployment_resource.go @@ -43,7 +43,7 @@ func (r *KubernetesDeploymentResource) ShouldStatusBeUpdated(context.Context, *k } func (r *KubernetesDeploymentResource) ShouldCleanup(tenantControlPlane *kamajiv1alpha1.TenantControlPlane) bool { - return tenantControlPlane.Spec.Addons.Konnectivity == nil + return tenantControlPlane.Spec.Addons.Konnectivity == nil && tenantControlPlane.Status.Addons.Konnectivity.Enabled == true } func (r *KubernetesDeploymentResource) CleanUp(ctx context.Context, _ *kamajiv1alpha1.TenantControlPlane) (bool, error) { diff --git a/internal/resources/sa_certificate.go b/internal/resources/sa_certificate.go index 4eeb698..c9031e7 100644 --- a/internal/resources/sa_certificate.go +++ b/internal/resources/sa_certificate.go @@ -16,6 +16,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1" + "github.com/clastix/kamaji/internal/crypto" "github.com/clastix/kamaji/internal/kubeadm" "github.com/clastix/kamaji/internal/utilities" ) @@ -84,10 +85,7 @@ func (r *SACertificate) mutate(ctx context.Context, tenantControlPlane *kamajiv1 logger := log.FromContext(ctx, "resource", r.GetName()) if checksum := tenantControlPlane.Status.Certificates.SA.Checksum; len(checksum) > 0 && checksum == r.resource.GetAnnotations()["checksum"] { - isValid, err := kubeadm.IsPublicKeyPrivateKeyPairValid( - r.resource.Data[kubeadmconstants.ServiceAccountPublicKeyName], - r.resource.Data[kubeadmconstants.ServiceAccountPrivateKeyName], - ) + isValid, err := crypto.CheckPublicAndPrivateKeyValidity(r.resource.Data[kubeadmconstants.ServiceAccountPublicKeyName], r.resource.Data[kubeadmconstants.ServiceAccountPrivateKeyName]) if err != nil { logger.Info(fmt.Sprintf("%s public_key-private_key pair is not valid: %s", kubeadmconstants.ServiceAccountKeyBaseName, err.Error())) }