mirror of
https://github.com/pomerium/pomerium.git
synced 2025-07-17 16:48:13 +02:00
cryptutil: add a function to normalize PEM files so that leaf certificates appear first (#5642)
## Summary Go requires that the first certificate in a bundle be the one associated with a private key: > LoadX509KeyPair reads and parses a public/private key pair from a pair of files. The files must contain PEM encoded data. The certificate file may contain intermediate certificates following the leaf certificate to form a certificate chain. On successful return, Certificate.Leaf will be populated. I don't think Go is unusual in this regard, but to make the code more tolerant, add a new `NormalizePEM` function which will take raw PEM data and rewrite it so that leaf certificates appear first. This will be used in zero and the enterprise console. ## Related issues - [ENG-2433](https://linear.app/pomerium/issue/ENG-2423/enterprise-console-updatekeypair-check-is-too-restrictive) ## Checklist - [x] reference any related issues - [x] updated unit tests - [x] add appropriate label (`enhancement`, `bug`, `breaking`, `dependencies`, `ci`) - [x] ready for review
This commit is contained in:
parent
6e765abe2e
commit
9631d9ff1c
3 changed files with 285 additions and 0 deletions
55
pkg/cryptutil/pem_test.go
Normal file
55
pkg/cryptutil/pem_test.go
Normal file
|
@ -0,0 +1,55 @@
|
|||
package cryptutil_test
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/pomerium/pomerium/internal/testutil"
|
||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||
)
|
||||
|
||||
func TestNormalizePEM(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
rootCA, intermediateCA, cert := testutil.GenerateCertificateChain(t)
|
||||
|
||||
for _, tc := range []struct {
|
||||
input []byte
|
||||
expect []byte
|
||||
}{
|
||||
{
|
||||
input: slices.Concat(rootCA.PublicPEM, intermediateCA.PublicPEM, cert.PublicPEM, cert.PrivateKeyPEM),
|
||||
expect: slices.Concat(cert.PublicPEM, cert.PrivateKeyPEM, intermediateCA.PublicPEM, rootCA.PublicPEM),
|
||||
},
|
||||
{
|
||||
input: slices.Concat(cert.PublicPEM, cert.PrivateKeyPEM, intermediateCA.PublicPEM, rootCA.PublicPEM),
|
||||
expect: slices.Concat(cert.PublicPEM, cert.PrivateKeyPEM, intermediateCA.PublicPEM, rootCA.PublicPEM),
|
||||
},
|
||||
{
|
||||
input: nil,
|
||||
expect: nil,
|
||||
},
|
||||
{
|
||||
input: []byte("\n\n\nNON PEM DATA\n\n\n"),
|
||||
expect: []byte("\n\n\nNON PEM DATA\n\n\n"),
|
||||
},
|
||||
{
|
||||
input: rootCA.PublicPEM,
|
||||
expect: rootCA.PublicPEM,
|
||||
},
|
||||
{
|
||||
input: slices.Concat(rootCA.PublicPEM, intermediateCA.PublicPEM, cert.PublicPEM, cert.PrivateKeyPEM),
|
||||
expect: slices.Concat(cert.PublicPEM, cert.PrivateKeyPEM, intermediateCA.PublicPEM, rootCA.PublicPEM),
|
||||
},
|
||||
{
|
||||
// looks a bit weird, but the text before a block gets moved with it
|
||||
input: slices.Concat([]byte("BEFORE\n"), intermediateCA.PublicPEM, []byte("BETWEEN\n"), cert.PublicPEM, []byte("AFTER\n")),
|
||||
expect: slices.Concat([]byte("BETWEEN\n"), cert.PublicPEM, []byte("AFTER\n"), []byte("BEFORE\n"), intermediateCA.PublicPEM),
|
||||
},
|
||||
} {
|
||||
actual := cryptutil.NormalizePEM(tc.input)
|
||||
assert.Equal(t, string(tc.expect), string(actual))
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue