Use known CA and add tier and gcs bucket options.

This commit is contained in:
Mariano Cano 2021-06-08 17:43:52 -07:00
parent 529eb4bae9
commit ac3c754a6d
3 changed files with 120 additions and 57 deletions

View file

@ -45,11 +45,15 @@ type Options struct {
// KeyManager is the KMS used to generate keys in SoftCAS. // KeyManager is the KMS used to generate keys in SoftCAS.
KeyManager kms.KeyManager `json:"-"` KeyManager kms.KeyManager `json:"-"`
// Project and Location are parameters used in CloudCAS to create a new // Project, Location, CaPool and GCSBucket are parameters used in CloudCAS
// certificate authority. // to create a new certificate authority. If a CaPool does not exists it
Project string `json:"-"` // will be created. GCSBucket is optional, if not provided GCloud will
Location string `json:"-"` // create a managed bucket.
CaPool string `json:"-"` Project string `json:"-"`
Location string `json:"-"`
CaPool string `json:"-"`
CaPoolTier string `json:"-"`
GCSBucket string `json:"-"`
} }
// CertificateIssuer contains the properties used to use the StepCAS certificate // CertificateIssuer contains the properties used to use the StepCAS certificate

View file

@ -5,6 +5,7 @@ import (
"crypto/rand" "crypto/rand"
"crypto/x509" "crypto/x509"
"encoding/asn1" "encoding/asn1"
"encoding/json"
"encoding/pem" "encoding/pem"
"regexp" "regexp"
"strings" "strings"
@ -67,6 +68,13 @@ var revocationCodeMap = map[int]pb.RevocationReason{
10: pb.RevocationReason_ATTRIBUTE_AUTHORITY_COMPROMISE, 10: pb.RevocationReason_ATTRIBUTE_AUTHORITY_COMPROMISE,
} }
// caPoolTierMap contains the map between apv1.Options.Tier and the pb type.
var caPoolTierMap = map[string]pb.CaPool_Tier{
"": pb.CaPool_DEVOPS,
"ENTERPRISE": pb.CaPool_ENTERPRISE,
"DEVOPS": pb.CaPool_DEVOPS,
}
// CloudCAS implements a Certificate Authority Service using Google Cloud CAS. // CloudCAS implements a Certificate Authority Service using Google Cloud CAS.
type CloudCAS struct { type CloudCAS struct {
client CertificateAuthorityClient client CertificateAuthorityClient
@ -74,6 +82,7 @@ type CloudCAS struct {
project string project string
location string location string
caPool string caPool string
caPoolTier pb.CaPool_Tier
gcsBucket string gcsBucket string
} }
@ -94,7 +103,8 @@ var newCertificateAuthorityClient = func(ctx context.Context, credentialsFile st
// New creates a new CertificateAuthorityService implementation using Google // New creates a new CertificateAuthorityService implementation using Google
// Cloud CAS. // Cloud CAS.
func New(ctx context.Context, opts apiv1.Options) (*CloudCAS, error) { func New(ctx context.Context, opts apiv1.Options) (*CloudCAS, error) {
if opts.IsCreator { var caPoolTier pb.CaPool_Tier
if opts.IsCreator && opts.CertificateAuthority == "" {
switch { switch {
case opts.Project == "": case opts.Project == "":
return nil, errors.New("cloudCAS 'project' cannot be empty") return nil, errors.New("cloudCAS 'project' cannot be empty")
@ -103,7 +113,10 @@ func New(ctx context.Context, opts apiv1.Options) (*CloudCAS, error) {
case opts.CaPool == "": case opts.CaPool == "":
return nil, errors.New("cloudCAS 'caPool' cannot be empty") return nil, errors.New("cloudCAS 'caPool' cannot be empty")
} }
var ok bool
if caPoolTier, ok = caPoolTierMap[strings.ToUpper(opts.CaPoolTier)]; !ok {
return nil, errors.New("cloudCAS 'caPoolTier' is not a valid tier")
}
} else { } else {
if opts.CertificateAuthority == "" { if opts.CertificateAuthority == "" {
return nil, errors.New("cloudCAS 'certificateAuthority' cannot be empty") return nil, errors.New("cloudCAS 'certificateAuthority' cannot be empty")
@ -130,12 +143,15 @@ func New(ctx context.Context, opts apiv1.Options) (*CloudCAS, error) {
return nil, err return nil, err
} }
// GCSBucket is the the bucket name or empty for a managed bucket.
return &CloudCAS{ return &CloudCAS{
client: client, client: client,
certificateAuthority: opts.CertificateAuthority, certificateAuthority: opts.CertificateAuthority,
project: opts.Project, project: opts.Project,
location: opts.Location, location: opts.Location,
caPool: opts.CaPool, caPool: opts.CaPool,
gcsBucket: opts.GCSBucket,
caPoolTier: caPoolTier,
}, nil }, nil
} }
@ -267,6 +283,8 @@ func (c *CloudCAS) CreateCertificateAuthority(req *apiv1.CreateCertificateAuthor
return nil, errors.New("cloudCAS `location` cannot be empty") return nil, errors.New("cloudCAS `location` cannot be empty")
case c.caPool == "": case c.caPool == "":
return nil, errors.New("cloudCAS `caPool` cannot be empty") return nil, errors.New("cloudCAS `caPool` cannot be empty")
case c.caPoolTier == 0:
return nil, errors.New("cloudCAS `caPoolTier` cannot be empty")
case req.Template == nil: case req.Template == nil:
return nil, errors.New("createCertificateAuthorityRequest `template` cannot be nil") return nil, errors.New("createCertificateAuthorityRequest `template` cannot be nil")
case req.Lifetime == 0: case req.Lifetime == 0:
@ -362,14 +380,6 @@ func (c *CloudCAS) CreateCertificateAuthority(req *apiv1.CreateCertificateAuthor
return nil, errors.Wrap(err, "cloudCAS CreateCertificateAuthority failed") return nil, errors.Wrap(err, "cloudCAS CreateCertificateAuthority failed")
} }
// Enable root certificate
if req.Type == apiv1.RootCA {
ca, err = c.enableCertificateAuthority(ca)
if err != nil {
return nil, err
}
}
// Sign Intermediate CAs with the parent. // Sign Intermediate CAs with the parent.
if req.Type == apiv1.IntermediateCA { if req.Type == apiv1.IntermediateCA {
ca, err = c.signIntermediateCA(parent, ca.Name, req) ca, err = c.signIntermediateCA(parent, ca.Name, req)
@ -378,6 +388,12 @@ func (c *CloudCAS) CreateCertificateAuthority(req *apiv1.CreateCertificateAuthor
} }
} }
// Enable Certificate Authority.
ca, err = c.enableCertificateAuthority(ca)
if err != nil {
return nil, err
}
if len(ca.PemCaCertificates) == 0 { if len(ca.PemCaCertificates) == 0 {
return nil, errors.New("cloudCAS CreateCertificateAuthority failed: PemCaCertificates is empty") return nil, errors.New("cloudCAS CreateCertificateAuthority failed: PemCaCertificates is empty")
} }
@ -397,6 +413,9 @@ func (c *CloudCAS) CreateCertificateAuthority(req *apiv1.CreateCertificateAuthor
} }
} }
b, _ := json.MarshalIndent(ca, "", "\t")
println(string(b))
return &apiv1.CreateCertificateAuthorityResponse{ return &apiv1.CreateCertificateAuthorityResponse{
Name: ca.Name, Name: ca.Name,
Certificate: cert, Certificate: cert,
@ -419,6 +438,12 @@ func (c *CloudCAS) createCaPoolIfNecessary() (string, error) {
return "", errors.Wrap(err, "cloudCAS GetCaPool failed") return "", errors.Wrap(err, "cloudCAS GetCaPool failed")
} }
// PublishCrl is only supported by the enterprise tier
var publishCrl bool
if c.caPoolTier == pb.CaPool_ENTERPRISE {
publishCrl = true
}
ctx, cancel = defaultContext() ctx, cancel = defaultContext()
defer cancel() defer cancel()
@ -426,11 +451,11 @@ func (c *CloudCAS) createCaPoolIfNecessary() (string, error) {
Parent: "projects/" + c.project + "/locations/" + c.location, Parent: "projects/" + c.project + "/locations/" + c.location,
CaPoolId: c.caPool, CaPoolId: c.caPool,
CaPool: &pb.CaPool{ CaPool: &pb.CaPool{
Tier: pb.CaPool_ENTERPRISE, Tier: c.caPoolTier,
IssuancePolicy: nil, IssuancePolicy: nil,
PublishingOptions: &pb.CaPool_PublishingOptions{ PublishingOptions: &pb.CaPool_PublishingOptions{
PublishCaCert: true, PublishCaCert: true,
PublishCrl: true, PublishCrl: publishCrl,
}, },
}, },
}) })
@ -507,7 +532,8 @@ func (c *CloudCAS) createCertificate(tpl *x509.Certificate, lifetime time.Durati
Lifetime: durationpb.New(lifetime), Lifetime: durationpb.New(lifetime),
Labels: map[string]string{}, Labels: map[string]string{},
}, },
RequestId: requestID, IssuingCertificateAuthorityId: getResourceName(c.certificateAuthority),
RequestId: requestID,
}) })
if err != nil { if err != nil {
return nil, nil, errors.Wrap(err, "cloudCAS CreateCertificate failed") return nil, nil, errors.Wrap(err, "cloudCAS CreateCertificate failed")
@ -583,7 +609,8 @@ func (c *CloudCAS) signIntermediateCA(parent, name string, req *apiv1.CreateCert
Lifetime: durationpb.New(req.Lifetime), Lifetime: durationpb.New(req.Lifetime),
Labels: map[string]string{}, Labels: map[string]string{},
}, },
RequestId: req.RequestID, IssuingCertificateAuthorityId: getResourceName(req.Parent.Name),
RequestId: req.RequestID,
}) })
if err != nil { if err != nil {
return nil, errors.Wrap(err, "cloudCAS CreateCertificate failed") return nil, errors.Wrap(err, "cloudCAS CreateCertificate failed")
@ -618,12 +645,6 @@ func (c *CloudCAS) signIntermediateCA(parent, name string, req *apiv1.CreateCert
return nil, errors.Wrap(err, "cloudCAS ActivateCertificateAuthority failed") return nil, errors.Wrap(err, "cloudCAS ActivateCertificateAuthority failed")
} }
// Enable certificate authority
ca, err = c.enableCertificateAuthority(ca)
if err != nil {
return nil, err
}
return ca, nil return ca, nil
} }
@ -690,7 +711,12 @@ func getCertificateAndChain(certpb *pb.Certificate) (*x509.Certificate, []*x509.
} }
return cert, chain, nil return cert, chain, nil
}
// getResourceName returns the last part of a resource.
func getResourceName(name string) string {
parts := strings.Split(name, "/")
return parts[len(parts)-1]
} }
// Normalize a certificate authority name to comply with [a-zA-Z0-9-_]. // Normalize a certificate authority name to comply with [a-zA-Z0-9-_].

View file

@ -279,6 +279,17 @@ func TestNew(t *testing.T) {
project: testProject, project: testProject,
location: testLocation, location: testLocation,
caPool: testCaPool, caPool: testCaPool,
caPoolTier: 0,
}, false},
{"ok authority and creator", args{context.Background(), apiv1.Options{
CertificateAuthority: testAuthorityName, IsCreator: true,
}}, &CloudCAS{
client: &testClient{},
certificateAuthority: testAuthorityName,
project: testProject,
location: testLocation,
caPool: testCaPool,
caPoolTier: 0,
}, false}, }, false},
{"ok with credentials", args{context.Background(), apiv1.Options{ {"ok with credentials", args{context.Background(), apiv1.Options{
CertificateAuthority: testAuthorityName, CredentialsFile: "testdata/credentials.json", CertificateAuthority: testAuthorityName, CredentialsFile: "testdata/credentials.json",
@ -288,14 +299,34 @@ func TestNew(t *testing.T) {
project: testProject, project: testProject,
location: testLocation, location: testLocation,
caPool: testCaPool, caPool: testCaPool,
caPoolTier: 0,
}, false}, }, false},
{"ok creator", args{context.Background(), apiv1.Options{ {"ok creator", args{context.Background(), apiv1.Options{
IsCreator: true, Project: testProject, Location: testLocation, CaPool: testCaPool, IsCreator: true, Project: testProject, Location: testLocation, CaPool: testCaPool,
}}, &CloudCAS{ }}, &CloudCAS{
client: &testClient{}, client: &testClient{},
project: testProject, project: testProject,
location: testLocation, location: testLocation,
caPool: testCaPool, caPool: testCaPool,
caPoolTier: pb.CaPool_DEVOPS,
}, false},
{"ok creator devops", args{context.Background(), apiv1.Options{
IsCreator: true, Project: testProject, Location: testLocation, CaPool: testCaPool, CaPoolTier: "DevOps",
}}, &CloudCAS{
client: &testClient{},
project: testProject,
location: testLocation,
caPool: testCaPool,
caPoolTier: pb.CaPool_DEVOPS,
}, false},
{"ok creator enterprise", args{context.Background(), apiv1.Options{
IsCreator: true, Project: testProject, Location: testLocation, CaPool: testCaPool, CaPoolTier: "ENTERPRISE",
}}, &CloudCAS{
client: &testClient{},
project: testProject,
location: testLocation,
caPool: testCaPool,
caPoolTier: pb.CaPool_ENTERPRISE,
}, false}, }, false},
{"fail certificate authority", args{context.Background(), apiv1.Options{ {"fail certificate authority", args{context.Background(), apiv1.Options{
CertificateAuthority: "projects/ok1234/locations/ok1234/caPools/ok1234/certificateAuthorities/ok1234/bad", CertificateAuthority: "projects/ok1234/locations/ok1234/caPools/ok1234/certificateAuthorities/ok1234/bad",
@ -1215,6 +1246,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) {
project string project string
location string location string
caPool string caPool string
caPoolTier pb.CaPool_Tier
} }
type args struct { type args struct {
req *apiv1.CreateCertificateAuthorityRequest req *apiv1.CreateCertificateAuthorityRequest
@ -1226,7 +1258,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) {
want *apiv1.CreateCertificateAuthorityResponse want *apiv1.CreateCertificateAuthorityResponse
wantErr bool wantErr bool
}{ }{
{"ok root", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"ok root", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_ENTERPRISE}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.RootCA, Type: apiv1.RootCA,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
@ -1234,7 +1266,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) {
Name: testAuthorityName, Name: testAuthorityName,
Certificate: rootCrt, Certificate: rootCrt,
}, false}, }, false},
{"ok intermediate", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"ok intermediate", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.IntermediateCA, Type: apiv1.IntermediateCA,
Template: mustParseCertificate(t, testIntermediateCertificate), Template: mustParseCertificate(t, testIntermediateCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
@ -1247,7 +1279,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) {
Certificate: intCrt, Certificate: intCrt,
CertificateChain: []*x509.Certificate{rootCrt}, CertificateChain: []*x509.Certificate{rootCrt},
}, false}, }, false},
{"ok intermediate local signer", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"ok intermediate local signer", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_ENTERPRISE}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.IntermediateCA, Type: apiv1.IntermediateCA,
Template: mustParseCertificate(t, testIntermediateCertificate), Template: mustParseCertificate(t, testIntermediateCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
@ -1260,7 +1292,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) {
Certificate: intCrt, Certificate: intCrt,
CertificateChain: []*x509.Certificate{rootCrt}, CertificateChain: []*x509.Certificate{rootCrt},
}, false}, }, false},
{"ok create key", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"ok create key", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.RootCA, Type: apiv1.RootCA,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
@ -1271,46 +1303,46 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) {
Name: testAuthorityName, Name: testAuthorityName,
Certificate: rootCrt, Certificate: rootCrt,
}, false}, }, false},
{"fail project", fields{m, "", "", testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail project", fields{m, "", "", testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.RootCA, Type: apiv1.RootCA,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
}}, nil, true}, }}, nil, true},
{"fail location", fields{m, "", testProject, "", testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail location", fields{m, "", testProject, "", testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.RootCA, Type: apiv1.RootCA,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
}}, nil, true}, }}, nil, true},
{"fail caPool", fields{m, "", testProject, testLocation, ""}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail caPool", fields{m, "", testProject, testLocation, "", pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.RootCA, Type: apiv1.RootCA,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
}}, nil, true}, }}, nil, true},
{"fail template", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail template", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.RootCA, Type: apiv1.RootCA,
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
}}, nil, true}, }}, nil, true},
{"fail lifetime", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail lifetime", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.RootCA, Type: apiv1.RootCA,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
}}, nil, true}, }}, nil, true},
{"fail parent", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail parent", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.IntermediateCA, Type: apiv1.IntermediateCA,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
}}, nil, true}, }}, nil, true},
{"fail parent name", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail parent name", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.IntermediateCA, Type: apiv1.IntermediateCA,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
Parent: &apiv1.CreateCertificateAuthorityResponse{}, Parent: &apiv1.CreateCertificateAuthorityResponse{},
}}, nil, true}, }}, nil, true},
{"fail type", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail type", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: 0, Type: 0,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
}}, nil, true}, }}, nil, true},
{"fail create key", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail create key", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.RootCA, Type: apiv1.RootCA,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
@ -1318,43 +1350,43 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) {
SignatureAlgorithm: kmsapi.PureEd25519, SignatureAlgorithm: kmsapi.PureEd25519,
}, },
}}, nil, true}, }}, nil, true},
{"fail GetCaPool", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail GetCaPool", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.RootCA, Type: apiv1.RootCA,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
}}, nil, true}, }}, nil, true},
{"fail CreateCaPool", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail CreateCaPool", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.RootCA, Type: apiv1.RootCA,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
}}, nil, true}, }}, nil, true},
{"fail CreateCaPool.Wait", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail CreateCaPool.Wait", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.RootCA, Type: apiv1.RootCA,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
}}, nil, true}, }}, nil, true},
{"fail CreateCertificateAuthority", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail CreateCertificateAuthority", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.RootCA, Type: apiv1.RootCA,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
}}, nil, true}, }}, nil, true},
{"fail CreateCertificateAuthority.Wait", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail CreateCertificateAuthority.Wait", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.RootCA, Type: apiv1.RootCA,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
}}, nil, true}, }}, nil, true},
{"fail EnableCertificateAuthority", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail EnableCertificateAuthority", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.RootCA, Type: apiv1.RootCA,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
}}, nil, true}, }}, nil, true},
{"fail EnableCertificateAuthority.Wait", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail EnableCertificateAuthority.Wait", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.RootCA, Type: apiv1.RootCA,
Template: mustParseCertificate(t, testRootCertificate), Template: mustParseCertificate(t, testRootCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
}}, nil, true}, }}, nil, true},
{"fail EnableCertificateAuthority intermediate", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail EnableCertificateAuthority intermediate", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.IntermediateCA, Type: apiv1.IntermediateCA,
Template: mustParseCertificate(t, testIntermediateCertificate), Template: mustParseCertificate(t, testIntermediateCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
@ -1363,7 +1395,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) {
Certificate: rootCrt, Certificate: rootCrt,
}, },
}}, nil, true}, }}, nil, true},
{"fail EnableCertificateAuthority.Wait intermediate", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail EnableCertificateAuthority.Wait intermediate", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.IntermediateCA, Type: apiv1.IntermediateCA,
Template: mustParseCertificate(t, testIntermediateCertificate), Template: mustParseCertificate(t, testIntermediateCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
@ -1373,7 +1405,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) {
}, },
}}, nil, true}, }}, nil, true},
{"fail FetchCertificateAuthorityCsr", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail FetchCertificateAuthorityCsr", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.IntermediateCA, Type: apiv1.IntermediateCA,
Template: mustParseCertificate(t, testIntermediateCertificate), Template: mustParseCertificate(t, testIntermediateCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
@ -1382,7 +1414,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) {
Certificate: rootCrt, Certificate: rootCrt,
}, },
}}, nil, true}, }}, nil, true},
{"fail CreateCertificate", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail CreateCertificate", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.IntermediateCA, Type: apiv1.IntermediateCA,
Template: mustParseCertificate(t, testIntermediateCertificate), Template: mustParseCertificate(t, testIntermediateCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
@ -1391,7 +1423,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) {
Certificate: rootCrt, Certificate: rootCrt,
}, },
}}, nil, true}, }}, nil, true},
{"fail ActivateCertificateAuthority", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail ActivateCertificateAuthority", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.IntermediateCA, Type: apiv1.IntermediateCA,
Template: mustParseCertificate(t, testIntermediateCertificate), Template: mustParseCertificate(t, testIntermediateCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
@ -1400,7 +1432,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) {
Certificate: rootCrt, Certificate: rootCrt,
}, },
}}, nil, true}, }}, nil, true},
{"fail ActivateCertificateAuthority.Wait", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail ActivateCertificateAuthority.Wait", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.IntermediateCA, Type: apiv1.IntermediateCA,
Template: mustParseCertificate(t, testIntermediateCertificate), Template: mustParseCertificate(t, testIntermediateCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
@ -1409,7 +1441,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) {
Certificate: rootCrt, Certificate: rootCrt,
}, },
}}, nil, true}, }}, nil, true},
{"fail x509util.CreateCertificate", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail x509util.CreateCertificate", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.IntermediateCA, Type: apiv1.IntermediateCA,
Template: mustParseCertificate(t, testIntermediateCertificate), Template: mustParseCertificate(t, testIntermediateCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
@ -1418,7 +1450,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) {
Signer: createBadSigner(t), Signer: createBadSigner(t),
}, },
}}, nil, true}, }}, nil, true},
{"fail parseCertificateRequest", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ {"fail parseCertificateRequest", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{
Type: apiv1.IntermediateCA, Type: apiv1.IntermediateCA,
Template: mustParseCertificate(t, testIntermediateCertificate), Template: mustParseCertificate(t, testIntermediateCertificate),
Lifetime: 24 * time.Hour, Lifetime: 24 * time.Hour,
@ -1436,6 +1468,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) {
project: tt.fields.project, project: tt.fields.project,
location: tt.fields.location, location: tt.fields.location,
caPool: tt.fields.caPool, caPool: tt.fields.caPool,
caPoolTier: tt.fields.caPoolTier,
} }
got, err := c.CreateCertificateAuthority(tt.args.req) got, err := c.CreateCertificateAuthority(tt.args.req)
if (err != nil) != tt.wantErr { if (err != nil) != tt.wantErr {