toolkit/certificates/certoperator/cert_operator.go (136 lines of code) (raw):

package certoperator import ( "bytes" "context" "crypto/rsa" "crypto/x509" "encoding/pem" "errors" "github.com/Azure/webhook-tls-manager/toolkit/certificates/certgenerator" "github.com/Azure/webhook-tls-manager/toolkit/log" "k8s.io/legacy-cloud-providers/azure/retry" ) type certOperatorImp struct { certGenerator certgenerator.CertGenerator } func NewCertOperator(certGenerator certgenerator.CertGenerator) CertOperator { return &certOperatorImp{certGenerator: certGenerator} } var encodeFunc = pem.Encode func (o *certOperatorImp) pemToPrivateKey(ctx context.Context, raw string) (*rsa.PrivateKey, error) { kpb, _ := pem.Decode([]byte(raw)) if kpb == nil { log.MustGetLogger(ctx).Errorf(ctx, "Decode returns nil") return nil, errors.New("The raw pem is not a valid PEM formatted block") } return x509.ParsePKCS1PrivateKey(kpb.Bytes) } func (o *certOperatorImp) CreateSelfSignedCertificateKeyPair( ctx context.Context, csr *x509.Certificate) (*x509.Certificate, string, *rsa.PrivateKey, string, *retry.Error) { cert, key, rerr := o.certGenerator.CreateSelfSignedCertificateKeyPair(ctx, csr) if rerr != nil { log.MustGetLogger(ctx).Errorf(ctx, "CreateSelfSignedCertificateKeyPair failed: %v", rerr) return nil, "", nil, "", rerr } certPem, keyPem, err := o.getCertKeyAsPem(ctx, cert, key) if err != nil { log.MustGetLogger(ctx).Errorf(ctx, "certKeyToPem failed: %s", err) return nil, "", nil, "", retry.NewError(false, err) } log.MustGetLogger(ctx).Infof(ctx, "self signed certificate '%v' is generated successfully", csr.Subject.CommonName) return cert, certPem, key, keyPem, nil } func (o *certOperatorImp) pemToCertificate(ctx context.Context, raw string) (*x509.Certificate, error) { cpb, _ := pem.Decode([]byte(raw)) if cpb == nil { log.MustGetLogger(ctx).Errorf(ctx, "Decode returns nil") return nil, errors.New("The raw pem is not a valid PEM formatted block") } return x509.ParseCertificate(cpb.Bytes) } func (o *certOperatorImp) certificateToPem(ctx context.Context, cert *x509.Certificate) ([]byte, error) { derBytes := cert.Raw pemBlock := &pem.Block{ Type: "CERTIFICATE", Bytes: derBytes, } pemBuffer := bytes.Buffer{} err := encodeFunc(&pemBuffer, pemBlock) if err != nil { log.MustGetLogger(ctx).Errorf(ctx, "pem encode() return error %s", err) return nil, err } return pemBuffer.Bytes(), nil } func (o *certOperatorImp) privateKeyToPem(ctx context.Context, privateKey *rsa.PrivateKey) ([]byte, error) { pemBlock := &pem.Block{ Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey), } pemBuffer := bytes.Buffer{} err := encodeFunc(&pemBuffer, pemBlock) if err != nil { log.MustGetLogger(ctx).Errorf(ctx, "pem encode() return error %s", err) return nil, err } return pemBuffer.Bytes(), nil } func (o *certOperatorImp) CreateCertificateKeyPair( ctx context.Context, csr *x509.Certificate, caCert *x509.Certificate, caKey *rsa.PrivateKey) (string, string, *retry.Error) { cert, key, rerr := o.certGenerator.CreateCertificateKeyPair(ctx, csr, caCert, caKey) if rerr != nil { log.MustGetLogger(ctx).Errorf(ctx, "CreateCertificateKeyPair failed: %v", rerr) return "", "", rerr } certPem, keyPem, err := o.getCertKeyAsPem(ctx, cert, key) if err != nil { log.MustGetLogger(ctx).Errorf(ctx, "getCertKeyAsPem failed: %s", err) return "", "", retry.NewError(false, err) } log.MustGetLogger(ctx).Infof(ctx, "certificate %v is generated successfully", csr.Subject.CommonName) return certPem, keyPem, nil } func (o *certOperatorImp) CreateCertificate( ctx context.Context, csr *x509.Certificate, keyPem string, caCert *x509.Certificate, caKey *rsa.PrivateKey) (string, *retry.Error) { key, err := o.pemToPrivateKey(ctx, keyPem) if err != nil { log.MustGetLogger(ctx).Errorf(ctx, "PemToPrivateKey failed: %s", err) return "", retry.NewError(false, err) } cert, rerr := o.certGenerator.CreateCertificate(ctx, csr, key, caCert, caKey) if rerr != nil { log.MustGetLogger(ctx).Errorf(ctx, "CreateCertificate failed: %v", rerr) return "", rerr } certBytes, err := o.certificateToPem(ctx, cert) if err != nil { log.MustGetLogger(ctx).Errorf(ctx, "CertificateToPem failed: %s", err) return "", retry.NewError(false, err) } log.MustGetLogger(ctx).Infof(ctx, "certificate %v is generated successfully", csr.Subject.CommonName) return string(certBytes), nil } func (o *certOperatorImp) getCertKeyAsPem( ctx context.Context, cert *x509.Certificate, key *rsa.PrivateKey) (string, string, error) { certBytes, err := o.certificateToPem(ctx, cert) if err != nil { log.MustGetLogger(ctx).Errorf(ctx, "CertificateToPem failed: %s", err) return "", "", err } keyBytes, err := o.privateKeyToPem(ctx, key) if err != nil { log.MustGetLogger(ctx).Errorf(ctx, "PrivateKeyToPem failed: %s", err) return "", "", err } return string(certBytes), string(keyBytes), nil }