From 404d0411c65097091085c6c07edc00f35fdacf8f Mon Sep 17 00:00:00 2001 From: pxp928 Date: Fri, 12 Aug 2022 13:40:06 -0400 Subject: [PATCH] added intoto v0.0.2 Signed-off-by: pxp928 --- Makefile.swagger | 2 +- cmd/rekor-cli/app/root.go | 1 + cmd/rekor-server/app/serve.go | 6 +- openapi.yaml | 17 - pkg/generated/models/dsse.go | 210 ----- pkg/generated/models/dsse_schema.go | 29 - pkg/generated/models/dsse_v001_schema.go | 369 --------- pkg/generated/models/intoto_v002_schema.go | 722 ++++++++++++++++++ pkg/generated/models/proposed_entry.go | 6 - pkg/generated/restapi/embedded_spec.go | 284 +++---- pkg/types/dsse/dsse.go | 75 -- pkg/types/dsse/dsse_schema.json | 12 - pkg/types/dsse/dsse_test.go | 92 --- pkg/types/dsse/v0.0.1/dsse_v0_0_1_schema.json | 61 -- pkg/types/entries.go | 4 +- pkg/types/intoto/intoto.go | 2 +- pkg/types/intoto/intoto_schema.json | 2 +- .../{dsse/v0.0.1 => intoto/v0.0.2}/entry.go | 206 +++-- pkg/types/intoto/v0.0.2/entry_test.go | 438 +++++++++++ .../intoto/v0.0.2/intoto_v0_0_2_schema.json | 101 +++ tests/e2e_test.go | 24 +- 21 files changed, 1531 insertions(+), 1132 deletions(-) delete mode 100644 pkg/generated/models/dsse.go delete mode 100644 pkg/generated/models/dsse_schema.go delete mode 100644 pkg/generated/models/dsse_v001_schema.go create mode 100644 pkg/generated/models/intoto_v002_schema.go delete mode 100644 pkg/types/dsse/dsse.go delete mode 100644 pkg/types/dsse/dsse_schema.json delete mode 100644 pkg/types/dsse/dsse_test.go delete mode 100644 pkg/types/dsse/v0.0.1/dsse_v0_0_1_schema.json rename pkg/types/{dsse/v0.0.1 => intoto/v0.0.2}/entry.go (55%) create mode 100644 pkg/types/intoto/v0.0.2/entry_test.go create mode 100644 pkg/types/intoto/v0.0.2/intoto_v0_0_2_schema.json diff --git a/Makefile.swagger b/Makefile.swagger index a141816e5..2ea5b3bd3 100644 --- a/Makefile.swagger +++ b/Makefile.swagger @@ -1,2 +1,2 @@ # This file is generated after swagger runs as part of the build; do not edit! -SWAGGER_GEN=pkg/generated/client/entries/create_log_entry_parameters.go pkg/generated/client/entries/create_log_entry_responses.go pkg/generated/client/entries/entries_client.go pkg/generated/client/entries/get_log_entry_by_index_parameters.go pkg/generated/client/entries/get_log_entry_by_index_responses.go pkg/generated/client/entries/get_log_entry_by_uuid_parameters.go pkg/generated/client/entries/get_log_entry_by_uuid_responses.go pkg/generated/client/entries/search_log_query_parameters.go pkg/generated/client/entries/search_log_query_responses.go pkg/generated/client/index/index_client.go pkg/generated/client/index/search_index_parameters.go pkg/generated/client/index/search_index_responses.go pkg/generated/client/pubkey/get_public_key_parameters.go pkg/generated/client/pubkey/get_public_key_responses.go pkg/generated/client/pubkey/pubkey_client.go pkg/generated/client/rekor_client.go pkg/generated/client/server/get_rekor_version_parameters.go pkg/generated/client/server/get_rekor_version_responses.go pkg/generated/client/server/server_client.go pkg/generated/client/tlog/get_log_info_parameters.go pkg/generated/client/tlog/get_log_info_responses.go pkg/generated/client/tlog/get_log_proof_parameters.go pkg/generated/client/tlog/get_log_proof_responses.go pkg/generated/client/tlog/tlog_client.go pkg/generated/models//alpine.go pkg/generated/models//alpine_schema.go pkg/generated/models//alpine_v001_schema.go pkg/generated/models//consistency_proof.go pkg/generated/models//cose.go pkg/generated/models//cose_schema.go pkg/generated/models//cose_v001_schema.go pkg/generated/models//dsse.go pkg/generated/models//dsse_schema.go pkg/generated/models//dsse_v001_schema.go pkg/generated/models//error.go pkg/generated/models//hashedrekord.go pkg/generated/models//hashedrekord_schema.go pkg/generated/models//hashedrekord_v001_schema.go pkg/generated/models//helm.go pkg/generated/models//helm_schema.go pkg/generated/models//helm_v001_schema.go pkg/generated/models//inactive_shard_log_info.go pkg/generated/models//inclusion_proof.go pkg/generated/models//intoto.go pkg/generated/models//intoto_schema.go pkg/generated/models//intoto_v001_schema.go pkg/generated/models//jar.go pkg/generated/models//jar_schema.go pkg/generated/models//jar_v001_schema.go pkg/generated/models//log_entry.go pkg/generated/models//log_info.go pkg/generated/models//proposed_entry.go pkg/generated/models//rekord.go pkg/generated/models//rekord_schema.go pkg/generated/models//rekord_v001_schema.go pkg/generated/models//rekor_version.go pkg/generated/models//rfc3161.go pkg/generated/models//rfc3161_schema.go pkg/generated/models//rfc3161_v001_schema.go pkg/generated/models//rpm.go pkg/generated/models//rpm_schema.go pkg/generated/models//rpm_v001_schema.go pkg/generated/models//search_index.go pkg/generated/models//search_log_query.go pkg/generated/models//tuf.go pkg/generated/models//tuf_schema.go pkg/generated/models//tuf_v001_schema.go pkg/generated/restapi//doc.go pkg/generated/restapi//embedded_spec.go pkg/generated/restapi//operations/entries/create_log_entry.go pkg/generated/restapi//operations/entries/create_log_entry_parameters.go pkg/generated/restapi//operations/entries/create_log_entry_responses.go pkg/generated/restapi//operations/entries/create_log_entry_urlbuilder.go pkg/generated/restapi//operations/entries/get_log_entry_by_index.go pkg/generated/restapi//operations/entries/get_log_entry_by_index_parameters.go pkg/generated/restapi//operations/entries/get_log_entry_by_index_responses.go pkg/generated/restapi//operations/entries/get_log_entry_by_index_urlbuilder.go pkg/generated/restapi//operations/entries/get_log_entry_by_uuid.go pkg/generated/restapi//operations/entries/get_log_entry_by_uuid_parameters.go pkg/generated/restapi//operations/entries/get_log_entry_by_uuid_responses.go pkg/generated/restapi//operations/entries/get_log_entry_by_uuid_urlbuilder.go pkg/generated/restapi//operations/entries/search_log_query.go pkg/generated/restapi//operations/entries/search_log_query_parameters.go pkg/generated/restapi//operations/entries/search_log_query_responses.go pkg/generated/restapi//operations/entries/search_log_query_urlbuilder.go pkg/generated/restapi//operations/index/search_index.go pkg/generated/restapi//operations/index/search_index_parameters.go pkg/generated/restapi//operations/index/search_index_responses.go pkg/generated/restapi//operations/index/search_index_urlbuilder.go pkg/generated/restapi//operations/pubkey/get_public_key.go pkg/generated/restapi//operations/pubkey/get_public_key_parameters.go pkg/generated/restapi//operations/pubkey/get_public_key_responses.go pkg/generated/restapi//operations/pubkey/get_public_key_urlbuilder.go pkg/generated/restapi//operations/rekor_server_api.go pkg/generated/restapi//operations/server/get_rekor_version.go pkg/generated/restapi//operations/server/get_rekor_version_parameters.go pkg/generated/restapi//operations/server/get_rekor_version_responses.go pkg/generated/restapi//operations/server/get_rekor_version_urlbuilder.go pkg/generated/restapi//operations/tlog/get_log_info.go pkg/generated/restapi//operations/tlog/get_log_info_parameters.go pkg/generated/restapi//operations/tlog/get_log_info_responses.go pkg/generated/restapi//operations/tlog/get_log_info_urlbuilder.go pkg/generated/restapi//operations/tlog/get_log_proof.go pkg/generated/restapi//operations/tlog/get_log_proof_parameters.go pkg/generated/restapi//operations/tlog/get_log_proof_responses.go pkg/generated/restapi//operations/tlog/get_log_proof_urlbuilder.go pkg/generated/restapi//server.go +SWAGGER_GEN=pkg/generated/client/entries/create_log_entry_parameters.go pkg/generated/client/entries/create_log_entry_responses.go pkg/generated/client/entries/entries_client.go pkg/generated/client/entries/get_log_entry_by_index_parameters.go pkg/generated/client/entries/get_log_entry_by_index_responses.go pkg/generated/client/entries/get_log_entry_by_uuid_parameters.go pkg/generated/client/entries/get_log_entry_by_uuid_responses.go pkg/generated/client/entries/search_log_query_parameters.go pkg/generated/client/entries/search_log_query_responses.go pkg/generated/client/index/index_client.go pkg/generated/client/index/search_index_parameters.go pkg/generated/client/index/search_index_responses.go pkg/generated/client/pubkey/get_public_key_parameters.go pkg/generated/client/pubkey/get_public_key_responses.go pkg/generated/client/pubkey/pubkey_client.go pkg/generated/client/rekor_client.go pkg/generated/client/server/get_rekor_version_parameters.go pkg/generated/client/server/get_rekor_version_responses.go pkg/generated/client/server/server_client.go pkg/generated/client/tlog/get_log_info_parameters.go pkg/generated/client/tlog/get_log_info_responses.go pkg/generated/client/tlog/get_log_proof_parameters.go pkg/generated/client/tlog/get_log_proof_responses.go pkg/generated/client/tlog/tlog_client.go pkg/generated/models//alpine.go pkg/generated/models//alpine_schema.go pkg/generated/models//alpine_v001_schema.go pkg/generated/models//consistency_proof.go pkg/generated/models//cose.go pkg/generated/models//cose_schema.go pkg/generated/models//cose_v001_schema.go pkg/generated/models//error.go pkg/generated/models//hashedrekord.go pkg/generated/models//hashedrekord_schema.go pkg/generated/models//hashedrekord_v001_schema.go pkg/generated/models//helm.go pkg/generated/models//helm_schema.go pkg/generated/models//helm_v001_schema.go pkg/generated/models//inactive_shard_log_info.go pkg/generated/models//inclusion_proof.go pkg/generated/models//intoto.go pkg/generated/models//intoto_schema.go pkg/generated/models//intoto_v001_schema.go pkg/generated/models//intoto_v002_schema.go pkg/generated/models//jar.go pkg/generated/models//jar_schema.go pkg/generated/models//jar_v001_schema.go pkg/generated/models//log_entry.go pkg/generated/models//log_info.go pkg/generated/models//proposed_entry.go pkg/generated/models//rekord.go pkg/generated/models//rekord_schema.go pkg/generated/models//rekord_v001_schema.go pkg/generated/models//rekor_version.go pkg/generated/models//rfc3161.go pkg/generated/models//rfc3161_schema.go pkg/generated/models//rfc3161_v001_schema.go pkg/generated/models//rpm.go pkg/generated/models//rpm_schema.go pkg/generated/models//rpm_v001_schema.go pkg/generated/models//search_index.go pkg/generated/models//search_log_query.go pkg/generated/models//tuf.go pkg/generated/models//tuf_schema.go pkg/generated/models//tuf_v001_schema.go pkg/generated/restapi//doc.go pkg/generated/restapi//embedded_spec.go pkg/generated/restapi//operations/entries/create_log_entry.go pkg/generated/restapi//operations/entries/create_log_entry_parameters.go pkg/generated/restapi//operations/entries/create_log_entry_responses.go pkg/generated/restapi//operations/entries/create_log_entry_urlbuilder.go pkg/generated/restapi//operations/entries/get_log_entry_by_index.go pkg/generated/restapi//operations/entries/get_log_entry_by_index_parameters.go pkg/generated/restapi//operations/entries/get_log_entry_by_index_responses.go pkg/generated/restapi//operations/entries/get_log_entry_by_index_urlbuilder.go pkg/generated/restapi//operations/entries/get_log_entry_by_uuid.go pkg/generated/restapi//operations/entries/get_log_entry_by_uuid_parameters.go pkg/generated/restapi//operations/entries/get_log_entry_by_uuid_responses.go pkg/generated/restapi//operations/entries/get_log_entry_by_uuid_urlbuilder.go pkg/generated/restapi//operations/entries/search_log_query.go pkg/generated/restapi//operations/entries/search_log_query_parameters.go pkg/generated/restapi//operations/entries/search_log_query_responses.go pkg/generated/restapi//operations/entries/search_log_query_urlbuilder.go pkg/generated/restapi//operations/index/search_index.go pkg/generated/restapi//operations/index/search_index_parameters.go pkg/generated/restapi//operations/index/search_index_responses.go pkg/generated/restapi//operations/index/search_index_urlbuilder.go pkg/generated/restapi//operations/pubkey/get_public_key.go pkg/generated/restapi//operations/pubkey/get_public_key_parameters.go pkg/generated/restapi//operations/pubkey/get_public_key_responses.go pkg/generated/restapi//operations/pubkey/get_public_key_urlbuilder.go pkg/generated/restapi//operations/rekor_server_api.go pkg/generated/restapi//operations/server/get_rekor_version.go pkg/generated/restapi//operations/server/get_rekor_version_parameters.go pkg/generated/restapi//operations/server/get_rekor_version_responses.go pkg/generated/restapi//operations/server/get_rekor_version_urlbuilder.go pkg/generated/restapi//operations/tlog/get_log_info.go pkg/generated/restapi//operations/tlog/get_log_info_parameters.go pkg/generated/restapi//operations/tlog/get_log_info_responses.go pkg/generated/restapi//operations/tlog/get_log_info_urlbuilder.go pkg/generated/restapi//operations/tlog/get_log_proof.go pkg/generated/restapi//operations/tlog/get_log_proof_parameters.go pkg/generated/restapi//operations/tlog/get_log_proof_responses.go pkg/generated/restapi//operations/tlog/get_log_proof_urlbuilder.go pkg/generated/restapi//server.go diff --git a/cmd/rekor-cli/app/root.go b/cmd/rekor-cli/app/root.go index 400b9acb4..2cb38e282 100644 --- a/cmd/rekor-cli/app/root.go +++ b/cmd/rekor-cli/app/root.go @@ -32,6 +32,7 @@ import ( _ "github.com/sigstore/rekor/pkg/types/hashedrekord/v0.0.1" _ "github.com/sigstore/rekor/pkg/types/helm/v0.0.1" _ "github.com/sigstore/rekor/pkg/types/intoto/v0.0.1" + _ "github.com/sigstore/rekor/pkg/types/intoto/v0.0.2" _ "github.com/sigstore/rekor/pkg/types/jar/v0.0.1" _ "github.com/sigstore/rekor/pkg/types/rekord/v0.0.1" _ "github.com/sigstore/rekor/pkg/types/rfc3161/v0.0.1" diff --git a/cmd/rekor-server/app/serve.go b/cmd/rekor-server/app/serve.go index 6e37f9503..46652bb21 100644 --- a/cmd/rekor-server/app/serve.go +++ b/cmd/rekor-server/app/serve.go @@ -33,13 +33,12 @@ import ( alpine_v001 "github.com/sigstore/rekor/pkg/types/alpine/v0.0.1" "github.com/sigstore/rekor/pkg/types/cose" cose_v001 "github.com/sigstore/rekor/pkg/types/cose/v0.0.1" - "github.com/sigstore/rekor/pkg/types/dsse" hashedrekord "github.com/sigstore/rekor/pkg/types/hashedrekord" hashedrekord_v001 "github.com/sigstore/rekor/pkg/types/hashedrekord/v0.0.1" "github.com/sigstore/rekor/pkg/types/helm" helm_v001 "github.com/sigstore/rekor/pkg/types/helm/v0.0.1" "github.com/sigstore/rekor/pkg/types/intoto" - intoto_v001 "github.com/sigstore/rekor/pkg/types/intoto/v0.0.1" + intoto_v002 "github.com/sigstore/rekor/pkg/types/intoto/v0.0.2" "github.com/sigstore/rekor/pkg/types/jar" jar_v001 "github.com/sigstore/rekor/pkg/types/jar/v0.0.1" "github.com/sigstore/rekor/pkg/types/rekord" @@ -89,14 +88,13 @@ var serveCmd = &cobra.Command{ rekord.KIND: rekord_v001.APIVERSION, rpm.KIND: rpm_v001.APIVERSION, jar.KIND: jar_v001.APIVERSION, - intoto.KIND: intoto_v001.APIVERSION, + intoto.KIND: intoto_v002.APIVERSION, cose.KIND: cose_v001.APIVERSION, rfc3161.KIND: rfc3161_v001.APIVERSION, alpine.KIND: alpine_v001.APIVERSION, helm.KIND: helm_v001.APIVERSION, tuf.KIND: tuf_v001.APIVERSION, hashedrekord.KIND: hashedrekord_v001.APIVERSION, - dsse.KIND: dsse_v001.APIVERSION, } for k, v := range pluggableTypeMap { diff --git a/openapi.yaml b/openapi.yaml index fbedd02c7..dcba72992 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -410,23 +410,6 @@ definitions: - spec additionalProperties: false - dsse: - type: object - description: DSSE object - allOf: - - $ref: '#/definitions/ProposedEntry' - - properties: - apiVersion: - type: string - pattern: ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ - spec: - type: object - $ref: 'pkg/types/dsse/dsse_schema.json' - required: - - apiVersion - - spec - additionalProperties: false - rfc3161: type: object description: RFC3161 Timestamp diff --git a/pkg/generated/models/dsse.go b/pkg/generated/models/dsse.go deleted file mode 100644 index 431e74b97..000000000 --- a/pkg/generated/models/dsse.go +++ /dev/null @@ -1,210 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -// -// Copyright 2021 The Sigstore Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - "bytes" - "context" - "encoding/json" - - "github.com/go-openapi/errors" - "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" - "github.com/go-openapi/validate" -) - -// Dsse DSSE object -// -// swagger:model dsse -type Dsse struct { - - // api version - // Required: true - // Pattern: ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ - APIVersion *string `json:"apiVersion"` - - // spec - // Required: true - Spec DsseSchema `json:"spec"` -} - -// Kind gets the kind of this subtype -func (m *Dsse) Kind() string { - return "dsse" -} - -// SetKind sets the kind of this subtype -func (m *Dsse) SetKind(val string) { -} - -// UnmarshalJSON unmarshals this object with a polymorphic type from a JSON structure -func (m *Dsse) UnmarshalJSON(raw []byte) error { - var data struct { - - // api version - // Required: true - // Pattern: ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ - APIVersion *string `json:"apiVersion"` - - // spec - // Required: true - Spec DsseSchema `json:"spec"` - } - buf := bytes.NewBuffer(raw) - dec := json.NewDecoder(buf) - dec.UseNumber() - - if err := dec.Decode(&data); err != nil { - return err - } - - var base struct { - /* Just the base type fields. Used for unmashalling polymorphic types.*/ - - Kind string `json:"kind"` - } - buf = bytes.NewBuffer(raw) - dec = json.NewDecoder(buf) - dec.UseNumber() - - if err := dec.Decode(&base); err != nil { - return err - } - - var result Dsse - - if base.Kind != result.Kind() { - /* Not the type we're looking for. */ - return errors.New(422, "invalid kind value: %q", base.Kind) - } - - result.APIVersion = data.APIVersion - result.Spec = data.Spec - - *m = result - - return nil -} - -// MarshalJSON marshals this object with a polymorphic type to a JSON structure -func (m Dsse) MarshalJSON() ([]byte, error) { - var b1, b2, b3 []byte - var err error - b1, err = json.Marshal(struct { - - // api version - // Required: true - // Pattern: ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ - APIVersion *string `json:"apiVersion"` - - // spec - // Required: true - Spec DsseSchema `json:"spec"` - }{ - - APIVersion: m.APIVersion, - - Spec: m.Spec, - }) - if err != nil { - return nil, err - } - b2, err = json.Marshal(struct { - Kind string `json:"kind"` - }{ - - Kind: m.Kind(), - }) - if err != nil { - return nil, err - } - - return swag.ConcatJSON(b1, b2, b3), nil -} - -// Validate validates this dsse -func (m *Dsse) Validate(formats strfmt.Registry) error { - var res []error - - if err := m.validateAPIVersion(formats); err != nil { - res = append(res, err) - } - - if err := m.validateSpec(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (m *Dsse) validateAPIVersion(formats strfmt.Registry) error { - - if err := validate.Required("apiVersion", "body", m.APIVersion); err != nil { - return err - } - - if err := validate.Pattern("apiVersion", "body", *m.APIVersion, `^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$`); err != nil { - return err - } - - return nil -} - -func (m *Dsse) validateSpec(formats strfmt.Registry) error { - - if m.Spec == nil { - return errors.Required("spec", "body", nil) - } - - return nil -} - -// ContextValidate validate this dsse based on the context it is used -func (m *Dsse) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - var res []error - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -// MarshalBinary interface implementation -func (m *Dsse) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *Dsse) UnmarshalBinary(b []byte) error { - var res Dsse - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/pkg/generated/models/dsse_schema.go b/pkg/generated/models/dsse_schema.go deleted file mode 100644 index fcb71c86c..000000000 --- a/pkg/generated/models/dsse_schema.go +++ /dev/null @@ -1,29 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -// -// Copyright 2021 The Sigstore Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -// DsseSchema DSSE Schema -// -// DSSE for Rekord objects -// -// swagger:model dsseSchema -type DsseSchema interface{} diff --git a/pkg/generated/models/dsse_v001_schema.go b/pkg/generated/models/dsse_v001_schema.go deleted file mode 100644 index bfaba9fe1..000000000 --- a/pkg/generated/models/dsse_v001_schema.go +++ /dev/null @@ -1,369 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - -// -// Copyright 2021 The Sigstore Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package models - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - "context" - "encoding/json" - "strconv" - - "github.com/go-openapi/errors" - "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" - "github.com/go-openapi/validate" -) - -// DsseV001Schema dsse v0.0.1 Schema -// -// Schema for dsse object -// -// swagger:model dsseV001Schema -type DsseV001Schema struct { - - // payload of the envelope - // Format: byte - Payload strfmt.Base64 `json:"payload,omitempty"` - - // payload hash - PayloadHash *DsseV001SchemaPayloadHash `json:"payloadHash,omitempty"` - - // type describing the payload - // Required: true - PayloadType *string `json:"payloadType"` - - // collection of all signatures of the envelope's payload - // Required: true - // Min Items: 1 - Signatures []*DsseV001SchemaSignaturesItems0 `json:"signatures"` -} - -// Validate validates this dsse v001 schema -func (m *DsseV001Schema) Validate(formats strfmt.Registry) error { - var res []error - - if err := m.validatePayloadHash(formats); err != nil { - res = append(res, err) - } - - if err := m.validatePayloadType(formats); err != nil { - res = append(res, err) - } - - if err := m.validateSignatures(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (m *DsseV001Schema) validatePayloadHash(formats strfmt.Registry) error { - if swag.IsZero(m.PayloadHash) { // not required - return nil - } - - if m.PayloadHash != nil { - if err := m.PayloadHash.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("payloadHash") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("payloadHash") - } - return err - } - } - - return nil -} - -func (m *DsseV001Schema) validatePayloadType(formats strfmt.Registry) error { - - if err := validate.Required("payloadType", "body", m.PayloadType); err != nil { - return err - } - - return nil -} - -func (m *DsseV001Schema) validateSignatures(formats strfmt.Registry) error { - - if err := validate.Required("signatures", "body", m.Signatures); err != nil { - return err - } - - iSignaturesSize := int64(len(m.Signatures)) - - if err := validate.MinItems("signatures", "body", iSignaturesSize, 1); err != nil { - return err - } - - for i := 0; i < len(m.Signatures); i++ { - if swag.IsZero(m.Signatures[i]) { // not required - continue - } - - if m.Signatures[i] != nil { - if err := m.Signatures[i].Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("signatures" + "." + strconv.Itoa(i)) - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("signatures" + "." + strconv.Itoa(i)) - } - return err - } - } - - } - - return nil -} - -// ContextValidate validate this dsse v001 schema based on the context it is used -func (m *DsseV001Schema) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - var res []error - - if err := m.contextValidatePayloadHash(ctx, formats); err != nil { - res = append(res, err) - } - - if err := m.contextValidateSignatures(ctx, formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (m *DsseV001Schema) contextValidatePayloadHash(ctx context.Context, formats strfmt.Registry) error { - - if m.PayloadHash != nil { - if err := m.PayloadHash.ContextValidate(ctx, formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("payloadHash") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("payloadHash") - } - return err - } - } - - return nil -} - -func (m *DsseV001Schema) contextValidateSignatures(ctx context.Context, formats strfmt.Registry) error { - - for i := 0; i < len(m.Signatures); i++ { - - if m.Signatures[i] != nil { - if err := m.Signatures[i].ContextValidate(ctx, formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("signatures" + "." + strconv.Itoa(i)) - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("signatures" + "." + strconv.Itoa(i)) - } - return err - } - } - - } - - return nil -} - -// MarshalBinary interface implementation -func (m *DsseV001Schema) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *DsseV001Schema) UnmarshalBinary(b []byte) error { - var res DsseV001Schema - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} - -// DsseV001SchemaPayloadHash hash of the envelope's payload after being PAE encoded -// -// swagger:model DsseV001SchemaPayloadHash -type DsseV001SchemaPayloadHash struct { - - // The hashing function used to compue the hash value - // Enum: [sha256] - Algorithm string `json:"algorithm,omitempty"` - - // The hash value of the PAE encoded payload - Value string `json:"value,omitempty"` -} - -// Validate validates this dsse v001 schema payload hash -func (m *DsseV001SchemaPayloadHash) Validate(formats strfmt.Registry) error { - var res []error - - if err := m.validateAlgorithm(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -var dsseV001SchemaPayloadHashTypeAlgorithmPropEnum []interface{} - -func init() { - var res []string - if err := json.Unmarshal([]byte(`["sha256"]`), &res); err != nil { - panic(err) - } - for _, v := range res { - dsseV001SchemaPayloadHashTypeAlgorithmPropEnum = append(dsseV001SchemaPayloadHashTypeAlgorithmPropEnum, v) - } -} - -const ( - - // DsseV001SchemaPayloadHashAlgorithmSha256 captures enum value "sha256" - DsseV001SchemaPayloadHashAlgorithmSha256 string = "sha256" -) - -// prop value enum -func (m *DsseV001SchemaPayloadHash) validateAlgorithmEnum(path, location string, value string) error { - if err := validate.EnumCase(path, location, value, dsseV001SchemaPayloadHashTypeAlgorithmPropEnum, true); err != nil { - return err - } - return nil -} - -func (m *DsseV001SchemaPayloadHash) validateAlgorithm(formats strfmt.Registry) error { - if swag.IsZero(m.Algorithm) { // not required - return nil - } - - // value enum - if err := m.validateAlgorithmEnum("payloadHash"+"."+"algorithm", "body", m.Algorithm); err != nil { - return err - } - - return nil -} - -// ContextValidate validate this dsse v001 schema payload hash based on the context it is used -func (m *DsseV001SchemaPayloadHash) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - var res []error - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -// MarshalBinary interface implementation -func (m *DsseV001SchemaPayloadHash) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *DsseV001SchemaPayloadHash) UnmarshalBinary(b []byte) error { - var res DsseV001SchemaPayloadHash - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} - -// DsseV001SchemaSignaturesItems0 a signature of the envelope's payload along with the public key for the signature -// -// swagger:model DsseV001SchemaSignaturesItems0 -type DsseV001SchemaSignaturesItems0 struct { - - // optional id of the key used to create the signature - Keyid string `json:"keyid,omitempty"` - - // public key that corresponds to this signature - // Read Only: true - // Format: byte - PublicKey strfmt.Base64 `json:"publicKey,omitempty"` - - // signature of the payload - Sig string `json:"sig,omitempty"` -} - -// Validate validates this dsse v001 schema signatures items0 -func (m *DsseV001SchemaSignaturesItems0) Validate(formats strfmt.Registry) error { - return nil -} - -// ContextValidate validate this dsse v001 schema signatures items0 based on the context it is used -func (m *DsseV001SchemaSignaturesItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - var res []error - - if err := m.contextValidatePublicKey(ctx, formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (m *DsseV001SchemaSignaturesItems0) contextValidatePublicKey(ctx context.Context, formats strfmt.Registry) error { - - if err := validate.ReadOnly(ctx, "publicKey", "body", strfmt.Base64(m.PublicKey)); err != nil { - return err - } - - return nil -} - -// MarshalBinary interface implementation -func (m *DsseV001SchemaSignaturesItems0) MarshalBinary() ([]byte, error) { - if m == nil { - return nil, nil - } - return swag.WriteJSON(m) -} - -// UnmarshalBinary interface implementation -func (m *DsseV001SchemaSignaturesItems0) UnmarshalBinary(b []byte) error { - var res DsseV001SchemaSignaturesItems0 - if err := swag.ReadJSON(b, &res); err != nil { - return err - } - *m = res - return nil -} diff --git a/pkg/generated/models/intoto_v002_schema.go b/pkg/generated/models/intoto_v002_schema.go new file mode 100644 index 000000000..06ddfd59f --- /dev/null +++ b/pkg/generated/models/intoto_v002_schema.go @@ -0,0 +1,722 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// +// Copyright 2021 The Sigstore Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "encoding/json" + "strconv" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// IntotoV002Schema intoto v0.0.2 Schema +// +// Schema for intoto object +// +// swagger:model intotoV002Schema +type IntotoV002Schema struct { + + // content + // Required: true + Content *IntotoV002SchemaContent `json:"content"` +} + +// Validate validates this intoto v002 schema +func (m *IntotoV002Schema) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateContent(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *IntotoV002Schema) validateContent(formats strfmt.Registry) error { + + if err := validate.Required("content", "body", m.Content); err != nil { + return err + } + + if m.Content != nil { + if err := m.Content.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("content") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("content") + } + return err + } + } + + return nil +} + +// ContextValidate validate this intoto v002 schema based on the context it is used +func (m *IntotoV002Schema) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateContent(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *IntotoV002Schema) contextValidateContent(ctx context.Context, formats strfmt.Registry) error { + + if m.Content != nil { + if err := m.Content.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("content") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("content") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *IntotoV002Schema) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *IntotoV002Schema) UnmarshalBinary(b []byte) error { + var res IntotoV002Schema + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// IntotoV002SchemaContent intoto v002 schema content +// +// swagger:model IntotoV002SchemaContent +type IntotoV002SchemaContent struct { + + // envelope + Envelope *IntotoV002SchemaContentEnvelope `json:"envelope,omitempty"` + + // hash + Hash *IntotoV002SchemaContentHash `json:"hash,omitempty"` + + // payload hash + PayloadHash *IntotoV002SchemaContentPayloadHash `json:"payloadHash,omitempty"` +} + +// Validate validates this intoto v002 schema content +func (m *IntotoV002SchemaContent) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateEnvelope(formats); err != nil { + res = append(res, err) + } + + if err := m.validateHash(formats); err != nil { + res = append(res, err) + } + + if err := m.validatePayloadHash(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *IntotoV002SchemaContent) validateEnvelope(formats strfmt.Registry) error { + if swag.IsZero(m.Envelope) { // not required + return nil + } + + if m.Envelope != nil { + if err := m.Envelope.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("content" + "." + "envelope") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("content" + "." + "envelope") + } + return err + } + } + + return nil +} + +func (m *IntotoV002SchemaContent) validateHash(formats strfmt.Registry) error { + if swag.IsZero(m.Hash) { // not required + return nil + } + + if m.Hash != nil { + if err := m.Hash.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("content" + "." + "hash") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("content" + "." + "hash") + } + return err + } + } + + return nil +} + +func (m *IntotoV002SchemaContent) validatePayloadHash(formats strfmt.Registry) error { + if swag.IsZero(m.PayloadHash) { // not required + return nil + } + + if m.PayloadHash != nil { + if err := m.PayloadHash.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("content" + "." + "payloadHash") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("content" + "." + "payloadHash") + } + return err + } + } + + return nil +} + +// ContextValidate validate this intoto v002 schema content based on the context it is used +func (m *IntotoV002SchemaContent) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateEnvelope(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateHash(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidatePayloadHash(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *IntotoV002SchemaContent) contextValidateEnvelope(ctx context.Context, formats strfmt.Registry) error { + + if m.Envelope != nil { + if err := m.Envelope.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("content" + "." + "envelope") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("content" + "." + "envelope") + } + return err + } + } + + return nil +} + +func (m *IntotoV002SchemaContent) contextValidateHash(ctx context.Context, formats strfmt.Registry) error { + + if m.Hash != nil { + if err := m.Hash.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("content" + "." + "hash") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("content" + "." + "hash") + } + return err + } + } + + return nil +} + +func (m *IntotoV002SchemaContent) contextValidatePayloadHash(ctx context.Context, formats strfmt.Registry) error { + + if m.PayloadHash != nil { + if err := m.PayloadHash.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("content" + "." + "payloadHash") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("content" + "." + "payloadHash") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *IntotoV002SchemaContent) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *IntotoV002SchemaContent) UnmarshalBinary(b []byte) error { + var res IntotoV002SchemaContent + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// IntotoV002SchemaContentEnvelope dsse envelope +// +// swagger:model IntotoV002SchemaContentEnvelope +type IntotoV002SchemaContentEnvelope struct { + + // payload of the envelope + Payload string `json:"payload,omitempty"` + + // type describing the payload + // Required: true + PayloadType *string `json:"payloadType"` + + // collection of all signatures of the envelope's payload + // Required: true + // Min Items: 1 + Signatures []*IntotoV002SchemaContentEnvelopeSignaturesItems0 `json:"signatures"` +} + +// Validate validates this intoto v002 schema content envelope +func (m *IntotoV002SchemaContentEnvelope) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validatePayloadType(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSignatures(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *IntotoV002SchemaContentEnvelope) validatePayloadType(formats strfmt.Registry) error { + + if err := validate.Required("content"+"."+"envelope"+"."+"payloadType", "body", m.PayloadType); err != nil { + return err + } + + return nil +} + +func (m *IntotoV002SchemaContentEnvelope) validateSignatures(formats strfmt.Registry) error { + + if err := validate.Required("content"+"."+"envelope"+"."+"signatures", "body", m.Signatures); err != nil { + return err + } + + iSignaturesSize := int64(len(m.Signatures)) + + if err := validate.MinItems("content"+"."+"envelope"+"."+"signatures", "body", iSignaturesSize, 1); err != nil { + return err + } + + for i := 0; i < len(m.Signatures); i++ { + if swag.IsZero(m.Signatures[i]) { // not required + continue + } + + if m.Signatures[i] != nil { + if err := m.Signatures[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("content" + "." + "envelope" + "." + "signatures" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("content" + "." + "envelope" + "." + "signatures" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// ContextValidate validate this intoto v002 schema content envelope based on the context it is used +func (m *IntotoV002SchemaContentEnvelope) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateSignatures(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *IntotoV002SchemaContentEnvelope) contextValidateSignatures(ctx context.Context, formats strfmt.Registry) error { + + for i := 0; i < len(m.Signatures); i++ { + + if m.Signatures[i] != nil { + if err := m.Signatures[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("content" + "." + "envelope" + "." + "signatures" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("content" + "." + "envelope" + "." + "signatures" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// MarshalBinary interface implementation +func (m *IntotoV002SchemaContentEnvelope) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *IntotoV002SchemaContentEnvelope) UnmarshalBinary(b []byte) error { + var res IntotoV002SchemaContentEnvelope + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// IntotoV002SchemaContentEnvelopeSignaturesItems0 a signature of the envelope's payload along with the public key for the signature +// +// swagger:model IntotoV002SchemaContentEnvelopeSignaturesItems0 +type IntotoV002SchemaContentEnvelopeSignaturesItems0 struct { + + // optional id of the key used to create the signature + Keyid string `json:"keyid,omitempty"` + + // public key that corresponds to this signature + // Read Only: true + // Format: byte + PublicKey strfmt.Base64 `json:"publicKey,omitempty"` + + // signature of the payload + Sig string `json:"sig,omitempty"` +} + +// Validate validates this intoto v002 schema content envelope signatures items0 +func (m *IntotoV002SchemaContentEnvelopeSignaturesItems0) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validate this intoto v002 schema content envelope signatures items0 based on the context it is used +func (m *IntotoV002SchemaContentEnvelopeSignaturesItems0) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidatePublicKey(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *IntotoV002SchemaContentEnvelopeSignaturesItems0) contextValidatePublicKey(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "publicKey", "body", strfmt.Base64(m.PublicKey)); err != nil { + return err + } + + return nil +} + +// MarshalBinary interface implementation +func (m *IntotoV002SchemaContentEnvelopeSignaturesItems0) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *IntotoV002SchemaContentEnvelopeSignaturesItems0) UnmarshalBinary(b []byte) error { + var res IntotoV002SchemaContentEnvelopeSignaturesItems0 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// IntotoV002SchemaContentHash Specifies the hash algorithm and value encompassing the entire signed envelope +// +// swagger:model IntotoV002SchemaContentHash +type IntotoV002SchemaContentHash struct { + + // The hashing function used to compute the hash value + // Required: true + // Enum: [sha256] + Algorithm *string `json:"algorithm"` + + // The hash value for the archive + // Required: true + Value *string `json:"value"` +} + +// Validate validates this intoto v002 schema content hash +func (m *IntotoV002SchemaContentHash) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateAlgorithm(formats); err != nil { + res = append(res, err) + } + + if err := m.validateValue(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +var intotoV002SchemaContentHashTypeAlgorithmPropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["sha256"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + intotoV002SchemaContentHashTypeAlgorithmPropEnum = append(intotoV002SchemaContentHashTypeAlgorithmPropEnum, v) + } +} + +const ( + + // IntotoV002SchemaContentHashAlgorithmSha256 captures enum value "sha256" + IntotoV002SchemaContentHashAlgorithmSha256 string = "sha256" +) + +// prop value enum +func (m *IntotoV002SchemaContentHash) validateAlgorithmEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, intotoV002SchemaContentHashTypeAlgorithmPropEnum, true); err != nil { + return err + } + return nil +} + +func (m *IntotoV002SchemaContentHash) validateAlgorithm(formats strfmt.Registry) error { + + if err := validate.Required("content"+"."+"hash"+"."+"algorithm", "body", m.Algorithm); err != nil { + return err + } + + // value enum + if err := m.validateAlgorithmEnum("content"+"."+"hash"+"."+"algorithm", "body", *m.Algorithm); err != nil { + return err + } + + return nil +} + +func (m *IntotoV002SchemaContentHash) validateValue(formats strfmt.Registry) error { + + if err := validate.Required("content"+"."+"hash"+"."+"value", "body", m.Value); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this intoto v002 schema content hash based on the context it is used +func (m *IntotoV002SchemaContentHash) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// MarshalBinary interface implementation +func (m *IntotoV002SchemaContentHash) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *IntotoV002SchemaContentHash) UnmarshalBinary(b []byte) error { + var res IntotoV002SchemaContentHash + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// IntotoV002SchemaContentPayloadHash Specifies the hash algorithm and value covering the envelope's payload after being PAE encoded +// +// swagger:model IntotoV002SchemaContentPayloadHash +type IntotoV002SchemaContentPayloadHash struct { + + // The hashing function used to compute the hash value + // Required: true + // Enum: [sha256] + Algorithm *string `json:"algorithm"` + + // The hash value of the PAE encoded payload + // Required: true + Value *string `json:"value"` +} + +// Validate validates this intoto v002 schema content payload hash +func (m *IntotoV002SchemaContentPayloadHash) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateAlgorithm(formats); err != nil { + res = append(res, err) + } + + if err := m.validateValue(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +var intotoV002SchemaContentPayloadHashTypeAlgorithmPropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["sha256"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + intotoV002SchemaContentPayloadHashTypeAlgorithmPropEnum = append(intotoV002SchemaContentPayloadHashTypeAlgorithmPropEnum, v) + } +} + +const ( + + // IntotoV002SchemaContentPayloadHashAlgorithmSha256 captures enum value "sha256" + IntotoV002SchemaContentPayloadHashAlgorithmSha256 string = "sha256" +) + +// prop value enum +func (m *IntotoV002SchemaContentPayloadHash) validateAlgorithmEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, intotoV002SchemaContentPayloadHashTypeAlgorithmPropEnum, true); err != nil { + return err + } + return nil +} + +func (m *IntotoV002SchemaContentPayloadHash) validateAlgorithm(formats strfmt.Registry) error { + + if err := validate.Required("content"+"."+"payloadHash"+"."+"algorithm", "body", m.Algorithm); err != nil { + return err + } + + // value enum + if err := m.validateAlgorithmEnum("content"+"."+"payloadHash"+"."+"algorithm", "body", *m.Algorithm); err != nil { + return err + } + + return nil +} + +func (m *IntotoV002SchemaContentPayloadHash) validateValue(formats strfmt.Registry) error { + + if err := validate.Required("content"+"."+"payloadHash"+"."+"value", "body", m.Value); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this intoto v002 schema content payload hash based on the context it is used +func (m *IntotoV002SchemaContentPayloadHash) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// MarshalBinary interface implementation +func (m *IntotoV002SchemaContentPayloadHash) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *IntotoV002SchemaContentPayloadHash) UnmarshalBinary(b []byte) error { + var res IntotoV002SchemaContentPayloadHash + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/generated/models/proposed_entry.go b/pkg/generated/models/proposed_entry.go index 0ab5970dc..6ebbf1016 100644 --- a/pkg/generated/models/proposed_entry.go +++ b/pkg/generated/models/proposed_entry.go @@ -127,12 +127,6 @@ func unmarshalProposedEntry(data []byte, consumer runtime.Consumer) (ProposedEnt return nil, err } return &result, nil - case "dsse": - var result Dsse - if err := consumer.Consume(buf2, &result); err != nil { - return nil, err - } - return &result, nil case "hashedrekord": var result Hashedrekord if err := consumer.Consume(buf2, &result); err != nil { diff --git a/pkg/generated/restapi/embedded_spec.go b/pkg/generated/restapi/embedded_spec.go index efbc11d4a..df050f5f3 100644 --- a/pkg/generated/restapi/embedded_spec.go +++ b/pkg/generated/restapi/embedded_spec.go @@ -701,32 +701,6 @@ func init() { } ] }, - "dsse": { - "description": "DSSE object", - "type": "object", - "allOf": [ - { - "$ref": "#/definitions/ProposedEntry" - }, - { - "required": [ - "apiVersion", - "spec" - ], - "properties": { - "apiVersion": { - "type": "string", - "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" - }, - "spec": { - "type": "object", - "$ref": "pkg/types/dsse/dsse_schema.json" - } - }, - "additionalProperties": false - } - ] - }, "hashedrekord": { "description": "Hashed Rekord object", "type": "object", @@ -1555,44 +1529,6 @@ func init() { }, "readOnly": true }, - "DsseV001SchemaPayloadHash": { - "description": "hash of the envelope's payload after being PAE encoded", - "type": "object", - "properties": { - "algorithm": { - "description": "The hashing function used to compue the hash value", - "type": "string", - "enum": [ - "sha256" - ] - }, - "value": { - "description": "The hash value of the PAE encoded payload", - "type": "string" - } - }, - "readOnly": true - }, - "DsseV001SchemaSignaturesItems0": { - "description": "a signature of the envelope's payload along with the public key for the signature", - "type": "object", - "properties": { - "keyid": { - "description": "optional id of the key used to create the signature", - "type": "string" - }, - "publicKey": { - "description": "public key that corresponds to this signature", - "type": "string", - "format": "byte", - "readOnly": true - }, - "sig": { - "description": "signature of the payload", - "type": "string" - } - } - }, "Error": { "type": "object", "properties": { @@ -1914,12 +1850,35 @@ func init() { } } }, - "IntotoV001SchemaContent": { + "IntotoV002SchemaContent": { "type": "object", "properties": { "envelope": { - "description": "envelope", - "type": "string", + "description": "dsse envelope", + "type": "object", + "required": [ + "payloadType", + "signatures" + ], + "properties": { + "payload": { + "description": "payload of the envelope", + "type": "string", + "writeOnly": true + }, + "payloadType": { + "description": "type describing the payload", + "type": "string" + }, + "signatures": { + "description": "collection of all signatures of the envelope's payload", + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/IntotoV002SchemaContentEnvelopeSignaturesItems0" + } + } + }, "writeOnly": true }, "hash": { @@ -1945,7 +1904,7 @@ func init() { "readOnly": true }, "payloadHash": { - "description": "Specifies the hash algorithm and value covering the payload within the DSSE envelope", + "description": "Specifies the hash algorithm and value covering the envelope's payload after being PAE encoded", "type": "object", "required": [ "algorithm", @@ -1960,7 +1919,7 @@ func init() { ] }, "value": { - "description": "The hash value for the envelope's payload", + "description": "The hash value of the PAE encoded payload", "type": "string" } }, @@ -1968,7 +1927,55 @@ func init() { } } }, - "IntotoV001SchemaContentHash": { + "IntotoV002SchemaContentEnvelope": { + "description": "dsse envelope", + "type": "object", + "required": [ + "payloadType", + "signatures" + ], + "properties": { + "payload": { + "description": "payload of the envelope", + "type": "string", + "writeOnly": true + }, + "payloadType": { + "description": "type describing the payload", + "type": "string" + }, + "signatures": { + "description": "collection of all signatures of the envelope's payload", + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/IntotoV002SchemaContentEnvelopeSignaturesItems0" + } + } + }, + "writeOnly": true + }, + "IntotoV002SchemaContentEnvelopeSignaturesItems0": { + "description": "a signature of the envelope's payload along with the public key for the signature", + "type": "object", + "properties": { + "keyid": { + "description": "optional id of the key used to create the signature", + "type": "string" + }, + "publicKey": { + "description": "public key that corresponds to this signature", + "type": "string", + "format": "byte", + "readOnly": true + }, + "sig": { + "description": "signature of the payload", + "type": "string" + } + } + }, + "IntotoV002SchemaContentHash": { "description": "Specifies the hash algorithm and value encompassing the entire signed envelope", "type": "object", "required": [ @@ -1990,8 +1997,8 @@ func init() { }, "readOnly": true }, - "IntotoV001SchemaContentPayloadHash": { - "description": "Specifies the hash algorithm and value covering the payload within the DSSE envelope", + "IntotoV002SchemaContentPayloadHash": { + "description": "Specifies the hash algorithm and value covering the envelope's payload after being PAE encoded", "type": "object", "required": [ "algorithm", @@ -2006,7 +2013,7 @@ func init() { ] }, "value": { - "description": "The hash value for the envelope's payload", + "description": "The hash value of the PAE encoded payload", "type": "string" } }, @@ -2851,92 +2858,6 @@ func init() { "$schema": "http://json-schema.org/draft-07/schema", "$id": "http://rekor.sigstore.dev/types/intoto/intoto_v0_0_1_schema.json" }, - "dsse": { - "description": "DSSE object", - "type": "object", - "allOf": [ - { - "$ref": "#/definitions/ProposedEntry" - }, - { - "required": [ - "apiVersion", - "spec" - ], - "properties": { - "apiVersion": { - "type": "string", - "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" - }, - "spec": { - "$ref": "#/definitions/dsseSchema" - } - }, - "additionalProperties": false - } - ] - }, - "dsseSchema": { - "description": "DSSE for Rekord objects", - "type": "object", - "title": "DSSE Schema", - "oneOf": [ - { - "$ref": "#/definitions/dsseV001Schema" - } - ], - "$schema": "http://json-schema.org/draft-07/schema", - "$id": "http://rekor.sigstore.dev/types/dsse/dsse_schema.json" - }, - "dsseV001Schema": { - "description": "Schema for dsse object", - "type": "object", - "title": "dsse v0.0.1 Schema", - "required": [ - "payloadType", - "signatures" - ], - "properties": { - "payload": { - "description": "payload of the envelope", - "type": "string", - "format": "byte", - "writeOnly": true - }, - "payloadHash": { - "description": "hash of the envelope's payload after being PAE encoded", - "type": "object", - "properties": { - "algorithm": { - "description": "The hashing function used to compue the hash value", - "type": "string", - "enum": [ - "sha256" - ] - }, - "value": { - "description": "The hash value of the PAE encoded payload", - "type": "string" - } - }, - "readOnly": true - }, - "payloadType": { - "description": "type describing the payload", - "type": "string" - }, - "signatures": { - "description": "collection of all signatures of the envelope's payload", - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/definitions/DsseV001SchemaSignaturesItems0" - } - } - }, - "$schema": "http://json-schema.org/draft-07/schema", - "$id": "http://rekor.sigstore.dev/types/dsse/dsse_v0_0_1_schema.json" - }, "hashedrekord": { "description": "Hashed Rekord object", "type": "object", @@ -3201,18 +3122,17 @@ func init() { "title": "Intoto Schema", "oneOf": [ { - "$ref": "#/definitions/intotoV001Schema" + "$ref": "#/definitions/intotoV002Schema" } ], "$schema": "http://json-schema.org/draft-07/schema", "$id": "http://rekor.sigstore.dev/types/intoto/intoto_schema.json" }, - "intotoV001Schema": { + "intotoV002Schema": { "description": "Schema for intoto object", "type": "object", - "title": "intoto v0.0.1 Schema", + "title": "intoto v0.0.2 Schema", "required": [ - "publicKey", "content" ], "properties": { @@ -3220,8 +3140,31 @@ func init() { "type": "object", "properties": { "envelope": { - "description": "envelope", - "type": "string", + "description": "dsse envelope", + "type": "object", + "required": [ + "payloadType", + "signatures" + ], + "properties": { + "payload": { + "description": "payload of the envelope", + "type": "string", + "writeOnly": true + }, + "payloadType": { + "description": "type describing the payload", + "type": "string" + }, + "signatures": { + "description": "collection of all signatures of the envelope's payload", + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/IntotoV002SchemaContentEnvelopeSignaturesItems0" + } + } + }, "writeOnly": true }, "hash": { @@ -3247,7 +3190,7 @@ func init() { "readOnly": true }, "payloadHash": { - "description": "Specifies the hash algorithm and value covering the payload within the DSSE envelope", + "description": "Specifies the hash algorithm and value covering the envelope's payload after being PAE encoded", "type": "object", "required": [ "algorithm", @@ -3262,22 +3205,17 @@ func init() { ] }, "value": { - "description": "The hash value for the envelope's payload", + "description": "The hash value of the PAE encoded payload", "type": "string" } }, "readOnly": true } } - }, - "publicKey": { - "description": "The public key that can verify the signature", - "type": "string", - "format": "byte" } }, "$schema": "http://json-schema.org/draft-07/schema", - "$id": "http://rekor.sigstore.dev/types/intoto/intoto_v0_0_1_schema.json" + "$id": "http://rekor.sigstore.dev/types/intoto/intoto_v0_0_2_schema.json" }, "jar": { "description": "Java Archive (JAR)", diff --git a/pkg/types/dsse/dsse.go b/pkg/types/dsse/dsse.go deleted file mode 100644 index e94c73c37..000000000 --- a/pkg/types/dsse/dsse.go +++ /dev/null @@ -1,75 +0,0 @@ -// -// Copyright 2022 The Sigstore Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package dsse - -import ( - "context" - "errors" - "fmt" - - "github.com/sigstore/rekor/pkg/generated/models" - "github.com/sigstore/rekor/pkg/types" -) - -const ( - KIND = "dsse" -) - -type BaseDsseType struct { - types.RekorType -} - -func init() { - types.TypeMap.Store(KIND, New) -} - -func New() types.TypeImpl { - bdt := BaseDsseType{} - bdt.Kind = KIND - bdt.VersionMap = VersionMap - return &bdt -} - -var VersionMap = types.NewSemVerEntryFactoryMap() - -func (bdt BaseDsseType) UnmarshalEntry(pe models.ProposedEntry) (types.EntryImpl, error) { - if pe == nil { - return nil, errors.New("proposed entry cannot be nil") - } - - in, ok := pe.(*models.Dsse) - if !ok { - return nil, errors.New("cannot unmarshal non-DSSE types") - } - - return bdt.VersionedUnmarshal(in, *in.APIVersion) -} - -func (bdt *BaseDsseType) CreateProposedEntry(ctx context.Context, version string, props types.ArtifactProperties) (models.ProposedEntry, error) { - if version == "" { - version = bdt.DefaultVersion() - } - ei, err := bdt.VersionedUnmarshal(nil, version) - if err != nil { - return nil, fmt.Errorf("fetching DSSE version implementation, %w", err) - } - - return ei.CreateFromArtifactProperties(ctx, props) -} - -func (bdt BaseDsseType) DefaultVersion() string { - return "0.0.1" -} diff --git a/pkg/types/dsse/dsse_schema.json b/pkg/types/dsse/dsse_schema.json deleted file mode 100644 index 511130952..000000000 --- a/pkg/types/dsse/dsse_schema.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://rekor.sigstore.dev/types/dsse/dsse_schema.json", - "title": "DSSE Schema", - "description": "DSSE for Rekord objects", - "type": "object", - "oneOf": [ - { - "$ref": "v0.0.1/dsse_v0_0_1_schema.json" - } - ] -} diff --git a/pkg/types/dsse/dsse_test.go b/pkg/types/dsse/dsse_test.go deleted file mode 100644 index 56addd41e..000000000 --- a/pkg/types/dsse/dsse_test.go +++ /dev/null @@ -1,92 +0,0 @@ -// -// Copyright 2022 The Sigstore Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package dsse - -import ( - "errors" - "testing" - - "github.com/go-openapi/swag" - - "github.com/sigstore/rekor/pkg/generated/models" - "github.com/sigstore/rekor/pkg/types" -) - -type UnmarshalTester struct { - models.Dsse - types.BaseUnmarshalTester -} - -type UnmarshalFailsTester struct { - types.BaseUnmarshalTester -} - -func (u UnmarshalFailsTester) NewEntry() types.EntryImpl { - return &UnmarshalFailsTester{} -} - -func (u UnmarshalFailsTester) Unmarshal(pe models.ProposedEntry) error { - return errors.New("error") -} - -func TestDsseType(t *testing.T) { - // empty to start - if VersionMap.Count() != 0 { - t.Error("semver range was not blank at start of test") - } - - u := UnmarshalTester{} - // ensure semver range parser is working - invalidSemVerRange := "not a valid semver range" - err := VersionMap.SetEntryFactory(invalidSemVerRange, u.NewEntry) - if err == nil || VersionMap.Count() > 0 { - t.Error("invalid semver range was incorrectly added to SemVerToFacFnMap") - } - - // valid semver range can be parsed - err = VersionMap.SetEntryFactory(">= 1.2.3", u.NewEntry) - if err != nil || VersionMap.Count() != 1 { - t.Error("valid semver range was not added to SemVerToFacFnMap") - } - - u.Dsse.APIVersion = swag.String("2.0.1") - brt := New() - - // version requested matches implementation in map - if _, err := brt.UnmarshalEntry(&u.Dsse); err != nil { - t.Errorf("unexpected error in Unmarshal: %v", err) - } - - // version requested fails to match implementation in map - u.Dsse.APIVersion = swag.String("1.2.2") - if _, err := brt.UnmarshalEntry(&u.Dsse); err == nil { - t.Error("unexpected success in Unmarshal for non-matching version") - } - - // error in Unmarshal call is raised appropriately - u.Dsse.APIVersion = swag.String("2.2.0") - u2 := UnmarshalFailsTester{} - _ = VersionMap.SetEntryFactory(">= 1.2.3", u2.NewEntry) - if _, err := brt.UnmarshalEntry(&u.Dsse); err == nil { - t.Error("unexpected success in Unmarshal when error is thrown") - } - - // version requested fails to match implementation in map - u.Dsse.APIVersion = swag.String("not_a_version") - if _, err := brt.UnmarshalEntry(&u.Dsse); err == nil { - t.Error("unexpected success in Unmarshal for invalid version") - } -} diff --git a/pkg/types/dsse/v0.0.1/dsse_v0_0_1_schema.json b/pkg/types/dsse/v0.0.1/dsse_v0_0_1_schema.json deleted file mode 100644 index 500335124..000000000 --- a/pkg/types/dsse/v0.0.1/dsse_v0_0_1_schema.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://rekor.sigstore.dev/types/dsse/dsse_v0_0_1_schema.json", - "title": "dsse v0.0.1 Schema", - "description": "Schema for dsse object", - "type": "object", - "properties": { - "payload": { - "description": "payload of the envelope", - "type": "string", - "format": "byte", - "writeOnly": true - }, - "payloadType": { - "description": "type describing the payload", - "type": "string" - }, - "payloadHash": { - "description": "hash of the envelope's payload after being PAE encoded", - "readOnly": true, - "type": "object", - "properties": { - "algorithm": { - "description": "The hashing function used to compue the hash value", - "type": "string", - "enum": ["sha256"] - }, - "value": { - "description": "The hash value of the PAE encoded payload", - "type": "string" - } - } - }, - "signatures": { - "description": "collection of all signatures of the envelope's payload", - "type": "array", - "minItems": 1, - "items": { - "description": "a signature of the envelope's payload along with the public key for the signature", - "type": "object", - "properties": { - "keyid": { - "description": "optional id of the key used to create the signature", - "type": "string" - }, - "sig": { - "description": "signature of the payload", - "type": "string" - }, - "publicKey": { - "description": "public key that corresponds to this signature", - "type": "string", - "format": "byte", - "readOnly": true - } - } - } - } - }, - "required": ["payloadType", "signatures"] -} diff --git a/pkg/types/entries.go b/pkg/types/entries.go index 120314b53..29756a7c4 100644 --- a/pkg/types/entries.go +++ b/pkg/types/entries.go @@ -134,7 +134,7 @@ type ArtifactProperties struct { SignatureBytes []byte PublicKeyPath *url.URL PublicKeyBytes []byte - PublicKeysBytes [][]byte - PublicKeysPaths []*url.URL + MultiPublicKeyBytes [][]byte + MultiPublicKeyPaths []*url.URL PKIFormat string } diff --git a/pkg/types/intoto/intoto.go b/pkg/types/intoto/intoto.go index f48daacbe..f682f7ede 100644 --- a/pkg/types/intoto/intoto.go +++ b/pkg/types/intoto/intoto.go @@ -70,5 +70,5 @@ func (it *BaseIntotoType) CreateProposedEntry(ctx context.Context, version strin } func (it BaseIntotoType) DefaultVersion() string { - return "0.0.1" + return "0.0.2" } diff --git a/pkg/types/intoto/intoto_schema.json b/pkg/types/intoto/intoto_schema.json index b99b3c2d9..852ba660d 100644 --- a/pkg/types/intoto/intoto_schema.json +++ b/pkg/types/intoto/intoto_schema.json @@ -6,7 +6,7 @@ "type": "object", "oneOf": [ { - "$ref": "v0.0.1/intoto_v0_0_1_schema.json" + "$ref": "v0.0.2/intoto_v0_0_2_schema.json" } ] } diff --git a/pkg/types/dsse/v0.0.1/entry.go b/pkg/types/intoto/v0.0.2/entry.go similarity index 55% rename from pkg/types/dsse/v0.0.1/entry.go rename to pkg/types/intoto/v0.0.2/entry.go index 9b71dcbd4..85f2e0b51 100644 --- a/pkg/types/dsse/v0.0.1/entry.go +++ b/pkg/types/intoto/v0.0.2/entry.go @@ -1,5 +1,5 @@ // -// Copyright 2022 The Sigstore Authors. +// Copyright 2021 The Sigstore Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package dsse +package intoto import ( "bytes" @@ -28,6 +28,7 @@ import ( "io/ioutil" "net/url" "path/filepath" + "strings" "github.com/in-toto/in-toto-golang/in_toto" "github.com/secure-systems-lab/go-securesystemslib/dsse" @@ -40,96 +41,141 @@ import ( "github.com/sigstore/rekor/pkg/log" "github.com/sigstore/rekor/pkg/pki/x509" "github.com/sigstore/rekor/pkg/types" - rekordsse "github.com/sigstore/rekor/pkg/types/dsse" + "github.com/sigstore/rekor/pkg/types/intoto" "github.com/sigstore/sigstore/pkg/signature" + "github.com/sigstore/sigstore/pkg/signature/options" ) const ( - APIVERSION = "0.0.1" + APIVERSION = "0.0.2" ) func init() { - if err := rekordsse.VersionMap.SetEntryFactory(APIVERSION, NewEntry); err != nil { + if err := intoto.VersionMap.SetEntryFactory(APIVERSION, NewEntry); err != nil { log.Logger.Panic(err) } } -type V001Entry struct { - DsseObj models.DsseV001Schema +type V002Entry struct { + IntotoObj models.IntotoV002Schema + env dsse.Envelope } -func (v V001Entry) APIVersion() string { +func (v V002Entry) APIVersion() string { return APIVERSION } func NewEntry() types.EntryImpl { - return &V001Entry{} + return &V002Entry{} } -func (v V001Entry) IndexKeys() ([]string, error) { +func (v V002Entry) IndexKeys() ([]string, error) { var result []string - fmt.Printf("%+v\n", v.DsseObj) - result = append(result, v.DsseObj.PayloadHash.Algorithm+":"+v.DsseObj.PayloadHash.Value) - for _, sig := range v.DsseObj.Signatures { + if v.IntotoObj.Content == nil || v.IntotoObj.Content.Envelope == nil { + log.Logger.Info("IntotoObj content or dsse envelope is nil") + return result, nil + } + + for _, sig := range v.IntotoObj.Content.Envelope.Signatures { keyHash := sha256.Sum256(sig.PublicKey) result = append(result, "sha256:"+hex.EncodeToString(keyHash[:])) + + keyObj, err := x509.NewPublicKey(bytes.NewReader(sig.PublicKey)) + if err != nil { + return nil, err + } + + result = append(result, keyObj.EmailAddresses()...) } - switch *v.DsseObj.PayloadType { + payloadKey := strings.ToLower(fmt.Sprintf("%s:%s", *v.IntotoObj.Content.PayloadHash.Algorithm, *v.IntotoObj.Content.PayloadHash.Value)) + result = append(result, payloadKey) + + switch *v.IntotoObj.Content.Envelope.PayloadType { case in_toto.PayloadType: - statement, err := parseIntotoStatement(v.DsseObj.Payload) + + hashkey := strings.ToLower(fmt.Sprintf("%s:%s", *v.IntotoObj.Content.Hash.Algorithm, *v.IntotoObj.Content.Hash.Value)) + result = append(result, hashkey) + + if v.IntotoObj.Content.Envelope.Payload == "" { + log.Logger.Info("IntotoObj DSSE payload is empty") + return result, nil + } + decodedPayload, err := base64.StdEncoding.DecodeString(string(v.IntotoObj.Content.Envelope.Payload)) + if err != nil { + return result, fmt.Errorf("could not decode envelope payload: %w", err) + } + statement, err := parseStatement(decodedPayload) if err != nil { return result, err } - for _, s := range statement.Subject { for alg, ds := range s.Digest { result = append(result, alg+":"+ds) } } + // Not all in-toto statements will contain a SLSA provenance predicate. + // See https://github.com/in-toto/attestation/blob/main/spec/README.md#predicate + // for other predicates. + if predicate, err := parseSlsaPredicate(decodedPayload); err == nil { + if predicate.Predicate.Materials != nil { + for _, s := range predicate.Predicate.Materials { + for alg, ds := range s.Digest { + result = append(result, alg+":"+ds) + } + } + } + } default: - log.Logger.Infof("Cannot index payload of type: %s", *v.DsseObj.PayloadType) + log.Logger.Infof("Unknown in_toto DSSE envelope Type: %s", *v.IntotoObj.Content.Envelope.PayloadType) } - return result, nil } -func parseIntotoStatement(p []byte) (*in_toto.Statement, error) { +func parseStatement(p []byte) (*in_toto.Statement, error) { ps := in_toto.Statement{} if err := json.Unmarshal(p, &ps); err != nil { return nil, err } - return &ps, nil } -func (v *V001Entry) Unmarshal(pe models.ProposedEntry) error { - dsseModel, ok := pe.(*models.Dsse) +func parseSlsaPredicate(p []byte) (*in_toto.ProvenanceStatement, error) { + predicate := in_toto.ProvenanceStatement{} + if err := json.Unmarshal(p, &predicate); err != nil { + return nil, err + } + return &predicate, nil +} + +func (v *V002Entry) Unmarshal(pe models.ProposedEntry) error { + it, ok := pe.(*models.Intoto) if !ok { - return errors.New("cannot unmarshal non DSSE v0.0.1 type") + return errors.New("cannot unmarshal non Intoto v0.0.1 type") } - if err := types.DecodeEntry(dsseModel.Spec, &v.DsseObj); err != nil { + var err error + if err := types.DecodeEntry(it.Spec, &v.IntotoObj); err != nil { return err } // field validation - if err := v.DsseObj.Validate(strfmt.Default); err != nil { + if err := v.IntotoObj.Validate(strfmt.Default); err != nil { return err } - if string(v.DsseObj.Payload) == "" { + if string(v.IntotoObj.Content.Envelope.Payload) == "" { return nil } env := &dsse.Envelope{ - Payload: string(v.DsseObj.Payload), - PayloadType: *v.DsseObj.PayloadType, + Payload: string(v.IntotoObj.Content.Envelope.Payload), + PayloadType: *v.IntotoObj.Content.Envelope.PayloadType, } allPubKeyBytes := make([][]byte, 0) - for _, sig := range v.DsseObj.Signatures { + for _, sig := range v.IntotoObj.Content.Envelope.Signatures { env.Signatures = append(env.Signatures, dsse.Signature{ KeyID: sig.Keyid, Sig: string(sig.Sig), @@ -142,59 +188,61 @@ func (v *V001Entry) Unmarshal(pe models.ProposedEntry) error { return err } - decodedPayload, err := base64.StdEncoding.DecodeString(string(v.DsseObj.Payload)) + v.env = *env + + decodedPayload, err := base64.StdEncoding.DecodeString(string(v.IntotoObj.Content.Envelope.Payload)) if err != nil { return fmt.Errorf("could not decode envelope payload: %w", err) } - paeEncodedPayload := dsse.PAE(*v.DsseObj.PayloadType, decodedPayload) + paeEncodedPayload := dsse.PAE(*v.IntotoObj.Content.Envelope.PayloadType, decodedPayload) h := sha256.Sum256(paeEncodedPayload) - v.DsseObj.PayloadHash = &models.DsseV001SchemaPayloadHash{ - Algorithm: models.DsseV001SchemaPayloadHashAlgorithmSha256, - Value: hex.EncodeToString(h[:]), + v.IntotoObj.Content.PayloadHash = &models.IntotoV002SchemaContentPayloadHash{ + Algorithm: swag.String(models.IntotoV002SchemaContentPayloadHashAlgorithmSha256), + Value: swag.String(hex.EncodeToString(h[:])), } return nil } -func (v *V001Entry) Canonicalize(ctx context.Context) ([]byte, error) { - canonicalEntry := models.DsseV001Schema{ - PayloadHash: v.DsseObj.PayloadHash, - Signatures: v.DsseObj.Signatures, - PayloadType: v.DsseObj.PayloadType, +func (v *V002Entry) Canonicalize(ctx context.Context) ([]byte, error) { + + canonicalEntry := models.IntotoV002Schema{ + Content: &models.IntotoV002SchemaContent{ + Envelope: v.IntotoObj.Content.Envelope, + Hash: v.IntotoObj.Content.Hash, + PayloadHash: v.IntotoObj.Content.PayloadHash, + }, } - model := models.Dsse{} - model.APIVersion = swag.String(APIVERSION) - model.Spec = canonicalEntry - return json.Marshal(&model) + itObj := models.Intoto{} + itObj.APIVersion = swag.String(APIVERSION) + itObj.Spec = &canonicalEntry + + return json.Marshal(&itObj) } -func (v *V001Entry) AttestationKey() string { - if v.DsseObj.PayloadHash != nil { - return fmt.Sprintf("%s:%s", v.DsseObj.PayloadHash.Algorithm, v.DsseObj.PayloadHash.Value) +// AttestationKey returns the digest of the attestation that was uploaded, to be used to lookup the attestation from storage +func (v *V002Entry) AttestationKey() string { + if v.IntotoObj.Content != nil && v.IntotoObj.Content.PayloadHash != nil { + return fmt.Sprintf("%s:%s", *v.IntotoObj.Content.PayloadHash.Algorithm, *v.IntotoObj.Content.PayloadHash.Value) } - return "" } -func (v *V001Entry) AttestationKeyValue() (string, []byte) { - storageSize := base64.StdEncoding.DecodedLen(len(v.DsseObj.Payload)) +// AttestationKeyValue returns both the key and value to be persisted into attestation storage +func (v *V002Entry) AttestationKeyValue() (string, []byte) { + storageSize := base64.StdEncoding.DecodedLen(len(v.env.Payload)) if storageSize > viper.GetInt("max_attestation_size") { log.Logger.Infof("Skipping attestation storage, size %d is greater than max %d", storageSize, viper.GetInt("max_attestation_size")) return "", nil } - - decodedPayload, err := base64.StdEncoding.DecodeString(string(v.DsseObj.Payload)) - if err != nil { - log.Logger.Infof("Skipping attestation storage, error while decoding attestation: %v", err) - return "", nil - } - - return v.AttestationKey(), decodedPayload + attBytes, _ := base64.StdEncoding.DecodeString(v.env.Payload) + return v.AttestationKey(), attBytes } type verifier struct { + s signature.Signer v signature.Verifier } @@ -211,6 +259,17 @@ func (v *verifier) Public() crypto.PublicKey { return nil } +func (v *verifier) Sign(data []byte) (sig []byte, err error) { + if v.s == nil { + return nil, errors.New("nil signer") + } + sig, err = v.s.SignMessage(bytes.NewReader(data), options.WithCryptoSignerOpts(crypto.SHA256)) + if err != nil { + return nil, err + } + return sig, nil +} + func (v *verifier) Verify(data, sig []byte) error { if v.v == nil { return errors.New("nil verifier") @@ -218,20 +277,19 @@ func (v *verifier) Verify(data, sig []byte) error { return v.v.VerifySignature(bytes.NewReader(sig), bytes.NewReader(data)) } -func (v V001Entry) CreateFromArtifactProperties(_ context.Context, props types.ArtifactProperties) (models.ProposedEntry, error) { - returnVal := models.Dsse{} - re := V001Entry{} +func (v V002Entry) CreateFromArtifactProperties(_ context.Context, props types.ArtifactProperties) (models.ProposedEntry, error) { + returnVal := models.Intoto{} + re := V002Entry{} + var err error artifactBytes := props.ArtifactBytes if artifactBytes == nil { if props.ArtifactPath == nil { return nil, errors.New("path to artifact file must be specified") } if props.ArtifactPath.IsAbs() { - return nil, errors.New("dsse envelopes cannot be fetched over HTTP(S)") + return nil, errors.New("intoto envelopes cannot be fetched over HTTP(S)") } - - var err error artifactBytes, err = ioutil.ReadFile(filepath.Clean(props.ArtifactPath.Path)) if err != nil { return nil, err @@ -248,12 +306,16 @@ func (v V001Entry) CreateFromArtifactProperties(_ context.Context, props types.A allPubKeyBytes = append(allPubKeyBytes, props.PublicKeyBytes) } - allPubKeyBytes = append(allPubKeyBytes, props.PublicKeysBytes...) + allPubKeyBytes = append(allPubKeyBytes, props.MultiPublicKeyBytes...) allPubKeyPaths := make([]*url.URL, 0) if props.PublicKeyPath != nil { allPubKeyPaths = append(allPubKeyPaths, props.PublicKeyPath) } + if props.MultiPublicKeyPaths != nil { + allPubKeyPaths = append(allPubKeyPaths, props.MultiPublicKeyPaths...) + } + for _, path := range allPubKeyPaths { if path.IsAbs() { return nil, errors.New("dsse public keys cannot be fetched over HTTP(S)") @@ -272,8 +334,9 @@ func (v V001Entry) CreateFromArtifactProperties(_ context.Context, props types.A return nil, err } - re.DsseObj.Payload = strfmt.Base64(env.Payload) - re.DsseObj.PayloadType = &env.PayloadType + re.IntotoObj.Content.Envelope.Payload = env.Payload + re.IntotoObj.Content.Envelope.PayloadType = &env.PayloadType + for _, sig := range env.Signatures { key, ok := keysBySig[sig.Sig] if !ok { @@ -286,15 +349,22 @@ func (v V001Entry) CreateFromArtifactProperties(_ context.Context, props types.A } keyBytes := strfmt.Base64(canonKey) - re.DsseObj.Signatures = append(re.DsseObj.Signatures, &models.DsseV001SchemaSignaturesItems0{ + re.IntotoObj.Content.Envelope.Signatures = append(re.IntotoObj.Content.Envelope.Signatures, &models.IntotoV002SchemaContentEnvelopeSignaturesItems0{ Keyid: sig.KeyID, Sig: sig.Sig, PublicKey: keyBytes, }) } + h := sha256.Sum256([]byte(artifactBytes)) + re.IntotoObj.Content.Hash = &models.IntotoV002SchemaContentHash{ + Algorithm: swag.String(models.IntotoV001SchemaContentHashAlgorithmSha256), + Value: swag.String(hex.EncodeToString(h[:])), + } + + returnVal.Spec = re.IntotoObj returnVal.APIVersion = swag.String(re.APIVersion()) - returnVal.Spec = re.DsseObj + return &returnVal, nil } diff --git a/pkg/types/intoto/v0.0.2/entry_test.go b/pkg/types/intoto/v0.0.2/entry_test.go new file mode 100644 index 000000000..2ed4073dc --- /dev/null +++ b/pkg/types/intoto/v0.0.2/entry_test.go @@ -0,0 +1,438 @@ +// +// Copyright 2021 The Sigstore Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package intoto + +import ( + "crypto" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/sha256" + "crypto/x509" + "encoding/base64" + "encoding/hex" + "encoding/json" + "encoding/pem" + "fmt" + "math/big" + "reflect" + "sort" + "strings" + "testing" + + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/google/go-cmp/cmp" + "github.com/in-toto/in-toto-golang/in_toto" + slsa "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2" + "github.com/secure-systems-lab/go-securesystemslib/dsse" + "github.com/sigstore/rekor/pkg/generated/models" + "github.com/sigstore/sigstore/pkg/signature" + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + goleak.VerifyTestMain(m) +} + +func TestNewEntryReturnType(t *testing.T) { + entry := NewEntry() + if reflect.TypeOf(entry) != reflect.ValueOf(&V002Entry{}).Type() { + t.Errorf("invalid type returned from NewEntry: %T", entry) + } +} + +func envelope(t *testing.T, k *ecdsa.PrivateKey, payload []byte) *dsse.Envelope { + + s, err := signature.LoadECDSASigner(k, crypto.SHA256) + if err != nil { + t.Fatal(err) + } + signer, err := in_toto.NewDSSESigner( + &verifier{ + s: s, + }) + if err != nil { + t.Fatal(err) + } + dsseEnv, err := signer.SignPayload(payload) + if err != nil { + t.Fatal(err) + } + + return dsseEnv +} + +func multiSignEnvelope(t *testing.T, k []*ecdsa.PrivateKey, payload []byte) *dsse.Envelope { + evps := []*verifier{} + for _, key := range k { + s, err := signature.LoadECDSASigner(key, crypto.SHA256) + if err != nil { + t.Fatal(err) + } + evps = append(evps, &verifier{ + s: s, + }) + } + + signer, err := dsse.NewMultiEnvelopeSigner(2, evps[0], evps[1]) + if err != nil { + t.Fatal(err) + } + dsseEnv, err := signer.SignPayload(in_toto.PayloadType, payload) + if err != nil { + t.Fatal(err) + } + + return dsseEnv +} + +func createRekorEnvelope(dsseEnv *dsse.Envelope, pub [][]byte) *models.IntotoV002SchemaContentEnvelope { + + env := &models.IntotoV002SchemaContentEnvelope{ + Payload: dsseEnv.Payload, + PayloadType: &dsseEnv.PayloadType, + } + + for i, sig := range dsseEnv.Signatures { + env.Signatures = append(env.Signatures, &models.IntotoV002SchemaContentEnvelopeSignaturesItems0{ + Keyid: sig.KeyID, + Sig: sig.Sig, + PublicKey: pub[i], + }) + } + return env +} + +func envelopeHash(t *testing.T, dsseEnv *dsse.Envelope) string { + val, err := json.Marshal(dsseEnv) + if err != nil { + t.Fatal(err) + } + h := sha256.Sum256(val) + return hex.EncodeToString(h[:]) +} + +func TestV002Entry_Unmarshal(t *testing.T) { + key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + t.Fatal(err) + } + der, err := x509.MarshalPKIXPublicKey(&key.PublicKey) + if err != nil { + t.Fatal(err) + } + pub := pem.EncodeToMemory(&pem.Block{ + Bytes: der, + Type: "PUBLIC KEY", + }) + + priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + t.Fatal(err) + } + + ca := &x509.Certificate{ + SerialNumber: big.NewInt(1), + } + caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &priv.PublicKey, priv) + if err != nil { + t.Fatal(err) + } + pemBytes := pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE", + Bytes: caBytes, + }) + + invalid := dsse.Envelope{ + Payload: "hello", + Signatures: []dsse.Signature{ + { + Sig: string(strfmt.Base64("foobar")), + }, + }, + } + + validPayload := "hellothispayloadisvalid" + + tests := []struct { + env *dsse.Envelope + name string + it *models.IntotoV002Schema + wantErr bool + }{ + { + name: "empty", + it: &models.IntotoV002Schema{}, + wantErr: true, + }, + { + name: "missing envelope", + it: &models.IntotoV002Schema{ + Content: &models.IntotoV002SchemaContent{ + Hash: &models.IntotoV002SchemaContentHash{ + Algorithm: swag.String(models.IntotoV002SchemaContentHashAlgorithmSha256), + }, + }, + }, + wantErr: true, + }, + { + env: envelope(t, key, []byte(validPayload)), + name: "valid", + it: &models.IntotoV002Schema{ + Content: &models.IntotoV002SchemaContent{ + Envelope: createRekorEnvelope(envelope(t, key, []byte(validPayload)), [][]byte{pub}), + Hash: &models.IntotoV002SchemaContentHash{ + Algorithm: swag.String(models.IntotoV002SchemaContentHashAlgorithmSha256), + Value: swag.String(envelopeHash(t, envelope(t, key, []byte(validPayload)))), + }, + }, + }, + wantErr: false, + }, + { + env: envelope(t, priv, []byte(validPayload)), + name: "cert", + it: &models.IntotoV002Schema{ + Content: &models.IntotoV002SchemaContent{ + Envelope: createRekorEnvelope(envelope(t, priv, []byte(validPayload)), [][]byte{pemBytes}), + Hash: &models.IntotoV002SchemaContentHash{ + Algorithm: swag.String(models.IntotoV002SchemaContentHashAlgorithmSha256), + Value: swag.String(envelopeHash(t, envelope(t, priv, []byte(validPayload)))), + }, + }, + }, + wantErr: false, + }, + { + env: &invalid, + name: "invalid", + it: &models.IntotoV002Schema{ + Content: &models.IntotoV002SchemaContent{ + Envelope: createRekorEnvelope(&invalid, [][]byte{pub}), + Hash: &models.IntotoV002SchemaContentHash{ + Algorithm: swag.String(models.IntotoV002SchemaContentHashAlgorithmSha256), + Value: swag.String(envelopeHash(t, &invalid)), + }, + }, + }, + wantErr: true, + }, + { + env: envelope(t, key, []byte(validPayload)), + name: "invalid key", + it: &models.IntotoV002Schema{ + Content: &models.IntotoV002SchemaContent{ + Envelope: createRekorEnvelope(envelope(t, key, []byte(validPayload)), [][]byte{[]byte("notavalidkey")}), + Hash: &models.IntotoV002SchemaContentHash{ + Algorithm: swag.String(models.IntotoV002SchemaContentHashAlgorithmSha256), + Value: swag.String(envelopeHash(t, envelope(t, key, []byte(validPayload)))), + }, + }, + }, + wantErr: true, + }, + { + env: multiSignEnvelope(t, []*ecdsa.PrivateKey{key, priv}, []byte(validPayload)), + name: "multi-key", + it: &models.IntotoV002Schema{ + Content: &models.IntotoV002SchemaContent{ + Envelope: createRekorEnvelope(multiSignEnvelope(t, []*ecdsa.PrivateKey{key, priv}, []byte(validPayload)), [][]byte{pub, pemBytes}), + Hash: &models.IntotoV002SchemaContentHash{ + Algorithm: swag.String(models.IntotoV002SchemaContentHashAlgorithmSha256), + Value: swag.String(envelopeHash(t, multiSignEnvelope(t, []*ecdsa.PrivateKey{key, priv}, []byte(validPayload)))), + }, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + v := &V002Entry{} + + it := &models.Intoto{ + Spec: tt.it, + } + + var uv = func() error { + if err := v.Unmarshal(it); err != nil { + return err + } + want := []string{} + for _, sig := range v.IntotoObj.Content.Envelope.Signatures { + keyHash := sha256.Sum256(sig.PublicKey) + want = append(want, "sha256:"+hex.EncodeToString(keyHash[:])) + } + decodedPayload, err := base64.StdEncoding.DecodeString(tt.env.Payload) + if err != nil { + return fmt.Errorf("could not decode envelope payload: %w", err) + } + paeEncodedPayload := dsse.PAE(tt.env.PayloadType, decodedPayload) + h := sha256.Sum256(paeEncodedPayload) + want = append(want, "sha256:"+hex.EncodeToString(h[:])) + + if !reflect.DeepEqual(v.AttestationKey(), "sha256:"+hex.EncodeToString(h[:])) { + t.Errorf("V002Entry.AttestationKey() = %v, want %v", v.AttestationKey(), "sha256:"+hex.EncodeToString(h[:])) + } + + hashkey := strings.ToLower(fmt.Sprintf("%s:%s", *tt.it.Content.Hash.Algorithm, *tt.it.Content.Hash.Value)) + want = append(want, hashkey) + got, _ := v.IndexKeys() + sort.Strings(got) + sort.Strings(want) + if !reflect.DeepEqual(got, want) { + t.Errorf("V002Entry.IndexKeys() = %v, want %v", got, want) + } + + return nil + } + if err := uv(); (err != nil) != tt.wantErr { + t.Errorf("V002Entry.Unmarshal() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestV002Entry_IndexKeys(t *testing.T) { + key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + t.Fatal(err) + } + der, err := x509.MarshalPKIXPublicKey(&key.PublicKey) + if err != nil { + t.Fatal(err) + } + pub := pem.EncodeToMemory(&pem.Block{ + Bytes: der, + Type: "PUBLIC KEY", + }) + + tests := []struct { + name string + statement in_toto.Statement + want []string + }{ + { + name: "standard", + want: []string{}, + statement: in_toto.Statement{ + Predicate: "hello", + }, + }, + { + name: "subject", + want: []string{"sha256:foo"}, + statement: in_toto.Statement{ + StatementHeader: in_toto.StatementHeader{ + Subject: []in_toto.Subject{ + { + Name: "foo", + Digest: map[string]string{ + "sha256": "foo", + }, + }, + }, + }, + Predicate: "hello", + }, + }, + { + name: "slsa", + want: []string{"sha256:bar"}, + statement: in_toto.Statement{ + Predicate: slsa.ProvenancePredicate{ + Materials: []slsa.ProvenanceMaterial{ + { + URI: "foo", + Digest: map[string]string{ + "sha256": "bar", + }}, + }, + }, + }, + }, + { + name: "slsa wit header", + want: []string{"sha256:foo", "sha256:bar"}, + statement: in_toto.Statement{ + StatementHeader: in_toto.StatementHeader{ + Subject: []in_toto.Subject{ + { + Name: "foo", + Digest: map[string]string{ + "sha256": "foo", + }, + }, + }, + }, + Predicate: slsa.ProvenancePredicate{ + Materials: []slsa.ProvenanceMaterial{ + { + URI: "foo", + Digest: map[string]string{ + "sha256": "bar", + }}, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + b, err := json.Marshal(tt.statement) + if err != nil { + t.Fatal(err) + } + paeEncodedPayload := dsse.PAE(in_toto.PayloadType, b) + payloadHash := sha256.Sum256(paeEncodedPayload) + v := V002Entry{ + IntotoObj: models.IntotoV002Schema{ + Content: &models.IntotoV002SchemaContent{ + Envelope: createRekorEnvelope(envelope(t, key, b), [][]byte{pub}), + Hash: &models.IntotoV002SchemaContentHash{ + Algorithm: swag.String(models.IntotoV001SchemaContentHashAlgorithmSha256), + Value: swag.String(envelopeHash(t, envelope(t, key, b))), + }, + PayloadHash: &models.IntotoV002SchemaContentPayloadHash{ + Algorithm: swag.String(models.IntotoV001SchemaContentHashAlgorithmSha256), + Value: swag.String(hex.EncodeToString(payloadHash[:])), + }, + }, + }, + env: *envelope(t, key, b), + } + want := []string{} + for _, sig := range v.IntotoObj.Content.Envelope.Signatures { + keyHash := sha256.Sum256(sig.PublicKey) + want = append(want, "sha256:"+hex.EncodeToString(keyHash[:])) + } + + want = append(want, "sha256:"+hex.EncodeToString(payloadHash[:])) + + hashkey := strings.ToLower("sha256:" + *v.IntotoObj.Content.Hash.Value) + want = append(want, hashkey) + want = append(want, tt.want...) + got, _ := v.IndexKeys() + sort.Strings(got) + sort.Strings(want) + if !cmp.Equal(got, want) { + t.Errorf("V001Entry.IndexKeys() = %v, want %v", got, want) + } + }) + } +} diff --git a/pkg/types/intoto/v0.0.2/intoto_v0_0_2_schema.json b/pkg/types/intoto/v0.0.2/intoto_v0_0_2_schema.json new file mode 100644 index 000000000..66415c765 --- /dev/null +++ b/pkg/types/intoto/v0.0.2/intoto_v0_0_2_schema.json @@ -0,0 +1,101 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://rekor.sigstore.dev/types/intoto/intoto_v0_0_2_schema.json", + "title": "intoto v0.0.2 Schema", + "description": "Schema for intoto object", + "type": "object", + "properties": { + "content": { + "type": "object", + "properties": { + "envelope": { + "description": "dsse envelope", + "type": "object", + "properties": { + "payload": { + "description": "payload of the envelope", + "type": "string", + "writeOnly": true + }, + "payloadType": { + "description": "type describing the payload", + "type": "string" + }, + "signatures": { + "description": "collection of all signatures of the envelope's payload", + "type": "array", + "minItems": 1, + "items": { + "description": "a signature of the envelope's payload along with the public key for the signature", + "type": "object", + "properties": { + "keyid": { + "description": "optional id of the key used to create the signature", + "type": "string" + }, + "sig": { + "description": "signature of the payload", + "type": "string" + }, + "publicKey": { + "description": "public key that corresponds to this signature", + "type": "string", + "format": "byte", + "readOnly": true + } + } + } + } + }, + "required": ["payloadType", "signatures"], + "writeOnly": true + }, + "hash": { + "description": "Specifies the hash algorithm and value encompassing the entire signed envelope", + "type": "object", + "properties": { + "algorithm": { + "description": "The hashing function used to compute the hash value", + "type": "string", + "enum": [ + "sha256" + ] + }, + "value": { + "description": "The hash value for the archive", + "type": "string" + } + }, + "required": [ + "algorithm", + "value" + ], + "readOnly": true + }, + "payloadHash": { + "description": "Specifies the hash algorithm and value covering the envelope's payload after being PAE encoded", + "type": "object", + "properties": { + "algorithm": { + "description": "The hashing function used to compute the hash value", + "type": "string", + "enum": [ "sha256" ] + }, + "value": { + "description": "The hash value of the PAE encoded payload", + "type": "string" + } + }, + "required": [ + "algorithm", + "value" + ], + "readOnly": true + } + } + } + }, + "required": [ + "content" + ] +} diff --git a/tests/e2e_test.go b/tests/e2e_test.go index 41d21668c..b9e7a9de5 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -30,7 +30,6 @@ import ( "encoding/json" "encoding/pem" "fmt" - "golang.org/x/sync/errgroup" "io/ioutil" "net/http" "os" @@ -41,6 +40,8 @@ import ( "testing" "time" + "golang.org/x/sync/errgroup" + "github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer" "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" @@ -496,7 +497,7 @@ func TestIntoto(t *testing.T) { } -func TestDsse(t *testing.T) { +func TestIntotoV002(t *testing.T) { td := t.TempDir() attestationPath := filepath.Join(td, "attestation.json") pubKeyPath := filepath.Join(td, "pub.pem") @@ -556,7 +557,7 @@ func TestDsse(t *testing.T) { write(t, ecdsaPub, pubKeyPath) // If we do it twice, it should already exist - out := runCli(t, "upload", "--artifact", attestationPath, "--type", "dsse", "--public-key", pubKeyPath) + out := runCli(t, "upload", "--artifact", attestationPath, "--type", "intoto", "--public-key", pubKeyPath) outputContains(t, out, "Created entry at") uuid := getUUIDFromUploadOutput(t, out) @@ -577,23 +578,24 @@ func TestDsse(t *testing.T) { attHash := sha256.Sum256(dsse.PAE("application/vnd.in-toto+json", []byte(g.Attestation))) - dsseModel := &models.DsseV001Schema{} - if err := types.DecodeEntry(g.Body.(map[string]interface{})["DsseObj"], dsseModel); err != nil { - t.Errorf("could not convert body into dsse type: %v", err) + intotoV002Model := &models.IntotoV002Schema{} + if err := types.DecodeEntry(g.Body.(map[string]interface{})["IntotoObj"], intotoV002Model); err != nil { + t.Errorf("could not convert body into intoto type: %v", err) } - if dsseModel.PayloadHash == nil { - t.Errorf("could not find hash over attestation %v", dsseModel) + if intotoV002Model.Content.Hash == nil { + t.Errorf("could not find hash over attestation %v", intotoV002Model) } - recordedPayloadHash, err := hex.DecodeString(dsseModel.PayloadHash.Value) + recordedPayloadHash, err := hex.DecodeString(*intotoV002Model.Content.PayloadHash.Value) if err != nil { t.Errorf("error converting attestation hash to []byte: %v", err) } if !bytes.Equal(attHash[:], recordedPayloadHash) { - t.Fatal(fmt.Errorf("attestation hash %v doesnt match the payload we sent %v", hex.EncodeToString(attHash[:]), dsseModel.PayloadHash.Value)) + t.Fatal(fmt.Errorf("attestation hash %v doesnt match the payload we sent %v", hex.EncodeToString(attHash[:]), + *intotoV002Model.Content.PayloadHash.Value)) } - out = runCli(t, "upload", "--artifact", attestationPath, "--type", "dsse", "--public-key", pubKeyPath) + out = runCli(t, "upload", "--artifact", attestationPath, "--type", "intoto", "--public-key", pubKeyPath) outputContains(t, out, "Entry already exists") }