Skip to content

Commit

Permalink
Merge pull request #146 from gardener/enh/ca-with-pkcs8
Browse files Browse the repository at this point in the history
PKCS8 private keys for CA issuers
  • Loading branch information
MartinWeindel authored Oct 26, 2023
2 parents 109398a + d625e83 commit cc16ebc
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 9 deletions.
6 changes: 3 additions & 3 deletions hack/check-cert-secret.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ prepareParts()
# extract certificate from certificate secret
kubectl -n $NS get secret $(kubectl -n $NS get certificates.cert.gardener.cloud $CERTNAME -o=jsonpath='{.spec.secretRef.name}') -o=jsonpath='{.data.tls\.crt}' | base64 -d > "$X509CERT"

CSPLIT=gcsplit # use gnu csplit on mac (install with "brew install coreutils")
which $CSPLIT || export CSPLIT=csplit
# split certificate and chain

#cat $X509CERT | awk -v PREFIX="$PREFIX" 'split_after == 1 {n++;split_after=0} /-----END CERTIFICATE-----/ {split_after=1} {print > (PREFIX "cert" n ".pem")}'
csplit -s -z -f "$PREFIX/cert-" -b "%d.pem" $X509CERT '/-----BEGIN CERTIFICATE-----/' '{*}'
$CSPLIT -s -z -f "$PREFIX/cert-" -b "%d.pem" $X509CERT '/-----BEGIN CERTIFICATE-----/' '{*}'
}

cleanup()
Expand Down
85 changes: 85 additions & 0 deletions pkg/cert/legobridge/cakeypair_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* SPDX-FileCopyrightText: 2022 SAP SE or an SAP affiliate company and Gardener contributors
*
* SPDX-License-Identifier: Apache-2.0
*/

package legobridge

import (
"crypto"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
)

var _ = Describe("PKI Helpers", func() {
Context("CAKeyPairFromSecretData", func() {
It("works for ec key", func() {
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
Expect(err).To(Succeed())
keyBytes, err := x509.MarshalECPrivateKey(priv)
Expect(err).To(Succeed())
data, err := createCertificate(priv, priv.Public(), "EC PRIVATE KEY", keyBytes)
Expect(err).To(Succeed())

_, err = CAKeyPairFromSecretData(data)
Expect(err).To(Succeed())
})

It("works for PKCS1 rsa key", func() {
priv, err := rsa.GenerateKey(rand.Reader, 2048)
Expect(err).To(Succeed())
keyBytes := x509.MarshalPKCS1PrivateKey(priv)
data, err := createCertificate(priv, priv.Public(), "RSA PRIVATE KEY", keyBytes)
Expect(err).To(Succeed())

_, err = CAKeyPairFromSecretData(data)
Expect(err).To(Succeed())
})

It("works for PKCS8 rsa key", func() {
priv, err := rsa.GenerateKey(rand.Reader, 2048)
Expect(err).To(Succeed())
keyBytes, err := x509.MarshalPKCS8PrivateKey(priv)
Expect(err).To(Succeed())
data, err := createCertificate(priv, priv.Public(), "PRIVATE KEY", keyBytes)
Expect(err).To(Succeed())

_, err = CAKeyPairFromSecretData(data)
Expect(err).To(Succeed())
})
})
})

func createCertificate(privKey crypto.PrivateKey, pubKey crypto.PublicKey, header string, privKeyBytes []byte) (map[string][]byte, error) {
template := &x509.Certificate{
SerialNumber: big.NewInt(1234),
Subject: pkix.Name{CommonName: "example.com"},
NotBefore: time.Now(),
NotAfter: time.Now().Add(time.Hour * 24 * 365),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
}
derBytes, err := x509.CreateCertificate(rand.Reader, template, template, pubKey, privKey)
if err != nil {
return nil, err
}
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
keyPEM := pem.EncodeToMemory(&pem.Block{Type: header, Bytes: privKeyBytes})
return map[string][]byte{
corev1.TLSCertKey: certPEM,
corev1.TLSPrivateKeyKey: keyPEM,
}, nil
}
19 changes: 19 additions & 0 deletions pkg/cert/legobridge/legobridge_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* SPDX-FileCopyrightText: 2022 SAP SE or an SAP affiliate company and Gardener contributors
*
* SPDX-License-Identifier: Apache-2.0
*/

package legobridge_test

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestCore(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Legobridge Suite")
}
13 changes: 7 additions & 6 deletions pkg/cert/legobridge/pki.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ var (
)

const (
// DefaultSigAlgo is the default Signature Algorithm (letsencrypt default).
DefaultSigAlgo x509.SignatureAlgorithm = x509.SHA256WithRSA
// DefaultPubKeyAlgo is the default Public Key Algorithm (letsencrypt default).
DefaultPubKeyAlgo x509.PublicKeyAlgorithm = x509.RSA
// DefaultCertKeyUsage is the default Key Usage (letsencrypt default).
Expand Down Expand Up @@ -389,10 +387,13 @@ func bytesToPrivateKey(data []byte) (crypto.PrivateKey, error) {
if err == nil {
return key, nil
}

key2, err2 := x509.ParsePKCS1PrivateKey(block.Bytes)
if err2 != nil {
return nil, fmt.Errorf("decoding private key failed with %s (ec) and %s (rsa)", err, err2)
if err2 == nil {
return key2, nil
}
key3, err3 := x509.ParsePKCS8PrivateKey(block.Bytes)
if err3 != nil {
return nil, fmt.Errorf("decoding private key failed with %s (ec) and %s (rsa PKCS1) and %s (PKCS8)", err, err2, err3)
}
return key2, nil
return key3, nil
}

0 comments on commit cc16ebc

Please sign in to comment.