Skip to content

Commit

Permalink
Fix matching of tlog entries to payload
Browse files Browse the repository at this point in the history
Signed-off-by: Aditya Sirish A Yelgundhalli <[email protected]>
  • Loading branch information
adityasaky committed Oct 21, 2024
1 parent da79e4b commit ca42682
Showing 1 changed file with 24 additions and 13 deletions.
37 changes: 24 additions & 13 deletions pkg/rekor/rekor.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
"encoding/pem"
"errors"
"fmt"
"strings"

"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
Expand Down Expand Up @@ -110,12 +109,16 @@ func (c *Client) WriteMessage(ctx context.Context, message, signature []byte, ce
}

func (c *Client) get(ctx context.Context, data []byte, cert *x509.Certificate) (*models.LogEntryAnon, error) {
h := sha256.New()
h.Write(data)
hash := hex.EncodeToString(h.Sum(nil))

pem, err := cryptoutils.MarshalCertificateToPEM(cert)
if err != nil {
return nil, err
}

uuids, err := c.findTLogEntriesByPayloadAndPK(ctx, data, pem)
uuids, err := c.findTLogEntriesByPK(ctx, pem)
if err != nil {
return nil, err
}
Expand All @@ -134,7 +137,7 @@ func (c *Client) get(ctx context.Context, data []byte, cert *x509.Certificate) (

// Verify that the cert used in the tlog matches the cert
// used to sign the data.
tlogCerts, err := extractCerts(e)
tlogCerts, err := extractCertsForHash(e, hash)
if err != nil {
fmt.Println("could not extract cert", err)
continue
Expand All @@ -149,16 +152,14 @@ func (c *Client) get(ctx context.Context, data []byte, cert *x509.Certificate) (
return nil, errors.New("could not find matching tlog entry")
}

// findTLogEntriesByPayloadAndPK is roughly equivalent to cosign.FindTLogEntriesByPayload,
// but also filters by the public key used.
func (c *Client) findTLogEntriesByPayloadAndPK(ctx context.Context, payload, pubKey []byte) (uuids []string, err error) {
// findTLogEntriesByPK is roughly equivalent to cosign.FindTLogEntriesByPayload,
// but only filters by the public key used. Earlier, this filtered on both the
// payload and the public key, but returned uuids of entries that matched
// either.
func (c *Client) findTLogEntriesByPK(ctx context.Context, pubKey []byte) (uuids []string, err error) {
params := index.NewSearchIndexParamsWithContext(ctx)
params.Query = &models.SearchIndex{}

h := sha256.New()
h.Write(payload)
params.Query.Hash = fmt.Sprintf("sha256:%s", strings.ToLower(hex.EncodeToString(h.Sum(nil))))

params.Query.PublicKey = &models.SearchIndexPublicKey{
Content: strfmt.Base64(pubKey),
Format: swag.String(models.SearchIndexPublicKeyFormatX509),
Expand Down Expand Up @@ -188,9 +189,10 @@ func (c *Client) Verify(ctx context.Context, commitSHA string, cert *x509.Certif
return e, cosign.VerifyTLogEntryOffline(ctx, e, c.publicKeys)
}

// extractCerts is taken from cosign's cmd/cosign/cli/verify/verify_blob.go.
// extractCertsForHash is taken from cosign's
// cmd/cosign/cli/verify/verify_blob.go.
// TODO: Refactor this into a shared lib.
func extractCerts(e *models.LogEntryAnon) ([]*x509.Certificate, error) {
func extractCertsForHash(e *models.LogEntryAnon, hash string) ([]*x509.Certificate, error) {
b, err := base64.StdEncoding.DecodeString(e.Body.(string))
if err != nil {
return nil, err
Expand All @@ -206,14 +208,19 @@ func extractCerts(e *models.LogEntryAnon) ([]*x509.Certificate, error) {
return nil, err
}

var publicKeyB64 []byte
var (
publicKeyB64 []byte
certHash string
)
switch e := eimpl.(type) {
case *rekord_v001.V001Entry:
certHash = *e.RekordObj.Data.Hash.Value
publicKeyB64, err = e.RekordObj.Signature.PublicKey.Content.MarshalText()
if err != nil {
return nil, err
}
case *hashedrekord_v001.V001Entry:
certHash = *e.HashedRekordObj.Data.Hash.Value
publicKeyB64, err = e.HashedRekordObj.Signature.PublicKey.Content.MarshalText()
if err != nil {
return nil, err
Expand All @@ -222,6 +229,10 @@ func extractCerts(e *models.LogEntryAnon) ([]*x509.Certificate, error) {
return nil, errors.New("unexpected tlog entry type")
}

if certHash != hash {
return nil, fmt.Errorf("hashes don't match")
}

publicKey, err := base64.StdEncoding.DecodeString(string(publicKeyB64))
if err != nil {
return nil, err
Expand Down

0 comments on commit ca42682

Please sign in to comment.