...

Source file src/github.com/in-toto/in-toto-golang/cmd/record.go

Documentation: github.com/in-toto/in-toto-golang/cmd

     1  package cmd
     2  
     3  import (
     4  	"fmt"
     5  	"path/filepath"
     6  
     7  	intoto "github.com/in-toto/in-toto-golang/in_toto"
     8  	"github.com/spf13/cobra"
     9  )
    10  
    11  var (
    12  	recordStepName       string
    13  	recordMaterialsPaths []string
    14  	recordProductsPaths  []string
    15  )
    16  
    17  var recordCmd = &cobra.Command{
    18  	Use: "record",
    19  	Short: `Creates a signed link metadata file in two steps, in order to provide
    20                evidence for supply chain steps that cannot be carried out by a single command`,
    21  	Long: `Creates a signed link metadata file in two steps, in order to provide
    22  evidence for supply chain steps that cannot be carried out by a single command
    23  (for which ‘in-toto-run’ should be used). It returns a non-zero value on
    24  failure and zero otherwise.`,
    25  	PersistentPreRunE: getKeyCert,
    26  }
    27  
    28  var recordStartCmd = &cobra.Command{
    29  	Use: "start",
    30  	Short: `Creates a preliminary link file recording the paths and hashes of the
    31  passed materials and signs it with the passed functionary’s key.`,
    32  	Long: `Creates a preliminary link file recording the paths and hashes of the
    33  passed materials and signs it with the passed functionary’s key.
    34  The resulting link file is stored as ‘.<name>.<keyid prefix>.link-unfinished’.`,
    35  	RunE: recordStart,
    36  }
    37  
    38  var recordStopCmd = &cobra.Command{
    39  	Use:   "stop",
    40  	Short: `Records and adds the paths and hashes of the passed products to the link metadata file and updates the signature.`,
    41  	Long: `Expects preliminary link file ‘.<name>.<keyid prefix>.link-unfinished’ in the CWD,
    42  signed by the passed functionary’s key. If found, it records
    43  and adds the paths and hashes of the passed products to the
    44  link metadata file, updates the signature and renames the
    45  file to ‘<name>.<keyid prefix>.link’.`,
    46  	RunE: recordStop,
    47  }
    48  
    49  func init() {
    50  	rootCmd.AddCommand(recordCmd)
    51  
    52  	recordCmd.PersistentFlags().StringVarP(
    53  		&recordStepName,
    54  		"name",
    55  		"n",
    56  		"",
    57  		`Name for the resulting link metadata file.
    58  It is also used to associate the link with a step defined
    59  in an in-toto layout.`,
    60  	)
    61  
    62  	recordCmd.PersistentFlags().StringVarP(
    63  		&keyPath,
    64  		"key",
    65  		"k",
    66  		"",
    67  		`Path to a private key file to sign the resulting link metadata.
    68  The keyid prefix is used as an infix for the link metadata filename,
    69  i.e. ‘<name>.<keyid prefix>.link’. See ‘–key-type’ for available
    70  formats. Passing one of ‘–key’ or ‘–gpg’ is required.`,
    71  	)
    72  
    73  	recordCmd.PersistentFlags().StringVarP(
    74  		&certPath,
    75  		"cert",
    76  		"c",
    77  		"",
    78  		`Path to a PEM formatted certificate that corresponds
    79  with the provided key.`,
    80  	)
    81  
    82  	recordCmd.PersistentFlags().StringVarP(
    83  		&outDir,
    84  		"metadata-directory",
    85  		"d",
    86  		"./",
    87  		`Directory to store link metadata`,
    88  	)
    89  
    90  	recordCmd.PersistentFlags().StringArrayVarP(
    91  		&lStripPaths,
    92  		"lstrip-paths",
    93  		"l",
    94  		[]string{},
    95  		`Path prefixes used to left-strip artifact paths before storing
    96  them to the resulting link metadata. If multiple prefixes
    97  are specified, only a single prefix can match the path of
    98  any artifact and that is then left-stripped. All prefixes
    99  are checked to ensure none of them are a left substring
   100  of another.`,
   101  	)
   102  
   103  	recordCmd.PersistentFlags().StringArrayVarP(
   104  		&exclude,
   105  		"exclude",
   106  		"e",
   107  		[]string{},
   108  		`Path patterns to match paths that should not be recorded as 
   109  ‘materials’ or ‘products’. Passed patterns override patterns defined
   110  in environment variables or config files. See Config docs for details.`,
   111  	)
   112  
   113  	recordCmd.PersistentFlags().StringVar(
   114  		&spiffeUDS,
   115  		"spiffe-workload-api-path",
   116  		"",
   117  		"UDS path for SPIFFE workload API",
   118  	)
   119  
   120  	recordCmd.PersistentFlags().BoolVar(
   121  		&lineNormalization,
   122  		"normalize-line-endings",
   123  		false,
   124  		`Enable line normalization in order to support different
   125  operating systems. It is done by replacing all line separators
   126  with a new line character.`,
   127  	)
   128  
   129  	recordCmd.PersistentFlags().BoolVar(
   130  		&useDSSE,
   131  		"use-dsse",
   132  		false,
   133  		"Create metadata using DSSE instead of the legacy signature wrapper.",
   134  	)
   135  
   136  	recordCmd.PersistentFlags().BoolVar(
   137  		&followSymlinkDirs,
   138  		"follow-symlink-dirs",
   139  		false,
   140  		`Follow symlinked directories to their targets. Note: this parameter
   141  toggles following linked directories only, linked files are always
   142  recorded independently of this parameter.`,
   143  	)
   144  
   145  	recordCmd.MarkPersistentFlagRequired("name")
   146  
   147  	// Record Start Command
   148  	recordCmd.AddCommand(recordStartCmd)
   149  
   150  	recordStartCmd.Flags().StringArrayVarP(
   151  		&recordMaterialsPaths,
   152  		"materials",
   153  		"m",
   154  		[]string{},
   155  		`Paths to files or directories, whose paths and hashes
   156  are stored in the resulting link metadata before the
   157  command is executed. Symlinks are followed.`,
   158  	)
   159  
   160  	// Record Stop Command
   161  	recordCmd.AddCommand(recordStopCmd)
   162  
   163  	recordStopCmd.Flags().StringArrayVarP(
   164  		&recordProductsPaths,
   165  		"products",
   166  		"p",
   167  		[]string{},
   168  		`Paths to files or directories, whose paths and hashes
   169  are stored in the resulting link metadata after the
   170  command is executed. Symlinks are followed.`,
   171  	)
   172  }
   173  
   174  func recordStart(cmd *cobra.Command, args []string) error {
   175  	block, err := intoto.InTotoRecordStart(recordStepName, recordMaterialsPaths, key, []string{"sha256"}, exclude, lStripPaths, lineNormalization, followSymlinkDirs, useDSSE)
   176  	if err != nil {
   177  		return fmt.Errorf("failed to create start link file: %w", err)
   178  	}
   179  
   180  	prelimLinkName := fmt.Sprintf(intoto.PreliminaryLinkNameFormat, recordStepName, key.KeyID)
   181  	prelimLinkPath := filepath.Join(outDir, prelimLinkName)
   182  	err = block.Dump(prelimLinkPath)
   183  	if err != nil {
   184  		return fmt.Errorf("failed to write start link file to %s: %w", prelimLinkName, err)
   185  	}
   186  
   187  	return nil
   188  }
   189  
   190  func recordStop(cmd *cobra.Command, args []string) error {
   191  	prelimLinkName := fmt.Sprintf(intoto.PreliminaryLinkNameFormat, recordStepName, key.KeyID)
   192  	prelimLinkPath := filepath.Join(outDir, prelimLinkName)
   193  	prelimLinkMb, err := intoto.LoadMetadata(prelimLinkPath)
   194  	if err != nil {
   195  		return fmt.Errorf("failed to load start link file at %s: %w", prelimLinkName, err)
   196  	}
   197  
   198  	linkMb, err := intoto.InTotoRecordStop(prelimLinkMb, recordProductsPaths, key, []string{"sha256"}, exclude, lStripPaths, lineNormalization, followSymlinkDirs, useDSSE)
   199  	if err != nil {
   200  		return fmt.Errorf("failed to create stop link file: %w", err)
   201  	}
   202  
   203  	linkName := fmt.Sprintf(intoto.LinkNameFormat, recordStepName, key.KeyID)
   204  	linkPath := filepath.Join(outDir, linkName)
   205  	err = linkMb.Dump(linkPath)
   206  	if err != nil {
   207  		return fmt.Errorf("failed to write stop link file to %s: %w", prelimLinkName, err)
   208  	}
   209  
   210  	return nil
   211  }
   212  

View as plain text