Skip to content

Commit

Permalink
Fix offline verification marshalling, add e2e tests. (#330)
Browse files Browse the repository at this point in the history
e2e verification was failing because we were using the wrong body to
recreate the tlog message.

To test this, this also adds an e2e test that verifies a real commit
only using offline verification. This is a bit brittle at the moment
because it will mutate the local TUF client state, but this will
hopefully be improved once the TUF client changes land in
sigstore/client-go.

Signed-off-by: Billy Lynch <[email protected]>
  • Loading branch information
wlynch authored Jun 6, 2023
1 parent 8f2250c commit 4bda12e
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ jobs:

- name: Unit Tests
run: make unit-test

- name: Live dependency tests
run: make e2e-test
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,8 @@ install-all: install-gitsign install-credential-cache
.PHONY: unit-test
unit-test:
go test -v ./...

# These tests use live dependencies, and may otherwise modify state.
.PHONY: e2e-test
e2e-test:
go test -tags e2e -v ./...
65 changes: 65 additions & 0 deletions internal/e2e/offline_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright 2023 The Sigstore Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build e2e
// +build e2e

package e2e

import (
"context"
"crypto/x509"
"testing"

"github.com/sigstore/gitsign/internal/fulcio/fulcioroots"
"github.com/sigstore/gitsign/internal/git/gittest"
"github.com/sigstore/gitsign/pkg/git"
"github.com/sigstore/gitsign/pkg/rekor"
"github.com/sigstore/sigstore/pkg/tuf"
)

func TestVerifyOffline(t *testing.T) {
ctx := context.Background()

// Initialize to prod root.
tuf.Initialize(ctx, tuf.DefaultRemoteRoot, nil)
root, intermediate, err := fulcioroots.New(x509.NewCertPool(), fulcioroots.FromTUF(ctx))
if err != nil {
t.Fatalf("error getting certificate root: %v", err)
}

client, err := rekor.New("https://rekor.sigstore.dev")
if err != nil {
t.Fatal(err)
}

commit := gittest.ParseCommit(t, "testdata/offline.commit")
body := gittest.MarshalCommitBody(t, commit)
sig := []byte(commit.PGPSignature)

verifier, err := git.NewCertVerifier(git.WithRootPool(root), git.WithIntermediatePool(intermediate))
if err != nil {
t.Fatal(err)
}

cert, err := verifier.Verify(ctx, body, sig, true)
if err != nil {
t.Fatal(err)
}
tlog, err := client.VerifyInclusion(ctx, sig, cert)
if err != nil {
t.Fatal(err)
}
t.Log(*tlog.LogIndex)
}
47 changes: 47 additions & 0 deletions internal/e2e/testdata/offline.commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
tree 045f683042529876c1fe28f97f416c1501ffa433
parent 74f0d242677d95a477f953260a2686712846c619
author Billy Lynch <[email protected]> 1685981477 -0400
committer Billy Lynch <[email protected]> 1685981477 -0400
gpgsig -----BEGIN SIGNED MESSAGE-----
MIIHPQYJKoZIhvcNAQcCoIIHLjCCByoCAQExDTALBglghkgBZQMEAgEwCwYJKoZI
hvcNAQcBoIIC0DCCAswwggJSoAMCAQICFAG6/a9VuUO5SlyJA02E3aCq+I7nMAoG
CCqGSM49BAMDMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2ln
c3RvcmUtaW50ZXJtZWRpYXRlMB4XDTIzMDYwNTE2MTExOVoXDTIzMDYwNTE2MjEx
OVowADBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKMghfIq5VOfOhMrxqHFiu8c
91EbkxLIDLL1kjdhbNS2EfXg7xH3Q789yMKGGWwh3PxMJ3+6tXYi62b2mWVYwOej
ggFxMIIBbTAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHQYD
VR0OBBYEFLNvhRMNCI6GVLzZjAKPQHfG+H62MB8GA1UdIwQYMBaAFN/T6c9WJBGW
+ajY6ShVosYuGGQ/MCIGA1UdEQEB/wQYMBaBFGJpbGx5QGNoYWluZ3VhcmQuZGV2
MCkGCisGAQQBg78wAQEEG2h0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbTArBgor
BgEEAYO/MAEIBB0MG2h0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbTCBiQYKKwYB
BAHWeQIEAgR7BHkAdwB1AN09MGrGxxEyYxkeHJlnNwKiSl643jyt/4eKcoAvKe6O
AAABiIxTwqMAAAQDAEYwRAIgHi+WbGvSz/kRzolvZfTodQZWomPXXVzV617mdESS
SzsCIG9lfwWn7Mh+m/EbdIIp7OxjA3av+ywcUDw1o/kSzegbMAoGCCqGSM49BAMD
A2gAMGUCMQDVOD6f+899Tiy7l+wominmzOPvkB2AZBr0OQ0JeEFeNRPuyBHrKF1l
UCupUEg9JsYCMCIR+qJqcKYkvDfrjQAnYXvuwc/lSZeLlQWCzNcZzACv14IcjklM
GA7DgiYJ6aL9tTGCBDMwggQvAgEBME8wNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2
MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUCFAG6/a9VuUO5SlyJA02E
3aCq+I7nMAsGCWCGSAFlAwQCAaBpMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEw
HAYJKoZIhvcNAQkFMQ8XDTIzMDYwNTE2MTExOVowLwYJKoZIhvcNAQkEMSIEIFVL
lVMl0NAe/AWmTBlo1LsuuVEnTnqXvagu9a1+USZ5MAoGCCqGSM49BAMCBEcwRQIg
MvJRYH8YjGI6aKjuj2BIvKtXauKmmfnTw6ftFHKHd7ICIQCtvl/bIvRutgXs2aIE
nLMhBKbUH7L3yIxCXXioSlMbbaGCAwowggMGBgorBgEEAYO/MAMBMYIC9gSCAvII
/9TuChIiCiDA0j1q1AaXP5VZ87otHKAfhBR9j/xbhEXCJPmLlZGAHRoVCgxoYXNo
ZWRyZWtvcmQSBTAuMC4xIKiS+KMGKkgKRjBEAiA2urRGPSYHNU7xitI+aOApUJy1
NoYOC+AhkrypnjFpEQIgf8+9b5Dyrut5SiCLZa9XdbyI3TjEIAFtOkpZtVObzrEy
3wQImMbwCBIgIwe35eP4Z02VSBqLyIBE1vGiNv+XuvMirTgfBSZKntsYmcbwCCIg
b8pcUOF3RAEn3Ky+i8xIkB35UCyvB9HLrnXBAbeNXSYiIDBOHEdPTzANJeEaYkQs
DHM9bIr0t1XLZY7buhOssc5HIiDIVqC3K3WpKXE5SzsayoO0znmjPcRJlswzcNNn
AR4KACIglPzBfGEElradbmop8hj8wjnhiC8SQEjpcSKPyiuNbyciIIffDga3d73Q
vvvgiTxtfGbEWjsVtYsZDrBsUtbvF7knIiA1tbjz90bJjXQVCOY8Q9SBJ09haNvU
gD4uolKhxpw1/SIg4XF+XqpJWXICWkRlRyHWQSx1Fc7Dc7HG4tF9k9nb9EUiIP4p
dv5jdzDOGD+/6oOodk2cCq4ukQkrI29bfF/p9UPFIiCtcSyYQk3g8ShNTxRLipW1
0iwYHUwKJGUY56miIL32Qyr+AQr7AXJla29yLnNpZ3N0b3JlLmRldiAtIDI2MDU3
MzY2NzA5NzI3OTQ3NDYKMTg2MjEyMDkKSXdlMzVlUDRaMDJWU0JxTHlJQkUxdkdp
TnYrWHV2TWlyVGdmQlNaS250cz0KVGltZXN0YW1wOiAxNjg1OTgxNDgwMTg3Mzc4
MzQ5CgrigJQgcmVrb3Iuc2lnc3RvcmUuZGV2IHdOSTlhakJFQWlBTTE2enROTGtN
azRtUzNqWW02TGVKLy9CdFhkV3VXZEpjd1JQMWtLeXYwUUlnSXB1Zm15MWVHNExF
TGh5RjJXbVJmVHdXbldXaGJnMzlxeE5IWWpEY0x6dz0K
-----END SIGNED MESSAGE-----

Mon Jun 5 12:11:17 EDT 2023
67 changes: 67 additions & 0 deletions internal/git/gittest/testing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright 2023 The Sigstore Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package gittest

import (
"io"
"os"
"testing"

"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/storage/memory"
)

func ParseCommit(t *testing.T, path string) *object.Commit {
raw, err := os.ReadFile(path)
if err != nil {
t.Fatalf("error reading input: %v", err)
}

storage := memory.NewStorage()
obj := storage.NewEncodedObject()
obj.SetType(plumbing.CommitObject)
w, err := obj.Writer()
if err != nil {
t.Fatalf("error getting git object writer: %v", err)
}
if _, err := w.Write(raw); err != nil {
t.Fatalf("error writing git commit: %v", err)
}

c, err := object.DecodeCommit(storage, obj)
if err != nil {
t.Fatalf("error decoding commit: %v", err)
}
return c
}

func MarshalCommitBody(t *testing.T, commit *object.Commit) []byte {
t.Helper()
storage := memory.NewStorage()
obj := storage.NewEncodedObject()
if err := commit.EncodeWithoutSignature(obj); err != nil {
t.Fatal(err)
}
r, err := obj.Reader()
if err != nil {
t.Fatal(err)
}
body, err := io.ReadAll(r)
if err != nil {
t.Fatal(err)
}

return body
}
2 changes: 1 addition & 1 deletion pkg/rekor/rekor.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ func (c *Client) VerifyInclusion(ctx context.Context, sig []byte, cert *x509.Cer
// Get HashedRekord body from the signature.
// We are assuming here that the signature has already been authenticated against the
// cert, so it is okay to rely the precomputed checksum in the SignerInfo.
message, err := si.GetMessageDigestAttribute()
message, err := si.SignedAttrs.MarshaledForVerification()
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 4bda12e

Please sign in to comment.