From 00d621a8c2538d7cc5cce3669e41cb598dc20083 Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Wed, 27 Oct 2021 13:53:31 -0700 Subject: [PATCH 1/4] Upgrade fulcios usage of the goole privateca api to v1 Signed-off-by: Scott Nichols --- go.mod | 2 +- go.sum | 3 ++- pkg/api/googleca_signing_cert.go | 7 +++--- pkg/ca/googleca/googleca.go | 42 ++++++++++++++------------------ 4 files changed, 24 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index 38d35fe71..07a672ca6 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( go.uber.org/multierr v1.7.0 // indirect go.uber.org/zap v1.19.1 golang.org/x/net v0.0.0-20210614182718-04defd469f4e - google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71 + google.golang.org/genproto v0.0.0-20211027162914-98a5263abeca google.golang.org/protobuf v1.27.1 gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b diff --git a/go.sum b/go.sum index 45427d95e..1de3a944b 100644 --- a/go.sum +++ b/go.sum @@ -991,8 +991,9 @@ google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKr google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71 h1:z+ErRPu0+KS02Td3fOAgdX+lnPDh/VyaABEJPD4JRQs= google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20211027162914-98a5263abeca h1:+e+aQDO4/c9KaG8PXWHTc6/+Du6kz+BKcXCSnV4SSTE= +google.golang.org/genproto v0.0.0-20211027162914-98a5263abeca/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= 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= diff --git a/pkg/api/googleca_signing_cert.go b/pkg/api/googleca_signing_cert.go index 66c0b012b..c64ec8898 100644 --- a/pkg/api/googleca_signing_cert.go +++ b/pkg/api/googleca_signing_cert.go @@ -18,12 +18,11 @@ package api import ( "context" - "github.com/sigstore/fulcio/pkg/ca/googleca" - privatecapb "google.golang.org/genproto/googleapis/cloud/security/privateca/v1beta1" - - "github.com/sigstore/fulcio/pkg/challenges" "github.com/spf13/viper" + privatecapb "google.golang.org/genproto/googleapis/cloud/security/privateca/v1" + "github.com/sigstore/fulcio/pkg/ca/googleca" + "github.com/sigstore/fulcio/pkg/challenges" "github.com/sigstore/fulcio/pkg/log" ) diff --git a/pkg/ca/googleca/googleca.go b/pkg/ca/googleca/googleca.go index 3fc21b2a8..312645fb3 100644 --- a/pkg/ca/googleca/googleca.go +++ b/pkg/ca/googleca/googleca.go @@ -24,8 +24,8 @@ import ( "fmt" "sync" - privateca "cloud.google.com/go/security/privateca/apiv1beta1" - privatecapb "google.golang.org/genproto/googleapis/cloud/security/privateca/v1beta1" + privateca "cloud.google.com/go/security/privateca/apiv1" + privatecapb "google.golang.org/genproto/googleapis/cloud/security/privateca/v1" "google.golang.org/protobuf/types/known/durationpb" ) @@ -47,19 +47,17 @@ func Client() *privateca.CertificateAuthorityClient { return c } -// Returns the PublicKey type required by gcp privateca (to handle both PEM_RSA_KEY / PEM_EC_KEY) -// https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/security/privateca/v1beta1#PublicKey_KeyType -func getPubKeyType(pemBytes []byte) interface{} { +// getPubKeyFormat Returns the PublicKey KeyFormat required by gcp privateca. +// https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/security/privateca/v1#PublicKey_KeyType +func getPubKeyFormat(pemBytes []byte) privatecapb.PublicKey_KeyFormat { block, _ := pem.Decode(pemBytes) pub, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { panic("failed to parse public key: " + err.Error()) } switch pub := pub.(type) { - case *rsa.PublicKey: - return privatecapb.PublicKey_KeyType(1) - case *ecdsa.PublicKey: - return privatecapb.PublicKey_KeyType(2) + case *rsa.PublicKey, *ecdsa.PublicKey: + return privatecapb.PublicKey_PEM default: panic(fmt.Errorf("unknown public key type: %v", pub)) } @@ -67,7 +65,7 @@ func getPubKeyType(pemBytes []byte) interface{} { func Req(parent string, subject *privatecapb.CertificateConfig_SubjectConfig, pemBytes []byte, extensions []*privatecapb.X509Extension) *privatecapb.CreateCertificateRequest { // TODO, use the right fields :) - pubkeyType := getPubKeyType(pemBytes) + pubkeyFormat := getPubKeyFormat(pemBytes) return &privatecapb.CreateCertificateRequest{ Parent: parent, Certificate: &privatecapb.Certificate{ @@ -75,23 +73,19 @@ func Req(parent string, subject *privatecapb.CertificateConfig_SubjectConfig, pe CertificateConfig: &privatecapb.Certificate_Config{ Config: &privatecapb.CertificateConfig{ PublicKey: &privatecapb.PublicKey{ - Type: pubkeyType.(privatecapb.PublicKey_KeyType), - Key: pemBytes, + Format: pubkeyFormat, + Key: pemBytes, }, - ReusableConfig: &privatecapb.ReusableConfigWrapper{ - ConfigValues: &privatecapb.ReusableConfigWrapper_ReusableConfigValues{ - ReusableConfigValues: &privatecapb.ReusableConfigValues{ - KeyUsage: &privatecapb.KeyUsage{ - BaseKeyUsage: &privatecapb.KeyUsage_KeyUsageOptions{ - DigitalSignature: true, - }, - ExtendedKeyUsage: &privatecapb.KeyUsage_ExtendedKeyUsageOptions{ - CodeSigning: true, - }, - }, - AdditionalExtensions: extensions, + X509Config: &privatecapb.X509Parameters{ + KeyUsage: &privatecapb.KeyUsage{ + BaseKeyUsage: &privatecapb.KeyUsage_KeyUsageOptions{ + DigitalSignature: true, + }, + ExtendedKeyUsage: &privatecapb.KeyUsage_ExtendedKeyUsageOptions{ + CodeSigning: true, }, }, + AdditionalExtensions: extensions, }, SubjectConfig: subject, }, From c0bc54fbdab1612b9c805974f3ba2495d50ad921 Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Wed, 27 Oct 2021 14:15:30 -0700 Subject: [PATCH 2/4] Adding a flag to select the google private ca api version at runtime Signed-off-by: Scott Nichols --- cmd/app/root.go | 1 + config/deployment.yaml | 4 +- pkg/api/googleca_signing_cert.go | 30 ++--- pkg/api/googleca_v1_signing_cert.go | 54 +++++++++ pkg/api/googleca_v1beta1_signing_cert.go | 54 +++++++++ pkg/ca/googleca/{ => v1}/googleca.go | 0 pkg/ca/googleca/{ => v1}/googleca_test.go | 0 pkg/ca/googleca/v1beta1/googleca.go | 138 ++++++++++++++++++++++ pkg/ca/googleca/v1beta1/googleca_test.go | 81 +++++++++++++ 9 files changed, 340 insertions(+), 22 deletions(-) create mode 100644 pkg/api/googleca_v1_signing_cert.go create mode 100644 pkg/api/googleca_v1beta1_signing_cert.go rename pkg/ca/googleca/{ => v1}/googleca.go (100%) rename pkg/ca/googleca/{ => v1}/googleca_test.go (100%) create mode 100644 pkg/ca/googleca/v1beta1/googleca.go create mode 100644 pkg/ca/googleca/v1beta1/googleca_test.go diff --git a/cmd/app/root.go b/cmd/app/root.go index 70b445ef9..e00ad416c 100644 --- a/cmd/app/root.go +++ b/cmd/app/root.go @@ -49,6 +49,7 @@ func init() { rootCmd.PersistentFlags().String("ca", "", "googleca | pkcs11ca") rootCmd.PersistentFlags().String("aws-hsm-root-ca-path", "", "Path to root CA on disk (only used with AWS HSM)") rootCmd.PersistentFlags().String("gcp_private_ca_parent", "", "private ca parent: /projects//locations// (only used with --ca googleca)") + rootCmd.PersistentFlags().String("gcp_private_ca_version", "v1", "private ca version: [v1|v1beta1] (only used with --ca googleca)") rootCmd.PersistentFlags().String("hsm-caroot-id", "", "HSM ID for Root CA (only used with --ca pkcs11ca)") rootCmd.PersistentFlags().String("ct-log-url", "http://localhost:6962/test", "host and path (with log prefix at the end) to the ct log") rootCmd.PersistentFlags().String("config-path", "/etc/fulcio-config/config.json", "path to fulcio config json") diff --git a/config/deployment.yaml b/config/deployment.yaml index 2defb223d..e38dbfc78 100644 --- a/config/deployment.yaml +++ b/config/deployment.yaml @@ -42,7 +42,9 @@ spec: - containerPort: 2112 # metrics args: [ "serve", - "--host=0.0.0.0", "--port=5555", "--ca=googleca", "--gcp_private_ca_parent=$(CA_PARENT)", "--ct-log-url=http://ct-log/test", "--log_type=prod", + "--host=0.0.0.0", "--port=5555", + "--ca=googleca", "--gcp_private_ca_parent=$(CA_PARENT)", "--gcp_private_ca_version=v1beta1", + "--ct-log-url=http://ct-log/test", "--log_type=prod", ] env: - name: CA_PARENT diff --git a/pkg/api/googleca_signing_cert.go b/pkg/api/googleca_signing_cert.go index c64ec8898..821ff66ee 100644 --- a/pkg/api/googleca_signing_cert.go +++ b/pkg/api/googleca_signing_cert.go @@ -17,11 +17,10 @@ package api import ( "context" + "fmt" "github.com/spf13/viper" - privatecapb "google.golang.org/genproto/googleapis/cloud/security/privateca/v1" - "github.com/sigstore/fulcio/pkg/ca/googleca" "github.com/sigstore/fulcio/pkg/challenges" "github.com/sigstore/fulcio/pkg/log" ) @@ -29,26 +28,15 @@ import ( func GoogleCASigningCertHandler(ctx context.Context, subj *challenges.ChallengeResult, publicKey []byte) (string, []string, error) { logger := log.ContextLogger(ctx) - parent := viper.GetString("gcp_private_ca_parent") - - // call a new function here to set the type, we may need to pass back the issuer? - var privca *privatecapb.CertificateConfig_SubjectConfig - switch subj.TypeVal { - case challenges.EmailValue: - privca = googleca.EmailSubject(subj.Value) - case challenges.SpiffeValue: - privca = googleca.SpiffeSubject(subj.Value) - case challenges.GithubWorkflowValue: - privca = googleca.GithubWorkflowSubject(subj.Value) - } + version := viper.GetString("gcp_private_ca_version") - extensions := googleca.IssuerExtension(subj.Issuer) - req := googleca.Req(parent, privca, publicKey, extensions) - logger.Infof("requesting cert from %s for %v", parent, Subject) + logger.Infof("using privateca api version %v", version) - resp, err := googleca.Client().CreateCertificate(ctx, req) - if err != nil { - return "", nil, err + switch version { + case "v1": + return GoogleCASigningCertHandlerV1(ctx, subj, publicKey) + case "v1beta1": + return GoogleCASigningCertHandlerV1Beta1(ctx, subj, publicKey) } - return resp.PemCertificate, resp.PemCertificateChain, nil + panic(fmt.Errorf("unknown gcp private ca version: %v", version)) } diff --git a/pkg/api/googleca_v1_signing_cert.go b/pkg/api/googleca_v1_signing_cert.go new file mode 100644 index 000000000..fe93f7bc6 --- /dev/null +++ b/pkg/api/googleca_v1_signing_cert.go @@ -0,0 +1,54 @@ +// Copyright 2021 The Sigstore Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package api + +import ( + "context" + + "github.com/spf13/viper" + privatecapb "google.golang.org/genproto/googleapis/cloud/security/privateca/v1" + + googleca "github.com/sigstore/fulcio/pkg/ca/googleca/v1" + "github.com/sigstore/fulcio/pkg/challenges" + "github.com/sigstore/fulcio/pkg/log" +) + +func GoogleCASigningCertHandlerV1(ctx context.Context, subj *challenges.ChallengeResult, publicKey []byte) (string, []string, error) { + logger := log.ContextLogger(ctx) + + parent := viper.GetString("gcp_private_ca_parent") + + // call a new function here to set the type, we may need to pass back the issuer? + var privca *privatecapb.CertificateConfig_SubjectConfig + switch subj.TypeVal { + case challenges.EmailValue: + privca = googleca.EmailSubject(subj.Value) + case challenges.SpiffeValue: + privca = googleca.SpiffeSubject(subj.Value) + case challenges.GithubWorkflowValue: + privca = googleca.GithubWorkflowSubject(subj.Value) + } + + extensions := googleca.IssuerExtension(subj.Issuer) + req := googleca.Req(parent, privca, publicKey, extensions) + logger.Infof("requesting cert from %s for %v", parent, Subject) + + resp, err := googleca.Client().CreateCertificate(ctx, req) + if err != nil { + return "", nil, err + } + return resp.PemCertificate, resp.PemCertificateChain, nil +} diff --git a/pkg/api/googleca_v1beta1_signing_cert.go b/pkg/api/googleca_v1beta1_signing_cert.go new file mode 100644 index 000000000..9c55bded3 --- /dev/null +++ b/pkg/api/googleca_v1beta1_signing_cert.go @@ -0,0 +1,54 @@ +// Copyright 2021 The Sigstore Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package api + +import ( + "context" + + "github.com/spf13/viper" + privatecapb "google.golang.org/genproto/googleapis/cloud/security/privateca/v1beta1" + + googleca "github.com/sigstore/fulcio/pkg/ca/googleca/v1beta1" + "github.com/sigstore/fulcio/pkg/challenges" + "github.com/sigstore/fulcio/pkg/log" +) + +func GoogleCASigningCertHandlerV1Beta1(ctx context.Context, subj *challenges.ChallengeResult, publicKey []byte) (string, []string, error) { + logger := log.ContextLogger(ctx) + + parent := viper.GetString("gcp_private_ca_parent") + + // call a new function here to set the type, we may need to pass back the issuer? + var privca *privatecapb.CertificateConfig_SubjectConfig + switch subj.TypeVal { + case challenges.EmailValue: + privca = googleca.EmailSubject(subj.Value) + case challenges.SpiffeValue: + privca = googleca.SpiffeSubject(subj.Value) + case challenges.GithubWorkflowValue: + privca = googleca.GithubWorkflowSubject(subj.Value) + } + + extensions := googleca.IssuerExtension(subj.Issuer) + req := googleca.Req(parent, privca, publicKey, extensions) + logger.Infof("requesting cert from %s for %v", parent, Subject) + + resp, err := googleca.Client().CreateCertificate(ctx, req) + if err != nil { + return "", nil, err + } + return resp.PemCertificate, resp.PemCertificateChain, nil +} diff --git a/pkg/ca/googleca/googleca.go b/pkg/ca/googleca/v1/googleca.go similarity index 100% rename from pkg/ca/googleca/googleca.go rename to pkg/ca/googleca/v1/googleca.go diff --git a/pkg/ca/googleca/googleca_test.go b/pkg/ca/googleca/v1/googleca_test.go similarity index 100% rename from pkg/ca/googleca/googleca_test.go rename to pkg/ca/googleca/v1/googleca_test.go diff --git a/pkg/ca/googleca/v1beta1/googleca.go b/pkg/ca/googleca/v1beta1/googleca.go new file mode 100644 index 000000000..3fc21b2a8 --- /dev/null +++ b/pkg/ca/googleca/v1beta1/googleca.go @@ -0,0 +1,138 @@ +// Copyright 2021 The Sigstore Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package googleca + +import ( + "context" + "crypto/ecdsa" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "fmt" + "sync" + + privateca "cloud.google.com/go/security/privateca/apiv1beta1" + privatecapb "google.golang.org/genproto/googleapis/cloud/security/privateca/v1beta1" + "google.golang.org/protobuf/types/known/durationpb" +) + +var ( + once sync.Once + c *privateca.CertificateAuthorityClient +) + +func Client() *privateca.CertificateAuthorityClient { + // Use a once block to avoid creating a new client every time. + once.Do(func() { + var err error + c, err = privateca.NewCertificateAuthorityClient(context.Background()) + if err != nil { + panic(err) + } + }) + + return c +} + +// Returns the PublicKey type required by gcp privateca (to handle both PEM_RSA_KEY / PEM_EC_KEY) +// https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/security/privateca/v1beta1#PublicKey_KeyType +func getPubKeyType(pemBytes []byte) interface{} { + block, _ := pem.Decode(pemBytes) + pub, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + panic("failed to parse public key: " + err.Error()) + } + switch pub := pub.(type) { + case *rsa.PublicKey: + return privatecapb.PublicKey_KeyType(1) + case *ecdsa.PublicKey: + return privatecapb.PublicKey_KeyType(2) + default: + panic(fmt.Errorf("unknown public key type: %v", pub)) + } +} + +func Req(parent string, subject *privatecapb.CertificateConfig_SubjectConfig, pemBytes []byte, extensions []*privatecapb.X509Extension) *privatecapb.CreateCertificateRequest { + // TODO, use the right fields :) + pubkeyType := getPubKeyType(pemBytes) + return &privatecapb.CreateCertificateRequest{ + Parent: parent, + Certificate: &privatecapb.Certificate{ + Lifetime: &durationpb.Duration{Seconds: 20 * 60}, + CertificateConfig: &privatecapb.Certificate_Config{ + Config: &privatecapb.CertificateConfig{ + PublicKey: &privatecapb.PublicKey{ + Type: pubkeyType.(privatecapb.PublicKey_KeyType), + Key: pemBytes, + }, + ReusableConfig: &privatecapb.ReusableConfigWrapper{ + ConfigValues: &privatecapb.ReusableConfigWrapper_ReusableConfigValues{ + ReusableConfigValues: &privatecapb.ReusableConfigValues{ + KeyUsage: &privatecapb.KeyUsage{ + BaseKeyUsage: &privatecapb.KeyUsage_KeyUsageOptions{ + DigitalSignature: true, + }, + ExtendedKeyUsage: &privatecapb.KeyUsage_ExtendedKeyUsageOptions{ + CodeSigning: true, + }, + }, + AdditionalExtensions: extensions, + }, + }, + }, + SubjectConfig: subject, + }, + }, + }, + } +} + +func EmailSubject(email string) *privatecapb.CertificateConfig_SubjectConfig { + return &privatecapb.CertificateConfig_SubjectConfig{ + SubjectAltName: &privatecapb.SubjectAltNames{ + EmailAddresses: []string{email}, + }} +} + +// SPIFFE IDs go as "Uris" according to the spec: https://github.com/spiffe/spiffe/blob/main/standards/X509-SVID.md +func SpiffeSubject(id string) *privatecapb.CertificateConfig_SubjectConfig { + return &privatecapb.CertificateConfig_SubjectConfig{ + SubjectAltName: &privatecapb.SubjectAltNames{ + Uris: []string{id}, + }, + } +} + +func GithubWorkflowSubject(id string) *privatecapb.CertificateConfig_SubjectConfig { + return &privatecapb.CertificateConfig_SubjectConfig{ + SubjectAltName: &privatecapb.SubjectAltNames{ + Uris: []string{id}, + }, + } +} + +func IssuerExtension(issuer string) []*privatecapb.X509Extension { + if issuer == "" { + return nil + } + + return []*privatecapb.X509Extension{{ + ObjectId: &privatecapb.ObjectId{ + ObjectIdPath: []int32{1, 3, 6, 1, 4, 1, 57264, 1, 1}, + }, + Value: []byte(issuer), + }} +} diff --git a/pkg/ca/googleca/v1beta1/googleca_test.go b/pkg/ca/googleca/v1beta1/googleca_test.go new file mode 100644 index 000000000..0d18c12c9 --- /dev/null +++ b/pkg/ca/googleca/v1beta1/googleca_test.go @@ -0,0 +1,81 @@ +// Copyright 2021 The Sigstore Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package googleca + +import ( + "crypto" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "testing" + + "github.com/sigstore/fulcio/pkg/challenges" +) + +func failErr(t *testing.T, err error) { + if err != nil { + t.Fatal(err) + } +} + +func TestCheckSignatureECDSA(t *testing.T) { + + priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + failErr(t, err) + + email := "test@gmail.com" + if err := challenges.CheckSignature(&priv.PublicKey, []byte("foo"), email); err == nil { + t.Fatal("check should have failed") + } + + h := sha256.Sum256([]byte(email)) + signature, err := priv.Sign(rand.Reader, h[:], crypto.SHA256) + failErr(t, err) + + if err := challenges.CheckSignature(&priv.PublicKey, signature, email); err != nil { + t.Fatal(err) + } + + // Try a bad email but "good" signature + if err := challenges.CheckSignature(&priv.PublicKey, signature, "bad@email.com"); err == nil { + t.Fatal("check should have failed") + } +} + +func TestCheckSignatureRSA(t *testing.T) { + priv, err := rsa.GenerateKey(rand.Reader, 2048) + failErr(t, err) + + email := "test@gmail.com" + if err := challenges.CheckSignature(&priv.PublicKey, []byte("foo"), email); err == nil { + t.Fatal("check should have failed") + } + + h := sha256.Sum256([]byte(email)) + signature, err := priv.Sign(rand.Reader, h[:], crypto.SHA256) + failErr(t, err) + + if err := challenges.CheckSignature(&priv.PublicKey, signature, email); err != nil { + t.Fatal(err) + } + + // Try a bad email but "good" signature + if err := challenges.CheckSignature(&priv.PublicKey, signature, "bad@email.com"); err == nil { + t.Fatal("check should have failed") + } +} From bcdb31af15384041456c804ad5f1ddb12f9ab627 Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Mon, 29 Nov 2021 10:26:26 -0800 Subject: [PATCH 3/4] lint fix. Signed-off-by: Scott Nichols --- pkg/api/ca.go | 10 +++++----- pkg/api/error.go | 5 +++-- pkg/ca/googleca/v1/googleca.go | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/pkg/api/ca.go b/pkg/api/ca.go index a5f39e180..30b9fccfa 100644 --- a/pkg/api/ca.go +++ b/pkg/api/ca.go @@ -26,19 +26,19 @@ import ( "strings" "sync" - googlecav1beta1 "github.com/sigstore/fulcio/pkg/ca/googleca/v1beta1" - googlecav1 "github.com/sigstore/fulcio/pkg/ca/googleca/v1" + "github.com/coreos/go-oidc/v3/oidc" + "github.com/go-openapi/runtime/middleware" certauth "github.com/sigstore/fulcio/pkg/ca" "github.com/sigstore/fulcio/pkg/ca/ephemeralca" + googlecav1 "github.com/sigstore/fulcio/pkg/ca/googleca/v1" + googlecav1beta1 "github.com/sigstore/fulcio/pkg/ca/googleca/v1beta1" "github.com/sigstore/fulcio/pkg/ca/x509ca" "github.com/sigstore/fulcio/pkg/challenges" - "github.com/sigstore/sigstore/pkg/cryptoutils" - "github.com/coreos/go-oidc/v3/oidc" - "github.com/go-openapi/runtime/middleware" "github.com/sigstore/fulcio/pkg/config" "github.com/sigstore/fulcio/pkg/ctl" "github.com/sigstore/fulcio/pkg/generated/restapi/operations" "github.com/sigstore/fulcio/pkg/log" + "github.com/sigstore/sigstore/pkg/cryptoutils" "github.com/spf13/viper" ) diff --git a/pkg/api/error.go b/pkg/api/error.go index 6f54f6727..ff6d475e3 100644 --- a/pkg/api/error.go +++ b/pkg/api/error.go @@ -34,8 +34,9 @@ const ( failedToEnterCertInCTL = "Error entering certificate in CTL @ '%v'" failedToMarshalSCT = "Error marshaling signed certificate timestamp" failedToMarshalCert = "Error marshaling code signing certificate" - invalidCredentials = "There was an error processing the credentials for this request" - genericCAError = "error communicating with CA backend" + //nolint + invalidCredentials = "There was an error processing the credentials for this request" + genericCAError = "error communicating with CA backend" ) func errorMsg(message string, code int) *models.Error { diff --git a/pkg/ca/googleca/v1/googleca.go b/pkg/ca/googleca/v1/googleca.go index db642cadc..10559ac18 100644 --- a/pkg/ca/googleca/v1/googleca.go +++ b/pkg/ca/googleca/v1/googleca.go @@ -24,14 +24,14 @@ import ( "fmt" "sync" - "github.com/spf13/viper" privateca "cloud.google.com/go/security/privateca/apiv1" - privatecapb "google.golang.org/genproto/googleapis/cloud/security/privateca/v1" - "google.golang.org/protobuf/types/known/durationpb" "github.com/sigstore/fulcio/pkg/ca" "github.com/sigstore/fulcio/pkg/challenges" "github.com/sigstore/fulcio/pkg/log" "github.com/sigstore/sigstore/pkg/cryptoutils" + "github.com/spf13/viper" + privatecapb "google.golang.org/genproto/googleapis/cloud/security/privateca/v1" + "google.golang.org/protobuf/types/known/durationpb" ) var ( From 5b1bcd822a5d4f40391c43bd9bc310aab3b472f7 Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Wed, 1 Dec 2021 08:16:55 -0800 Subject: [PATCH 4/4] correct which api is called. Signed-off-by: Scott Nichols --- pkg/api/ca.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/api/ca.go b/pkg/api/ca.go index 30b9fccfa..0308dc517 100644 --- a/pkg/api/ca.go +++ b/pkg/api/ca.go @@ -56,9 +56,9 @@ func CA() certauth.CertificateAuthority { version := viper.GetString("gcp_private_ca_version") switch version { case "v1": - ca, err = googlecav1beta1.NewCertAuthorityService() - case "v1beta1": ca, err = googlecav1.NewCertAuthorityService() + case "v1beta1": + ca, err = googlecav1beta1.NewCertAuthorityService() default: err = fmt.Errorf("invalid value for gcp_private_ca_version: %v", version) }