diff --git a/pkg/api/entries.go b/pkg/api/entries.go index f8b207a6b..81a00af56 100644 --- a/pkg/api/entries.go +++ b/pkg/api/entries.go @@ -237,12 +237,12 @@ func createLogEntry(params entries.CreateLogEntryParams) (models.LogEntry, middl go func() { keys, err := entry.IndexKeys() if err != nil { - log.ContextLogger(ctx).Error(fmt.Errorf("error generating index keys: %w", err)) + log.ContextLogger(ctx).Error(err) return } for _, key := range keys { if err := addToIndex(context.Background(), key, entryID); err != nil { - log.ContextLogger(ctx).Error(fmt.Errorf("error inserting key/value pairs into index: %w", err)) + log.ContextLogger(ctx).Error(err) } } }() diff --git a/pkg/generated/models/intoto_v002_schema.go b/pkg/generated/models/intoto_v002_schema.go index bdd7b3b63..86c0b47f5 100644 --- a/pkg/generated/models/intoto_v002_schema.go +++ b/pkg/generated/models/intoto_v002_schema.go @@ -313,9 +313,9 @@ func (m *IntotoV002SchemaContent) UnmarshalBinary(b []byte) error { // swagger:model IntotoV002SchemaContentEnvelope type IntotoV002SchemaContentEnvelope struct { - // base64 encoded payload of the envelope - // Pattern: ^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$ - Payload string `json:"payload,omitempty"` + // payload of the envelope + // Format: byte + Payload strfmt.Base64 `json:"payload,omitempty"` // type describing the payload // Required: true @@ -331,10 +331,6 @@ type IntotoV002SchemaContentEnvelope struct { func (m *IntotoV002SchemaContentEnvelope) Validate(formats strfmt.Registry) error { var res []error - if err := m.validatePayload(formats); err != nil { - res = append(res, err) - } - if err := m.validatePayloadType(formats); err != nil { res = append(res, err) } @@ -349,18 +345,6 @@ func (m *IntotoV002SchemaContentEnvelope) Validate(formats strfmt.Registry) erro return nil } -func (m *IntotoV002SchemaContentEnvelope) validatePayload(formats strfmt.Registry) error { - if swag.IsZero(m.Payload) { // not required - return nil - } - - if err := validate.Pattern("content"+"."+"envelope"+"."+"payload", "body", m.Payload, `^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$`); err != nil { - return err - } - - return nil -} - func (m *IntotoV002SchemaContentEnvelope) validatePayloadType(formats strfmt.Registry) error { if err := validate.Required("content"+"."+"envelope"+"."+"payloadType", "body", m.PayloadType); err != nil { @@ -468,34 +452,13 @@ type IntotoV002SchemaContentEnvelopeSignaturesItems0 struct { // Format: byte PublicKey strfmt.Base64 `json:"publicKey,omitempty"` - // base64 encoded signature of the payload - // Pattern: ^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$ - Sig string `json:"sig,omitempty"` + // signature of the payload + // Format: byte + Sig strfmt.Base64 `json:"sig,omitempty"` } // Validate validates this intoto v002 schema content envelope signatures items0 func (m *IntotoV002SchemaContentEnvelopeSignaturesItems0) Validate(formats strfmt.Registry) error { - var res []error - - if err := m.validateSig(formats); err != nil { - res = append(res, err) - } - - if len(res) > 0 { - return errors.CompositeValidationError(res...) - } - return nil -} - -func (m *IntotoV002SchemaContentEnvelopeSignaturesItems0) validateSig(formats strfmt.Registry) error { - if swag.IsZero(m.Sig) { // not required - return nil - } - - if err := validate.Pattern("sig", "body", m.Sig, `^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$`); err != nil { - return err - } - return nil } diff --git a/pkg/generated/restapi/embedded_spec.go b/pkg/generated/restapi/embedded_spec.go index 73e606d1e..697bc220b 100644 --- a/pkg/generated/restapi/embedded_spec.go +++ b/pkg/generated/restapi/embedded_spec.go @@ -1935,9 +1935,9 @@ func init() { ], "properties": { "payload": { - "description": "base64 encoded payload of the envelope", + "description": "payload of the envelope", "type": "string", - "pattern": "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$", + "format": "byte", "writeOnly": true }, "payloadType": { @@ -2009,9 +2009,9 @@ func init() { ], "properties": { "payload": { - "description": "base64 encoded payload of the envelope", + "description": "payload of the envelope", "type": "string", - "pattern": "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$", + "format": "byte", "writeOnly": true }, "payloadType": { @@ -2043,9 +2043,9 @@ func init() { "readOnly": true }, "sig": { - "description": "base64 encoded signature of the payload", + "description": "signature of the payload", "type": "string", - "pattern": "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$" + "format": "byte" } } }, @@ -3286,9 +3286,9 @@ func init() { ], "properties": { "payload": { - "description": "base64 encoded payload of the envelope", + "description": "payload of the envelope", "type": "string", - "pattern": "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$", + "format": "byte", "writeOnly": true }, "payloadType": { diff --git a/pkg/types/intoto/v0.0.2/entry.go b/pkg/types/intoto/v0.0.2/entry.go index 4e91d0c4b..6b7a62a45 100644 --- a/pkg/types/intoto/v0.0.2/entry.go +++ b/pkg/types/intoto/v0.0.2/entry.go @@ -84,7 +84,7 @@ func (v V002Entry) IndexKeys() ([]string, error) { canonKey, err := keyObj.CanonicalValue() if err != nil { - return result, fmt.Errorf("could not canonicalize key: %w", err) + return result, fmt.Errorf("could not canonicize key: %w", err) } keyHash := sha256.Sum256(canonKey) @@ -102,7 +102,7 @@ func (v V002Entry) IndexKeys() ([]string, error) { switch *v.IntotoObj.Content.Envelope.PayloadType { case in_toto.PayloadType: - if v.IntotoObj.Content.Envelope.Payload == "" { + if v.IntotoObj.Content.Envelope.Payload == nil { log.Logger.Info("IntotoObj DSSE payload is empty") return result, nil } @@ -159,6 +159,7 @@ func (v *V002Entry) Unmarshal(pe models.ProposedEntry) error { return errors.New("cannot unmarshal non Intoto v0.0.2 type") } + var err error if err := types.DecodeEntry(it.Spec, &v.IntotoObj); err != nil { return err } @@ -172,44 +173,17 @@ func (v *V002Entry) Unmarshal(pe models.ProposedEntry) error { return nil } - payloadToUse := v.IntotoObj.Content.Envelope.Payload - // we need the decoded payload to calculate the correct SHA256 digest - decodedPayload, err := base64.StdEncoding.DecodeString(payloadToUse) - if err != nil { - return fmt.Errorf("envelope payload must be base64 encoded string: %w", err) - } - // in rekor v0.12 & v1.0.0, rekor-cli would (incorrectly) double encode the payload. - // handle that gracefully here - doubleDecodedPayload, err := base64.StdEncoding.DecodeString(string(decodedPayload)) - if err == nil { - payloadToUse = string(decodedPayload) - v.IntotoObj.Content.Envelope.Payload = payloadToUse - decodedPayload = doubleDecodedPayload - } - env := &dsse.Envelope{ - Payload: payloadToUse, // must be base64 encoded string + Payload: string(v.IntotoObj.Content.Envelope.Payload), PayloadType: *v.IntotoObj.Content.Envelope.PayloadType, } allPubKeyBytes := make([][]byte, 0) for _, sig := range v.IntotoObj.Content.Envelope.Signatures { - sigToUse := sig.Sig - decodedSig, err := base64.StdEncoding.DecodeString(string(sig.Sig)) - if err != nil { - return fmt.Errorf("envelope signature must be a base64 encoded string: %w", err) - } - // in rekor v0.12 & v1.0.0, rekor-cli would (incorrectly) double encode the signature. - // handle that gracefully here - if _, err = base64.StdEncoding.DecodeString(string(decodedSig)); err == nil { - sigToUse = string(decodedSig) - } - env.Signatures = append(env.Signatures, dsse.Signature{ KeyID: sig.Keyid, - Sig: sigToUse, // must be base64 encoded string + Sig: string(sig.Sig), }) - sig.Sig = sigToUse // overwrite value in local object to ensure we canonicalize correctly allPubKeyBytes = append(allPubKeyBytes, sig.PublicKey) } @@ -220,6 +194,11 @@ func (v *V002Entry) Unmarshal(pe models.ProposedEntry) error { 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) + } + h := sha256.Sum256(decodedPayload) v.IntotoObj.Content.PayloadHash = &models.IntotoV002SchemaContentPayloadHash{ Algorithm: swag.String(models.IntotoV002SchemaContentPayloadHashAlgorithmSha256), @@ -360,7 +339,8 @@ func (v V002Entry) CreateFromArtifactProperties(_ context.Context, props types.A return nil, err } - re.IntotoObj.Content.Envelope.Payload = env.Payload + b64 := strfmt.Base64([]byte(env.Payload)) + re.IntotoObj.Content.Envelope.Payload = b64 re.IntotoObj.Content.Envelope.PayloadType = &env.PayloadType for _, sig := range env.Signatures { @@ -371,13 +351,13 @@ func (v V002Entry) CreateFromArtifactProperties(_ context.Context, props types.A canonKey, err := key.CanonicalValue() if err != nil { - return nil, fmt.Errorf("could not canonicalize key: %w", err) + return nil, fmt.Errorf("could not canonicize key: %w", err) } keyBytes := strfmt.Base64(canonKey) re.IntotoObj.Content.Envelope.Signatures = append(re.IntotoObj.Content.Envelope.Signatures, &models.IntotoV002SchemaContentEnvelopeSignaturesItems0{ Keyid: sig.KeyID, - Sig: sig.Sig, + Sig: strfmt.Base64([]byte(sig.Sig)), PublicKey: keyBytes, }) } diff --git a/pkg/types/intoto/v0.0.2/entry_test.go b/pkg/types/intoto/v0.0.2/entry_test.go index 82700000c..66bd21a23 100644 --- a/pkg/types/intoto/v0.0.2/entry_test.go +++ b/pkg/types/intoto/v0.0.2/entry_test.go @@ -108,13 +108,14 @@ func multiSignEnvelope(t *testing.T, k []*ecdsa.PrivateKey, payload []byte) *dss func createRekorEnvelope(dsseEnv *dsse.Envelope, pub [][]byte) *models.IntotoV002SchemaContentEnvelope { env := &models.IntotoV002SchemaContentEnvelope{} - env.Payload = dsseEnv.Payload + b64 := strfmt.Base64([]byte(dsseEnv.Payload)) + env.Payload = b64 env.PayloadType = &dsseEnv.PayloadType for i, sig := range dsseEnv.Signatures { env.Signatures = append(env.Signatures, &models.IntotoV002SchemaContentEnvelopeSignaturesItems0{ Keyid: sig.KeyID, - Sig: sig.Sig, + Sig: strfmt.Base64([]byte(sig.Sig)), PublicKey: strfmt.Base64(pub[i]), }) } @@ -172,12 +173,6 @@ func TestV002Entry_Unmarshal(t *testing.T) { validPayload := "hellothispayloadisvalid" - doubleEncodedEnvelope := createRekorEnvelope(envelope(t, key, []byte(validPayload)), [][]byte{pub}) - doubleEncodedPayload := base64.StdEncoding.EncodeToString([]byte(doubleEncodedEnvelope.Payload)) - doubleEncodedEnvelope.Payload = doubleEncodedPayload - doubleEncodedSig := base64.StdEncoding.EncodeToString([]byte(doubleEncodedEnvelope.Signatures[0].Sig)) - doubleEncodedEnvelope.Signatures[0].Sig = doubleEncodedSig - tests := []struct { env *dsse.Envelope name string @@ -270,20 +265,6 @@ func TestV002Entry_Unmarshal(t *testing.T) { }, wantErr: false, }, - { - env: envelope(t, key, []byte(validPayload)), - name: "double base64 encoded envelope (testing backwards compat with v0.12.x and v1.0.0", - it: &models.IntotoV002Schema{ - Content: &models.IntotoV002SchemaContent{ - Envelope: doubleEncodedEnvelope, - Hash: &models.IntotoV002SchemaContentHash{ - Algorithm: swag.String(models.IntotoV002SchemaContentHashAlgorithmSha256), - Value: swag.String(envelopeHash(t, envelope(t, priv, []byte(validPayload)))), - }, - }, - }, - wantErr: false, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { 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 index a18f2b562..0008e46fb 100644 --- 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 @@ -13,9 +13,9 @@ "type": "object", "properties": { "payload": { - "description": "base64 encoded payload of the envelope", + "description": "payload of the envelope", "type": "string", - "pattern": "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$", + "format": "byte", "writeOnly": true }, "payloadType": { @@ -35,9 +35,9 @@ "type": "string" }, "sig": { - "description": "base64 encoded signature of the payload", + "description": "signature of the payload", "type": "string", - "pattern": "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$" + "format": "byte" }, "publicKey": { "description": "public key that corresponds to this signature",