diff --git a/cmd/cli/app/pflags.go b/cmd/cli/app/pflags.go index de834cd4c06c4c4fb8ffc93728f2f4368d8a0e9b..57a40388e22054c61813acc88da1137225a52f4b 100644 --- a/cmd/cli/app/pflags.go +++ b/cmd/cli/app/pflags.go @@ -44,7 +44,7 @@ func addSearchPFlags(cmd *cobra.Command) error { cmd.Flags().Var(&fileOrURLFlag{}, "artifact", "path or URL to artifact file") - cmd.Flags().Var(&shaFlag{}, "sha", "the sha of the artifact") + cmd.Flags().Var(&uuidFlag{}, "sha", "the SHA256 sum of the artifact") return nil } @@ -76,14 +76,13 @@ func addArtifactPFlags(cmd *cobra.Command) error { cmd.Flags().Var(&fileOrURLFlag{}, "entry", "path or URL to pre-formatted entry file") - cmd.Flags().Var(&shaFlag{}, "sha", "the sha of the artifact") return nil } func validateArtifactPFlags(uuidValid, indexValid bool) error { uuidGiven := false if uuidValid { - uuid := shaFlag{} + uuid := uuidFlag{} uuidStr := viper.GetString("uuid") if uuidStr != "" { @@ -105,7 +104,7 @@ func validateArtifactPFlags(uuidValid, indexValid bool) error { indexGiven = true } } - // we will need artifact, public-key, signature, and potentially SHA + // we will need artifact, public-key, signature typeStr := viper.GetString("type") entry := viper.GetString("entry") @@ -119,7 +118,6 @@ func validateArtifactPFlags(uuidValid, indexValid bool) error { signature := viper.GetString("signature") publicKey := viper.GetString("public-key") - sha := viper.GetString("sha") if entry == "" && artifact.String() == "" { if (uuidGiven && uuidValid) || (indexGiven && indexValid) { @@ -129,9 +127,6 @@ func validateArtifactPFlags(uuidValid, indexValid bool) error { } if entry == "" { - if artifact.IsURL && sha == "" { - return errors.New("a valid SHA hash must be specified when specifying a URL for --artifact") - } if signature == "" && typeStr == "rekord" { return errors.New("--signature is required when --artifact is used") } @@ -173,7 +168,7 @@ func CreateRpmFromPFlags() (models.ProposedEntry, error) { return nil, fmt.Errorf("error parsing rpm file: %w", err) } } else { - // we will need artifact, public-key, signature, and potentially SHA + // we will need artifact, public-key, signature re.RPMModel = models.RpmV001Schema{} re.RPMModel.Package = &models.RpmV001SchemaPackage{} @@ -181,9 +176,6 @@ func CreateRpmFromPFlags() (models.ProposedEntry, error) { dataURL, err := url.Parse(artifact) if err == nil && dataURL.IsAbs() { re.RPMModel.Package.URL = strfmt.URI(artifact) - re.RPMModel.Package.Hash = &models.RpmV001SchemaPackageHash{} - re.RPMModel.Package.Hash.Algorithm = swag.String(models.RpmV001SchemaPackageHashAlgorithmSha256) - re.RPMModel.Package.Hash.Value = swag.String(viper.GetString("sha")) } else { artifactBytes, err := ioutil.ReadFile(filepath.Clean(artifact)) if err != nil { @@ -252,16 +244,13 @@ func CreateRekordFromPFlags() (models.ProposedEntry, error) { return nil, fmt.Errorf("error parsing rekord file: %w", err) } } else { - // we will need artifact, public-key, signature, and potentially SHA + // we will need artifact, public-key, signature re.RekordObj.Data = &models.RekordV001SchemaData{} artifact := viper.GetString("artifact") dataURL, err := url.Parse(artifact) if err == nil && dataURL.IsAbs() { re.RekordObj.Data.URL = strfmt.URI(artifact) - re.RekordObj.Data.Hash = &models.RekordV001SchemaDataHash{} - re.RekordObj.Data.Hash.Algorithm = swag.String("sha256") - re.RekordObj.Data.Hash.Value = swag.String(viper.GetString("sha")) } else { artifactBytes, err := ioutil.ReadFile(filepath.Clean(artifact)) if err != nil { @@ -402,15 +391,15 @@ func (f *pkiFormatFlag) Set(s string) error { return fmt.Errorf("value specified is invalid: [%s] supported values are: [pgp, minisign, x509, ssh]", s) } -type shaFlag struct { +type uuidFlag struct { hash string } -func (s *shaFlag) String() string { - return s.hash +func (u *uuidFlag) String() string { + return u.hash } -func (s *shaFlag) Set(v string) error { +func (u *uuidFlag) Set(v string) error { if v == "" { return errors.New("flag must be specified") } @@ -420,16 +409,16 @@ func (s *shaFlag) Set(v string) error { } return fmt.Errorf("value specified is invalid: %w", err) } - s.hash = v + u.hash = v return nil } -func (s *shaFlag) Type() string { - return "sha" +func (u *uuidFlag) Type() string { + return "uuid" } func addUUIDPFlags(cmd *cobra.Command, required bool) error { - cmd.Flags().Var(&shaFlag{}, "uuid", "UUID of entry in transparency log (if known)") + cmd.Flags().Var(&uuidFlag{}, "uuid", "UUID of entry in transparency log (if known)") if required { if err := cmd.MarkFlagRequired("uuid"); err != nil { return err diff --git a/cmd/cli/app/pflags_test.go b/cmd/cli/app/pflags_test.go index 3f3ff28826fe1a8e83024aac888c5d459c61aa62..252e7f810803252e01691fea74fe683a7462068e 100644 --- a/cmd/cli/app/pflags_test.go +++ b/cmd/cli/app/pflags_test.go @@ -37,7 +37,6 @@ func TestArtifactPFlags(t *testing.T) { artifact string signature string publicKey string - sha string uuid string uuidRequired bool logIndex string @@ -147,24 +146,6 @@ func TestArtifactPFlags(t *testing.T) { expectParseSuccess: true, expectValidateSuccess: true, }, - { - caseDesc: "valid local artifact with incorrect length hex SHA value", - artifact: "../../../tests/test_file.txt", - sha: "12345abcde", - signature: "../../../tests/test_file.sig", - publicKey: "../../../tests/test_public_key.key", - expectParseSuccess: false, - expectValidateSuccess: false, - }, - { - caseDesc: "valid rekord - remote artifact with incorrect length hex SHA value", - artifact: testServer.URL + "/artifact", - sha: "12345abcde", - signature: "../../../tests/test_file.sig", - publicKey: "../../../tests/test_public_key.key", - expectParseSuccess: false, - expectValidateSuccess: false, - }, { caseDesc: "nonexistant local artifact", artifact: "../../../tests/not_a_file", @@ -238,7 +219,6 @@ func TestArtifactPFlags(t *testing.T) { { caseDesc: "valid rekord - remote artifact with required flags", artifact: testServer.URL + "/artifact", - sha: "45c7b11fcbf07dec1694adecd8c5b85770a12a6c8dfdcf2580a2db0c47c31779", signature: "../../../tests/test_file.sig", publicKey: "../../../tests/test_public_key.key", expectParseSuccess: true, @@ -248,7 +228,6 @@ func TestArtifactPFlags(t *testing.T) { caseDesc: "valid rpm - remote artifact with required flags", typeStr: "rpm", artifact: testServer.URL + "/rpm", - sha: "c8b0bc59708d74f53aab0089ac587d5c348d6ead143dab9f6d9c4b48c973bfd8", publicKey: "../../../tests/test_rpm_public_key.key", expectParseSuccess: true, expectValidateSuccess: true, @@ -256,24 +235,6 @@ func TestArtifactPFlags(t *testing.T) { { caseDesc: "remote artifact with invalid URL", artifact: "hteeteep%**/test_file.txt", - sha: "45c7b11fcbf07dec1694adecd8c5b85770a12a6c8dfdcf2580a2db0c47c31779", - signature: "../../../tests/test_file.sig", - publicKey: "../../../tests/test_public_key.key", - expectParseSuccess: false, - expectValidateSuccess: false, - }, - { - caseDesc: "remote artifact without required sha", - artifact: testServer.URL + "/artifact", - signature: "../../../tests/test_file.sig", - publicKey: "../../../tests/test_public_key.key", - expectParseSuccess: true, - expectValidateSuccess: false, - }, - { - caseDesc: "remote artifact with invalid sha", - artifact: testServer.URL + "/artifact", - sha: "1345not%hash%", signature: "../../../tests/test_file.sig", publicKey: "../../../tests/test_public_key.key", expectParseSuccess: false, @@ -377,9 +338,6 @@ func TestArtifactPFlags(t *testing.T) { if tc.publicKey != "" { args = append(args, "--public-key", tc.publicKey) } - if tc.sha != "" { - args = append(args, "--sha", tc.sha) - } if tc.uuid != "" { args = append(args, "--uuid", tc.uuid) } diff --git a/go.mod b/go.mod index 14f4466c8ce04ff2512e0e5223f83a64583918f7..5c0bb81c89bebbccfe1a1637ab29cca6520d02e0 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/google/trillian v1.3.13 github.com/jedisct1/go-minisign v0.0.0-20210106175330-e54e81d562c7 github.com/magiconair/properties v1.8.4 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mediocregopher/radix/v4 v4.0.0-beta.1 github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/mapstructure v1.4.1 @@ -41,10 +42,10 @@ require ( go.uber.org/zap v1.16.0 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad golang.org/x/mod v0.4.1 // indirect - golang.org/x/net v0.0.0-20210119194325-5f4716e94777 + golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 - golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78 // indirect - golang.org/x/tools v0.0.0-20210115202250-e0d201561e39 // indirect + golang.org/x/sys v0.0.0-20210301091718-77cc2087c03b // indirect + golang.org/x/tools v0.1.0 // indirect google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 google.golang.org/grpc v1.36.0 gopkg.in/ini.v1 v1.62.0 // indirect diff --git a/go.sum b/go.sum index d934e0d1aa8e91767767a03adf21cc1e15d043f2..c24114cf5daf323e89316393d7390bd8f2eaea84 100644 --- a/go.sum +++ b/go.sum @@ -514,8 +514,9 @@ github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -898,8 +899,9 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -967,8 +969,9 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78 h1:nVuTkr9L6Bq62qpUqKo/RnZCFfzDBL0bYo6w9OJUqZY= -golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210301091718-77cc2087c03b h1:kHlr0tATeLRMEiZJu5CknOw/E8V6h69sXXQFGoPtjcc= +golang.org/x/sys v0.0.0-20210301091718-77cc2087c03b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1048,8 +1051,8 @@ golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20210115202250-e0d201561e39 h1:BTs2GMGSMWpgtCpv1CE7vkJTv7XcHdcLLnAMu7UbgTY= -golang.org/x/tools v0.0.0-20210115202250-e0d201561e39/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/generated/restapi/embedded_spec.go b/pkg/generated/restapi/embedded_spec.go index 484ef500e6589c6d257086950ededf674594695c..33d4c2d07b4b8f55ae7383ee16e18da9db1cae06 100644 --- a/pkg/generated/restapi/embedded_spec.go +++ b/pkg/generated/restapi/embedded_spec.go @@ -1200,7 +1200,6 @@ func init() { "oneOf": [ { "required": [ - "hash", "url" ] }, @@ -1369,7 +1368,6 @@ func init() { "oneOf": [ { "required": [ - "hash", "url" ] }, @@ -1608,7 +1606,6 @@ func init() { "oneOf": [ { "required": [ - "hash", "url" ] }, @@ -1788,7 +1785,6 @@ func init() { "oneOf": [ { "required": [ - "hash", "url" ] }, diff --git a/pkg/types/rekord/v0.0.1/entry.go b/pkg/types/rekord/v0.0.1/entry.go index c8df0c7e5f3a146dc6a994e7b8331e4c2ec38dc7..8c8e95b70cb407ace1a06322f58064539a07e626 100644 --- a/pkg/types/rekord/v0.0.1/entry.go +++ b/pkg/types/rekord/v0.0.1/entry.go @@ -399,10 +399,6 @@ func (v V001Entry) Validate() error { } hash := data.Hash - if data.URL.String() != "" && hash == nil { - return errors.New("hash must be specified if 'url' is present for data") - } - if hash != nil { if !govalidator.IsHash(swag.StringValue(hash.Value), swag.StringValue(hash.Algorithm)) { return errors.New("invalid value for hash") diff --git a/pkg/types/rekord/v0.0.1/entry_test.go b/pkg/types/rekord/v0.0.1/entry_test.go index 3852b8d32fe38f8b5cd3deee10968a480798bcf5..eed600db62fa73251155e352709383ce5e15f0bc 100644 --- a/pkg/types/rekord/v0.0.1/entry_test.go +++ b/pkg/types/rekord/v0.0.1/entry_test.go @@ -178,8 +178,9 @@ func TestCrossFieldValidation(t *testing.T) { }, }, }, - hasExtEntities: true, - expectUnmarshalSuccess: false, + hasExtEntities: true, + expectUnmarshalSuccess: true, + expectCanonicalizeSuccess: true, }, { caseDesc: "signature with data & url and empty hash", diff --git a/pkg/types/rekord/v0.0.1/rekord_v0_0_1_schema.json b/pkg/types/rekord/v0.0.1/rekord_v0_0_1_schema.json index 5dd6edc483f79ae1ade0f250a3933dfa26df5d7b..5beb510d41847adeae5ad239ddbd88032fa65db1 100644 --- a/pkg/types/rekord/v0.0.1/rekord_v0_0_1_schema.json +++ b/pkg/types/rekord/v0.0.1/rekord_v0_0_1_schema.json @@ -91,7 +91,7 @@ }, "oneOf": [ { - "required": [ "hash", "url" ] + "required": [ "url" ] }, { "required": [ "content" ] diff --git a/pkg/types/rpm/v0.0.1/entry.go b/pkg/types/rpm/v0.0.1/entry.go index c2ab81c4654c55192d534572631771a9931d8b27..fbb3096c82bf7bc8937ab37301fb4f10ada114a0 100644 --- a/pkg/types/rpm/v0.0.1/entry.go +++ b/pkg/types/rpm/v0.0.1/entry.go @@ -380,10 +380,6 @@ func (v V001Entry) Validate() error { } hash := pkg.Hash - if pkg.URL.String() != "" && hash == nil { - return errors.New("hash must be specified if 'url' is present for package") - } - if hash != nil { if !govalidator.IsHash(swag.StringValue(hash.Value), swag.StringValue(hash.Algorithm)) { return errors.New("invalid value for hash") diff --git a/pkg/types/rpm/v0.0.1/entry_test.go b/pkg/types/rpm/v0.0.1/entry_test.go index 093c12c6f312d46ab35d5a4ddd1bc03c0cc83236..d838d499d37058e777ac701571cb2753171c4d91 100644 --- a/pkg/types/rpm/v0.0.1/entry_test.go +++ b/pkg/types/rpm/v0.0.1/entry_test.go @@ -134,8 +134,9 @@ func TestCrossFieldValidation(t *testing.T) { }, }, }, - hasExtEntities: true, - expectUnmarshalSuccess: false, + hasExtEntities: true, + expectUnmarshalSuccess: true, + expectCanonicalizeSuccess: true, }, { caseDesc: "public key with data & url and empty hash", diff --git a/pkg/types/rpm/v0.0.1/rpm_v0_0_1_schema.json b/pkg/types/rpm/v0.0.1/rpm_v0_0_1_schema.json index cacd8f66d13f5fb8ab0729421d7fb309a8649b38..f74e960eab48e7a36285881348941d73a1c83e18 100644 --- a/pkg/types/rpm/v0.0.1/rpm_v0_0_1_schema.json +++ b/pkg/types/rpm/v0.0.1/rpm_v0_0_1_schema.json @@ -69,7 +69,7 @@ }, "oneOf": [ { - "required": [ "hash", "url" ] + "required": [ "url" ] }, { "required": [ "content" ]