Skip to content

Commit

Permalink
CLI, "corim create" subcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
thomas-fossati committed Oct 5, 2021
1 parent 31ee322 commit 3ff20db
Show file tree
Hide file tree
Showing 14 changed files with 475 additions and 21 deletions.
9 changes: 1 addition & 8 deletions cli/cmd/comid.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,7 @@ import (

var comidCmd = &cobra.Command{
Use: "comid",
Short: "CoMID specific manipulation",
Long: `CoMID specific manipulation
Create CoMID from template t1.json and save the result in the current working directory.
cli comid create --file=t1.json
`,
Short: "CoMID manipulation",

Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
Expand Down
16 changes: 9 additions & 7 deletions cli/cmd/comidCreate.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ func NewComidCreateCmd() *cobra.Command {
Short: "create one or more CBOR-encoded CoMID(s) from the supplied JSON template(s)",
Long: `create one or more CBOR-encoded CoMID(s) from the supplied JSON template(s)
Create CoMIDs from templates t1.json and t2.json, plus any template found in the
templates/ directory. Save them to the current working directory.
cli comid create --tmpl-file=t1.json --tmpl-file=t2.json --tmpl-dir=templates
Create CoMIDs from templates t1.json and t2.json, plus any template found in
the templates/ directory. Save them to the current working directory.
cli comid create --tmpl-file=t1.json \
--tmpl-file=t2.json \
--tmpl-dir=templates
Create one CoMID from template t3.json and save it to the comids/ directory.
Note that the output directory must exist.
cli comid create --tmpl-file=t3.json --output-dir=comids
`,

Expand Down Expand Up @@ -110,7 +112,7 @@ func templateToCBOR(tmplFile, outputDir string) (string, error) {
// we can use tag-id as the basename, since it is supposedly unique
cborFile = filepath.Join(outputDir, c.TagIdentity.TagID.String()+".cbor")

err = afero.WriteFile(fs, cborFile, cborData, 0400)
err = afero.WriteFile(fs, cborFile, cborData, 0644)
if err != nil {
return "", fmt.Errorf("error saving CBOR file %s: %w", cborFile, err)
}
Expand Down
8 changes: 4 additions & 4 deletions cli/cmd/comidCreate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func Test_ComidCreateCmd_template_with_invalid_json(t *testing.T) {
cmd := NewComidCreateCmd()

fs = afero.NewMemMapFs()
err = afero.WriteFile(fs, "invalid.json", []byte("..."), 0400)
err = afero.WriteFile(fs, "invalid.json", []byte("..."), 0644)
require.NoError(t, err)

args := []string{
Expand All @@ -68,7 +68,7 @@ func Test_ComidCreateCmd_template_with_invalid_comid(t *testing.T) {
cmd := NewComidCreateCmd()

fs = afero.NewMemMapFs()
err = afero.WriteFile(fs, "bad-comid.json", []byte("{}"), 0400)
err = afero.WriteFile(fs, "bad-comid.json", []byte("{}"), 0644)
require.NoError(t, err)

args := []string{
Expand All @@ -86,7 +86,7 @@ func Test_ComidCreateCmd_template_from_file_to_default_dir(t *testing.T) {
cmd := NewComidCreateCmd()

fs = afero.NewMemMapFs()
err = afero.WriteFile(fs, "ok.json", []byte(comid.PSARefValJSONTemplate), 0400)
err = afero.WriteFile(fs, "ok.json", []byte(comid.PSARefValJSONTemplate), 0644)
require.NoError(t, err)

args := []string{
Expand All @@ -110,7 +110,7 @@ func Test_ComidCreateCmd_template_from_dir_to_custom_dir(t *testing.T) {
cmd := NewComidCreateCmd()

fs = afero.NewMemMapFs()
err = afero.WriteFile(fs, "testdir/ok.json", []byte(comid.PSARefValJSONTemplate), 0400)
err = afero.WriteFile(fs, "testdir/ok.json", []byte(comid.PSARefValJSONTemplate), 0644)
require.NoError(t, err)

args := []string{
Expand Down
2 changes: 1 addition & 1 deletion cli/cmd/comidDisplay.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func NewComidDisplayCmd() *cobra.Command {
Display CoMIDs in files c1.cbor, c2.cbor and any cbor file in the comids/
directory.
cli comid display --file=c1.cbor --file=c2.cbor --dir=comids
`,

Expand Down
2 changes: 1 addition & 1 deletion cli/cmd/comidValidate.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func NewComidValidateCmd() *cobra.Command {
Validate CoMIDs in files c1.cbor, c2.cbor and any cbor file in the comids/
directory.
cli comid validate --file=c1.cbor --file=c2.cbor --dir=comids
`,

Expand Down
26 changes: 26 additions & 0 deletions cli/cmd/corim.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2021 Contributors to the Veraison project.
// SPDX-License-Identifier: Apache-2.0

package cmd

import (
"os"

"github.com/spf13/cobra"
)

var corimCmd = &cobra.Command{
Use: "corim",
Short: "CoRIM manipulation",

Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
cmd.Help() // nolint: errcheck
os.Exit(0)
}
},
}

func init() {
rootCmd.AddCommand(corimCmd)
}
202 changes: 202 additions & 0 deletions cli/cmd/corimCreate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
// Copyright 2021 Contributors to the Veraison project.
// SPDX-License-Identifier: Apache-2.0

package cmd

import (
"errors"
"fmt"

"github.com/spf13/afero"
"github.com/spf13/cobra"
"github.com/veraison/corim/comid"
"github.com/veraison/corim/corim"
"github.com/veraison/swid"
)

var (
corimCreateCorimFile *string
corimCreateCoswidFiles []string
corimCreateCoswidDirs []string
corimCreateComidFiles []string
corimCreateComidDirs []string
corimCreateOutputFile *string
)

var corimCreateCmd = NewCorimCreateCmd()

func NewCorimCreateCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "create",
Short: "create a CBOR-encoded CoRIM from the supplied JSON template, CoMID(s) and/or CoSWID(s)",
Long: `create a CBOR-encoded CoRIM from the supplied JSON template, CoMID(s) and/or CoSWID(s)",
Create a CoRIM from template t1.json, adding CoMIDs found in the comid/
directory and CoSWIDs found in the coswid/ directory. Since no explicit
output file is set, the (unsigned) CoRIM is saved to the current directory
with tag-id as basename and a .cbor extension.
cli corim create --tmpl-file=t1.json --comid-dir=comid --coswid-dir=coswid
Create a CoRIM from template corim-template.json, adding CoMID stored in
comid1.cbor and the two CoSWIDs stored in coswid1.cbor and dir/coswid2.cbor.
The (unsigned) CoRIM is saved to corim.cbor.
cli corim create --tmpl-file=corim-template.json \
--comid-file=comid1.cbor \
--coswid-file=coswid1.cbor \
--coswid-file=dir/coswid2.cbor \
--ouptut-file=corim.cbor
`,

RunE: func(cmd *cobra.Command, args []string) error {
if err := checkCorimCreateArgs(); err != nil {
return err
}

comidFilesList := filesList(corimCreateComidFiles, corimCreateComidDirs, ".cbor")
coswidFilesList := filesList(corimCreateCoswidFiles, corimCreateCoswidDirs, ".cbor")

if len(comidFilesList)+len(coswidFilesList) == 0 {
return errors.New("no CoMID or CoSWID files found")
}

// checkCorimCreateArgs makes sure corimCreateCorimFile is not nil
cborFile, err := corimTemplateToCBOR(*corimCreateCorimFile,
comidFilesList, coswidFilesList, corimCreateOutputFile)
if err != nil {
return err
}
fmt.Printf("created %q from %q\n", cborFile, *corimCreateCorimFile)

return nil
},
}

corimCreateCorimFile = cmd.Flags().StringP("tmpl-file", "f", "", "a CoMID template file (in JSON format)")

cmd.Flags().StringArrayVarP(
&corimCreateComidDirs, "comid-dir", "M", []string{}, "a directory containing CBOR-encoded CoMID files",
)

cmd.Flags().StringArrayVarP(
&corimCreateComidFiles, "comid-file", "m", []string{}, "a CBOR-encoded CoMID file",
)

cmd.Flags().StringArrayVarP(
&corimCreateCoswidDirs, "coswid-dir", "S", []string{}, "a directory containing CBOR-encoded CoSWID files",
)

cmd.Flags().StringArrayVarP(
&corimCreateCoswidFiles, "coswid-file", "s", []string{}, "a CBOR-encoded CoSWID file",
)

corimCreateOutputFile = cmd.Flags().StringP("output-file", "o", "", "name of the generated (unsigned) CoRIM file")

return cmd
}

func checkCorimCreateArgs() error {
if corimCreateCorimFile == nil || *corimCreateCorimFile == "" {
return errors.New("no CoRIM template supplied")
}

if len(corimCreateComidDirs)+len(corimCreateComidFiles)+
len(corimCreateCoswidDirs)+len(corimCreateCoswidFiles) == 0 {
return errors.New("no CoMID or CoSWID files or folders supplied")
}

return nil
}

func corimTemplateToCBOR(tmplFile string, comidFiles, coswidFiles []string, outputFile *string) (string, error) {
var (
tmplData, corimCBOR []byte
c corim.UnsignedCorim
corimFile string
err error
)

if tmplData, err = afero.ReadFile(fs, tmplFile); err != nil {
return "", fmt.Errorf("error loading template from %s: %w", tmplFile, err)
}

if err = c.FromJSON(tmplData); err != nil {
return "", fmt.Errorf("error decoding template from %s: %w", tmplFile, err)
}

// append CoMID(s)
for _, comidFile := range comidFiles {
var (
comidCBOR []byte
m comid.Comid
)

comidCBOR, err = afero.ReadFile(fs, comidFile)
if err != nil {
return "", fmt.Errorf("error loading CoMID from %s: %w", comidFile, err)
}

err = m.FromCBOR(comidCBOR)
if err != nil {
return "", fmt.Errorf("error loading CoMID from %s: %w", comidFile, err)
}

if c.AddComid(m) == nil {
return "", fmt.Errorf(
"error adding CoMID from %s (check its validity using the %q sub-command)",
comidFile, "comid validate",
)
}
}

// append CoSWID(s)
for _, coswidFile := range coswidFiles {
var (
coswidCBOR []byte
s swid.SoftwareIdentity
)

coswidCBOR, err = afero.ReadFile(fs, coswidFile)
if err != nil {
return "", fmt.Errorf("error loading CoSWID from %s: %w", coswidFile, err)
}

err = s.FromCBOR(coswidCBOR)
if err != nil {
return "", fmt.Errorf("error loading CoSWID from %s: %w", coswidFile, err)
}

if c.AddCoswid(s) == nil {
return "", fmt.Errorf("error adding CoSWID from %s", coswidFile)
}
}

// check the result
if err = c.Valid(); err != nil {
return "", fmt.Errorf("error validating CoRIM: %w", err)
}

corimCBOR, err = c.ToCBOR()
if err != nil {
return "", fmt.Errorf("error encoding CoRIM to CBOR: %w", err)
}

if outputFile == nil || *outputFile == "" {
// we can use tag-id as the basename, since it is supposedly unique
corimFile = c.ID.String() + ".cbor"
} else {
corimFile = *outputFile
}

err = afero.WriteFile(fs, corimFile, corimCBOR, 0644)
if err != nil {
return "", fmt.Errorf("error saving CoRIM to file %s: %w", corimFile, err)
}

return corimFile, nil
}

func init() {
corimCmd.AddCommand(corimCreateCmd)
}
Loading

0 comments on commit 3ff20db

Please sign in to comment.