Skip to content

Commit

Permalink
Fetch verification targets by TUF custom metadata
Browse files Browse the repository at this point in the history
This uses GetTargetsByMeta to read the targets
using the custom metadata, or fallback to the old
targets by filename.

Signed-off-by: Hayden Blauzvern <[email protected]>
  • Loading branch information
haydentherapper committed Feb 7, 2022
1 parent f540493 commit 6b3a143
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 31 deletions.
23 changes: 11 additions & 12 deletions cmd/cosign/cli/fulcio/fulcioroots/fulcioroots.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,26 +63,25 @@ func initRoots() (*x509.CertPool, error) {
return nil, errors.New("error creating root cert pool")
}
} else {
tuf, err := tuf.NewFromEnv(context.Background())
tufClient, err := tuf.NewFromEnv(context.Background())
if err != nil {
return nil, errors.Wrap(err, "initializing tuf")
}
defer tuf.Close()
defer tufClient.Close()
// Retrieve from the embedded or cached TUF root. If expired, a network
// call is made to update the root.
rootFound := false
for _, fulcioTarget := range []string{fulcioTargetStr, fulcioV1TargetStr} {
b, err := tuf.GetTarget(fulcioTarget)
if err == nil {
rootFound = true
if !cp.AppendCertsFromPEM(b) {
return nil, errors.New("error creating root cert pool")
}
}
targets, err := tufClient.GetTargetsByMeta(tuf.Fulcio, []string{fulcioTargetStr, fulcioV1TargetStr})
if err != nil {
return nil, errors.New("error getting targets")
}
if !rootFound {
if len(targets) == 0 {
return nil, errors.New("none of the Fulcio roots have been found")
}
for _, t := range targets {
if !cp.AppendCertsFromPEM(t.Target) {
return nil, errors.New("error creating root cert pool")
}
}
}
return cp, nil
}
24 changes: 24 additions & 0 deletions cmd/cosign/cli/fulcio/fulcioroots/fulcioroots_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2022 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 fulcioroots

import "testing"

func TestGetFulcioRoots(t *testing.T) {
certPool := Get()
if len(certPool.Subjects()) == 0 {
t.Errorf("expected 1 or more certificates, got 0")
}
}
28 changes: 16 additions & 12 deletions cmd/cosign/cli/fulcio/fulcioverifier/fulcioverifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,27 +51,28 @@ const altCTLogPublicKeyLocation = "SIGSTORE_CT_LOG_PUBLIC_KEY_FILE"
// The SCT is a `Signed Certificate Timestamp`, which promises that
// the certificate issued by Fulcio was also added to the public CT log within
// some defined time period
func verifySCT(certPEM, rawSCT []byte) error {
func verifySCT(certPEM, rawSCT []byte, ctx context.Context) error {
var pubKeys []crypto.PublicKey
var err error
rootEnv := os.Getenv(altCTLogPublicKeyLocation)
if rootEnv == "" {
ctx := context.TODO()
tuf, err := tuf.NewFromEnv(ctx)
tufClient, err := tuf.NewFromEnv(ctx)
if err != nil {
return err
}
defer tuf.Close()
ctPub, err := tuf.GetTarget(ctPublicKeyStr)
defer tufClient.Close()

targets, err := tufClient.GetTargetsByMeta(tuf.CTFE, []string{ctPublicKeyStr})
if err != nil {
return err
}
// Is there a reason why this must be ECDSA key?
pubKey, err := cosign.PemToECDSAKey(ctPub)
if err != nil {
return errors.Wrap(err, "converting Public CT to ECDSAKey")
for _, t := range targets {
ctPub, err := cosign.PemToECDSAKey(t.Target)
if err != nil {
return errors.Wrap(err, "converting Public CT to ECDSAKey")
}
pubKeys = append(pubKeys, ctPub)
}
pubKeys = append(pubKeys, pubKey)
} else {
fmt.Fprintf(os.Stderr, "**Warning** Using a non-standard public key for verifying SCT: %s\n", rootEnv)
raw, err := os.ReadFile(rootEnv)
Expand All @@ -84,6 +85,9 @@ func verifySCT(certPEM, rawSCT []byte) error {
}
pubKeys = append(pubKeys, pubKey)
}
if len(pubKeys) == 0 {
return errors.New("none of the CTFE keys have been found")
}
cert, err := x509util.CertificateFromPEM(certPEM)
if err != nil {
return err
Expand All @@ -96,7 +100,7 @@ func verifySCT(certPEM, rawSCT []byte) error {
for _, pubKey := range pubKeys {
verifySctErr = ctutil.VerifySCT(pubKey, []*ctx509.Certificate{cert}, &sct, false)
// Exit after successful verification of the SCT
if err == nil {
if verifySctErr == nil {
return nil
}
}
Expand All @@ -111,7 +115,7 @@ func NewSigner(ctx context.Context, idToken, oidcIssuer, oidcClientID, oidcClien
}

// verify the sct
if err := verifySCT(fs.Cert, fs.SCT); err != nil {
if err := verifySCT(fs.Cert, fs.SCT, ctx); err != nil {
return nil, errors.Wrap(err, "verifying SCT")
}
fmt.Fprintln(os.Stderr, "Successfully verified SCT...")
Expand Down
21 changes: 14 additions & 7 deletions pkg/cosign/tlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,27 @@ var rekorTargetStr = `rekor.pub`
// GetRekorPubs retrieves trusted Rekor public keys from the embedded or cached
// TUF root. If expired, makes a network call to retrieve the updated targets.
func GetRekorPubs(ctx context.Context) ([]*ecdsa.PublicKey, error) {
tuf, err := tuf.NewFromEnv(ctx)
tufClient, err := tuf.NewFromEnv(ctx)
if err != nil {
return nil, err
}
defer tuf.Close()
b, err := tuf.GetTarget(rekorTargetStr)
defer tufClient.Close()
targets, err := tufClient.GetTargetsByMeta(tuf.Rekor, []string{rekorTargetStr})
if err != nil {
return nil, err
}
rekorPubKey, err := PemToECDSAKey(b)
if err != nil {
return nil, errors.Wrap(err, "pem to ecdsa")
var publicKeys []*ecdsa.PublicKey
for _, t := range targets {
rekorPubKey, err := PemToECDSAKey(t.Target)
if err != nil {
return nil, errors.Wrap(err, "pem to ecdsa")
}
publicKeys = append(publicKeys, rekorPubKey)
}
if len(publicKeys) == 0 {
return nil, errors.New("none of the Rekor public keys have been found")
}
return []*ecdsa.PublicKey{rekorPubKey}, nil
return publicKeys, nil
}

// TLogUpload will upload the signature, public key and payload to the transparency log.
Expand Down

0 comments on commit 6b3a143

Please sign in to comment.