2022-05-11 08:05:13 +00:00
|
|
|
package tls
|
|
|
|
|
|
|
|
import (
|
2022-05-11 14:58:14 +00:00
|
|
|
"crypto/rsa"
|
|
|
|
"crypto/x509"
|
|
|
|
"encoding/pem"
|
2022-05-12 14:07:25 +00:00
|
|
|
"time"
|
2022-05-11 14:58:14 +00:00
|
|
|
|
2022-09-19 09:11:12 +00:00
|
|
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
2022-05-11 14:58:14 +00:00
|
|
|
"github.com/kyverno/kyverno/pkg/config"
|
2022-05-11 08:05:13 +00:00
|
|
|
appsv1 "k8s.io/api/apps/v1"
|
2022-05-17 14:14:31 +00:00
|
|
|
corev1 "k8s.io/api/core/v1"
|
2022-05-11 08:05:13 +00:00
|
|
|
)
|
|
|
|
|
2022-05-12 14:07:25 +00:00
|
|
|
func privateKeyToPem(rsaKey *rsa.PrivateKey) []byte {
|
2022-05-11 14:58:14 +00:00
|
|
|
privateKey := &pem.Block{
|
|
|
|
Type: "PRIVATE KEY",
|
|
|
|
Bytes: x509.MarshalPKCS1PrivateKey(rsaKey),
|
|
|
|
}
|
|
|
|
return pem.EncodeToMemory(privateKey)
|
|
|
|
}
|
|
|
|
|
2022-05-12 14:07:25 +00:00
|
|
|
func certificateToPem(certs ...*x509.Certificate) []byte {
|
|
|
|
var raw []byte
|
|
|
|
for _, cert := range certs {
|
|
|
|
certificate := &pem.Block{
|
|
|
|
Type: "CERTIFICATE",
|
|
|
|
Bytes: cert.Raw,
|
|
|
|
}
|
|
|
|
raw = append(raw, pem.EncodeToMemory(certificate)...)
|
|
|
|
}
|
|
|
|
return raw
|
|
|
|
}
|
|
|
|
|
|
|
|
func pemToPrivateKey(raw []byte) (*rsa.PrivateKey, error) {
|
|
|
|
block, _ := pem.Decode(raw)
|
|
|
|
return x509.ParsePKCS1PrivateKey(block.Bytes)
|
|
|
|
}
|
|
|
|
|
|
|
|
func pemToCertificates(raw []byte) []*x509.Certificate {
|
|
|
|
var certs []*x509.Certificate
|
|
|
|
for {
|
|
|
|
certPemBlock, next := pem.Decode(raw)
|
|
|
|
if certPemBlock == nil {
|
|
|
|
return certs
|
|
|
|
}
|
|
|
|
raw = next
|
|
|
|
cert, err := x509.ParseCertificate(certPemBlock.Bytes)
|
|
|
|
if err == nil {
|
|
|
|
certs = append(certs, cert)
|
|
|
|
} else {
|
|
|
|
logger.Error(err, "failed to parse cert")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func removeExpiredCertificates(now time.Time, certs ...*x509.Certificate) []*x509.Certificate {
|
|
|
|
var result []*x509.Certificate
|
|
|
|
for _, cert := range certs {
|
|
|
|
if !now.After(cert.NotAfter) {
|
|
|
|
result = append(result, cert)
|
|
|
|
}
|
2022-05-11 14:58:14 +00:00
|
|
|
}
|
2022-05-12 14:07:25 +00:00
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
func allCertificatesExpired(now time.Time, certs ...*x509.Certificate) bool {
|
|
|
|
for _, cert := range certs {
|
|
|
|
if !now.After(cert.NotAfter) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
func validateCert(now time.Time, cert *x509.Certificate, caCerts ...*x509.Certificate) bool {
|
|
|
|
pool := x509.NewCertPool()
|
|
|
|
for _, cert := range caCerts {
|
|
|
|
pool.AddCert(cert)
|
|
|
|
}
|
|
|
|
if _, err := cert.Verify(x509.VerifyOptions{Roots: pool, CurrentTime: now}); err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
2022-05-11 14:58:14 +00:00
|
|
|
}
|
|
|
|
|
2022-05-11 08:05:13 +00:00
|
|
|
// IsKyvernoInRollingUpdate returns true if Kyverno is in rolling update
|
2022-05-12 14:07:25 +00:00
|
|
|
func IsKyvernoInRollingUpdate(deploy *appsv1.Deployment) bool {
|
2022-05-11 08:05:13 +00:00
|
|
|
var replicas int32 = 1
|
|
|
|
if deploy.Spec.Replicas != nil {
|
|
|
|
replicas = *deploy.Spec.Replicas
|
|
|
|
}
|
|
|
|
nonTerminatedReplicas := deploy.Status.Replicas
|
|
|
|
if nonTerminatedReplicas > replicas {
|
|
|
|
logger.Info("detect Kyverno is in rolling update, won't trigger the update again")
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2022-05-17 14:14:31 +00:00
|
|
|
func IsSecretManagedByKyverno(secret *corev1.Secret) bool {
|
2022-05-11 14:58:14 +00:00
|
|
|
if secret != nil {
|
|
|
|
labels := secret.GetLabels()
|
|
|
|
if labels == nil {
|
|
|
|
return false
|
|
|
|
}
|
2022-10-13 09:46:05 +00:00
|
|
|
if labels[managedByLabel] != kyvernov1.ValueKyvernoApp {
|
2022-05-11 14:58:14 +00:00
|
|
|
return false
|
|
|
|
}
|
2022-05-11 08:05:13 +00:00
|
|
|
}
|
2022-05-11 14:58:14 +00:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// InClusterServiceName The generated service name should be the common name for TLS certificate
|
|
|
|
func InClusterServiceName() string {
|
|
|
|
return config.KyvernoServiceName() + "." + config.KyvernoNamespace() + ".svc"
|
|
|
|
}
|
|
|
|
|
|
|
|
func GenerateTLSPairSecretName() string {
|
|
|
|
return InClusterServiceName() + ".kyverno-tls-pair"
|
|
|
|
}
|
2022-05-11 08:05:13 +00:00
|
|
|
|
2022-05-11 14:58:14 +00:00
|
|
|
func GenerateRootCASecretName() string {
|
|
|
|
return InClusterServiceName() + ".kyverno-tls-ca"
|
2022-05-11 08:05:13 +00:00
|
|
|
}
|