Skip to content

Commit

Permalink
parent 4869a0a
Browse files Browse the repository at this point in the history
author pxp928 <parth.psu@gmail.com> 1631470550 -0400
committer pxp928 <parth.psu@gmail.com> 1631823796 -0400

go mod tidy using go version 1.17

updated record/run commands and readme

added omitempty to private field

removed omitempty as test fails

added replace to remove empty private field in key layout

updated key layout and added check for key or cert in run/record
  • Loading branch information
pxp928 committed Sep 16, 2021
1 parent 4869a0a commit 6862711
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 48 deletions.
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ test-sign: build generate_layout
# Running test-sign
@./bin/in-toto sign -f ./test/tmp/test.layout -k ./certs/example.com.layout.key.pem -o ./test/tmp/signed.layout

test-record: build generate_layout
# Running record start
@./bin/in-toto record start -n write-code -c ./certs/example.com.write-code.cert.pem -k ./certs/example.com.write-code.key.pem -d ./test/tmp
# Record running step
@echo goodbye > ./test/tmp/foo.py
# Running record stop
@./bin/in-toto record stop -n write-code -c ./certs/example.com.write-code.cert.pem -p ./test/tmp/foo.py -k ./certs/example.com.write-code.key.pem -d ./test/tmp

test-run: build generate_layout
# Running write code step
@./bin/in-toto run -n write-code -c ./certs/example.com.write-code.cert.pem -k ./certs/example.com.write-code.key.pem -p ./test/tmp/foo.py -d ./test/tmp -- /bin/sh -c "echo hello > ./test/tmp/foo.py"
Expand All @@ -51,9 +59,8 @@ test-verify: test-sign test-run

generate_layout: leaf_certs
@mkdir -p ./test/tmp
$(eval rootid := $(shell ./bin/in-toto key id ./certs/root.cert.pem))
$(eval rootca := $(shell ./bin/in-toto key layout ./certs/root.cert.pem | sed -e 's/\\n/\\\\n/g'))
@cat $(LAYOUT_TMPL) | sed -e 's#{{ROOTCA}}#$(rootca)#' -e 's#{{ROOTID}}#$(rootid)#' > ./test/tmp/test.layout
@cat $(LAYOUT_TMPL) | sed -e 's#{{ROOTCA}}#$(rootca)#' > ./test/tmp/test.layout

root-cert:
# Generate root cert openssl conf file
Expand Down
63 changes: 49 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ Usage:
Available Commands:
help Help about any command
record Creates a signed link metadata file in two steps, in order to provide
evidence for supply chain steps that cannot be carried out by a single command
key Key management commands
record Creates a signed link metadata file in two steps, in order to provide evidence for supply chain steps that cannot be carried out by a single command
run Executes the passed command and records paths and hashes of 'materials'
sign Provides command line interface to sign in-toto link or layout metadata
verify Verify that the software supply chain of the delivered product
Expand All @@ -84,6 +84,24 @@ Flags:
Use "in-toto [command] --help" for more information about a command.
```

### key

```text
Key management commands
Usage:
in-toto key [command]
Available Commands:
id Output the key id for a given key
layout Output the key layout for a given key in <KEYID>: <KEYOBJ> format
Flags:
-h, --help help for key
Use "in-toto key [command] --help" for more information about a command.
```

### run

```text
Expand All @@ -99,11 +117,14 @@ Usage:
Flags:
-c, --cert string Path to a PEM formatted certificate that corresponds with
the provided key.
-e, --exclude stringArray path patterns to match paths that should not be recorded as 0
‘materials’ or ‘products’. Passed patterns override patterns defined
in environment variables or config files. See Config docs for details.
-h, --help help for run
-k, --key string Path to a PEM formatted private key file used to sign
the resulting link metadata. (passing one of '--key'
or '--gpg' is required)
--lstrip-paths stringArray path prefixes used to left-strip artifact paths before storing
-l, --lstrip-paths stringArray path prefixes used to left-strip artifact paths before storing
them to the resulting link metadata. If multiple prefixes
are specified, only a single prefix can match the path of
any artifact and that is then left-stripped. All prefixes
Expand All @@ -115,10 +136,14 @@ Flags:
-n, --name string Name used to associate the resulting link metadata
with the corresponding step defined in an in-toto
layout.
-d, --output-directory string directory to store link metadata (default "./")
-d, --metadata-directory string directory to store link metadata (default "./")
-p, --products stringArray Paths to files or directories, whose paths and hashes
are stored in the resulting link metadata after the
command is executed. Symlinks are followed.
-r, --run-dir string runDir specifies the working directory of the command.
If runDir is the empty string, the command will run in the
calling process's current directory. The runDir directory must
exist, be writable, and not be a symlink.
```

### sign
Expand Down Expand Up @@ -181,22 +206,32 @@ Available Commands:
stop Records and adds the paths and hashes of the passed products to the link metadata file and updates the signature.
Flags:
-c, --cert string Path to a PEM formatted certificate that corresponds with the provided key.
-h, --help help for record
-k, --key string Path to a private key file to sign the resulting link metadata.
The keyid prefix is used as an infix for the link metadata filename,
i.e. ‘<name>.<keyid prefix>.link’. See ‘–key-type’ for available
formats. Passing one of ‘–key’ or ‘–gpg’ is required.
-n, --name string name for the resulting link metadata file.
It is also used to associate the link with a step defined
in an in-toto layout.
-c, --cert string Path to a PEM formatted certificate that corresponds with the provided key.
-e, --exclude stringArray Path patterns to match paths that should not be recorded as
‘materials’ or ‘products’. Passed patterns override patterns defined
in environment variables or config files. See Config docs for details.
-h, --help help for record
-k, --key string Path to a private key file to sign the resulting link metadata.
The keyid prefix is used as an infix for the link metadata filename,
i.e. ‘<name>.<keyid prefix>.link’. See ‘–key-type’ for available
formats. Passing one of ‘–key’ or ‘–gpg’ is required.
-l, --lstrip-paths stringArray Path prefixes used to left-strip artifact paths before storing
them to the resulting link metadata. If multiple prefixes
are specified, only a single prefix can match the path of
any artifact and that is then left-stripped. All prefixes
are checked to ensure none of them are a left substring
of another.
-d, --metadata-directory string directory to store link metadata (default "./")
-n, --name string name for the resulting link metadata file.
It is also used to associate the link with a step defined
in an in-toto layout.
Use "in-toto record [command] --help" for more information about a command.
```

## Layout Certificate Constraints

Currently only URIs and common name constraints supported:
Currently the following constraints supported:

```json
{
Expand Down
2 changes: 1 addition & 1 deletion certs/layout.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"keys": {},
"readme": "",
"rootcas": {
"{{ROOTID}}": {{ROOTCA}}
{{ROOTCA}}
},
"steps": [
{
Expand Down
9 changes: 7 additions & 2 deletions cmd/in-toto/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"encoding/json"
"fmt"
"strings"

intoto "github.com/in-toto/in-toto-golang/in_toto"
"github.com/spf13/cobra"
Expand All @@ -23,7 +24,7 @@ var keyIDCmd = &cobra.Command{

var keyLayoutCmd = &cobra.Command{
Use: "layout <file>",
Short: "Output the key layout for a given key",
Short: "Output the key layout for a given key in <KEYID>: <KEYOBJ> format",
Long: "Output is a json formatted pubkey suitable for embedding in a layout file",
Args: cobra.ExactArgs(1),
RunE: keyLayout,
Expand Down Expand Up @@ -57,12 +58,16 @@ func keyLayout(cmd *cobra.Command, args []string) error {
return err
}

// removed the private key from the struct such that it is not printed for use in the layout
key.KeyVal.Private = ""

b, err := json.Marshal(key)
if err != nil {
return err
}

fmt.Printf("%s\n", b)
s2 := strings.ReplaceAll(string(b), `"private":"",`, "")
fmt.Printf(`"%v": %s`, key.KeyID, s2)

return nil
}
74 changes: 62 additions & 12 deletions cmd/in-toto/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package main

import (
"fmt"
"os"
"path/filepath"

intoto "github.com/in-toto/in-toto-golang/in_toto"
"github.com/spf13/cobra"
Expand All @@ -16,7 +18,7 @@ var (
var recordCmd = &cobra.Command{
Use: "record",
Short: `Creates a signed link metadata file in two steps, in order to provide
evidence for supply chain steps that cannot be carried out by a single command`,
evidence for supply chain steps that cannot be carried out by a single command`,
Long: `Creates a signed link metadata file in two steps, in order to provide
evidence for supply chain steps that cannot be carried out by a single command
(for which ‘in-toto-run’ should be used). It returns a non-zero value on
Expand Down Expand Up @@ -78,6 +80,37 @@ formats. Passing one of ‘–key’ or ‘–gpg’ is required.`,
with the provided key.`,
)

recordCmd.PersistentFlags().StringVarP(
&outDir,
"metadata-directory",
"d",
"./",
`Directory to store link metadata`,
)

recordCmd.PersistentFlags().StringArrayVarP(
&lStripPaths,
"lstrip-paths",
"l",
[]string{},
`Path prefixes used to left-strip artifact paths before storing
them to the resulting link metadata. If multiple prefixes
are specified, only a single prefix can match the path of
any artifact and that is then left-stripped. All prefixes
are checked to ensure none of them are a left substring
of another.`,
)

recordCmd.PersistentFlags().StringArrayVarP(
&exclude,
"exclude",
"e",
[]string{},
`Path patterns to match paths that should not be recorded as
‘materials’ or ‘products’. Passed patterns override patterns defined
in environment variables or config files. See Config docs for details.`,
)

recordCmd.MarkPersistentFlagRequired("name")

// Record Start Command
Expand Down Expand Up @@ -110,28 +143,43 @@ command is executed. Symlinks are followed.`,
func recordPreRun(cmd *cobra.Command, args []string) error {
key = intoto.Key{}
cert = intoto.Key{}
if err := key.LoadKeyDefaults(keyPath); err != nil {
return fmt.Errorf("invalid key at %s: %w", keyPath, err)

if keyPath == "" && certPath == "" {
return fmt.Errorf("key or cert must be provided")
}

if len(certPath) > 0 {
if err := cert.LoadKeyDefaults(certPath); err != nil {
return fmt.Errorf("invalid cert at %s: %w", certPath, err)
if len(keyPath) > 0 {
if _, err := os.Stat(keyPath); err == nil {
if err := key.LoadKeyDefaults(keyPath); err != nil {
return fmt.Errorf("invalid key at %s: %w", keyPath, err)
}
} else {
return fmt.Errorf("key not found at %s: %w", keyPath, err)
}
}

key.KeyVal.Certificate = cert.KeyVal.Certificate
if len(certPath) > 0 {
if _, err := os.Stat(certPath); err == nil {
if err := cert.LoadKeyDefaults(certPath); err != nil {
return fmt.Errorf("invalid cert at %s: %w", certPath, err)
}
key.KeyVal.Certificate = cert.KeyVal.Certificate
} else {
return fmt.Errorf("cert not found at %s: %w", certPath, err)
}
}
return nil
}

func recordStart(cmd *cobra.Command, args []string) error {
block, err := intoto.InTotoRecordStart(recordStepName, recordMaterialsPaths, key, []string{"sha256"}, []string{}, nil)
block, err := intoto.InTotoRecordStart(recordStepName, recordMaterialsPaths, key, []string{"sha256"}, exclude, lStripPaths)
if err != nil {
return fmt.Errorf("failed to create start link file: %w", err)
}

prelimLinkName := fmt.Sprintf(intoto.PreliminaryLinkNameFormat, recordStepName, key.KeyID)
err = block.Dump(prelimLinkName)
prelimLinkPath := filepath.Join(outDir, prelimLinkName)
err = block.Dump(prelimLinkPath)
if err != nil {
return fmt.Errorf("failed to write start link file to %s: %w", prelimLinkName, err)
}
Expand All @@ -142,17 +190,19 @@ func recordStart(cmd *cobra.Command, args []string) error {
func recordStop(cmd *cobra.Command, args []string) error {
var prelimLinkMb intoto.Metablock
prelimLinkName := fmt.Sprintf(intoto.PreliminaryLinkNameFormat, recordStepName, key.KeyID)
if err := prelimLinkMb.Load(prelimLinkName); err != nil {
prelimLinkPath := filepath.Join(outDir, prelimLinkName)
if err := prelimLinkMb.Load(prelimLinkPath); err != nil {
return fmt.Errorf("failed to load start link file at %s: %w", prelimLinkName, err)
}

linkMb, err := intoto.InTotoRecordStop(prelimLinkMb, recordProductsPaths, key, []string{"sha256"}, []string{}, nil)
linkMb, err := intoto.InTotoRecordStop(prelimLinkMb, recordProductsPaths, key, []string{"sha256"}, exclude, lStripPaths)
if err != nil {
return fmt.Errorf("failed to create stop link file: %w", err)
}

linkName := fmt.Sprintf(intoto.LinkNameFormat, recordStepName, key.KeyID)
err = linkMb.Dump(linkName)
linkPath := filepath.Join(outDir, linkName)
err = linkMb.Dump(linkPath)
if err != nil {
return fmt.Errorf("failed to write stop link file to %s: %w", prelimLinkName, err)
}
Expand Down
13 changes: 8 additions & 5 deletions cmd/in-toto/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ import (
)

var (
layoutPath string
keyPath string
certPath string
key intoto.Key
cert intoto.Key
layoutPath string
keyPath string
certPath string
key intoto.Key
cert intoto.Key
lStripPaths []string
exclude []string
outDir string
)

var rootCmd = &cobra.Command{
Expand Down
Loading

0 comments on commit 6862711

Please sign in to comment.