Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 30 additions & 11 deletions pkg/controllers/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ import (
"errors"
"fmt"
"math/rand"
"strings"
"regexp"
"time"

privateca "cloud.google.com/go/security/privateca/apiv1"
casapi "cloud.google.com/go/security/privateca/apiv1/privatecapb"
cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
issuerapi "github.com/cert-manager/issuer-lib/api/v1alpha1"
controllers "github.com/cert-manager/issuer-lib/controllers"
"github.com/cert-manager/issuer-lib/controllers/signer"
"github.com/google/uuid"
"github.com/spf13/viper"
"google.golang.org/api/option"
casapi "google.golang.org/genproto/googleapis/cloud/security/privateca/v1"
durationpb "google.golang.org/protobuf/types/known/durationpb"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who is (Arkea)?


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
}
34 changes: 33 additions & 1 deletion pkg/controllers/signer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"google.golang.org/genproto/googleapis/cloud/security/privateca/v1"
"google.golang.org/api/privateca/v1"

"github.com/jetstack/google-cas-issuer/api/v1beta1"
)
Expand Down 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