Skip to content

Commit

Permalink
V1 go tuf update (#3598)
Browse files Browse the repository at this point in the history
* Updated v1 to support latest version of go-tuf

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* Udated documentation to be correct

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>

* Update sign_test.go

swap out deprecated lib

Signed-off-by: Bob Callaway <bobcallaway@users.noreply.github.com>

* Update keys.go

swap out deprecated lib

Signed-off-by: Bob Callaway <bobcallaway@users.noreply.github.com>

* Update sign_test.go

fix gofmt issue

Signed-off-by: Bob Callaway <bobcallaway@users.noreply.github.com>

* Update go.mod

go mod tidy

Signed-off-by: Bob Callaway <bobcallaway@users.noreply.github.com>

* Update validate-release.yml

free up space ahead of running goreleaser

Signed-off-by: Bob Callaway <bobcallaway@users.noreply.github.com>

---------

Signed-off-by: Fredrik Skogman <kommendorkapten@github.com>
Signed-off-by: Bob Callaway <bobcallaway@users.noreply.github.com>
Co-authored-by: Bob Callaway <bobcallaway@users.noreply.github.com>
  • Loading branch information
kommendorkapten and bobcallaway committed Mar 21, 2024
1 parent ea92927 commit 566ab9d
Show file tree
Hide file tree
Showing 12 changed files with 648 additions and 519 deletions.
51 changes: 51 additions & 0 deletions .github/workflows/validate-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,57 @@ jobs:
- name: check disk space
run: df -h

- name: free up disk space
run: |
rm -rf /usr/share/dotnet/
rm -rf "$AGENT_TOOLSDIRECTORY"
rm -rf "/usr/local/share/boost"
rm -rf /opt/ghc
docker rmi $(docker image ls -aq) || true
swapoff /swapfile || true
rm -rf /swapfile /usr/share/dotnet /usr/local/lib/android /opt/ghc || true
apt purge aria2 ansible hhvm mono-devel azure-cli shellcheck rpm xorriso zsync \
clang-6.0 lldb-6.0 lld-6.0 clang-format-6.0 clang-8 lldb-8 lld-8 clang-format-8 \
clang-9 lldb-9 lld-9 clangd-9 clang-format-9 dotnet-sdk-3.0 dotnet-sdk-3.1=3.1.101-1 \
esl-erlang firefox g++-8 g++-9 gfortran-8 gfortran-9 google-chrome-stable \
google-cloud-sdk ghc-8.0.2 ghc-8.2.2 ghc-8.4.4 ghc-8.6.2 ghc-8.6.3 ghc-8.6.4 \
ghc-8.6.5 ghc-8.8.1 ghc-8.8.2 ghc-8.8.3 ghc-8.10.1 cabal-install-2.0 cabal-install-2.2 \
cabal-install-2.4 cabal-install-3.0 cabal-install-3.2 heroku imagemagick \
libmagickcore-dev libmagickwand-dev libmagic-dev ant ant-optional kubectl \
mercurial apt-transport-https mono-complete mysql-client libmysqlclient-dev \
mysql-server mssql-tools unixodbc-dev yarn bazel chrpath libssl-dev libxft-dev \
libfreetype6 libfreetype6-dev libfontconfig1 libfontconfig1-dev php7.1 php7.1-bcmath \
php7.1-bz2 php7.1-cgi php7.1-cli php7.1-common php7.1-curl php7.1-dba php7.1-dev \
php7.1-enchant php7.1-fpm php7.1-gd php7.1-gmp php7.1-imap php7.1-interbase php7.1-intl \
php7.1-json php7.1-ldap php7.1-mbstring php7.1-mcrypt php7.1-mysql php7.1-odbc \
php7.1-opcache php7.1-pgsql php7.1-phpdbg php7.1-pspell php7.1-readline php7.1-recode \
php7.1-snmp php7.1-soap php7.1-sqlite3 php7.1-sybase php7.1-tidy php7.1-xml \
php7.1-xmlrpc php7.1-xsl php7.1-zip php7.2 php7.2-bcmath php7.2-bz2 php7.2-cgi \
php7.2-cli php7.2-common php7.2-curl php7.2-dba php7.2-dev php7.2-enchant php7.2-fpm \
php7.2-gd php7.2-gmp php7.2-imap php7.2-interbase php7.2-intl php7.2-json php7.2-ldap \
php7.2-mbstring php7.2-mysql php7.2-odbc php7.2-opcache php7.2-pgsql php7.2-phpdbg \
php7.2-pspell php7.2-readline php7.2-recode php7.2-snmp php7.2-soap php7.2-sqlite3 \
php7.2-sybase php7.2-tidy php7.2-xml php7.2-xmlrpc php7.2-xsl php7.2-zip php7.3 \
php7.3-bcmath php7.3-bz2 php7.3-cgi php7.3-cli php7.3-common php7.3-curl php7.3-dba \
php7.3-dev php7.3-enchant php7.3-fpm php7.3-gd php7.3-gmp php7.3-imap php7.3-interbase \
php7.3-intl php7.3-json php7.3-ldap php7.3-mbstring php7.3-mysql php7.3-odbc \
php7.3-opcache php7.3-pgsql php7.3-phpdbg php7.3-pspell php7.3-readline php7.3-recode \
php7.3-snmp php7.3-soap php7.3-sqlite3 php7.3-sybase php7.3-tidy php7.3-xml \
php7.3-xmlrpc php7.3-xsl php7.3-zip php7.4 php7.4-bcmath php7.4-bz2 php7.4-cgi \
php7.4-cli php7.4-common php7.4-curl php7.4-dba php7.4-dev php7.4-enchant php7.4-fpm \
php7.4-gd php7.4-gmp php7.4-imap php7.4-interbase php7.4-intl php7.4-json php7.4-ldap \
php7.4-mbstring php7.4-mysql php7.4-odbc php7.4-opcache php7.4-pgsql php7.4-phpdbg \
php7.4-pspell php7.4-readline php7.4-snmp php7.4-soap php7.4-sqlite3 php7.4-sybase \
php7.4-tidy php7.4-xml php7.4-xmlrpc php7.4-xsl php7.4-zip php-amqp php-apcu \
php-igbinary php-memcache php-memcached php-mongodb php-redis php-xdebug \
php-zmq snmp pollinate libpq-dev postgresql-client powershell ruby-full \
sphinxsearch subversion mongodb-org -yq >/dev/null 2>&1 || true
apt-get remove -y 'php.*' || true
apt-get autoremove -y >/dev/null 2>&1 || true
apt-get autoclean -y >/dev/null 2>&1 || true
- name: check disk space
run: df -h

- name: goreleaser snapshot
run: make snapshot
env:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ lint: golangci-lint ## Run golangci-lint linter
$(GOLANGCI_LINT_BIN) run -n

test:
go test $(shell go list ./... | grep -v third_party/)
GODEBUG=x509sha1=1 go test $(shell go list ./... | grep -v third_party/)

clean:
rm -rf cosign
Expand Down
15 changes: 7 additions & 8 deletions cmd/cosign/cli/policy_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import (
"github.com/sigstore/cosign/pkg/sget" //nolint:staticcheck
sigs "github.com/sigstore/cosign/pkg/signature"
signatureoptions "github.com/sigstore/sigstore/pkg/signature/options"
"github.com/sigstore/sigstore/pkg/tuf"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -86,7 +85,7 @@ func initPolicy() *cobra.Command {
cosign policy init -ns <project_namespace> --maintainers {email_addresses} --threshold <int> --expires <int>(days)`,
PersistentPreRun: options.BindViper,
RunE: func(cmd *cobra.Command, args []string) error {
var publicKeys []*tuf.Key
var publicKeys []*Key

// Process the list of maintainers by
// 1. Ensure each entry is a correctly formatted email address
Expand All @@ -96,13 +95,13 @@ func initPolicy() *cobra.Command {
panic(fmt.Sprintf("Invalid email format: %s", email))
} else {
// Currently only a single issuer can be set for all the maintainers.
key := tuf.FulcioVerificationKey(strings.TrimSpace(email), o.Issuer)
key := FulcioVerificationKey(strings.TrimSpace(email), o.Issuer)
publicKeys = append(publicKeys, key)
}
}

// Create a new root.
root := tuf.NewRoot()
root := NewRoot()

// Add the maintainer identities to the root's trusted keys.
for _, key := range publicKeys {
Expand All @@ -112,7 +111,7 @@ func initPolicy() *cobra.Command {
// Set root keys, threshold, and namespace.
role, ok := root.Roles["root"]
if !ok {
role = &tuf.Role{KeyIDs: []string{}, Threshold: 1}
role = &Role{KeyIDs: []string{}, Threshold: 1}
}
role.AddKeysWithThreshold(publicKeys, o.Threshold)
root.Roles["root"] = role
Expand Down Expand Up @@ -240,18 +239,18 @@ func signPolicy() *cobra.Command {
}

// Unmarshal policy and verify that Fulcio signer email is in the trusted
signed := &tuf.Signed{}
signed := &Signed{}
if err := json.Unmarshal(b, signed); err != nil {
return fmt.Errorf("unmarshalling signed root policy: %w", err)
}

// Create and add signature
key := tuf.FulcioVerificationKey(signerEmail, signerIssuer)
key := FulcioVerificationKey(signerEmail, signerIssuer)
sig, err := sv.SignMessage(bytes.NewReader(signed.Signed), signatureoptions.WithContext(ctx))
if err != nil {
return fmt.Errorf("error occurred while during artifact signing): %w", err)
}
signature := tuf.Signature{
signature := Signature{
Signature: base64.StdEncoding.EncodeToString(sig),
Cert: base64.StdEncoding.EncodeToString(sv.Cert),
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/cosign/cli/sign/sign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ import (

"github.com/google/go-containerregistry/pkg/name"

"github.com/secure-systems-lab/go-securesystemslib/encrypted"
"github.com/sigstore/cosign/cmd/cosign/cli/generate"
"github.com/sigstore/cosign/cmd/cosign/cli/options"
"github.com/sigstore/cosign/pkg/cosign"
"github.com/sigstore/cosign/test"
"github.com/sigstore/sigstore/pkg/cryptoutils"
"github.com/theupdateframework/go-tuf/encrypted"
)

func pass(s string) cosign.PassFunc {
Expand Down
232 changes: 232 additions & 0 deletions cmd/cosign/cli/tuf_policy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
//
// Copyright 2024 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.

// For backwards compatibility
// Verbatim copy of https://github.com/sigstore/sigstore/blob/v1.4.5/pkg/tuf/policy.go

package cli

import (
"bytes"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"sync"
"time"

cjson "github.com/secure-systems-lab/go-securesystemslib/cjson"
)

type Signed struct {
Signed json.RawMessage `json:"signed"`
Signatures []Signature `json:"signatures"`
}

type Signature struct {
KeyID string `json:"keyid"`
Signature string `json:"sig"`
Cert string `json:"cert,omitempty"`
}

type Key struct {
Type string `json:"keytype"`
Scheme string `json:"scheme"`
Algorithms []string `json:"keyid_hash_algorithms,omitempty"`
Value json.RawMessage `json:"keyval"`

id string
idOnce sync.Once
}

func (k *Key) ID() string {
k.idOnce.Do(func() {
data, _ := cjson.EncodeCanonical(k)
digest := sha256.Sum256(data)
k.id = hex.EncodeToString(digest[:])
})
return k.id
}

func (k *Key) ContainsID(id string) bool {
return id == k.ID()
}

type Root struct {
Type string `json:"_type"`
SpecVersion string `json:"spec_version"`
Version int `json:"version"`
Expires time.Time `json:"expires"`
Keys map[string]*Key `json:"keys"`
Roles map[string]*Role `json:"roles"`
Namespace string `json:"namespace"`

ConsistentSnapshot bool `json:"consistent_snapshot"`
}

func NewRoot() *Root {
return &Root{
Type: "root",
SpecVersion: "1.0",
Version: 1,
// Default expires in 3 months
Expires: time.Now().AddDate(0, 3, 0).UTC().Round(time.Second),
Keys: make(map[string]*Key),
Roles: make(map[string]*Role),
ConsistentSnapshot: true,
}
}

func (r *Root) AddKey(key *Key) bool {
changed := false
if _, ok := r.Keys[key.ID()]; !ok {
changed = true
r.Keys[key.ID()] = key
}

return changed
}

type Role struct {
KeyIDs []string `json:"keyids"`
Threshold int `json:"threshold"`
}

func (r *Role) AddKeysWithThreshold(keys []*Key, threshold int) bool {
roleIDs := make(map[string]struct{})
for _, id := range r.KeyIDs {
roleIDs[id] = struct{}{}
}
changed := false
for _, key := range keys {
if _, ok := roleIDs[key.ID()]; !ok {
changed = true
r.KeyIDs = append(r.KeyIDs, key.ID())
}
}
r.Threshold = threshold
return changed
}

func (r *Root) Marshal() (*Signed, error) {
// Marshals the Root into a Signed type
b, err := cjson.EncodeCanonical(r)
if err != nil {
return nil, err
}
return &Signed{Signed: b}, nil
}

func (r *Root) ValidKey(key *Key, role string) (string, error) {
// Checks if id is a valid key for role by matching the identity and issuer if specified.
// Returns the key ID or an error if invalid key.
fulcioKeyVal, err := GetFulcioKeyVal(key)
if err != nil {
return "", fmt.Errorf("error parsing signer key: %w", err)
}

result := ""
for keyid, rootKey := range r.Keys {
fulcioRootKeyVal, err := GetFulcioKeyVal(rootKey)
if err != nil {
return "", fmt.Errorf("error parsing root key: %w", err)
}
if fulcioKeyVal.Identity == fulcioRootKeyVal.Identity {
if fulcioRootKeyVal.Issuer == "" || fulcioRootKeyVal.Issuer == fulcioKeyVal.Issuer {
result = keyid
break
}
}
}
if result == "" {
return "", errors.New("key not found in root keys")
}

rootRole, ok := r.Roles[role]
if !ok {
return "", errors.New("invalid role")
}
for _, id := range rootRole.KeyIDs {
if id == result {
return result, nil
}
}
return "", errors.New("key not found in role")
}

func (s *Signed) JSONMarshal(prefix, indent string) ([]byte, error) {
// Marshals Signed with prefix and indent.
b, err := cjson.EncodeCanonical(s)
if err != nil {
return []byte{}, err
}

var out bytes.Buffer
if err := json.Indent(&out, b, prefix, indent); err != nil {
return []byte{}, err
}

return out.Bytes(), nil
}

func (s *Signed) AddOrUpdateSignature(key *Key, signature Signature) error {
root := &Root{}
if err := json.Unmarshal(s.Signed, root); err != nil {
return fmt.Errorf("unmarshalling root policy: %w", err)
}
var err error
signature.KeyID, err = root.ValidKey(key, "root")
if err != nil {
return errors.New("invalid root key")
}
signatures := []Signature{}
for _, sig := range s.Signatures {
if sig.KeyID != signature.KeyID {
signatures = append(signatures, sig)
}
}
signatures = append(signatures, signature)
s.Signatures = signatures
return nil
}

const (
KeyTypeFulcio = "sigstore-oidc"
KeySchemeFulcio = "https://fulcio.sigstore.dev"
)

var KeyAlgorithms = []string{"sha256", "sha512"}

type FulcioKeyVal struct {
Identity string `json:"identity"`
Issuer string `json:"issuer,omitempty"`
}

func FulcioVerificationKey(email, issuer string) *Key {
keyValBytes, _ := json.Marshal(FulcioKeyVal{Identity: email, Issuer: issuer})
return &Key{
Type: KeyTypeFulcio,
Scheme: KeySchemeFulcio,
Algorithms: KeyAlgorithms,
Value: keyValBytes,
}
}

func GetFulcioKeyVal(key *Key) (*FulcioKeyVal, error) {
fulcioKeyVal := &FulcioKeyVal{}
err := json.Unmarshal(key.Value, fulcioKeyVal)
return fulcioKeyVal, err
}
2 changes: 1 addition & 1 deletion cmd/cosign/cli/verify/verify_blob_attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func (c *VerifyBlobAttestationCommand) Exec(ctx context.Context, artifactPath st
if err != nil {
return fmt.Errorf("new envelope verifier: %w", err)
}
if _, err := dssev.Verify(&env); err != nil {
if _, err := dssev.Verify(ctx, &env); err != nil {
return fmt.Errorf("dsse verify: %w", err)
}

Expand Down
2 changes: 1 addition & 1 deletion doc/cosign_initialize.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 566ab9d

Please sign in to comment.