Skip to content

Commit

Permalink
✨ Iterate thru subjects when verifying subject's hash (slsa-framework…
Browse files Browse the repository at this point in the history
…#112)

* Iterate thru subjects

* missing file

* update
  • Loading branch information
laurentsimon authored Jun 29, 2022
1 parent 2f00514 commit a7f78c7
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 23 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ You have two options to install the verifier.

#### Option 1: Install via go
```
$ go install github.com/slsa-framework/slsa-verifier@v1.1.0
$ go install github.com/slsa-framework/slsa-verifier@v1.1.1
$ slsa-verifier <options>
```

Expand Down
41 changes: 20 additions & 21 deletions pkg/provenance.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,25 +92,34 @@ func intotoEntry(certPem []byte, provenance []byte) (*intotod.V001Entry, error)
}, nil
}

// Get SHA256 Subject Digest from the provenance statement.
func getSha256Digest(env *dsselib.Envelope) (string, error) {
// Verify SHA256 Subject Digest from the provenance statement.
func verifySha256Digest(env *dsselib.Envelope, expectedHash string) error {
pyld, err := base64.StdEncoding.DecodeString(env.Payload)
if err != nil {
return "", fmt.Errorf("%w: %s", ErrorInvalidDssePayload, "decoding payload")
return fmt.Errorf("%w: %s", ErrorInvalidDssePayload, "decoding payload")
}
prov := &intoto.ProvenanceStatement{}
if err := json.Unmarshal([]byte(pyld), prov); err != nil {
return "", fmt.Errorf("%w: %s", ErrorInvalidDssePayload, "unmarshalling json")
return fmt.Errorf("%w: %s", ErrorInvalidDssePayload, "unmarshalling json")
}

if len(prov.Subject) == 0 {
return "", fmt.Errorf("%w: %s", ErrorInvalidDssePayload, "no subjects")
return fmt.Errorf("%w: %s", ErrorInvalidDssePayload, "no subjects")
}
digestSet := prov.Subject[0].Digest
hash, exists := digestSet["sha256"]
if !exists {
return "", fmt.Errorf("%w: %s", ErrorInvalidDssePayload, "no sha256 subject digest")

for _, subject := range prov.Subject {
digestSet := subject.Digest
hash, exists := digestSet["sha256"]
if !exists {
return fmt.Errorf("%w: %s", ErrorInvalidDssePayload, "no sha256 subject digest")
}

if strings.EqualFold(hash, expectedHash) {
return nil
}
}
return hash, nil

return fmt.Errorf("expected hash '%s' not found: %w", expectedHash, errorMismatchHash)
}

// GetRekorEntries finds all entry UUIDs by the digest of the artifact binary.
Expand Down Expand Up @@ -182,7 +191,6 @@ func GetRekorEntriesWithCert(rClient *client.Rekor, artifactHash string, provena
}
if len(certs) != 1 {
return nil, nil, fmt.Errorf("error unmarshaling certificate from pem")

}

return env, certs[0], nil
Expand Down Expand Up @@ -558,16 +566,7 @@ func verifyTrustedBuilderRef(id *WorkflowIdentity, ref string) error {
}

func VerifyProvenance(env *dsselib.Envelope, expectedHash string) error {
hash, err := getSha256Digest(env)
if err != nil {
return err
}

if !strings.EqualFold(hash, expectedHash) {
return fmt.Errorf("expected hash '%s', got '%s': %w", expectedHash, hash, errorMismatchHash)
}

return nil
return verifySha256Digest(env, expectedHash)
}

func VerifyBranch(env *dsselib.Envelope, expectedBranch string) error {
Expand Down
20 changes: 19 additions & 1 deletion pkg/provenance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,29 @@ func Test_VerifyProvenance(t *testing.T) {
expected: errorMismatchHash,
},
{
name: "valid rekor entries found",
name: "valid entry",
path: "./testdata/dsse-valid.intoto.jsonl",
artifactHash: "0ae7e4fa71686538440012ee36a2634dbaa19df2dd16a466f52411fb348bbc4e",
expected: nil,
},
{
name: "valid entry multiple subjects last entry",
path: "./testdata/dsse-valid-multi-subjects.intoto.jsonl",
artifactHash: "03e7e4fa71686538440012ee36a2634dbaa19df2dd16a466f52411fb348bbc4e",
expected: nil,
},
{
name: "valid multiple subjects second entry",
path: "./testdata/dsse-valid-multi-subjects.intoto.jsonl",
artifactHash: "02e7e4fa71686538440012ee36a2634dbaa19df2dd16a466f52411fb348bbc4e",
expected: nil,
},
{
name: "multiple subjects invalid hash",
path: "./testdata/dsse-valid-multi-subjects.intoto.jsonl",
artifactHash: "04e7e4fa71686538440012ee36a2634dbaa19df2dd16a466f52411fb348bbc4e",
expected: errorMismatchHash,
},
}
for _, tt := range tests {
tt := tt // Re-initializing variable so it is not changed while executing the closure below
Expand Down
10 changes: 10 additions & 0 deletions pkg/testdata/dsse-valid-multi-subjects.intoto.jsonl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"payloadType": "application/vnd.in-toto+json",
"payload": "ewogICJfdHlwZSI6ICJodHRwczovL2luLXRvdG8uaW8vU3RhdGVtZW50L3YwLjEiLAogICJwcmVkaWNhdGUiOiB7CiAgICAiYnVpbGRUeXBlIjogImh0dHBzOi8vZ2l0aHViLmNvbS9BdHRlc3RhdGlvbnMvR2l0SHViQWN0aW9uc1dvcmtmbG93QHYxIiwKICAgICJidWlsZGVyIjogewogICAgICAiaWQiOiAiaHR0cHM6Ly9naXRodWIuY29tL0F0dGVzdGF0aW9ucy9HaXRIdWJIb3N0ZWRBY3Rpb25zQHYxIgogICAgfSwKICAgICJpbnZvY2F0aW9uIjogewogICAgICAiY29uZmlnU291cmNlIjogewogICAgICAgICJkaWdlc3QiOiB7CiAgICAgICAgICAic2hhMSI6ICI0NTA2MjkwZTJlOGZlYjFmMzRiMjdhMDQ0ZjdjYzg2M2M4MzBlZjZiIgogICAgICAgIH0sCiAgICAgICAgImVudHJ5UG9pbnQiOiAiVGVzdCBTTFNBIiwKICAgICAgICAidXJpIjogImdpdCthc3JhYS9zbHNhLW9uLWdpdGh1Yi10ZXN0LmdpdCIKICAgICAgfSwKICAgICAgImVudmlyb25tZW50IjogewogICAgICAgICJhcmNoIjogImFtZDY0IiwKICAgICAgICAiZW52IjogewogICAgICAgICAgIkdJVEhVQl9FVkVOVF9OQU1FIjogIndvcmtmbG93X2Rpc3BhdGNoIiwKICAgICAgICAgICJHSVRIVUJfUlVOX0lEIjogIjE4OTM3OTkyMjAiLAogICAgICAgICAgIkdJVEhVQl9SVU5fTlVNQkVSIjogIjc2IgogICAgICAgIH0KICAgICAgfQogICAgfSwKICAgICJtYXRlcmlhbHMiOiBbCiAgICAgIHsKICAgICAgICAiZGlnZXN0IjogewogICAgICAgICAgInNoYTEiOiAiNDUwNjI5MGUyZThmZWIxZjM0YjI3YTA0NGY3Y2M4NjNjODMwZWY2YiIKICAgICAgICB9LAogICAgICAgICJ1cmkiOiAiZ2l0K2FzcmFhL3Nsc2Etb24tZ2l0aHViLXRlc3QuZ2l0IgogICAgICB9CiAgICBdCiAgfSwKICAicHJlZGljYXRlVHlwZSI6ICJodHRwczovL3Nsc2EuZGV2L3Byb3ZlbmFuY2UvdjAuMiIsCiAgInN1YmplY3QiOiBbCiAgICB7CiAgICAgICJkaWdlc3QiOiB7CiAgICAgICAgInNoYTI1NiI6ICIwMWU3ZTRmYTcxNjg2NTM4NDQwMDEyZWUzNmEyNjM0ZGJhYTE5ZGYyZGQxNmE0NjZmNTI0MTFmYjM0OGJiYzRlIgogICAgICB9LAogICAgICAibmFtZSI6ICJiaW5hcnktbGludXgtYW1kNjQtMSIKICAgIH0sCiAgICB7CiAgICAgICJkaWdlc3QiOiB7CiAgICAgICAgInNoYTI1NiI6ICIwMmU3ZTRmYTcxNjg2NTM4NDQwMDEyZWUzNmEyNjM0ZGJhYTE5ZGYyZGQxNmE0NjZmNTI0MTFmYjM0OGJiYzRlIgogICAgICB9LAogICAgICAibmFtZSI6ICJiaW5hcnktbGludXgtYW1kNjQtMiIKICAgIH0sCiAgICB7CiAgICAgICJkaWdlc3QiOiB7CiAgICAgICAgInNoYTI1NiI6ICIwM2U3ZTRmYTcxNjg2NTM4NDQwMDEyZWUzNmEyNjM0ZGJhYTE5ZGYyZGQxNmE0NjZmNTI0MTFmYjM0OGJiYzRlIgogICAgICB9LAogICAgICAibmFtZSI6ICJiaW5hcnktbGludXgtYW1kNjQtMyIKICAgIH0KICBdCn0K",
"signatures": [
{
"keyid": "",
"sig": "MEUCIGIitQ1z1kUQEEaYdGLUtremEsfBzJyGm+Wp2t3PtzSSAiEAiibeJkqt6tTWcxbHNQqUKmtcteyH49NO8U7KiWtu+yc="
}
]
}

0 comments on commit a7f78c7

Please # to comment.