From b275758018653864a2cc05040003a5e7d682172d Mon Sep 17 00:00:00 2001 From: Mariano Cano Date: Tue, 27 Oct 2020 17:59:32 -0700 Subject: [PATCH] Complete CloudCAS tests. Upgrade cloud.google.com/go --- cas/cloudcas/certificate.go | 29 ++- cas/cloudcas/certificate_test.go | 74 ++++++ cas/cloudcas/cloudcas.go | 31 +-- cas/cloudcas/cloudcas_test.go | 409 ++++++++++++++++++++++++++++--- go.mod | 6 +- go.sum | 52 ++-- 6 files changed, 508 insertions(+), 93 deletions(-) diff --git a/cas/cloudcas/certificate.go b/cas/cloudcas/certificate.go index ba823d86..d7789992 100644 --- a/cas/cloudcas/certificate.go +++ b/cas/cloudcas/certificate.go @@ -343,6 +343,16 @@ func createKeyVersionSpec(alg kmsapi.SignatureAlgorithm, bits int) (*pb.Certific Algorithm: pb.CertificateAuthority_EC_P384_SHA384, }, }, nil + case kmsapi.SHA256WithRSA: + algo, err := getRSAPKCS1Algorithm(bits) + if err != nil { + return nil, err + } + return &pb.CertificateAuthority_KeyVersionSpec{ + KeyVersion: &pb.CertificateAuthority_KeyVersionSpec_Algorithm{ + Algorithm: algo, + }, + }, nil case kmsapi.SHA256WithRSAPSS: algo, err := getRSAPSSAlgorithm(bits) if err != nil { @@ -358,14 +368,27 @@ func createKeyVersionSpec(alg kmsapi.SignatureAlgorithm, bits int) (*pb.Certific } } +func getRSAPKCS1Algorithm(bits int) (pb.CertificateAuthority_SignHashAlgorithm, error) { + switch bits { + case 0, 3072: + return pb.CertificateAuthority_RSA_PKCS1_3072_SHA256, nil + case 2048: + return pb.CertificateAuthority_RSA_PKCS1_2048_SHA256, nil + case 4096: + return pb.CertificateAuthority_RSA_PKCS1_4096_SHA256, nil + default: + return 0, fmt.Errorf("unsupported RSA PKCS #1 key size '%d'", bits) + } +} + func getRSAPSSAlgorithm(bits int) (pb.CertificateAuthority_SignHashAlgorithm, error) { switch bits { case 0, 3072: - return pb.CertificateAuthority_RSA_PSS_3072_SHA_256, nil + return pb.CertificateAuthority_RSA_PSS_3072_SHA256, nil case 2048: - return pb.CertificateAuthority_RSA_PSS_2048_SHA_256, nil + return pb.CertificateAuthority_RSA_PSS_2048_SHA256, nil case 4096: - return pb.CertificateAuthority_RSA_PSS_4096_SHA_256, nil + return pb.CertificateAuthority_RSA_PSS_4096_SHA256, nil default: return 0, fmt.Errorf("unsupported RSA-PSS key size '%d'", bits) } diff --git a/cas/cloudcas/certificate_test.go b/cas/cloudcas/certificate_test.go index 4f30ea79..0822e4c1 100644 --- a/cas/cloudcas/certificate_test.go +++ b/cas/cloudcas/certificate_test.go @@ -14,6 +14,7 @@ import ( "reflect" "testing" + kmsapi "github.com/smallstep/certificates/kms/apiv1" pb "google.golang.org/genproto/googleapis/cloud/security/privateca/v1beta1" wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" ) @@ -548,3 +549,76 @@ func Test_isExtraExtension(t *testing.T) { }) } } + +func Test_createKeyVersionSpec(t *testing.T) { + type args struct { + alg kmsapi.SignatureAlgorithm + bits int + } + tests := []struct { + name string + args args + want *pb.CertificateAuthority_KeyVersionSpec + wantErr bool + }{ + {"ok P256", args{0, 0}, &pb.CertificateAuthority_KeyVersionSpec{ + KeyVersion: &pb.CertificateAuthority_KeyVersionSpec_Algorithm{ + Algorithm: pb.CertificateAuthority_EC_P256_SHA256, + }}, false}, + {"ok P256", args{kmsapi.ECDSAWithSHA256, 0}, &pb.CertificateAuthority_KeyVersionSpec{ + KeyVersion: &pb.CertificateAuthority_KeyVersionSpec_Algorithm{ + Algorithm: pb.CertificateAuthority_EC_P256_SHA256, + }}, false}, + {"ok P384", args{kmsapi.ECDSAWithSHA384, 0}, &pb.CertificateAuthority_KeyVersionSpec{ + KeyVersion: &pb.CertificateAuthority_KeyVersionSpec_Algorithm{ + Algorithm: pb.CertificateAuthority_EC_P384_SHA384, + }}, false}, + {"ok RSA default", args{kmsapi.SHA256WithRSA, 0}, &pb.CertificateAuthority_KeyVersionSpec{ + KeyVersion: &pb.CertificateAuthority_KeyVersionSpec_Algorithm{ + Algorithm: pb.CertificateAuthority_RSA_PKCS1_3072_SHA256, + }}, false}, + {"ok RSA 2048", args{kmsapi.SHA256WithRSA, 2048}, &pb.CertificateAuthority_KeyVersionSpec{ + KeyVersion: &pb.CertificateAuthority_KeyVersionSpec_Algorithm{ + Algorithm: pb.CertificateAuthority_RSA_PKCS1_2048_SHA256, + }}, false}, + {"ok RSA 3072", args{kmsapi.SHA256WithRSA, 3072}, &pb.CertificateAuthority_KeyVersionSpec{ + KeyVersion: &pb.CertificateAuthority_KeyVersionSpec_Algorithm{ + Algorithm: pb.CertificateAuthority_RSA_PKCS1_3072_SHA256, + }}, false}, + {"ok RSA 4096", args{kmsapi.SHA256WithRSA, 4096}, &pb.CertificateAuthority_KeyVersionSpec{ + KeyVersion: &pb.CertificateAuthority_KeyVersionSpec_Algorithm{ + Algorithm: pb.CertificateAuthority_RSA_PKCS1_4096_SHA256, + }}, false}, + {"ok RSA-PSS default", args{kmsapi.SHA256WithRSAPSS, 0}, &pb.CertificateAuthority_KeyVersionSpec{ + KeyVersion: &pb.CertificateAuthority_KeyVersionSpec_Algorithm{ + Algorithm: pb.CertificateAuthority_RSA_PSS_3072_SHA256, + }}, false}, + {"ok RSA-PSS 2048", args{kmsapi.SHA256WithRSAPSS, 2048}, &pb.CertificateAuthority_KeyVersionSpec{ + KeyVersion: &pb.CertificateAuthority_KeyVersionSpec_Algorithm{ + Algorithm: pb.CertificateAuthority_RSA_PSS_2048_SHA256, + }}, false}, + {"ok RSA-PSS 3072", args{kmsapi.SHA256WithRSAPSS, 3072}, &pb.CertificateAuthority_KeyVersionSpec{ + KeyVersion: &pb.CertificateAuthority_KeyVersionSpec_Algorithm{ + Algorithm: pb.CertificateAuthority_RSA_PSS_3072_SHA256, + }}, false}, + {"ok RSA-PSS 4096", args{kmsapi.SHA256WithRSAPSS, 4096}, &pb.CertificateAuthority_KeyVersionSpec{ + KeyVersion: &pb.CertificateAuthority_KeyVersionSpec_Algorithm{ + Algorithm: pb.CertificateAuthority_RSA_PSS_4096_SHA256, + }}, false}, + {"fail Ed25519", args{kmsapi.PureEd25519, 0}, nil, true}, + {"fail RSA size", args{kmsapi.SHA256WithRSA, 1024}, nil, true}, + {"fail RSA-PSS size", args{kmsapi.SHA256WithRSAPSS, 1024}, nil, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := createKeyVersionSpec(tt.args.alg, tt.args.bits) + if (err != nil) != tt.wantErr { + t.Errorf("createKeyVersionSpec() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("createKeyVersionSpec() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/cas/cloudcas/cloudcas.go b/cas/cloudcas/cloudcas.go index 087febc7..4fb75b3a 100644 --- a/cas/cloudcas/cloudcas.go +++ b/cas/cloudcas/cloudcas.go @@ -262,6 +262,16 @@ func (c *CloudCAS) CreateCertificateAuthority(req *apiv1.CreateCertificateAuthor return nil, errors.New("createCertificateAuthorityRequest `parent.name` cannot be empty") } + var caType pb.CertificateAuthority_Type + switch req.Type { + case apiv1.RootCA: + caType = pb.CertificateAuthority_SELF_SIGNED + case apiv1.IntermediateCA: + caType = pb.CertificateAuthority_SUBORDINATE + default: + return nil, errors.Errorf("createCertificateAuthorityRequest `type=%d' is invalid or not supported", req.Type) + } + // Select key and signature algorithm to use var err error var keySpec *pb.CertificateAuthority_KeyVersionSpec @@ -276,17 +286,17 @@ func (c *CloudCAS) CreateCertificateAuthority(req *apiv1.CreateCertificateAuthor } // Normalize or generate id. - certificateAuthorityID := normalizeCertificateAuthorityName(req.Name) - if certificateAuthorityID == "" { + caID := normalizeCertificateAuthorityName(req.Name) + if caID == "" { id, err := createCertificateID() if err != nil { return nil, err } - certificateAuthorityID = id + caID = id } // Add CertificateAuthority extension - casExtension, err := apiv1.CreateCertificateAuthorityExtension(apiv1.CloudCAS, certificateAuthorityID) + casExtension, err := apiv1.CreateCertificateAuthorityExtension(apiv1.CloudCAS, caID) if err != nil { return nil, err } @@ -295,10 +305,10 @@ func (c *CloudCAS) CreateCertificateAuthority(req *apiv1.CreateCertificateAuthor // Prepare CreateCertificateAuthorityRequest pbReq := &pb.CreateCertificateAuthorityRequest{ Parent: "projects/" + c.project + "/locations/" + c.location, - CertificateAuthorityId: certificateAuthorityID, + CertificateAuthorityId: caID, RequestId: req.RequestID, CertificateAuthority: &pb.CertificateAuthority{ - Type: pb.CertificateAuthority_TYPE_UNSPECIFIED, + Type: caType, Tier: pb.CertificateAuthority_ENTERPRISE, Config: &pb.CertificateConfig{ SubjectConfig: &pb.CertificateConfig_SubjectConfig{ @@ -317,15 +327,6 @@ func (c *CloudCAS) CreateCertificateAuthority(req *apiv1.CreateCertificateAuthor }, } - switch req.Type { - case apiv1.RootCA: - pbReq.CertificateAuthority.Type = pb.CertificateAuthority_SELF_SIGNED - case apiv1.IntermediateCA: - pbReq.CertificateAuthority.Type = pb.CertificateAuthority_SUBORDINATE - default: - return nil, errors.Errorf("createCertificateAuthorityRequest `type=%d' is invalid or not supported", req.Type) - } - // Create certificate authority. ctx, cancel := defaultContext() defer cancel() diff --git a/cas/cloudcas/cloudcas_test.go b/cas/cloudcas/cloudcas_test.go index 6aa67842..2383059d 100644 --- a/cas/cloudcas/cloudcas_test.go +++ b/cas/cloudcas/cloudcas_test.go @@ -3,9 +3,14 @@ package cloudcas import ( "bytes" "context" + "crypto" + "crypto/ecdsa" + "crypto/ed25519" "crypto/rand" "crypto/x509" "encoding/asn1" + "encoding/pem" + "fmt" "io" "net" "os" @@ -20,6 +25,7 @@ import ( gax "github.com/googleapis/gax-go/v2" "github.com/pkg/errors" "github.com/smallstep/certificates/cas/apiv1" + kmsapi "github.com/smallstep/certificates/kms/apiv1" "google.golang.org/api/option" pb "google.golang.org/genproto/googleapis/cloud/security/privateca/v1beta1" longrunningpb "google.golang.org/genproto/googleapis/longrunning" @@ -34,27 +40,25 @@ var ( testProject = "test-project" testLocation = "us-west1" testRootCertificate = `-----BEGIN CERTIFICATE----- -MIIBhjCCAS2gAwIBAgIQLbKTuXau4+t3KFbGpJJAADAKBggqhkjOPQQDAjAiMSAw -HgYDVQQDExdHb29nbGUgQ0FTIFRlc3QgUm9vdCBDQTAeFw0yMDA5MTQyMjQ4NDla -Fw0zMDA5MTIyMjQ4NDlaMCIxIDAeBgNVBAMTF0dvb2dsZSBDQVMgVGVzdCBSb290 -IENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYKGgQ3/0D7+oBTc0CXoYfSC6 -M8hOqLsmzBapPZSYpfwjgEsjdNU84jdrYmW1zF1+p+MrL4c7qJv9NLo/picCuqNF -MEMwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYE -FFVn9V7Qymd7cUJh9KAhnUDAQL5YMAoGCCqGSM49BAMCA0cAMEQCIA4LzttYoT3u -8TYgSrvFT+Z+cklfi4UrPBU6aSbcUaW2AiAPfaqbyccQT3CxMVyHg+xZZjAirZp8 -lAeA/T4FxAonHA== +MIIBeDCCAR+gAwIBAgIQcXWWjtSZ/PAyH8D1Ou4L9jAKBggqhkjOPQQDAjAbMRkw +FwYDVQQDExBDbG91ZENBUyBSb290IENBMB4XDTIwMTAyNzIyNTM1NFoXDTMwMTAy +NzIyNTM1NFowGzEZMBcGA1UEAxMQQ2xvdWRDQVMgUm9vdCBDQTBZMBMGByqGSM49 +AgEGCCqGSM49AwEHA0IABIySHA4b78Yu4LuGhZIlv/PhNwXz4ZoV1OUZQ0LrK3vj +B13O12DLZC5uj1z3kxdQzXUttSbtRv49clMpBiTpsZKjRTBDMA4GA1UdDwEB/wQE +AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1UdDgQWBBSZ+t9RMHbFTl5BatM3 +5bJlHPOu3DAKBggqhkjOPQQDAgNHADBEAiASah6gg0tVM3WI0meCQ4SEKk7Mjhbv ++SmhuZHWV1QlXQIgRXNyWcpVUrAoG6Uy1KQg07LDpF5dFeK9InrDxSJAkVo= -----END CERTIFICATE-----` testIntermediateCertificate = `-----BEGIN CERTIFICATE----- -MIIBsDCCAVagAwIBAgIQOb91kHxWKVzSJ9ESW1ViVzAKBggqhkjOPQQDAjAiMSAw -HgYDVQQDExdHb29nbGUgQ0FTIFRlc3QgUm9vdCBDQTAeFw0yMDA5MTQyMjQ4NDla -Fw0zMDA5MTIyMjQ4NDlaMCoxKDAmBgNVBAMTH0dvb2dsZSBDQVMgVGVzdCBJbnRl -cm1lZGlhdGUgQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASUHN1cNyId4Ei/ -4MxD5VrZFc51P50caMUdDZVrPveidChBYCU/9IM6vnRlZHx2HLjQ0qAvqHwY3rT0 -xc7n+PfCo2YwZDAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAd -BgNVHQ4EFgQUSDlasiw0pRKyS7llhL0ZuVFNa9UwHwYDVR0jBBgwFoAUVWf1XtDK -Z3txQmH0oCGdQMBAvlgwCgYIKoZIzj0EAwIDSAAwRQIgMmsLcoC4KriXw+s+cZx2 -bJMf6Mx/WESj31buJJhpzY0CIQCBUa/JtvS3nyce/4DF5tK2v49/NWHREgqAaZ57 -DcYyHQ== +MIIBpDCCAUmgAwIBAgIRALLKxnxyl0GBeKevIcbx02wwCgYIKoZIzj0EAwIwGzEZ +MBcGA1UEAxMQQ2xvdWRDQVMgUm9vdCBDQTAeFw0yMDEwMjcyMjUzNTRaFw0zMDEw +MjcyMjUzNTRaMCMxITAfBgNVBAMTGENsb3VkQ0FTIEludGVybWVkaWF0ZSBDQTBZ +MBMGByqGSM49AgEGCCqGSM49AwEHA0IABPLuqxgBY+QmaXc8zKIC8FMgjJ6dF/cL +b+Dig0XKc5GH/T1ORrhgOkRayrQcjPMu+jkjg25qn6vvp43LRtUKPXOjZjBkMA4G +A1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQ8RVQI +VgXAmRNDX8qItalVpSBEGjAfBgNVHSMEGDAWgBSZ+t9RMHbFTl5BatM35bJlHPOu +3DAKBggqhkjOPQQDAgNJADBGAiEA70MVYVqjm8SBHJf5cOlWfiXXOfHUsctTJ+/F +pLsKBogCIQDJJkoQqYl9B59Dq3zydl8bpJevQxsoaa4Wqg+ZBMkvbQ== -----END CERTIFICATE-----` testLeafCertificate = `-----BEGIN CERTIFICATE----- MIIB1jCCAX2gAwIBAgIQQfOn+COMeuD8VYF1TiDkEzAKBggqhkjOPQQDAjAqMSgw @@ -82,20 +86,22 @@ SM49BAMCA0gAMEUCIGxl+pqJ50WYWUqK2l4V1FHoXSi0Nht5kwTxFxnWZu1xAiEA zemu3bhWLFaGg3s8i+HTEhw4RqkHP74vF7AVYp88bAw= -----END CERTIFICATE-----` testIntermediateCsr = `-----BEGIN CERTIFICATE REQUEST----- -MIIBIjCByQIBADAqMSgwJgYDVQQDEx9Hb29nbGUgQ0FTIFRlc3QgSW50ZXJtZWRp -YXRlIENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqoztio0c4XuaaGxHFiU7 -UBk3YRGTae9GtlKwyZJDk740hg6ZIoKcaXrzJT5taUpPiQLi7rP1eRui0dhl/bHo -o6A9MDsGCSqGSIb3DQEJDjEuMCwwKgYDVR0RBCMwIYIfR29vZ2xlIENBUyBUZXN0 -IEludGVybWVkaWF0ZSBDQTAKBggqhkjOPQQDAgNIADBFAiEAvRKBPE32scAvsMe8 -R7ecx91q58ZmeLaRdSzL7stsnJYCIEBu+vQUSTbUpKL2YQNclT9kbilips5pEMr3 -ojxK6mk3 +MIHeMIGFAgEAMCMxITAfBgNVBAMTGENsb3VkQ0FTIEludGVybWVkaWF0ZSBDQTBZ +MBMGByqGSM49AgEGCCqGSM49AwEHA0IABPLuqxgBY+QmaXc8zKIC8FMgjJ6dF/cL +b+Dig0XKc5GH/T1ORrhgOkRayrQcjPMu+jkjg25qn6vvp43LRtUKPXOgADAKBggq +hkjOPQQDAgNIADBFAiEAn3pkYXb2OzoQZ+AExFqd7qZ7pg2nyP2kBZZ01Pl8KfcC +IHKplBXDR79/i7kjOtv1iWfgf5S/XQHrz178gXA0YQe7 -----END CERTIFICATE REQUEST-----` - -// testIntermediateKey = `-----BEGIN EC PRIVATE KEY----- -// MHcCAQEEIMM+DSPChJgcYyqDWs0eRA5BctIo+VSNqRzCTL2ARYAqoAoGCCqGSM49 -// AwEHoUQDQgAEqoztio0c4XuaaGxHFiU7UBk3YRGTae9GtlKwyZJDk740hg6ZIoKc -// aXrzJT5taUpPiQLi7rP1eRui0dhl/bHoow== -// -----END EC PRIVATE KEY-----` + testRootKey = `-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIN51Rgg6YcQVLeCRzumdw4pjM3VWqFIdCbnsV3Up1e/goAoGCCqGSM49 +AwEHoUQDQgAEjJIcDhvvxi7gu4aFkiW/8+E3BfPhmhXU5RlDQusre+MHXc7XYMtk +Lm6PXPeTF1DNdS21Ju1G/j1yUykGJOmxkg== +-----END EC PRIVATE KEY-----` + testIntermediateKey = `-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIMMX/XkXGnRDD4fYu7Z4rHACdJn/iyOy2UTwsv+oZ0C+oAoGCCqGSM49 +AwEHoUQDQgAE8u6rGAFj5CZpdzzMogLwUyCMnp0X9wtv4OKDRcpzkYf9PU5GuGA6 +RFrKtByM8y76OSODbmqfq++njctG1Qo9cw== +-----END EC PRIVATE KEY-----` ) type testClient struct { @@ -158,6 +164,29 @@ func setTeeReader(t *testing.T, w *bytes.Buffer) { rand.Reader = io.TeeReader(reader, w) } +type badSigner struct { + pub crypto.PublicKey +} + +func createBadSigner(t *testing.T) *badSigner { + t.Helper() + pub, _, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + t.Fatal(err) + } + return &badSigner{ + pub: pub, + } +} + +func (b *badSigner) Public() crypto.PublicKey { + return b.pub +} + +func (b *badSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) { + return nil, fmt.Errorf("💥") +} + func (c *testClient) CreateCertificate(ctx context.Context, req *pb.CreateCertificateRequest, opts ...gax.CallOption) (*pb.Certificate, error) { return c.certificate, c.err } @@ -191,6 +220,19 @@ func mustParseCertificate(t *testing.T, pemCert string) *x509.Certificate { return crt } +func mustParseECKey(t *testing.T, pemKey string) *ecdsa.PrivateKey { + t.Helper() + block, _ := pem.Decode([]byte(pemKey)) + if block == nil { + t.Fatal("failed to parse key") + } + key, err := x509.ParseECPrivateKey(block.Bytes) + if err != nil { + t.Fatal(err) + } + return key +} + func TestNew(t *testing.T) { tmp := newCertificateAuthorityClient newCertificateAuthorityClient = func(ctx context.Context, credentialsFile string) (CertificateAuthorityClient, error) { @@ -233,7 +275,10 @@ func TestNew(t *testing.T) { project: testProject, location: testLocation, }, false}, - {"fail certificate authority", args{context.Background(), apiv1.Options{}}, nil, true}, + {"fail certificate authority", args{context.Background(), apiv1.Options{ + CertificateAuthority: "projects/ok1234/locations/ok1234/certificateAuthorities/ok1234/bad", + }}, nil, true}, + {"fail certificate authority regex", args{context.Background(), apiv1.Options{}}, nil, true}, {"fail with credentials", args{context.Background(), apiv1.Options{ CertificateAuthority: testAuthorityName, CredentialsFile: "testdata/error.json", }}, nil, true}, @@ -735,8 +780,6 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { return a } - // client, close := mockTestClient() - // defer close() ctrl := gomock.NewController(t) defer ctrl.Finish() mosCtrl := gomock.NewController(t) @@ -801,6 +844,31 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { m.EXPECT().FetchCertificateAuthorityCsr(any, any).Return(&pb.FetchCertificateAuthorityCsrResponse{ PemCsr: testIntermediateCsr, }, nil) + m.EXPECT().ActivateCertificateAuthority(any, any).Return(fake.ActivateCertificateAuthorityOperation("ActivateCertificateAuthority"), nil) + mos.EXPECT().GetOperation(any, any).Return(&longrunningpb.Operation{ + Name: "ActivateCertificateAuthority", + Done: true, + Result: &longrunningpb.Operation_Response{ + Response: must(anypb.New(&pb.CertificateAuthority{ + Name: testAuthorityName, + PemCaCertificates: []string{testIntermediateCertificate, testRootCertificate}, + })).(*anypb.Any), + }, + }, nil) + // ok intermediate local signer + m.EXPECT().CreateCertificateAuthority(any, any).Return(fake.CreateCertificateAuthorityOperation("CreateCertificateAuthority"), nil) + mos.EXPECT().GetOperation(any, any).Return(&longrunningpb.Operation{ + Name: "CreateCertificateAuthority", + Done: true, + Result: &longrunningpb.Operation_Response{ + Response: must(anypb.New(&pb.CertificateAuthority{ + Name: testAuthorityName, + })).(*anypb.Any), + }, + }, nil) + m.EXPECT().FetchCertificateAuthorityCsr(any, any).Return(&pb.FetchCertificateAuthorityCsrResponse{ + PemCsr: testIntermediateCsr, + }, nil) m.EXPECT().CreateCertificate(any, any).Return(&pb.Certificate{ PemCertificate: testIntermediateCertificate, PemCertificateChain: []string{testRootCertificate}, @@ -817,6 +885,126 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { }, }, nil) + // ok create key + m.EXPECT().CreateCertificateAuthority(any, any).Return(fake.CreateCertificateAuthorityOperation("CreateCertificateAuthority"), nil) + mos.EXPECT().GetOperation(any, any).Return(&longrunningpb.Operation{ + Name: "CreateCertificateAuthority", + Done: true, + Result: &longrunningpb.Operation_Response{ + Response: must(anypb.New(&pb.CertificateAuthority{ + Name: testAuthorityName, + PemCaCertificates: []string{testRootCertificate}, + })).(*anypb.Any), + }, + }, nil) + + // fail CreateCertificateAuthority + m.EXPECT().CreateCertificateAuthority(any, any).Return(nil, errTest) + + // fail CreateCertificateAuthority.Wait + m.EXPECT().CreateCertificateAuthority(any, any).Return(fake.CreateCertificateAuthorityOperation("CreateCertificateAuthority"), nil) + mos.EXPECT().GetOperation(any, any).Return(nil, errTest) + + // fail FetchCertificateAuthorityCsr + m.EXPECT().CreateCertificateAuthority(any, any).Return(fake.CreateCertificateAuthorityOperation("CreateCertificateAuthority"), nil) + mos.EXPECT().GetOperation(any, any).Return(&longrunningpb.Operation{ + Name: "CreateCertificateAuthority", + Done: true, + Result: &longrunningpb.Operation_Response{ + Response: must(anypb.New(&pb.CertificateAuthority{ + Name: testAuthorityName, + })).(*anypb.Any), + }, + }, nil) + m.EXPECT().FetchCertificateAuthorityCsr(any, any).Return(nil, errTest) + + // fail CreateCertificate + m.EXPECT().CreateCertificateAuthority(any, any).Return(fake.CreateCertificateAuthorityOperation("CreateCertificateAuthority"), nil) + mos.EXPECT().GetOperation(any, any).Return(&longrunningpb.Operation{ + Name: "CreateCertificateAuthority", + Done: true, + Result: &longrunningpb.Operation_Response{ + Response: must(anypb.New(&pb.CertificateAuthority{ + Name: testAuthorityName, + })).(*anypb.Any), + }, + }, nil) + m.EXPECT().FetchCertificateAuthorityCsr(any, any).Return(&pb.FetchCertificateAuthorityCsrResponse{ + PemCsr: testIntermediateCsr, + }, nil) + m.EXPECT().CreateCertificate(any, any).Return(nil, errTest) + + // fail ActivateCertificateAuthority + m.EXPECT().CreateCertificateAuthority(any, any).Return(fake.CreateCertificateAuthorityOperation("CreateCertificateAuthority"), nil) + mos.EXPECT().GetOperation(any, any).Return(&longrunningpb.Operation{ + Name: "CreateCertificateAuthority", + Done: true, + Result: &longrunningpb.Operation_Response{ + Response: must(anypb.New(&pb.CertificateAuthority{ + Name: testAuthorityName, + })).(*anypb.Any), + }, + }, nil) + m.EXPECT().FetchCertificateAuthorityCsr(any, any).Return(&pb.FetchCertificateAuthorityCsrResponse{ + PemCsr: testIntermediateCsr, + }, nil) + m.EXPECT().CreateCertificate(any, any).Return(&pb.Certificate{ + PemCertificate: testIntermediateCertificate, + PemCertificateChain: []string{testRootCertificate}, + }, nil) + m.EXPECT().ActivateCertificateAuthority(any, any).Return(nil, errTest) + + // fail ActivateCertificateAuthority.Wait + m.EXPECT().CreateCertificateAuthority(any, any).Return(fake.CreateCertificateAuthorityOperation("CreateCertificateAuthority"), nil) + mos.EXPECT().GetOperation(any, any).Return(&longrunningpb.Operation{ + Name: "CreateCertificateAuthority", + Done: true, + Result: &longrunningpb.Operation_Response{ + Response: must(anypb.New(&pb.CertificateAuthority{ + Name: testAuthorityName, + })).(*anypb.Any), + }, + }, nil) + m.EXPECT().FetchCertificateAuthorityCsr(any, any).Return(&pb.FetchCertificateAuthorityCsrResponse{ + PemCsr: testIntermediateCsr, + }, nil) + m.EXPECT().CreateCertificate(any, any).Return(&pb.Certificate{ + PemCertificate: testIntermediateCertificate, + PemCertificateChain: []string{testRootCertificate}, + }, nil) + m.EXPECT().ActivateCertificateAuthority(any, any).Return(fake.ActivateCertificateAuthorityOperation("ActivateCertificateAuthority"), nil) + mos.EXPECT().GetOperation(any, any).Return(nil, errTest) + + // fail x509util.CreateCertificate + m.EXPECT().CreateCertificateAuthority(any, any).Return(fake.CreateCertificateAuthorityOperation("CreateCertificateAuthority"), nil) + mos.EXPECT().GetOperation(any, any).Return(&longrunningpb.Operation{ + Name: "CreateCertificateAuthority", + Done: true, + Result: &longrunningpb.Operation_Response{ + Response: must(anypb.New(&pb.CertificateAuthority{ + Name: testAuthorityName, + })).(*anypb.Any), + }, + }, nil) + m.EXPECT().FetchCertificateAuthorityCsr(any, any).Return(&pb.FetchCertificateAuthorityCsrResponse{ + PemCsr: testIntermediateCsr, + }, nil) + + // fail parseCertificateRequest + m.EXPECT().CreateCertificateAuthority(any, any).Return(fake.CreateCertificateAuthorityOperation("CreateCertificateAuthority"), nil) + mos.EXPECT().GetOperation(any, any).Return(&longrunningpb.Operation{ + Name: "CreateCertificateAuthority", + Done: true, + Result: &longrunningpb.Operation_Response{ + Response: must(anypb.New(&pb.CertificateAuthority{ + Name: testAuthorityName, + })).(*anypb.Any), + }, + }, nil) + m.EXPECT().FetchCertificateAuthorityCsr(any, any).Return(&pb.FetchCertificateAuthorityCsrResponse{ + PemCsr: "Not a CSR", + }, nil) + rootCrt := mustParseCertificate(t, testRootCertificate) intCrt := mustParseCertificate(t, testIntermediateCertificate) @@ -857,6 +1045,136 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { Certificate: intCrt, CertificateChain: []*x509.Certificate{rootCrt}, }, false}, + {"ok intermediate local signer", fields{m, "", testProject, testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.IntermediateCA, + Template: mustParseCertificate(t, testIntermediateCertificate), + Lifetime: 24 * time.Hour, + Parent: &apiv1.CreateCertificateAuthorityResponse{ + Certificate: rootCrt, + Signer: mustParseECKey(t, testRootKey), + }, + }}, &apiv1.CreateCertificateAuthorityResponse{ + Name: testAuthorityName, + Certificate: intCrt, + CertificateChain: []*x509.Certificate{rootCrt}, + }, false}, + {"ok create key", fields{m, "", testProject, testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.RootCA, + Template: mustParseCertificate(t, testRootCertificate), + Lifetime: 24 * time.Hour, + CreateKey: &kmsapi.CreateKeyRequest{ + SignatureAlgorithm: kmsapi.ECDSAWithSHA256, + }, + }}, &apiv1.CreateCertificateAuthorityResponse{ + Name: testAuthorityName, + Certificate: rootCrt, + }, false}, + {"fail project", fields{m, "", "", testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.RootCA, + Template: mustParseCertificate(t, testRootCertificate), + Lifetime: 24 * time.Hour, + }}, nil, true}, + {"fail location", fields{m, "", testProject, ""}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.RootCA, + Template: mustParseCertificate(t, testRootCertificate), + Lifetime: 24 * time.Hour, + }}, nil, true}, + {"fail template", fields{m, "", testProject, testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.RootCA, + Lifetime: 24 * time.Hour, + }}, nil, true}, + {"fail lifetime", fields{m, "", testProject, testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.RootCA, + Template: mustParseCertificate(t, testRootCertificate), + }}, nil, true}, + {"fail parent", fields{m, "", testProject, testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.IntermediateCA, + Template: mustParseCertificate(t, testRootCertificate), + Lifetime: 24 * time.Hour, + }}, nil, true}, + {"fail parent name", fields{m, "", testProject, testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.IntermediateCA, + Template: mustParseCertificate(t, testRootCertificate), + Lifetime: 24 * time.Hour, + Parent: &apiv1.CreateCertificateAuthorityResponse{}, + }}, nil, true}, + {"fail type", fields{m, "", testProject, testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: 0, + Template: mustParseCertificate(t, testRootCertificate), + Lifetime: 24 * time.Hour, + }}, nil, true}, + {"fail create key", fields{m, "", testProject, testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.RootCA, + Template: mustParseCertificate(t, testRootCertificate), + Lifetime: 24 * time.Hour, + CreateKey: &kmsapi.CreateKeyRequest{ + SignatureAlgorithm: kmsapi.PureEd25519, + }, + }}, nil, true}, + {"fail CreateCertificateAuthority", fields{m, "", testProject, testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.RootCA, + Template: mustParseCertificate(t, testRootCertificate), + Lifetime: 24 * time.Hour, + }}, nil, true}, + {"fail CreateCertificateAuthority.Wait", fields{m, "", testProject, testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.RootCA, + Template: mustParseCertificate(t, testRootCertificate), + Lifetime: 24 * time.Hour, + }}, nil, true}, + {"fail FetchCertificateAuthorityCsr", fields{m, "", testProject, testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.IntermediateCA, + Template: mustParseCertificate(t, testIntermediateCertificate), + Lifetime: 24 * time.Hour, + Parent: &apiv1.CreateCertificateAuthorityResponse{ + Name: testAuthorityName, + Certificate: rootCrt, + }, + }}, nil, true}, + {"fail CreateCertificate", fields{m, "", testProject, testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.IntermediateCA, + Template: mustParseCertificate(t, testIntermediateCertificate), + Lifetime: 24 * time.Hour, + Parent: &apiv1.CreateCertificateAuthorityResponse{ + Name: testAuthorityName, + Certificate: rootCrt, + }, + }}, nil, true}, + {"fail ActivateCertificateAuthority", fields{m, "", testProject, testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.IntermediateCA, + Template: mustParseCertificate(t, testIntermediateCertificate), + Lifetime: 24 * time.Hour, + Parent: &apiv1.CreateCertificateAuthorityResponse{ + Name: testAuthorityName, + Certificate: rootCrt, + }, + }}, nil, true}, + {"fail ActivateCertificateAuthority.Wait", fields{m, "", testProject, testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.IntermediateCA, + Template: mustParseCertificate(t, testIntermediateCertificate), + Lifetime: 24 * time.Hour, + Parent: &apiv1.CreateCertificateAuthorityResponse{ + Name: testAuthorityName, + Certificate: rootCrt, + }, + }}, nil, true}, + {"fail x509util.CreateCertificate", fields{m, "", testProject, testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.IntermediateCA, + Template: mustParseCertificate(t, testIntermediateCertificate), + Lifetime: 24 * time.Hour, + Parent: &apiv1.CreateCertificateAuthorityResponse{ + Certificate: rootCrt, + Signer: createBadSigner(t), + }, + }}, nil, true}, + {"fail parseCertificateRequest", fields{m, "", testProject, testLocation}, args{&apiv1.CreateCertificateAuthorityRequest{ + Type: apiv1.IntermediateCA, + Template: mustParseCertificate(t, testIntermediateCertificate), + Lifetime: 24 * time.Hour, + Parent: &apiv1.CreateCertificateAuthorityResponse{ + Certificate: rootCrt, + Signer: createBadSigner(t), + }, + }}, nil, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -877,3 +1195,24 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { }) } } + +func Test_normalizeCertificateAuthorityName(t *testing.T) { + type args struct { + name string + } + tests := []struct { + name string + args args + want string + }{ + {"ok", args{"Test-CA-Name_1234"}, "Test-CA-Name_1234"}, + {"change", args{"💥 CA"}, "--CA"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := normalizeCertificateAuthorityName(tt.args.name); got != tt.want { + t.Errorf("normalizeCertificateAuthorityName() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/go.mod b/go.mod index dd15016c..8d48913e 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/smallstep/certificates go 1.14 require ( - cloud.google.com/go v0.65.1-0.20200904011802-3c2db50b5678 + cloud.google.com/go v0.70.0 github.com/Masterminds/sprig/v3 v3.1.0 github.com/aws/aws-sdk-go v1.30.29 github.com/go-chi/chi v4.0.2+incompatible @@ -28,8 +28,8 @@ require ( >>>>>>> Update go.step.sm/crypto dependency. golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 golang.org/x/net v0.0.0-20201021035429-f5854403a974 - google.golang.org/api v0.31.0 - google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d + google.golang.org/api v0.33.0 + google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154 google.golang.org/grpc v1.32.0 google.golang.org/protobuf v1.25.0 gopkg.in/square/go-jose.v2 v2.5.1 diff --git a/go.sum b/go.sum index ba7ca75a..835b926a 100644 --- a/go.sum +++ b/go.sum @@ -16,6 +16,8 @@ cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.65.1-0.20200904011802-3c2db50b5678 h1:5YqZUrIf2QELwPqw1kLpGIE0z0I++b7HhzSNKjZlIY0= cloud.google.com/go v0.65.1-0.20200904011802-3c2db50b5678/go.mod h1:Ihp2NV3Qr9BWHCDNA8LXF9fZ1HGBl6Jx1xd7KP3nxkI= +cloud.google.com/go v0.70.0 h1:ujhG1RejZYi+HYfJNlgBh3j/bVKD8DewM7AkJ5UPyBc= +cloud.google.com/go v0.70.0/go.mod h1:/UTKYRQTWjVnSe7nGvoSzxEFUELzSI/yAYd0JQT6cRo= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -136,6 +138,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -160,6 +163,7 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201009210932-67992a1a5a35/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -207,12 +211,7 @@ github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRU github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -<<<<<<< HEAD github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -======= -github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= ->>>>>>> Update go.step.sm/crypto dependency. github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= @@ -251,13 +250,6 @@ github.com/smallstep/assert v0.0.0-20180720014142-de77670473b5 h1:lX6ybsQW9Agn3q github.com/smallstep/assert v0.0.0-20180720014142-de77670473b5/go.mod h1:TC9A4+RjIOS+HyTH7wG17/gSqVv95uDw2J64dQZx7RE= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262 h1:unQFBIznI+VYD1/1fApl1A+9VcBk+9dcqGfnePY87LY= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262/go.mod h1:MyOHs9Po2fbM1LHej6sBUT8ozbxmMOFG+E+rx/GSGuc= -<<<<<<< HEAD -======= -github.com/smallstep/certificates v0.15.5/go.mod h1:T0L78wJmhdj1AyrfrNG5mPP2MG15cRM/9d1frw8NnJ0= -github.com/smallstep/certinfo v1.4.0/go.mod h1:1gQJekdPwPvUwFWGTi7bZELmQT09cxC9wJ0VBkBNiwU= -github.com/smallstep/cli v0.15.3 h1:t9LBO53PK4SEG6FSo0UOxI306m9pHb+h632oFZe+ZwA= -github.com/smallstep/cli v0.15.3/go.mod h1:KBcpj/m28/uhK+lH0/ctbncZqWQvxDFWk8T2cUyeFg0= ->>>>>>> Update go.step.sm/crypto dependency. github.com/smallstep/nosql v0.3.0 h1:V1X5vfDsDt89499h3jZFUlR4VnnsYYs5tXaQZ0w8z5U= github.com/smallstep/nosql v0.3.0/go.mod h1:QG7gNOpidifn99MjZaiNbm7HPesIyBd97F/OfacNz8Q= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -277,16 +269,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -<<<<<<< HEAD -======= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/timakin/bodyclose v0.0.0-20190721030226-87058b9bfcec/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= -github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= -github.com/tommy-muehle/go-mnd v1.1.1/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= ->>>>>>> Update go.step.sm/crypto dependency. github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -308,21 +290,6 @@ go.step.sm/cli-utils v0.1.0 h1:uuQ73MuAh5P5Eg+3zfqwrtlTLx5DWSfGqGCrSSjYqdk= go.step.sm/cli-utils v0.1.0/go.mod h1:+t4qCp5NO+080DdGkJxEh3xL5S4TcYC2JTPLMM72b6Y= go.step.sm/crypto v0.6.1 h1:nJoRFGrGNf/mKVVMdWnfLbBfIFt/z4NdJlSL5nipQMQ= go.step.sm/crypto v0.6.1/go.mod h1:AKS4yMZVZD4EGjpSkY4eibuMenrvKCscb+BpWMet8c0= -<<<<<<< HEAD -======= -go.step.sm/crypto v0.7.0 h1:azKRI4CBRzDbhHsLAnvzvGJ0aVbGI+wrh2COrPd/mks= -go.step.sm/crypto v0.7.0/go.mod h1:AKS4yMZVZD4EGjpSkY4eibuMenrvKCscb+BpWMet8c0= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= ->>>>>>> Update go.step.sm/crypto dependency. golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -395,6 +362,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -404,6 +372,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6 h1:pE8b58s1HRDMi8RDc79m0H golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -445,6 +415,7 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200828194041-157a740278f4 h1:kCCpuwSAoYJPkNc6x0xT9yTtV4oKtARo4RGBQWOfg9E= golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -501,6 +472,9 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200828161849-5deb26317202/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200903185744-af4cc2cd812e h1:RvNtqusJ+6DJ07/by/M84a6/Dd17XU6n8QvhvknjJno= golang.org/x/tools v0.0.0-20200903185744-af4cc2cd812e/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201017001424-6003fad69a88 h1:ZB1XYzdDo7c/O48jzjMkvIjnC120Z9/CwgDWhePjQdQ= +golang.org/x/tools v0.0.0-20201017001424-6003fad69a88/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -526,6 +500,8 @@ google.golang.org/api v0.30.0 h1:yfrXXP61wVuLb0vBcG6qaOoIoqYEzOQS8jum51jkv2w= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.31.0 h1:1w5Sz/puhxFo9lTtip2n47k7toB/U2nCqOKNHd3Yrbo= google.golang.org/api v0.31.0/go.mod h1:CL+9IBCa2WWU6gRuBWaKqGWLFFwbEUXkfeMkHLQWYWo= +google.golang.org/api v0.33.0 h1:+gL0XvACeMIvpwLZ5rQZzLn5cwOsgg8dIcfJ2SYfBVw= +google.golang.org/api v0.33.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -568,6 +544,8 @@ google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200831141814-d751682dd103/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d h1:92D1fum1bJLKSdr11OJ+54YeCMCGYIygTA7R/YZxH5M= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154 h1:bFFRpT+e8JJVY7lMMfvezL1ZIwqiwmPl2bsE2yx4HqM= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=