Skip to content

Commit

Permalink
Fix issue cert-manager#148
Browse files Browse the repository at this point in the history
  • Loading branch information
F5748 authored and ZzubbuzZ committed May 7, 2024
1 parent ce03726 commit 40b7f86
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 10 deletions.
39 changes: 29 additions & 10 deletions pkg/controllers/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"errors"
"fmt"
"math/rand"
"strings"
"regexp"
"time"

privateca "cloud.google.com/go/security/privateca/apiv1"
Expand Down Expand Up @@ -194,25 +194,44 @@ func (c *GoogleCAS) createCasClient(ctx context.Context, resourceNamespace strin
// Additionally, for each PEM block, all whitespace is trimmed and a single new line is
// appended, in case software consuming the resulting secret writes the PEM blocks
// directly into a config file without parsing them.
//
// Unfortunatly, Google CAS API can send multiple certs within the same pemCertificateChain
// element, so we (Arkea) have to parse and re-order this

func extractCertAndCA(resp *casapi.Certificate) (cert []byte, ca []byte, err error) {
if resp == nil {
return nil, nil, errors.New("extractCertAndCA: certificate response is nil")
}

certBuf := &bytes.Buffer{}
var certs []string

re := regexp.MustCompile(`(?sU)-{5}BEGIN CERTIFICATE(?:.+)END CERTIFICATE-{5}`)

// Write the leaf to the buffer
certBuf.WriteString(strings.TrimSpace(resp.PemCertificate))
certBuf.WriteRune('\n')
// parse the certificate and store it in certs slice
match := re.FindString(resp.PemCertificate)
if match == "" {
return nil, nil, errors.New("extractCertAndCA: leaf certificate is not properly parsed")
}
certs = append(certs, match)

// Write any remaining certificates except for the root-most one
for _, c := range resp.PemCertificateChain[:len(resp.PemCertificateChain)-1] {
certBuf.WriteString(strings.TrimSpace(c))
for _, casCert := range resp.PemCertificateChain {
match := re.FindAllString(casCert, -1)
if len(match) == 0 {
return nil, nil, errors.New("extractCertAndCA: the certificate chain is not properly parsed")
}
// Append all matched certs from the certificate chain to the certs slice
certs = append(certs, match...)
}

for _, cert := range certs[:len(certs)-1] {
// For all the certificate chain, but the most root one (CA cert)
// We write it to the cert buffer
certBuf.WriteString(cert)
certBuf.WriteRune('\n')
}

// Return the root-most certificate in the CA field.
return certBuf.Bytes(), []byte(
strings.TrimSpace(
resp.PemCertificateChain[len(resp.PemCertificateChain)-1],
) + "\n"), nil
return certBuf.Bytes(), []byte(certs[len(certs)-1] + "\n"), nil
}
32 changes: 32 additions & 0 deletions pkg/controllers/signer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,38 @@ intermediate1
[]byte(`-----BEGIN CERTIFICATE-----
root
-----END CERTIFICATE-----
`),
nil,
},
},
{
name: "Extract the root cert if several certificates are passed within the last element of the certificate chain",
input: &privateca.Certificate{
PemCertificate: `-----BEGIN CERTIFICATE-----
leaf
-----END CERTIFICATE-----`,
PemCertificateChain: []string{`-----BEGIN CERTIFICATE-----
intermediate2
-----END CERTIFICATE-----`, `-----BEGIN CERTIFICATE-----
intermediate1
-----END CERTIFICATE-----\r\n-----BEGIN CERTIFICATE-----
root
-----END CERTIFICATE-----`},
},
expected: expected{
[]byte(`-----BEGIN CERTIFICATE-----
leaf
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
intermediate2
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
intermediate1
-----END CERTIFICATE-----
`),
[]byte(`-----BEGIN CERTIFICATE-----
root
-----END CERTIFICATE-----
`),
nil,
},
Expand Down

0 comments on commit 40b7f86

Please sign in to comment.