Skip to content

Commit

Permalink
Add basic sigstore bundle parsing
Browse files Browse the repository at this point in the history
Signed-off-by: Marcela Melara <[email protected]>
  • Loading branch information
marcelamelara committed May 29, 2024
1 parent e57ba1e commit 900a062
Show file tree
Hide file tree
Showing 5 changed files with 348 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package main

import (
"fmt"
"os"

"github.com/chkimes/image-attestation/internal"
"github.com/in-toto/scai-demos/scai-gen/pkg/fileio"
Expand All @@ -12,65 +11,54 @@ import (
"github.com/spf13/cobra"
)

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "attestor",
var generateCmd = &cobra.Command{
Use: "generate",
Args: cobra.ExactArgs(1),
Short: "Generates a JSON-encoded VM image attestation (in-toto format)",
RunE: genAttestation,
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
Short: "Generates a JSON-encoded in-toto Statement (unsigned) for a predicate about a given subject artifact",
RunE: genStatement,
}

var (
outFile string
targetFile string
evidenceFile string
prettyPrint bool
)

func init() {
rootCmd.Flags().StringVarP(
generateCmd.Flags().StringVarP(
&outFile,
"out-file",
"o",
"",
"Filename to write out the JSON-encoded object",
)
rootCmd.MarkFlagRequired("out-file") //nolint:errcheck
generateCmd.MarkFlagRequired("out-file") //nolint:errcheck

rootCmd.Flags().StringVarP(
generateCmd.Flags().StringVarP(
&targetFile,
"target",
"t",
"",
"The filename of the JSON-encoded target attestation file",
)

rootCmd.Flags().StringVarP(
generateCmd.Flags().StringVarP(
&evidenceFile,
"evidence",
"e",
"",
"The filename of the JSON-encoded evidence file",
)

rootCmd.Flags().BoolVar(
generateCmd.Flags().BoolVar(
&prettyPrint,
"pretty-print",
false,
"Flag to JSON pretty-print the generated Report",
)
}

func genAttestation(_ *cobra.Command, args []string) error {
func genStatement(_ *cobra.Command, args []string) error {
// want to make sure the AttributeAssertion is a JSON file
if !fileio.HasJSONExt(outFile) {
return fmt.Errorf("expected a .json extension for the generated SCAI AttributeAssertion file %s", outFile)
Expand All @@ -92,7 +80,3 @@ func genAttestation(_ *cobra.Command, args []string) error {

return fileio.WritePbToFile(st, outFile, prettyPrint)
}

func main() {
Execute()
}
76 changes: 76 additions & 0 deletions attest/cmd/in-toto-attest/parse_sigstore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package main

import (
"encoding/pem"
"fmt"
"os"

"github.com/in-toto/scai-demos/scai-gen/pkg/fileio"

sigbundle "github.com/sigstore/protobuf-specs/gen/pb-go/bundle/v1"
"github.com/spf13/cobra"
)

var parseCmd = &cobra.Command{
Use: "parse-sigstore",
Short: "Parses a JSON-encoded Sigstore bundle",
}

var pubkeyCmd = &cobra.Command{
Use: "pubkey",
Args: cobra.ExactArgs(1),
Short: "Outputs the PEM-formatted public key contained in a Sigstore bundle body",
RunE: getPubKey,
}

func init() {
pubkeyCmd.Flags().StringVarP(
&outFile,
"out-file",
"o",
"",
"Filename to write out the JSON-encoded object",
)

parseCmd.AddCommand(pubkeyCmd)
}

func getPubKey(_ *cobra.Command, args []string) error {
// read in the sigstore bundle file
bundleFile := args[0]
bundle := &sigbundle.Bundle{}

err := fileio.ReadPbFromFile(bundleFile, bundle)
if err != nil {
return fmt.Errorf("failed to read Sigstore bundle file %s: %w", bundleFile, err)
}

certChain := bundle.GetVerificationMaterial().GetX509CertificateChain()
if certChain == nil {
return fmt.Errorf("failed to retrieve x509 certificatefrom Sigstore bundle %s", bundleFile)
}

certs := certChain.GetCertificates()
if certs == nil || len(certs[0].GetRawBytes()) == 0 {
return fmt.Errorf("failed to retrieve x509 leaf certificate from Sigstore bundle %s", bundleFile)
}

block := &pem.Block{
Type: "CERTIFICATE",
Bytes: certs[0].GetRawBytes(),
}

encoded := pem.EncodeToMemory(block)
if encoded == nil {
return fmt.Errorf("failed to PEM-encode x509 certificate for Sigstore bundle %s", bundleFile)
}


if len(outFile) > 0 {
err = os.WriteFile(outFile, encoded, 0644)
} else{
fmt.Printf("Parsed: \n\n%s", string(encoded))
err = nil
}
return err
}
35 changes: 35 additions & 0 deletions attest/cmd/in-toto-attest/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package main

import (
"os"

"github.com/spf13/cobra"
)

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "in-toto-attest",
Short: "A CLI tool for generating/verifying attestations about build environments",
}

var (
outFile string
)

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
}

func init() {
rootCmd.AddCommand(generateCmd)
rootCmd.AddCommand(parseCmd)
}

func main() {
Execute()
}
77 changes: 72 additions & 5 deletions attest/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,95 @@ require (
github.com/google/go-tpm v0.9.0
github.com/in-toto/attestation v1.0.1
github.com/in-toto/scai-demos v0.3.0
github.com/sigstore/protobuf-specs v0.3.2
github.com/sigstore/sigstore-go v0.3.0
github.com/spf13/cobra v1.8.0
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3
google.golang.org/protobuf v1.33.0
google.golang.org/protobuf v1.34.1
)

require (
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/blang/semver v3.5.1+incompatible // indirect
github.com/cyberphone/json-canonicalization v0.0.0-20231011164504-785e29786b46 // indirect
github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect
github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-chi/chi v4.1.2+incompatible // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/analysis v0.23.0 // indirect
github.com/go-openapi/errors v0.22.0 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/loads v0.22.0 // indirect
github.com/go-openapi/runtime v0.28.0 // indirect
github.com/go-openapi/spec v0.21.0 // indirect
github.com/go-openapi/strfmt v0.23.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-openapi/validate v0.24.0 // indirect
github.com/google/cel-go v0.20.1 // indirect
github.com/google/certificate-transparency-go v1.1.8 // indirect
github.com/google/go-containerregistry v0.19.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
github.com/hashicorp/hcl v1.0.1-vault-5 // indirect
github.com/in-toto/attestation-verifier v0.0.0-20231007025621-3193280f5194 // indirect
github.com/in-toto/in-toto-golang v0.9.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/letsencrypt/boulder v0.0.0-20231026200631-000cd05d5491 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sassoftware/relic v7.2.1+incompatible // indirect
github.com/secure-systems-lab/go-securesystemslib v0.8.0 // indirect
github.com/shibumi/go-pathspec v1.3.0 // indirect
github.com/sigstore/rekor v1.3.6 // indirect
github.com/sigstore/sigstore v1.8.3 // indirect
github.com/sigstore/timestamp-authority v1.2.2 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.18.2 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
golang.org/x/crypto v0.20.0 // indirect
golang.org/x/sys v0.17.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/theupdateframework/go-tuf v0.7.0 // indirect
github.com/theupdateframework/go-tuf/v2 v2.0.0-20240223092044-1e7978e83f63 // indirect
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
github.com/transparency-dev/merkle v0.0.2 // indirect
go.mongodb.org/mongo-driver v1.14.0 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/term v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect
google.golang.org/genproto v0.0.0-20240311173647-c811ad7063a7 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240311173647-c811ad7063a7 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect
gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.120.1 // indirect
)

replace github.com/chkimes/image-attestation => /home/mmelara/build-env-attestation/attest
Loading

0 comments on commit 900a062

Please sign in to comment.