Skip to content

Commit

Permalink
Add support for SigningConfig
Browse files Browse the repository at this point in the history
Created a simple wrapper around the protobuf SigningConfig. I mirrored
the existing code for TrustedRoot, though this is far simpler since
this is just a few strings.

I didn't add support for ClientTrustConfig since we won't distribute
this file via TUF, but this would be easy enough to add later on.

Fixes sigstore#185

Signed-off-by: Hayden Blauzvern <hblauzvern@google.com>
  • Loading branch information
haydentherapper committed Jan 9, 2025
1 parent e5df725 commit cd57778
Show file tree
Hide file tree
Showing 8 changed files with 382 additions and 25 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
/tufdata
/conformance
/pkg/tuf/testing.local.json
/examples/oci-image-verification/oci-image-verification
/examples/sigstore-go-signing/sigstore-go-signing
4 changes: 2 additions & 2 deletions examples/oci-image-verification/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ replace github.com/sigstore/sigstore-go => ../../

require (
github.com/google/go-containerregistry v0.20.2
github.com/sigstore/protobuf-specs v0.3.2
github.com/sigstore/protobuf-specs v0.3.3
github.com/sigstore/sigstore v1.8.11
github.com/sigstore/sigstore-go v0.6.2
)
Expand Down Expand Up @@ -91,7 +91,7 @@ require (
golang.org/x/term v0.27.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect
google.golang.org/protobuf v1.36.1 // indirect
google.golang.org/protobuf v1.36.2 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
Expand Down
8 changes: 4 additions & 4 deletions examples/oci-image-verification/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,8 @@ github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI=
github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE=
github.com/sigstore/protobuf-specs v0.3.2 h1:nCVARCN+fHjlNCk3ThNXwrZRqIommIeNKWwQvORuRQo=
github.com/sigstore/protobuf-specs v0.3.2/go.mod h1:RZ0uOdJR4OB3tLQeAyWoJFbNCBFrPQdcokntde4zRBA=
github.com/sigstore/protobuf-specs v0.3.3 h1:RMZQgXTD/pF7KW6b5NaRLYxFYZ/wzx44PQFXN2PEo5g=
github.com/sigstore/protobuf-specs v0.3.3/go.mod h1:vIhZ6Uor1a38+wvRrKcqL2PtYNlgoIW9lhzYzkyy4EU=
github.com/sigstore/rekor v1.3.7 h1:Z5UW5TmqbTZnyOFkMRfi32q/CWcxK6VuzIkx+33mbq8=
github.com/sigstore/rekor v1.3.7/go.mod h1:TihqJscZ6L6398x68EHY82t0AOnGYfrQ0siXe3WgbR4=
github.com/sigstore/sigstore v1.8.11 h1:tEqeQqbT+awtM87ec9KEeSUxT/AFvJNawneYJyAkFrQ=
Expand Down Expand Up @@ -396,8 +396,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f h1:
google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU=
google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
Expand Down
36 changes: 23 additions & 13 deletions examples/sigstore-go-signing/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,18 @@ func main() {
log.Fatal(err)
}

trustedRootJSON, err := tufClient.GetTarget("trusted_root.json")
trustedRoot, err := root.GetTrustedRoot(tufClient)
if err != nil {
log.Fatal(err)
}

trustedRoot, err := root.NewTrustedRootFromJSON(trustedRootJSON)
// TODO: Uncomment once the TUF staging root distributes this file
// signingConfig, err := root.GetSigningConfig(tufClient)
signingConfig, err := root.NewSigningConfig(root.SigningConfigMediaType01,
"https://fulcio.sigstage.dev",
"https://oauth2.sigstage.dev/auth",
[]string{"https://rekor.sigstage.dev"},
[]string{"https://timestamp.githubapp.com/api/v1/timestamp"})
if err != nil {
log.Fatal(err)
}
Expand All @@ -110,7 +116,7 @@ func main() {

if *idToken != "" {
fulcioOpts := &sign.FulcioOptions{
BaseURL: "https://fulcio.sigstage.dev",
BaseURL: signingConfig.FulcioCertificateAuthorityURL(),
Timeout: time.Duration(30 * time.Second),
Retries: 1,
}
Expand All @@ -121,24 +127,28 @@ func main() {
}

if *tsa {
tsaOpts := &sign.TimestampAuthorityOptions{
URL: "https://timestamp.githubapp.com/api/v1/timestamp",
Timeout: time.Duration(30 * time.Second),
Retries: 1,
for _, tsaURL := range signingConfig.TimestampAuthorityURLs() {
tsaOpts := &sign.TimestampAuthorityOptions{
URL: tsaURL,
Timeout: time.Duration(30 * time.Second),
Retries: 1,
}
opts.TimestampAuthorities = append(opts.TimestampAuthorities, sign.NewTimestampAuthority(tsaOpts))
}
opts.TimestampAuthorities = append(opts.TimestampAuthorities, sign.NewTimestampAuthority(tsaOpts))

// staging TUF repo doesn't have accessible timestamp authorities
opts.TrustedRoot = nil
}

if *rekor {
rekorOpts := &sign.RekorOptions{
BaseURL: "https://rekor.sigstage.dev",
Timeout: time.Duration(90 * time.Second),
Retries: 1,
for _, rekorURL := range signingConfig.RekorLogURLs() {
rekorOpts := &sign.RekorOptions{
BaseURL: rekorURL,
Timeout: time.Duration(90 * time.Second),
Retries: 1,
}
opts.TransparencyLogs = append(opts.TransparencyLogs, sign.NewRekor(rekorOpts))
}
opts.TransparencyLogs = append(opts.TransparencyLogs, sign.NewRekor(rekorOpts))
}

bundle, err := sign.Bundle(content, keypair, opts)
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ require (
github.com/in-toto/attestation v1.1.0
github.com/in-toto/in-toto-golang v0.9.0
github.com/secure-systems-lab/go-securesystemslib v0.9.0
github.com/sigstore/protobuf-specs v0.3.2
github.com/sigstore/protobuf-specs v0.3.3
github.com/sigstore/rekor v1.3.7
github.com/sigstore/sigstore v1.8.11
github.com/sigstore/timestamp-authority v1.2.3
github.com/stretchr/testify v1.10.0
github.com/theupdateframework/go-tuf/v2 v2.0.2
golang.org/x/crypto v0.31.0
golang.org/x/mod v0.22.0
google.golang.org/protobuf v1.36.1
google.golang.org/protobuf v1.36.2
)

require (
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,8 @@ github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI=
github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE=
github.com/sigstore/protobuf-specs v0.3.2 h1:nCVARCN+fHjlNCk3ThNXwrZRqIommIeNKWwQvORuRQo=
github.com/sigstore/protobuf-specs v0.3.2/go.mod h1:RZ0uOdJR4OB3tLQeAyWoJFbNCBFrPQdcokntde4zRBA=
github.com/sigstore/protobuf-specs v0.3.3 h1:RMZQgXTD/pF7KW6b5NaRLYxFYZ/wzx44PQFXN2PEo5g=
github.com/sigstore/protobuf-specs v0.3.3/go.mod h1:vIhZ6Uor1a38+wvRrKcqL2PtYNlgoIW9lhzYzkyy4EU=
github.com/sigstore/rekor v1.3.7 h1:Z5UW5TmqbTZnyOFkMRfi32q/CWcxK6VuzIkx+33mbq8=
github.com/sigstore/rekor v1.3.7/go.mod h1:TihqJscZ6L6398x68EHY82t0AOnGYfrQ0siXe3WgbR4=
github.com/sigstore/sigstore v1.8.11 h1:tEqeQqbT+awtM87ec9KEeSUxT/AFvJNawneYJyAkFrQ=
Expand Down Expand Up @@ -441,8 +441,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f h1:
google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU=
google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
Expand Down
130 changes: 130 additions & 0 deletions pkg/root/signing_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// 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.

package root

import (
"fmt"
"os"

prototrustroot "github.com/sigstore/protobuf-specs/gen/pb-go/trustroot/v1"
"github.com/sigstore/sigstore-go/pkg/tuf"
"google.golang.org/protobuf/encoding/protojson"
)

const SigningConfigMediaType01 = "application/vnd.dev.sigstore.signingconfig.v0.1+json"

type SigningConfig struct {
signingConfig *prototrustroot.SigningConfig
}

func (sc *SigningConfig) FulcioCertificateAuthorityURL() string {
return sc.signingConfig.GetCaUrl()
}

func (sc *SigningConfig) OIDCProviderURL() string {
return sc.signingConfig.GetOidcUrl()
}

func (sc *SigningConfig) RekorLogURLs() []string {
return sc.signingConfig.GetTlogUrls()
}

func (sc *SigningConfig) TimestampAuthorityURLs() []string {
return sc.signingConfig.GetTsaUrls()
}

// NewSigningConfig initializes a SigningConfig object from a mediaType string, Fulcio certificate
// authority URL, OIDC provider URL, list of Rekor transpraency log URLs, and a list of
// timestamp authorities.
func NewSigningConfig(mediaType string,
fulcioCertificateAuthority string,
oidcProvider string,
rekorLogs []string,
timestampAuthorities []string) (*SigningConfig, error) {
if mediaType != SigningConfigMediaType01 {
return nil, fmt.Errorf("unsupported SigningConfig media type, must be: %s", SigningConfigMediaType01)
}
sc := &SigningConfig{
signingConfig: &prototrustroot.SigningConfig{
MediaType: mediaType,
CaUrl: fulcioCertificateAuthority,
OidcUrl: oidcProvider,
TlogUrls: rekorLogs,
TsaUrls: timestampAuthorities,
},
}
return sc, nil
}

// NewSigningConfigFromProtobuf returns a Sigstore signing configuration.
func NewSigningConfigFromProtobuf(sc *prototrustroot.SigningConfig) (*SigningConfig, error) {
if sc.GetMediaType() != SigningConfigMediaType01 {
return nil, fmt.Errorf("unsupported SigningConfig media type: %s", sc.GetMediaType())
}
return &SigningConfig{signingConfig: sc}, nil
}

// NewSigningConfigFromPath returns a Sigstore signing configuration from a file.
func NewSigningConfigFromPath(path string) (*SigningConfig, error) {
scJSON, err := os.ReadFile(path)
if err != nil {
return nil, err
}

return NewSigningConfigFromJSON(scJSON)
}

// NewSigningConfigFromJSON returns a Sigstore signing configuration from JSON.
func NewSigningConfigFromJSON(rootJSON []byte) (*SigningConfig, error) {
pbSC, err := NewSigningConfigProtobuf(rootJSON)
if err != nil {
return nil, err
}

return NewSigningConfigFromProtobuf(pbSC)
}

// NewSigningConfigProtobuf returns a Sigstore signing configuration as a protobuf.
func NewSigningConfigProtobuf(scJSON []byte) (*prototrustroot.SigningConfig, error) {
pbSC := &prototrustroot.SigningConfig{}
err := protojson.Unmarshal(scJSON, pbSC)
if err != nil {
return nil, err
}
return pbSC, nil
}

// FetchSigningConfig fetches the public-good Sigstore signing configuration from TUF.
func FetchSigningConfig() (*SigningConfig, error) {
return FetchSigningConfigWithOptions(tuf.DefaultOptions())
}

// FetchSigningConfig fetches the public-good Sigstore signing configuration with the given options from TUF.
func FetchSigningConfigWithOptions(opts *tuf.Options) (*SigningConfig, error) {
client, err := tuf.New(opts)
if err != nil {
return nil, err
}
return GetSigningConfig(client)
}

// FetchSigningConfig fetches the public-good Sigstore signing configuration target from TUF.
func GetSigningConfig(c *tuf.Client) (*SigningConfig, error) {
jsonBytes, err := c.GetTarget("signing_config.json")
if err != nil {
return nil, err
}
return NewSigningConfigFromJSON(jsonBytes)
}
Loading

0 comments on commit cd57778

Please sign in to comment.