Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor kmsca constructor to accept x509.Certificates #917

Merged
merged 2 commits into from
Dec 12, 2022
Merged
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
15 changes: 14 additions & 1 deletion cmd/app/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
package app

import (
"bytes"
"context"
"crypto/x509"
"flag"
"fmt"
"net/http"
Expand All @@ -38,6 +40,7 @@ import (
"github.com/sigstore/fulcio/pkg/ca/tinkca"
"github.com/sigstore/fulcio/pkg/config"
"github.com/sigstore/fulcio/pkg/log"
"github.com/sigstore/sigstore/pkg/cryptoutils"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
Expand Down Expand Up @@ -211,7 +214,17 @@ func runServeCmd(cmd *cobra.Command, args []string) {
case "ephemeralca":
baseca, err = ephemeralca.NewEphemeralCA()
case "kmsca":
baseca, err = kmsca.NewKMSCA(cmd.Context(), viper.GetString("kms-resource"), viper.GetString("kms-cert-chain-path"))
var data []byte
data, err = os.ReadFile(filepath.Clean(viper.GetString("kms-cert-chain-path")))
if err != nil {
log.Logger.Fatalf("error reading the kms certificate chain from '%s': %v", viper.GetString("kms-cert-chain-path"), err)
}
var certs []*x509.Certificate
certs, err = cryptoutils.LoadCertificatesFromPEM(bytes.NewReader(data))
if err != nil {
log.Logger.Fatalf("error loading the PEM certificates from the kms certificate chain from '%s': %v", viper.GetString("kms-cert-chain-path"), err)
}
baseca, err = kmsca.NewKMSCA(cmd.Context(), viper.GetString("kms-resource"), certs)
case "tinkca":
baseca, err = tinkca.NewTinkCA(cmd.Context(),
viper.GetString("tink-kms-resource"), viper.GetString("tink-keyset-path"), viper.GetString("tink-cert-chain-path"))
Expand Down
17 changes: 3 additions & 14 deletions pkg/ca/kmsca/kmsca.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,12 @@
package kmsca

import (
"bytes"
"context"
"crypto"
"os"
"path/filepath"
"crypto/x509"

"github.com/sigstore/fulcio/pkg/ca"
"github.com/sigstore/fulcio/pkg/ca/baseca"
"github.com/sigstore/sigstore/pkg/cryptoutils"
"github.com/sigstore/sigstore/pkg/signature/kms"

// Register the provider-specific plugins
Expand All @@ -38,7 +35,7 @@ type kmsCA struct {
baseca.BaseCA
}

func NewKMSCA(ctx context.Context, kmsKey, certPath string) (ca.CertificateAuthority, error) {
func NewKMSCA(ctx context.Context, kmsKey string, certs []*x509.Certificate) (ca.CertificateAuthority, error) {
var ica kmsCA

kmsSigner, err := kms.Get(ctx, kmsKey, crypto.SHA256)
Expand All @@ -54,15 +51,7 @@ func NewKMSCA(ctx context.Context, kmsKey, certPath string) (ca.CertificateAutho
ica.SignerWithChain = &sc

sc.Signer = signer

data, err := os.ReadFile(filepath.Clean(certPath))
if err != nil {
return nil, err
}
sc.Certs, err = cryptoutils.LoadCertificatesFromPEM(bytes.NewReader(data))
if err != nil {
return nil, err
}
sc.Certs = certs
if err := ca.VerifyCertChain(sc.Certs, sc.Signer); err != nil {
return nil, err
}
Expand Down
29 changes: 4 additions & 25 deletions pkg/ca/kmsca/kmsca_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ import (
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"os"
"path/filepath"
"reflect"
"strings"
"testing"
Expand All @@ -33,23 +31,12 @@ import (
)

func TestNewKMSCA(t *testing.T) {
dir := t.TempDir()
certPath := filepath.Join(dir, "cert.pem")

rootCert, rootKey, _ := test.GenerateRootCA()
subCert, subKey, _ := test.GenerateSubordinateCA(rootCert, rootKey)

chain := []*x509.Certificate{subCert, rootCert}
pemChain, err := cryptoutils.MarshalCertificatesToPEM(chain)
if err != nil {
t.Fatalf("error marshalling cert chain: %v", err)
}
err = os.WriteFile(certPath, pemChain, 0600)
if err != nil {
t.Fatalf("error writing pem chain: %v", err)
}

ca, err := NewKMSCA(context.WithValue(context.TODO(), fake.KmsCtxKey{}, subKey), "fakekms://key", certPath)
ca, err := NewKMSCA(context.WithValue(context.TODO(), fake.KmsCtxKey{}, subKey), "fakekms://key", chain)
if err != nil {
t.Fatalf("unexpected error creating KMS CA: %v", err)
}
Expand All @@ -63,7 +50,7 @@ func TestNewKMSCA(t *testing.T) {
t.Fatalf("unexpected number of chains: %d", len(rootChains))
}
if !reflect.DeepEqual(rootChains[0], chain) {
t.Fatal("cert chains do not match")
t.Fatalf("cert chains do not match")
}

// Expect signer and certificate's public keys match
Expand All @@ -78,22 +65,14 @@ func TestNewKMSCA(t *testing.T) {

// Failure: Mismatch between signer and certificate key
otherPriv, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
_, err = NewKMSCA(context.WithValue(context.TODO(), fake.KmsCtxKey{}, otherPriv), "fakekms://key", certPath)
_, err = NewKMSCA(context.WithValue(context.TODO(), fake.KmsCtxKey{}, otherPriv), "fakekms://key", chain)
if err == nil || !strings.Contains(err.Error(), "ecdsa public keys are not equal") {
t.Fatalf("expected error with mismatched public keys, got %v", err)
}

// Failure: Invalid certificate chain
otherRootCert, _, _ := test.GenerateRootCA()
pemChain, err = cryptoutils.MarshalCertificatesToPEM([]*x509.Certificate{subCert, otherRootCert})
if err != nil {
t.Fatalf("error marshalling cert chain: %v", err)
}
err = os.WriteFile(certPath, pemChain, 0600)
if err != nil {
t.Fatalf("error writing pem chain: %v", err)
}
_, err = NewKMSCA(context.WithValue(context.TODO(), fake.KmsCtxKey{}, subKey), "fakekms://key", certPath)
_, err = NewKMSCA(context.WithValue(context.TODO(), fake.KmsCtxKey{}, subKey), "fakekms://key", []*x509.Certificate{subCert, otherRootCert})
if err == nil || !strings.Contains(err.Error(), "certificate signed by unknown authority") {
t.Fatalf("expected error with invalid certificate chain, got %v", err)
}
Expand Down