Skip to content

Commit

Permalink
Remove requirement for specifying certificateAuthority
Browse files Browse the repository at this point in the history
Signed-off-by: Priya Wadhwa <[email protected]>
  • Loading branch information
priyawadhwa committed Nov 22, 2022
1 parent 1322979 commit 29c44b1
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 14 deletions.
2 changes: 1 addition & 1 deletion cmd/app/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func newServeCmd() *cobra.Command {
cmd.Flags().String("log_type", "dev", "logger type to use (dev/prod)")
cmd.Flags().String("ca", "", "googleca | tinkca | pkcs11ca | fileca | kmsca | ephemeralca (for testing)")
cmd.Flags().String("aws-hsm-root-ca-path", "", "Path to root CA on disk (only used with AWS HSM)")
cmd.Flags().String("gcp_private_ca_parent", "", "private ca parent: projects/<project>/locations/<location>/caPools/<caPool>/certificateAuthorities/<certificateAuthority> (only used with --ca googleca)")
cmd.Flags().String("gcp_private_ca_parent", "", "private ca parent: projects/<project>/locations/<location>/caPools/<caPool> (only used with --ca googleca)")
cmd.Flags().String("hsm-caroot-id", "", "HSM ID for Root CA (only used with --ca pkcs11ca)")
cmd.Flags().String("ct-log-url", "http://localhost:6962/test", "host and path (with log prefix at the end) to the ct log")
cmd.Flags().String("ct-log-public-key-path", "", "Path to a PEM-encoded public key of the CT log, used to verify SCTs")
Expand Down
71 changes: 58 additions & 13 deletions pkg/ca/googleca/v1/googleca.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ import (
"github.com/sigstore/fulcio/pkg/ca"
"github.com/sigstore/fulcio/pkg/identity"
"github.com/sigstore/sigstore/pkg/cryptoutils"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
"google.golang.org/protobuf/types/known/durationpb"
)

type CertAuthorityService struct {
parent string
caPoolParent string
client *privateca.CertificateAuthorityClient
certAuthorityParent string
caPoolParent string
client *privateca.CertificateAuthorityClient

// protected by once
cachedRoots [][]*x509.Certificate
Expand All @@ -52,14 +53,19 @@ func NewCertAuthorityService(ctx context.Context, parent string, opts ...option.
if err != nil {
return nil, err
}
// parent should be in the form projects/*/locations/*/caPools/*/certificateAuthorities/*
// to create a cert, we only want projects/*/locations/*/caPools/*
caPoolParent := strings.Split(parent, "/certificateAuthorities")
return &CertAuthorityService{
parent: parent,
client: client,
caPoolParent: caPoolParent[0],
}, nil
c := CertAuthorityService{
client: client,
}
if !strings.Contains(parent, "certificateAuthorities") {
c.caPoolParent = parent
} else {
// parent should be in the form projects/*/locations/*/caPools/*/certificateAuthorities/*
// to create a cert, we only want projects/*/locations/*/caPools/*
caPoolParent := strings.Split(parent, "/certificateAuthorities")
c.caPoolParent = caPoolParent[0]
c.certAuthorityParent = parent
}
return &c, nil
}

// getPubKeyFormat Returns the PublicKey KeyFormat required by gcp privateca.
Expand Down Expand Up @@ -147,10 +153,18 @@ func (c *CertAuthorityService) TrustBundle(ctx context.Context) ([][]*x509.Certi
return c.cachedRoots, nil
}

// fetch the latest values for the specified CA
// if a specific certificate authority was specified, use that one
if c.certAuthorityParent != "" {
return c.getCertificateAuthorityTrustBundle(ctx)
}
// otherwise, get certs from all of the CAs in the pool
return c.listCertificateAuthorityTrustBundle(ctx)
}

func (c *CertAuthorityService) getCertificateAuthorityTrustBundle(ctx context.Context) ([][]*x509.Certificate, error) {
var roots [][]*x509.Certificate
ca, err := c.client.GetCertificateAuthority(ctx, &privatecapb.GetCertificateAuthorityRequest{
Name: c.parent,
Name: c.certAuthorityParent,
})
if err != nil {
return nil, err
Expand All @@ -172,6 +186,37 @@ func (c *CertAuthorityService) TrustBundle(ctx context.Context) ([][]*x509.Certi
return c.cachedRoots, nil
}

func (c *CertAuthorityService) listCertificateAuthorityTrustBundle(ctx context.Context) ([][]*x509.Certificate, error) {
// fetch the latest values for the specified CA pool
var roots [][]*x509.Certificate
cas := c.client.ListCertificateAuthorities(ctx, &privatecapb.ListCertificateAuthoritiesRequest{
Parent: c.caPoolParent,
})
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
}
// if we fail to parse the PEM content, return an error
caCerts, err := cryptoutils.LoadCertificatesFromPEM(strings.NewReader(strings.Join(ca.PemCaCertificates, "")))
if err != nil {
return [][]*x509.Certificate{}, fmt.Errorf("failed parsing PemCACertificates response: %w", err)
}
if len(caCerts) == 0 {
return [][]*x509.Certificate{}, fmt.Errorf("error fetching root certificates")
}
roots = append(roots, caCerts)
}
c.cachedRootsOnce.Do(func() {
c.cachedRoots = roots
})

return c.cachedRoots, nil
}

func (c *CertAuthorityService) CreateCertificate(ctx context.Context, principal identity.Principal, publicKey crypto.PublicKey) (*ca.CodeSigningCertificate, error) {
cert, err := ca.MakeX509(ctx, principal, publicKey)
if err != nil {
Expand Down

0 comments on commit 29c44b1

Please sign in to comment.