From ad5157af7faac9149d11a51eb6a6b7f880944036 Mon Sep 17 00:00:00 2001 From: Max Lambrecht Date: Sat, 22 Jun 2024 09:42:16 -0500 Subject: [PATCH 1/5] Set bundleVerified to true after Rekor verification (Resolves #3740) Signed-off-by: Max Lambrecht --- pkg/cosign/verify.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/cosign/verify.go b/pkg/cosign/verify.go index abd551d8028..3ab5d76026a 100644 --- a/pkg/cosign/verify.go +++ b/pkg/cosign/verify.go @@ -710,6 +710,7 @@ func verifyInternal(ctx context.Context, sig oci.Signature, h v1.Hash, } t := time.Unix(*e.IntegratedTime, 0) acceptableRekorBundleTime = &t + bundleVerified = true } } From 8372f1a0691f626e9184b903bc57b8f62b2de71b Mon Sep 17 00:00:00 2001 From: Max Lambrecht Date: Sat, 29 Jun 2024 17:56:02 -0500 Subject: [PATCH 2/5] Add TestImageSignatureVerificationWithRekor Signed-off-by: Max Lambrecht --- pkg/cosign/verify_test.go | 233 +++++++++++++++++++++++++++++++++----- 1 file changed, 203 insertions(+), 30 deletions(-) diff --git a/pkg/cosign/verify_test.go b/pkg/cosign/verify_test.go index 03d88842d4e..27992f80a6b 100644 --- a/pkg/cosign/verify_test.go +++ b/pkg/cosign/verify_test.go @@ -18,6 +18,7 @@ import ( "bytes" "context" "crypto" + "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/rsa" @@ -38,6 +39,7 @@ import ( "github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer" "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/in-toto/in-toto-golang/in_toto" "github.com/secure-systems-lab/go-securesystemslib/dsse" @@ -51,12 +53,15 @@ import ( "github.com/sigstore/cosign/v2/pkg/types" "github.com/sigstore/cosign/v2/test" "github.com/sigstore/rekor/pkg/generated/client" + "github.com/sigstore/rekor/pkg/generated/client/entries" "github.com/sigstore/rekor/pkg/generated/models" rtypes "github.com/sigstore/rekor/pkg/types" + hashedrekord_v001 "github.com/sigstore/rekor/pkg/types/hashedrekord/v0.0.1" "github.com/sigstore/sigstore/pkg/cryptoutils" "github.com/sigstore/sigstore/pkg/signature" "github.com/sigstore/sigstore/pkg/signature/options" "github.com/sigstore/sigstore/pkg/tuf" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/transparency-dev/merkle/rfc6962" ) @@ -524,41 +529,131 @@ func uuid(e models.LogEntryAnon) string { return hex.EncodeToString(rfc6962.DefaultHasher.HashLeaf(entryBytes)) } -// This test ensures that image signature validation fails properly if we are -// using a SigVerifier with Rekor. -// In other words, we require checking against RekorPubKeys when verifying -// image signature. -// This could be made more robust with supplying a mismatched trusted RekorPubKeys -// rather than none. -// See https://github.com/sigstore/cosign/v2/issues/1816 for more details. -func TestVerifyImageSignatureWithSigVerifierAndRekor(t *testing.T) { - sv, privKey, err := signature.NewDefaultECDSASignerVerifier() - if err != nil { - t.Fatalf("error generating verifier: %v", err) +func TestImageSignatureVerificationWithRekor(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + // Generate signer and public key + privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + require.NoError(t, err, "error generating private key") + + signer, err := signature.LoadECDSASignerVerifier(privateKey, crypto.SHA256) + require.NoError(t, err, "error loading signer") + + publicKey, err := signer.PublicKey() + require.NoError(t, err, "error getting public key") + publicKeyPEM, err := cryptoutils.MarshalPublicKeyToPEM(publicKey) + require.NoError(t, err, "error marshalling public key to PEM") + + blob := []byte("foo") + blobSignature, err := signer.SignMessage(bytes.NewReader(blob)) + require.NoError(t, err, "error signing blob") + blobSignatureBase64 := base64.StdEncoding.EncodeToString(blobSignature) + + ociSignature, err := static.NewSignature(blob, blobSignatureBase64) + require.NoError(t, err, "error creating OCI signature") + + // Mock Rekor entry setup + rekorPrivateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + require.NoError(t, err, "error generating Rekor private key") + + rekorSigner, err := signature.LoadECDSASignerVerifier(rekorPrivateKey, crypto.SHA256) + require.NoError(t, err, "error loading Rekor signer") + + rekorPublicKey := rekorPrivateKey.Public().(*ecdsa.PublicKey) + logID, err := calculateLogID(rekorPublicKey) + require.NoError(t, err, "error calculating Rekor log ID") + + rekorEntry := createRekorEntry(t, ctx, logID, rekorSigner, blob, blobSignature, publicKeyPEM) + + mockClient := &client.Rekor{ + Entries: &mockEntriesClient{ + searchLogQueryFunc: func(params *entries.SearchLogQueryParams, opts ...entries.ClientOption) (*entries.SearchLogQueryOK, error) { + return &entries.SearchLogQueryOK{ + Payload: []models.LogEntry{*rekorEntry}, + }, nil + }, + }, } - payload := []byte{1, 2, 3, 4} - h := sha256.Sum256(payload) - sig, _ := privKey.Sign(rand.Reader, h[:], crypto.SHA256) - ociSig, _ := static.NewSignature(payload, base64.StdEncoding.EncodeToString(sig)) + // Mock Rekor public key + trustedRekorPubKeys := &TrustedTransparencyLogPubKeys{ + Keys: map[string]TransparencyLogPubKey{ + logID: { + PubKey: rekorPublicKey, + Status: tuf.Active, + }, + }, + } - // Add a fake rekor client - this makes it look like there's a matching - // tlog entry for the signature during validation (even though it does not - // match the underlying data / key) - mClient := new(client.Rekor) - mClient.Entries = &mock.EntriesClient{ - Entries: []*models.LogEntry{&data}, + // Non-matching Rekor public key + nonMatchingPrivateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + require.NoError(t, err, "error generating invalid private key") + nonMatchingPublicKey := nonMatchingPrivateKey.Public().(*ecdsa.PublicKey) + + nonMatchingRekorPubKeys := &TrustedTransparencyLogPubKeys{ + Keys: map[string]TransparencyLogPubKey{ + logID: { + PubKey: nonMatchingPublicKey, + Status: tuf.Active, + }, + }, } - if _, err := VerifyImageSignature(context.TODO(), ociSig, v1.Hash{}, &CheckOpts{ - SigVerifier: sv, - RekorClient: mClient, - Identities: []Identity{{Subject: "subject@mail.com", Issuer: "oidc-issuer"}}, - }); err == nil || !strings.Contains(err.Error(), "no valid tlog entries found no trusted rekor public keys provided") { - // This is failing to validate the Rekor public key itself. - // At the very least this ensures - // that we're hitting tlog validation during signature checking. - t.Fatalf("expected error while verifying signature, got %s", err) + tests := []struct { + name string + checkOpts CheckOpts + rekorClient *client.Rekor + expectError bool + errorMsg string + }{ + { + name: "Verification succeeds with valid Rekor public keys", + checkOpts: CheckOpts{ + SigVerifier: signer, + RekorClient: mockClient, + RekorPubKeys: trustedRekorPubKeys, + Identities: []Identity{{Subject: "subject@mail.com", Issuer: "oidc-issuer"}}, + }, + rekorClient: mockClient, + expectError: false, + }, + { + name: "Verification fails with no Rekor public keys", + checkOpts: CheckOpts{ + SigVerifier: signer, + RekorClient: mockClient, + Identities: []Identity{{Subject: "subject@mail.com", Issuer: "oidc-issuer"}}, + }, + rekorClient: mockClient, + expectError: true, + errorMsg: "no valid tlog entries found no trusted rekor public keys provided", + }, + { + name: "Verification fails with non-matching Rekor public keys", + checkOpts: CheckOpts{ + SigVerifier: signer, + RekorClient: mockClient, + RekorPubKeys: nonMatchingRekorPubKeys, + Identities: []Identity{{Subject: "subject@mail.com", Issuer: "oidc-issuer"}}, + }, + rekorClient: mockClient, + expectError: true, + errorMsg: "verifying signedEntryTimestamp: unable to verify SET", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + bundleVerified, err := VerifyImageSignature(ctx, ociSignature, v1.Hash{}, &tt.checkOpts) + if tt.expectError { + assert.Error(t, err) + assert.Contains(t, err.Error(), tt.errorMsg) + } else { + assert.NoError(t, err) + assert.True(t, bundleVerified, "bundle verification failed") + } + }) } } @@ -1499,3 +1594,81 @@ func TestVerifyRFC3161Timestamp(t *testing.T) { t.Fatalf("expected error verifying without a root certificate, got: %v", err) } } + +// Mock Rekor client +type mockEntriesClient struct { + entries.ClientService + searchLogQueryFunc func(params *entries.SearchLogQueryParams, opts ...entries.ClientOption) (*entries.SearchLogQueryOK, error) +} + +func (m *mockEntriesClient) SearchLogQuery(params *entries.SearchLogQueryParams, opts ...entries.ClientOption) (*entries.SearchLogQueryOK, error) { + if m.searchLogQueryFunc != nil { + return m.searchLogQueryFunc(params, opts...) + } + return nil, nil +} + +func createRekorEntry(t *testing.T, ctx context.Context, logID string, rekorSigner signature.SignerVerifier, payload, signature, publicKeyPEM []byte) *models.LogEntry { + hashedRekorEntry := &hashedrekord_v001.V001Entry{} + payloadHash := sha256.Sum256(payload) + + artifactProperties := rtypes.ArtifactProperties{ + ArtifactHash: hex.EncodeToString(payloadHash[:]), + SignatureBytes: signature, + PublicKeyBytes: [][]byte{publicKeyPEM}, + PKIFormat: "x509", + } + + entryProps, err := hashedRekorEntry.CreateFromArtifactProperties(ctx, artifactProperties) + require.NoError(t, err) + + rekorEntry, err := rtypes.UnmarshalEntry(entryProps) + require.NoError(t, err) + + canonicalEntry, err := rekorEntry.Canonicalize(ctx) + require.NoError(t, err) + + integratedTime := time.Now() + certificates, _ := cryptoutils.UnmarshalCertificatesFromPEM(publicKeyPEM) + if len(certificates) > 0 { + integratedTime = certificates[0].NotAfter.Add(-1 * time.Second) + } + + logEntry := models.LogEntryAnon{ + Body: base64.StdEncoding.EncodeToString(canonicalEntry), + IntegratedTime: swag.Int64(integratedTime.Unix()), + LogIndex: swag.Int64(0), + LogID: swag.String(logID), + } + + jsonLogEntry, err := json.Marshal(logEntry) + require.NoError(t, err) + + canonicalPayload, err := jsoncanonicalizer.Transform(jsonLogEntry) + require.NoError(t, err) + + signedEntryTimestamp, err := rekorSigner.SignMessage(bytes.NewReader(canonicalPayload)) + require.NoError(t, err) + + entryUUID, _ := ComputeLeafHash(&logEntry) + + logEntry.Verification = &models.LogEntryAnonVerification{ + SignedEntryTimestamp: signedEntryTimestamp, + InclusionProof: &models.InclusionProof{ + LogIndex: swag.Int64(0), + TreeSize: swag.Int64(1), + RootHash: swag.String(hex.EncodeToString(entryUUID)), + Hashes: []string{}, + }, + } + return &models.LogEntry{hex.EncodeToString(entryUUID): logEntry} +} + +func calculateLogID(pub crypto.PublicKey) (string, error) { + pubBytes, err := x509.MarshalPKIXPublicKey(pub) + if err != nil { + return "", err + } + digest := sha256.Sum256(pubBytes) + return hex.EncodeToString(digest[:]), nil +} From c502e84c11d3edd10df8a265b68e3e8791bcebde Mon Sep 17 00:00:00 2001 From: Max Lambrecht Date: Sat, 29 Jun 2024 18:44:27 -0500 Subject: [PATCH 3/5] Fix lint issues Signed-off-by: Max Lambrecht --- pkg/cosign/verify_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/cosign/verify_test.go b/pkg/cosign/verify_test.go index 27992f80a6b..5d09953dc78 100644 --- a/pkg/cosign/verify_test.go +++ b/pkg/cosign/verify_test.go @@ -564,11 +564,11 @@ func TestImageSignatureVerificationWithRekor(t *testing.T) { logID, err := calculateLogID(rekorPublicKey) require.NoError(t, err, "error calculating Rekor log ID") - rekorEntry := createRekorEntry(t, ctx, logID, rekorSigner, blob, blobSignature, publicKeyPEM) + rekorEntry := createRekorEntry(ctx, t, logID, rekorSigner, blob, blobSignature, publicKeyPEM) mockClient := &client.Rekor{ Entries: &mockEntriesClient{ - searchLogQueryFunc: func(params *entries.SearchLogQueryParams, opts ...entries.ClientOption) (*entries.SearchLogQueryOK, error) { + searchLogQueryFunc: func(_ *entries.SearchLogQueryParams, _ ...entries.ClientOption) (*entries.SearchLogQueryOK, error) { return &entries.SearchLogQueryOK{ Payload: []models.LogEntry{*rekorEntry}, }, nil @@ -1608,7 +1608,7 @@ func (m *mockEntriesClient) SearchLogQuery(params *entries.SearchLogQueryParams, return nil, nil } -func createRekorEntry(t *testing.T, ctx context.Context, logID string, rekorSigner signature.SignerVerifier, payload, signature, publicKeyPEM []byte) *models.LogEntry { +func createRekorEntry(ctx context.Context, t *testing.T, logID string, rekorSigner signature.SignerVerifier, payload, signature, publicKeyPEM []byte) *models.LogEntry { hashedRekorEntry := &hashedrekord_v001.V001Entry{} payloadHash := sha256.Sum256(payload) From ac765d2a27d2fec9d529454ed6bdffb0369b0b5d Mon Sep 17 00:00:00 2001 From: Max Lambrecht Date: Mon, 1 Jul 2024 11:05:26 -0500 Subject: [PATCH 4/5] Improve TestImageSignatureVerificationWithRekor Signed-off-by: Max Lambrecht --- pkg/cosign/verify_test.go | 96 ++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/pkg/cosign/verify_test.go b/pkg/cosign/verify_test.go index 5d09953dc78..1b5274c75dc 100644 --- a/pkg/cosign/verify_test.go +++ b/pkg/cosign/verify_test.go @@ -533,39 +533,22 @@ func TestImageSignatureVerificationWithRekor(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - // Generate signer and public key - privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - require.NoError(t, err, "error generating private key") - - signer, err := signature.LoadECDSASignerVerifier(privateKey, crypto.SHA256) - require.NoError(t, err, "error loading signer") - - publicKey, err := signer.PublicKey() - require.NoError(t, err, "error getting public key") - publicKeyPEM, err := cryptoutils.MarshalPublicKeyToPEM(publicKey) - require.NoError(t, err, "error marshalling public key to PEM") - - blob := []byte("foo") - blobSignature, err := signer.SignMessage(bytes.NewReader(blob)) - require.NoError(t, err, "error signing blob") - blobSignatureBase64 := base64.StdEncoding.EncodeToString(blobSignature) + // Generate ECDSA signer and public key for signing the blob. + signer, publicKey := generateSigner(t) + blob, blobSignature, blobSignatureBase64 := generateBlobSignature(t, signer) + // Create an OCI signature which will be verified. ociSignature, err := static.NewSignature(blob, blobSignatureBase64) require.NoError(t, err, "error creating OCI signature") - // Mock Rekor entry setup - rekorPrivateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - require.NoError(t, err, "error generating Rekor private key") - - rekorSigner, err := signature.LoadECDSASignerVerifier(rekorPrivateKey, crypto.SHA256) - require.NoError(t, err, "error loading Rekor signer") - - rekorPublicKey := rekorPrivateKey.Public().(*ecdsa.PublicKey) - logID, err := calculateLogID(rekorPublicKey) - require.NoError(t, err, "error calculating Rekor log ID") + // Set up mock Rekor signer and log ID. + rekorSigner, rekorPublicKey := generateSigner(t) + logID := calculateLogID(t, rekorPublicKey) - rekorEntry := createRekorEntry(ctx, t, logID, rekorSigner, blob, blobSignature, publicKeyPEM) + // Create a mock Rekor log entry to simulate Rekor behavior. + rekorEntry := createRekorEntry(ctx, t, logID, rekorSigner, blob, blobSignature, publicKey) + // Mock Rekor client to return the mock log entry for verification. mockClient := &client.Rekor{ Entries: &mockEntriesClient{ searchLogQueryFunc: func(_ *entries.SearchLogQueryParams, _ ...entries.ClientOption) (*entries.SearchLogQueryOK, error) { @@ -576,7 +559,7 @@ func TestImageSignatureVerificationWithRekor(t *testing.T) { }, } - // Mock Rekor public key + // Define trusted Rekor public keys for verification. trustedRekorPubKeys := &TrustedTransparencyLogPubKeys{ Keys: map[string]TransparencyLogPubKey{ logID: { @@ -586,11 +569,8 @@ func TestImageSignatureVerificationWithRekor(t *testing.T) { }, } - // Non-matching Rekor public key - nonMatchingPrivateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - require.NoError(t, err, "error generating invalid private key") - nonMatchingPublicKey := nonMatchingPrivateKey.Public().(*ecdsa.PublicKey) - + // Generate non-matching public key for failure test cases. + _, nonMatchingPublicKey := generateSigner(t) nonMatchingRekorPubKeys := &TrustedTransparencyLogPubKeys{ Keys: map[string]TransparencyLogPubKey{ logID: { @@ -1608,14 +1588,18 @@ func (m *mockEntriesClient) SearchLogQuery(params *entries.SearchLogQueryParams, return nil, nil } -func createRekorEntry(ctx context.Context, t *testing.T, logID string, rekorSigner signature.SignerVerifier, payload, signature, publicKeyPEM []byte) *models.LogEntry { +// createRekorEntry creates a mock Rekor log entry. +func createRekorEntry(ctx context.Context, t *testing.T, logID string, signer signature.Signer, payload, signature []byte, publicKey crypto.PublicKey) *models.LogEntry { hashedRekorEntry := &hashedrekord_v001.V001Entry{} payloadHash := sha256.Sum256(payload) + publicKeyBytes, err := cryptoutils.MarshalPublicKeyToPEM(publicKey) + require.NoError(t, err) + artifactProperties := rtypes.ArtifactProperties{ ArtifactHash: hex.EncodeToString(payloadHash[:]), SignatureBytes: signature, - PublicKeyBytes: [][]byte{publicKeyPEM}, + PublicKeyBytes: [][]byte{publicKeyBytes}, PKIFormat: "x509", } @@ -1629,11 +1613,6 @@ func createRekorEntry(ctx context.Context, t *testing.T, logID string, rekorSign require.NoError(t, err) integratedTime := time.Now() - certificates, _ := cryptoutils.UnmarshalCertificatesFromPEM(publicKeyPEM) - if len(certificates) > 0 { - integratedTime = certificates[0].NotAfter.Add(-1 * time.Second) - } - logEntry := models.LogEntryAnon{ Body: base64.StdEncoding.EncodeToString(canonicalEntry), IntegratedTime: swag.Int64(integratedTime.Unix()), @@ -1647,10 +1626,11 @@ func createRekorEntry(ctx context.Context, t *testing.T, logID string, rekorSign canonicalPayload, err := jsoncanonicalizer.Transform(jsonLogEntry) require.NoError(t, err) - signedEntryTimestamp, err := rekorSigner.SignMessage(bytes.NewReader(canonicalPayload)) + signedEntryTimestamp, err := signer.SignMessage(bytes.NewReader(canonicalPayload)) require.NoError(t, err) - entryUUID, _ := ComputeLeafHash(&logEntry) + entryUUID, err := ComputeLeafHash(&logEntry) + require.NoError(t, err) logEntry.Verification = &models.LogEntryAnonVerification{ SignedEntryTimestamp: signedEntryTimestamp, @@ -1664,11 +1644,33 @@ func createRekorEntry(ctx context.Context, t *testing.T, logID string, rekorSign return &models.LogEntry{hex.EncodeToString(entryUUID): logEntry} } -func calculateLogID(pub crypto.PublicKey) (string, error) { +// generateSigner creates an ECDSA signer and public key. +func generateSigner(t *testing.T) (signature.SignerVerifier, crypto.PublicKey) { + privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + require.NoError(t, err, "error generating private key") + + signer, err := signature.LoadECDSASignerVerifier(privateKey, crypto.SHA256) + require.NoError(t, err, "error loading signer") + + publicKey, err := signer.PublicKey() + require.NoError(t, err, "error getting public key") + + return signer, publicKey +} + +// generateBlobSignature signs a blob and returns the blob, its signature, and the base64-encoded signature. +func generateBlobSignature(t *testing.T, signer signature.Signer) ([]byte, []byte, string) { + blob := []byte("foo") + blobSignature, err := signer.SignMessage(bytes.NewReader(blob)) + require.NoError(t, err, "error signing blob") + blobSignatureBase64 := base64.StdEncoding.EncodeToString(blobSignature) + return blob, blobSignature, blobSignatureBase64 +} + +// calculateLogID generates a SHA-256 hash of the given public key and returns it as a hexadecimal string. +func calculateLogID(t *testing.T, pub crypto.PublicKey) string { pubBytes, err := x509.MarshalPKIXPublicKey(pub) - if err != nil { - return "", err - } + require.NoError(t, err, "error marshalling public key") digest := sha256.Sum256(pubBytes) - return hex.EncodeToString(digest[:]), nil + return hex.EncodeToString(digest[:]) } From b62e437b690a75856632029361e902f94b47df53 Mon Sep 17 00:00:00 2001 From: Max Lambrecht Date: Mon, 1 Jul 2024 11:16:24 -0500 Subject: [PATCH 5/5] Add comments to test functions Signed-off-by: Max Lambrecht --- pkg/cosign/verify_test.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/pkg/cosign/verify_test.go b/pkg/cosign/verify_test.go index 1b5274c75dc..30586d4a759 100644 --- a/pkg/cosign/verify_test.go +++ b/pkg/cosign/verify_test.go @@ -1590,7 +1590,6 @@ func (m *mockEntriesClient) SearchLogQuery(params *entries.SearchLogQueryParams, // createRekorEntry creates a mock Rekor log entry. func createRekorEntry(ctx context.Context, t *testing.T, logID string, signer signature.Signer, payload, signature []byte, publicKey crypto.PublicKey) *models.LogEntry { - hashedRekorEntry := &hashedrekord_v001.V001Entry{} payloadHash := sha256.Sum256(payload) publicKeyBytes, err := cryptoutils.MarshalPublicKeyToPEM(publicKey) @@ -1603,7 +1602,8 @@ func createRekorEntry(ctx context.Context, t *testing.T, logID string, signer si PKIFormat: "x509", } - entryProps, err := hashedRekorEntry.CreateFromArtifactProperties(ctx, artifactProperties) + // Create and canonicalize Rekor entry + entryProps, err := hashedrekord_v001.V001Entry{}.CreateFromArtifactProperties(ctx, artifactProperties) require.NoError(t, err) rekorEntry, err := rtypes.UnmarshalEntry(entryProps) @@ -1612,14 +1612,16 @@ func createRekorEntry(ctx context.Context, t *testing.T, logID string, signer si canonicalEntry, err := rekorEntry.Canonicalize(ctx) require.NoError(t, err) - integratedTime := time.Now() + // Create log entry + integratedTime := time.Now().Unix() logEntry := models.LogEntryAnon{ Body: base64.StdEncoding.EncodeToString(canonicalEntry), - IntegratedTime: swag.Int64(integratedTime.Unix()), + IntegratedTime: swag.Int64(integratedTime), LogIndex: swag.Int64(0), LogID: swag.String(logID), } + // Canonicalize the log entry and sign it jsonLogEntry, err := json.Marshal(logEntry) require.NoError(t, err) @@ -1629,6 +1631,7 @@ func createRekorEntry(ctx context.Context, t *testing.T, logID string, signer si signedEntryTimestamp, err := signer.SignMessage(bytes.NewReader(canonicalPayload)) require.NoError(t, err) + // Calculate leaf hash and add verification entryUUID, err := ComputeLeafHash(&logEntry) require.NoError(t, err) @@ -1641,6 +1644,8 @@ func createRekorEntry(ctx context.Context, t *testing.T, logID string, signer si Hashes: []string{}, }, } + + // Return the constructed log entry return &models.LogEntry{hex.EncodeToString(entryUUID): logEntry} }