Skip to content

Commit 52c099b

Browse files
feat: Add support for DSSE Rekor type (#742)
This is in preparation for switching over the Rekor entry type in the slsa github generator to be the newer DSSE type. This adds support for searching for both intoto v001 and dsse v001 entries. Signed-off-by: Hayden Blauzvern <[email protected]>
1 parent bb41cb6 commit 52c099b

File tree

1 file changed

+41
-23
lines changed

1 file changed

+41
-23
lines changed

verifiers/internal/gha/rekor.go

+41-23
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,21 @@ import (
1515

1616
cjson "github.com/docker/go/canonical/json"
1717
"github.com/go-openapi/runtime"
18-
"github.com/go-openapi/strfmt"
19-
"github.com/go-openapi/swag"
2018
"github.com/sigstore/cosign/v2/pkg/cosign"
2119
"github.com/sigstore/rekor/pkg/generated/client"
2220
"github.com/sigstore/rekor/pkg/generated/client/entries"
2321
"github.com/sigstore/rekor/pkg/generated/client/index"
2422
"github.com/sigstore/rekor/pkg/generated/models"
2523
"github.com/sigstore/rekor/pkg/sharding"
2624
"github.com/sigstore/rekor/pkg/types"
27-
intotod "github.com/sigstore/rekor/pkg/types/intoto/v0.0.1"
25+
"github.com/sigstore/rekor/pkg/types/dsse"
26+
dsse_v001 "github.com/sigstore/rekor/pkg/types/dsse/v0.0.1"
27+
"github.com/sigstore/rekor/pkg/types/intoto"
28+
intoto_v001 "github.com/sigstore/rekor/pkg/types/intoto/v0.0.1"
2829
rverify "github.com/sigstore/rekor/pkg/verify"
2930
"github.com/sigstore/sigstore/pkg/cryptoutils"
3031
"github.com/sigstore/sigstore/pkg/signature"
31-
"github.com/sigstore/sigstore/pkg/signature/dsse"
32+
dsseverifier "github.com/sigstore/sigstore/pkg/signature/dsse"
3233
"github.com/slsa-framework/slsa-github-generator/signing/envelope"
3334

3435
serrors "github.com/slsa-framework/slsa-verifier/v2/errors"
@@ -123,14 +124,19 @@ func extractCert(e *models.LogEntryAnon) (*x509.Certificate, error) {
123124

124125
var publicKeyB64 []byte
125126
switch e := eimpl.(type) {
126-
case *intotod.V001Entry:
127+
case *intoto_v001.V001Entry:
127128
publicKeyB64, err = e.IntotoObj.PublicKey.MarshalText()
128-
if err != nil {
129-
return nil, err
129+
case *dsse_v001.V001Entry:
130+
if len(e.DSSEObj.Signatures) > 1 {
131+
return nil, errors.New("multiple signatures on DSSE envelopes are not currently supported")
130132
}
133+
publicKeyB64, err = e.DSSEObj.Signatures[0].Verifier.MarshalText()
131134
default:
132135
return nil, errors.New("unexpected tlog entry type")
133136
}
137+
if err != nil {
138+
return nil, err
139+
}
134140

135141
publicKey, err := base64.StdEncoding.DecodeString(string(publicKeyB64))
136142
if err != nil {
@@ -149,19 +155,31 @@ func extractCert(e *models.LogEntryAnon) (*x509.Certificate, error) {
149155
return certs[0], err
150156
}
151157

152-
func intotoEntry(certPem, provenance []byte) (*intotod.V001Entry, error) {
158+
func intotoEntry(certPem, provenance []byte) (models.ProposedEntry, error) {
153159
if len(certPem) == 0 {
154160
return nil, fmt.Errorf("no signing certificate found in intoto envelope")
155161
}
156-
cert := strfmt.Base64(certPem)
157-
return &intotod.V001Entry{
158-
IntotoObj: models.IntotoV001Schema{
159-
Content: &models.IntotoV001SchemaContent{
160-
Envelope: string(provenance),
161-
},
162-
PublicKey: &cert,
163-
},
164-
}, nil
162+
var pubKeyBytes [][]byte
163+
pubKeyBytes = append(pubKeyBytes, certPem)
164+
165+
return types.NewProposedEntry(context.Background(), intoto.KIND, intoto_v001.APIVERSION, types.ArtifactProperties{
166+
ArtifactBytes: provenance,
167+
PublicKeyBytes: pubKeyBytes,
168+
})
169+
}
170+
171+
func dsseEntry(certPem, provenance []byte) (models.ProposedEntry, error) {
172+
if len(certPem) == 0 {
173+
return nil, fmt.Errorf("no signing certificate found in intoto envelope")
174+
}
175+
176+
var pubKeyBytes [][]byte
177+
pubKeyBytes = append(pubKeyBytes, certPem)
178+
179+
return types.NewProposedEntry(context.Background(), dsse.KIND, dsse_v001.APIVERSION, types.ArtifactProperties{
180+
ArtifactBytes: provenance,
181+
PublicKeyBytes: pubKeyBytes,
182+
})
165183
}
166184

167185
// getUUIDsByArtifactDigest finds all entry UUIDs by the digest of the artifact binary.
@@ -195,15 +213,15 @@ func GetValidSignedAttestationWithCert(rClient *client.Rekor,
195213
return nil, fmt.Errorf("error getting certificate from provenance: %w", err)
196214
}
197215

198-
e, err := intotoEntry(certPem, provenance)
216+
intotoEntry, err := intotoEntry(certPem, provenance)
199217
if err != nil {
200218
return nil, fmt.Errorf("error creating intoto entry: %w", err)
201219
}
202-
entry := models.Intoto{
203-
APIVersion: swag.String(e.APIVersion()),
204-
Spec: e.IntotoObj,
220+
dsseEntry, err := dsseEntry(certPem, provenance)
221+
if err != nil {
222+
return nil, err
205223
}
206-
searchLogQuery.SetEntries([]models.ProposedEntry{&entry})
224+
searchLogQuery.SetEntries([]models.ProposedEntry{intotoEntry, dsseEntry})
207225

208226
params.SetEntry(&searchLogQuery)
209227
resp, err := rClient.Entries.SearchLogQuery(params)
@@ -347,7 +365,7 @@ func verifySignedAttestation(signedAtt *SignedAttestation, trustedRoot *TrustedR
347365
}
348366

349367
// 2. Verify signature using validated certificate.
350-
verifier = dsse.WrapVerifier(verifier)
368+
verifier = dsseverifier.WrapVerifier(verifier)
351369
if err := verifier.VerifySignature(bytes.NewReader(attBytes), bytes.NewReader(attBytes)); err != nil {
352370
return fmt.Errorf("%w: %s", serrors.ErrorInvalidSignature, err)
353371
}

0 commit comments

Comments
 (0)