Skip to content

Commit

Permalink
return [][]*x509.Certificate
Browse files Browse the repository at this point in the history
Signed-off-by: Bob Callaway <bcallaway@google.com>
  • Loading branch information
bobcallaway committed Jul 19, 2022
1 parent fb15fe9 commit a3fcc08
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 48 deletions.
4 changes: 2 additions & 2 deletions cmd/app/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,6 @@ type TrivialCertificateAuthority struct {
func (tca *TrivialCertificateAuthority) CreateCertificate(context.Context, identity.Principal, crypto.PublicKey) (*ca.CodeSigningCertificate, error) {
return nil, errors.New("CreateCertificate always fails for testing")
}
func (tca *TrivialCertificateAuthority) Root(ctx context.Context) ([]*x509.Certificate, error) {
return []*x509.Certificate{}, nil
func (tca *TrivialCertificateAuthority) TrustBundle(ctx context.Context) ([][]*x509.Certificate, error) {
return [][]*x509.Certificate{}, nil
}
4 changes: 2 additions & 2 deletions pkg/ca/baseca/baseca.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func (bca *BaseCA) CreateCertificate(ctx context.Context, principal identity.Pri
return ca.CreateCSCFromDER(finalCertBytes, certChain)
}

func (bca *BaseCA) Root(ctx context.Context) ([]*x509.Certificate, error) {
func (bca *BaseCA) TrustBundle(ctx context.Context) ([][]*x509.Certificate, error) {
certs, _ := bca.GetSignerWithChain()
return certs, nil
return [][]*x509.Certificate{certs}, nil
}
7 changes: 5 additions & 2 deletions pkg/ca/baseca/baseca_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,15 @@ func TestBaseCARoot(t *testing.T) {
SignerWithChain: &ca.SignerCerts{Certs: certChain, Signer: signer},
}

rootBytes, err := bca.Root(context.TODO())
rootChains, err := bca.TrustBundle(context.TODO())
if err != nil {
t.Fatalf("unexpected error reading root: %v", err)
}
if len(rootChains) != 1 {
t.Fatalf("unexpected number of chains: %d", len(rootChains))
}

if !reflect.DeepEqual(certChain, rootBytes) {
if !reflect.DeepEqual(certChain, rootChains[0]) {
t.Fatal("expected cert chains to be equivalent")
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/ca/ca.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ import (
// fetching the CA trust bundle.
type CertificateAuthority interface {
CreateCertificate(context.Context, identity.Principal, crypto.PublicKey) (*CodeSigningCertificate, error)
Root(ctx context.Context) ([]*x509.Certificate, error)
TrustBundle(ctx context.Context) ([][]*x509.Certificate, error)
}
56 changes: 32 additions & 24 deletions pkg/ca/googleca/v1/googleca.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,32 +136,40 @@ func Req(parent string, pemBytes []byte, cert *x509.Certificate) (*privatecapb.C
}, nil
}

func (c *CertAuthorityService) Root(ctx context.Context) ([]*x509.Certificate, error) {
c.cachedRootsOnce.Do(func() {
var pems string
var err error
cas := c.client.ListCertificateAuthorities(ctx, &privatecapb.ListCertificateAuthoritiesRequest{
Parent: c.parent,
})
for {
c, done := cas.Next()
if done == iterator.Done {
break
}
if done != nil {
break
}
pems += strings.Join(c.PemCaCertificates, "")
}
c.cachedRoots, err = cryptoutils.LoadCertificatesFromPEM(strings.NewReader(pems))
if err != nil {
panic(fmt.Errorf("failed parsing PemCACertificates: %w", err))
}
func (c *CertAuthorityService) TrustBundle(ctx context.Context) ([][]*x509.Certificate, error) {
// if we've already successfully fetched the CA info, just use the cached value
if c.cachedRoots != nil {
return [][]*x509.Certificate{c.cachedRoots}, nil
}

// fetch the latest values for the specified CA
var pems string
cas := c.client.ListCertificateAuthorities(ctx, &privatecapb.ListCertificateAuthoritiesRequest{
Parent: c.parent,
})
if len(c.cachedRoots) == 0 {
return c.cachedRoots, fmt.Errorf("error fetching root certificates")
for {
ca, done := cas.Next()
if done == iterator.Done {
break
} else if done != nil {
// if the iterator returns an issue for some reason, exit
return [][]*x509.Certificate{}, done
}
pems += strings.Join(ca.PemCaCertificates, "")
}
return c.cachedRoots, nil
// if we fail to parse the PEM content, return an error
roots, err := cryptoutils.LoadCertificatesFromPEM(strings.NewReader(pems))
if err != nil {
return [][]*x509.Certificate{}, fmt.Errorf("failed parsing PemCACertificates response: %w", err)
}
if len(roots) == 0 {
return [][]*x509.Certificate{}, fmt.Errorf("error fetching root certificates")
}
c.cachedRootsOnce.Do(func() {
c.cachedRoots = roots
})

return [][]*x509.Certificate{c.cachedRoots}, nil
}

func (c *CertAuthorityService) CreateCertificate(ctx context.Context, principal identity.Principal, publicKey crypto.PublicKey) (*ca.CodeSigningCertificate, error) {
Expand Down
8 changes: 5 additions & 3 deletions pkg/ca/kmsca/kmsca_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
"github.com/sigstore/fulcio/pkg/test"
"github.com/sigstore/sigstore/pkg/cryptoutils"
"github.com/sigstore/sigstore/pkg/signature/kms/fake"
_ "github.com/sigstore/sigstore/pkg/signature/kms/fake"
)

func TestNewKMSCA(t *testing.T) {
Expand All @@ -56,11 +55,14 @@ func TestNewKMSCA(t *testing.T) {
}

// Expect certificate chain from Root matches provided certificate chain
rootBytes, err := ca.Root(context.TODO())
rootChains, err := ca.TrustBundle(context.TODO())
if err != nil {
t.Fatalf("error fetching root: %v", err)
}
if !reflect.DeepEqual(rootBytes, chain) {
if len(rootChains) != 1 {
t.Fatalf("unexpected number of chains: %d", len(rootChains))
}
if !reflect.DeepEqual(rootChains[0], chain) {
t.Fatal("cert chains do not match")
}

Expand Down
7 changes: 5 additions & 2 deletions pkg/ca/tinkca/tinkca_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,14 @@ func TestNewTinkCA(t *testing.T) {
}

// Expect certificate chain from Root matches provided certificate chain
rootBytes, err := ca.Root(context.TODO())
rootChains, err := ca.TrustBundle(context.TODO())
if err != nil {
t.Fatalf("error fetching root: %v", err)
}
if !reflect.DeepEqual(rootBytes, chain) {
if len(rootChains) != 1 {
t.Fatalf("unexpected number of chains: %d", len(rootChains))
}
if !reflect.DeepEqual(rootChains[0], chain) {
t.Fatal("cert chains do not match")
}

Expand Down
25 changes: 15 additions & 10 deletions pkg/server/grpc_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,23 +234,28 @@ func (g *grpcCAServer) CreateSigningCertificate(ctx context.Context, request *fu
func (g *grpcCAServer) GetTrustBundle(ctx context.Context, _ *fulciogrpc.GetTrustBundleRequest) (*fulciogrpc.TrustBundle, error) {
logger := log.ContextLogger(ctx)

root, err := g.ca.Root(ctx)
trustBundle, err := g.ca.TrustBundle(ctx)
if err != nil {
logger.Error("Error retrieving root cert: ", err)
logger.Error("Error retrieving trust bundle: ", err)
return nil, handleFulcioGRPCError(ctx, codes.Internal, err, genericCAError)
}

tb := &fulciogrpc.TrustBundle{
Chains: []*fulciogrpc.CertificateChain{{}},
resp := &fulciogrpc.TrustBundle{
Chains: []*fulciogrpc.CertificateChain{},
}
for _, cert := range root {
certPEM, err := cryptoutils.MarshalCertificateToPEM(cert)
if err != nil {
return nil, handleFulcioGRPCError(ctx, codes.Internal, err, genericCAError)

for _, chain := range trustBundle {
certChain := &fulciogrpc.CertificateChain{}
for _, cert := range chain {
certPEM, err := cryptoutils.MarshalCertificateToPEM(cert)
if err != nil {
return nil, handleFulcioGRPCError(ctx, codes.Internal, err, genericCAError)
}
certChain.Certificates = append(certChain.Certificates, string(certPEM))
}
tb.Chains[0].Certificates = append(tb.Chains[0].Certificates, string(certPEM))
resp.Chains = append(resp.Chains, certChain)
}
return tb, nil
return resp, nil
}

func (g *grpcCAServer) GetConfiguration(ctx context.Context, _ *fulciogrpc.GetConfigurationRequest) (*fulciogrpc.Configuration, error) {
Expand Down
4 changes: 2 additions & 2 deletions pkg/server/grpc_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1463,6 +1463,6 @@ type FailingCertificateAuthority struct {
func (fca *FailingCertificateAuthority) CreateCertificate(context.Context, identity.Principal, crypto.PublicKey) (*ca.CodeSigningCertificate, error) {
return nil, errors.New("CreateCertificate always fails for testing")
}
func (fca *FailingCertificateAuthority) Root(ctx context.Context) ([]*x509.Certificate, error) {
return nil, errors.New("Root always fails for testing")
func (fca *FailingCertificateAuthority) TrustBundle(ctx context.Context) ([][]*x509.Certificate, error) {
return nil, errors.New("TrustBundle always fails for testing")
}

0 comments on commit a3fcc08

Please sign in to comment.