2021-03-13 00:09:16 +00:00
|
|
|
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
2020-09-23 13:53:21 +00:00
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
|
|
|
package dynamiccertauthority
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
|
|
|
"go.pinniped.dev/internal/dynamiccert"
|
|
|
|
"go.pinniped.dev/internal/testutil"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestCAIssuePEM(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2021-03-11 21:20:25 +00:00
|
|
|
provider := dynamiccert.New(t.Name())
|
2020-09-23 13:53:21 +00:00
|
|
|
ca := New(provider)
|
|
|
|
|
2020-10-23 19:34:25 +00:00
|
|
|
goodCACrtPEM0, goodCAKeyPEM0, err := testutil.CreateCertificate(
|
|
|
|
time.Now().Add(-time.Hour),
|
|
|
|
time.Now().Add(time.Hour),
|
|
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
goodCACrtPEM1, goodCAKeyPEM1, err := testutil.CreateCertificate(
|
|
|
|
time.Now().Add(-time.Hour),
|
|
|
|
time.Now().Add(time.Hour),
|
|
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-09-23 13:53:21 +00:00
|
|
|
steps := []struct {
|
2020-10-23 19:34:25 +00:00
|
|
|
name string
|
|
|
|
caCrtPEM, caKeyPEM []byte
|
|
|
|
wantError string
|
2020-09-23 13:53:21 +00:00
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "no cert+key",
|
|
|
|
wantError: "could not load CA: tls: failed to find any PEM data in certificate input",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "only cert",
|
2020-10-23 19:34:25 +00:00
|
|
|
caCrtPEM: goodCACrtPEM0,
|
2021-03-11 21:20:25 +00:00
|
|
|
wantError: "TestCAIssuePEM: attempt to set invalid key pair: tls: failed to find any PEM data in key input",
|
2020-09-23 13:53:21 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "only key",
|
2020-10-23 19:34:25 +00:00
|
|
|
caKeyPEM: goodCAKeyPEM0,
|
2021-03-11 21:20:25 +00:00
|
|
|
wantError: "TestCAIssuePEM: attempt to set invalid key pair: tls: failed to find any PEM data in certificate input",
|
2020-09-23 13:53:21 +00:00
|
|
|
},
|
|
|
|
{
|
2020-10-23 19:34:25 +00:00
|
|
|
name: "new cert+key",
|
|
|
|
caCrtPEM: goodCACrtPEM0,
|
|
|
|
caKeyPEM: goodCAKeyPEM0,
|
2020-09-23 13:53:21 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "same cert+key",
|
|
|
|
},
|
|
|
|
{
|
2020-10-23 19:34:25 +00:00
|
|
|
name: "another new cert+key",
|
|
|
|
caCrtPEM: goodCACrtPEM1,
|
|
|
|
caKeyPEM: goodCAKeyPEM1,
|
2020-09-23 13:53:21 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "bad cert",
|
2020-10-23 19:34:25 +00:00
|
|
|
caCrtPEM: []byte("this is not a cert"),
|
|
|
|
caKeyPEM: goodCAKeyPEM0,
|
2021-03-11 21:20:25 +00:00
|
|
|
wantError: "TestCAIssuePEM: attempt to set invalid key pair: tls: failed to find any PEM data in certificate input",
|
2020-09-23 13:53:21 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "bad key",
|
2020-10-23 19:34:25 +00:00
|
|
|
caCrtPEM: goodCACrtPEM0,
|
|
|
|
caKeyPEM: []byte("this is not a key"),
|
2021-03-11 21:20:25 +00:00
|
|
|
wantError: "TestCAIssuePEM: attempt to set invalid key pair: tls: failed to find any PEM data in key input",
|
2020-09-23 13:53:21 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "mismatch cert+key",
|
2020-10-23 19:34:25 +00:00
|
|
|
caCrtPEM: goodCACrtPEM0,
|
|
|
|
caKeyPEM: goodCAKeyPEM1,
|
2021-03-11 21:20:25 +00:00
|
|
|
wantError: "TestCAIssuePEM: attempt to set invalid key pair: tls: private key does not match public key",
|
2020-09-23 13:53:21 +00:00
|
|
|
},
|
|
|
|
{
|
2020-10-23 19:34:25 +00:00
|
|
|
name: "good cert+key again",
|
|
|
|
caCrtPEM: goodCACrtPEM0,
|
|
|
|
caKeyPEM: goodCAKeyPEM0,
|
2020-09-23 13:53:21 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, step := range steps {
|
|
|
|
step := step
|
|
|
|
t.Run(step.name, func(t *testing.T) {
|
2020-10-23 19:34:25 +00:00
|
|
|
// Can't run these steps in parallel, because each one depends on the previous steps being
|
|
|
|
// run.
|
2020-09-23 13:53:21 +00:00
|
|
|
|
2021-03-11 21:20:25 +00:00
|
|
|
crtPEM, keyPEM, err := issuePEM(provider, ca, step.caCrtPEM, step.caKeyPEM)
|
2020-09-23 13:53:21 +00:00
|
|
|
|
|
|
|
if step.wantError != "" {
|
|
|
|
require.EqualError(t, err, step.wantError)
|
|
|
|
require.Empty(t, crtPEM)
|
|
|
|
require.Empty(t, keyPEM)
|
|
|
|
} else {
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotEmpty(t, crtPEM)
|
|
|
|
require.NotEmpty(t, keyPEM)
|
|
|
|
|
2020-10-23 19:34:25 +00:00
|
|
|
caCrtPEM, _ := provider.CurrentCertKeyContent()
|
2021-03-13 00:09:16 +00:00
|
|
|
crtAssertions := testutil.ValidateClientCertificate(t, string(caCrtPEM), string(crtPEM))
|
|
|
|
crtAssertions.RequireCommonName("some-username")
|
|
|
|
crtAssertions.RequireOrganizations([]string{"some-group1", "some-group2"})
|
2020-09-23 13:53:21 +00:00
|
|
|
crtAssertions.RequireLifetime(time.Now(), time.Now().Add(time.Hour*24), time.Minute*10)
|
|
|
|
crtAssertions.RequireMatchesPrivateKey(string(keyPEM))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2021-03-11 21:20:25 +00:00
|
|
|
|
|
|
|
func issuePEM(provider dynamiccert.Provider, ca *CA, caCrt, caKey []byte) ([]byte, []byte, error) {
|
|
|
|
// if setting fails, look at that error
|
|
|
|
if caCrt != nil || caKey != nil {
|
|
|
|
if err := provider.SetCertKeyContent(caCrt, caKey); err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// otherwise check to see if their is an issuing error
|
2021-03-13 00:09:16 +00:00
|
|
|
return ca.IssueClientCertPEM("some-username", []string{"some-group1", "some-group2"}, time.Hour*24)
|
2021-03-11 21:20:25 +00:00
|
|
|
}
|