Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove requirement of PayloadHash for intoto 0.0.1 #1490

Merged
merged 2 commits into from
May 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions pkg/types/intoto/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,3 +394,35 @@ func TestValidationSearchIntotoV002MissingPayloadHash(t *testing.T) {
t.Fatalf("expected status 400, got %d instead: %v", resp.StatusCode, string(c))
}
}

func TestValidationSearchIntotoV001MissingPayloadHash(t *testing.T) {
body := `{
"entries":[
{
"kind":"intoto",
"apiVersion": "0.0.1",
"spec":{
"content":{
"hash":{
"algorithm":"sha256",
"value":"ebbfddda6277af199e93c5bb5cf5998a79311de238e49bcc8ac24102698761bb"
}
},
"publicKey":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNwRENDQWlxZ0F3SUJBZ0lVYWhsOEFRd1lZV05ZbnV6dlFvOEVrN1dMTURvd0NnWUlLb1pJemowRUF3TXcKTnpFVk1CTUdBMVVFQ2hNTWMybG5jM1J2Y21VdVpHVjJNUjR3SEFZRFZRUURFeFZ6YVdkemRHOXlaUzFwYm5SbApjbTFsWkdsaGRHVXdIaGNOTWpJd09ESTJNREV4TnpFM1doY05Nakl3T0RJMk1ERXlOekUzV2pBQU1Ga3dFd1lICktvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVLWmZEQzlpalVyclpBWE9jWFYrQXFHRUlTSlEzVHRqSndJdEEKdTE3Rml2aWpnSk1hYUhGNDcrT3Z2OVR1ekFDQ3lpSUV5UDUyZXI2ZmF5bmZKYVVqOEtPQ0FVa3dnZ0ZGTUE0RwpBMVVkRHdFQi93UUVBd0lIZ0RBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREF6QWRCZ05WSFE0RUZnUVVHQldUCkMwdUU3dTRQcURVRjFYV0c0QlVWVUpBd0h3WURWUjBqQkJnd0ZvQVUzOVBwejFZa0VaYjVxTmpwS0ZXaXhpNFkKWkQ4d0pRWURWUjBSQVFIL0JCc3dHWUVYYzJGemIyRnJhWEpoTmpFeE5FQm5iV0ZwYkM1amIyMHdLUVlLS3dZQgpCQUdEdnpBQkFRUWJhSFIwY0hNNkx5OWhZMk52ZFc1MGN5NW5iMjluYkdVdVkyOXRNSUdMQmdvckJnRUVBZFo1CkFnUUNCSDBFZXdCNUFIY0FDR0NTOENoUy8yaEYwZEZySjRTY1JXY1lyQlk5d3pqU2JlYThJZ1kyYjNJQUFBR0MKMTdtSmhnQUFCQU1BU0RCR0FpRUFoS09BSkdWVlhCb1cxTDR4alk5eWJWOGZUUXN5TStvUEpIeDk5S29LYUpVQwpJUURCZDllc1Q0Mk1STng3Vm9BM1paKzV4akhNZWR6amVxQ2ZoZTcvd1pxYTlUQUtCZ2dxaGtqT1BRUURBd05vCkFEQmxBakVBcnBkeXlFRjc3b2JyTENMUXpzYmIxM2lsNjd3dzM4Y050amdNQml6Y2VUakRiY2VLeVFSN1RKNHMKZENsclkxY1BBakE4aXB6SUQ4VU1CaGxkSmUvZXJGcGdtN2swNWFic2lPN3V5dVZuS29VNk0rTXJ6VVUrZTlGdwpJRGhCanVRa1dRYz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="
}
}
]
}
`
resp, err := http.Post(fmt.Sprintf("%s/api/v1/log/entries/retrieve", rekorServer()),
"application/json",
bytes.NewBuffer([]byte(body)))
if err != nil {
t.Fatal(err)
}
c, _ := ioutil.ReadAll(resp.Body)
// No failure when payload hash is not present for canonicalization
if resp.StatusCode != 200 {
t.Fatalf("expected status 200, got %d instead: %v", resp.StatusCode, string(c))
}
}
25 changes: 14 additions & 11 deletions pkg/types/intoto/v0.0.1/entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,8 @@ func (v *V001Entry) Canonicalize(_ context.Context) ([]byte, error) {
if v.IntotoObj.Content.Hash == nil {
return nil, errors.New("missing envelope hash")
}
if v.IntotoObj.Content.PayloadHash == nil {
return nil, errors.New("missing payload hash")
}
// PayloadHash is not present for old entries

pk, err := v.keyObj.CanonicalValue()
if err != nil {
return nil, err
Expand All @@ -209,12 +208,15 @@ func (v *V001Entry) Canonicalize(_ context.Context) ([]byte, error) {
Algorithm: v.IntotoObj.Content.Hash.Algorithm,
Value: v.IntotoObj.Content.Hash.Value,
},
PayloadHash: &models.IntotoV001SchemaContentPayloadHash{
Algorithm: v.IntotoObj.Content.PayloadHash.Algorithm,
Value: v.IntotoObj.Content.PayloadHash.Value,
},
},
}
// Set PayloadHash if present
if v.IntotoObj.Content.PayloadHash != nil {
canonicalEntry.Content.PayloadHash = &models.IntotoV001SchemaContentPayloadHash{
Algorithm: v.IntotoObj.Content.PayloadHash.Algorithm,
Value: v.IntotoObj.Content.PayloadHash.Value,
}
}

itObj := models.Intoto{}
itObj.APIVersion = swag.String(APIVERSION)
Expand All @@ -237,10 +239,11 @@ func (v *V001Entry) validate() error {
} else if err := v.IntotoObj.Content.Hash.Validate(strfmt.Default); err != nil {
return fmt.Errorf("validation error on envelope hash: %w", err)
}
if v.IntotoObj.Content.PayloadHash == nil {
return fmt.Errorf("missing hash value for payload")
} else if err := v.IntotoObj.Content.PayloadHash.Validate(strfmt.Default); err != nil {
return fmt.Errorf("validation error on payload hash: %w", err)
// PayloadHash is not present for old entries
if v.IntotoObj.Content.PayloadHash != nil {
if err := v.IntotoObj.Content.PayloadHash.Validate(strfmt.Default); err != nil {
return fmt.Errorf("validation error on payload hash: %w", err)
}
}
// if there is no envelope, and hash/payloadHash are valid, then there's nothing else to do here
return nil
Expand Down
37 changes: 37 additions & 0 deletions pkg/types/intoto/v0.0.1/entry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,43 @@ func TestV001Entry_Unmarshal(t *testing.T) {
}
}

// Demonstrates that Unmarshal and Canonicalize will succeed with only a hash,
// since committed entries will have no envelope and may have no payload hash
func TestV001EntryWithoutEnvelopeOrPayloadHash(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",
})
m := &models.IntotoV001Schema{
PublicKey: p(pub),
Content: &models.IntotoV001SchemaContent{
Hash: &models.IntotoV001SchemaContentHash{
Algorithm: swag.String(models.IntotoV001SchemaContentHashAlgorithmSha256),
Value: swag.String("1a1707bb54e5fb4deddd19f07adcb4f1e022ca7879e3c8348da8d4fa496ae8e2"),
},
},
}
v := &V001Entry{}
it := &models.Intoto{
Spec: m,
}
if err := v.Unmarshal(it); err != nil {
t.Fatalf("error umarshalling intoto without envelope: %v", err)
}
_, err = v.Canonicalize(context.TODO())
if err != nil {
t.Fatalf("error canonicalizing intoto without envelope: %v", err)
}
}

func TestV001Entry_IndexKeys(t *testing.T) {
h := sha256.Sum256([]byte("foo"))
dataSHA := hex.EncodeToString(h[:])
Expand Down