Skip to content

Commit

Permalink
cliplugin: semver, add tests for hash func encoding (sigstore#1948)
Browse files Browse the repository at this point in the history
Adds tests against know hash func and their JSON encoding.
The current set of hash funcs and their encoding has not changed in ~8 years, but they might change in the future, since they are ordered by iota.

https://cs.opensource.google/go/go/+/refs/tags/go1.23.5:src/crypto/crypto.go;l=68-89;bpv=0
This PR

adds a test that can give us a warning if and when they do change, and we would likely need a major version bump of the protocol version.
adds semver to the plugin protocol version at "v1".

Signed-off-by: Ramon Petgrave <ramon.petgrave64@gmail.com>
  • Loading branch information
ramonpetgrave64 authored Feb 6, 2025
1 parent c5b7d21 commit 67bd820
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 9 deletions.
3 changes: 1 addition & 2 deletions pkg/signature/kms/cliplugin/common/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ const (
// Breaking changes to the PluginClient and this schema necessarily mean major version bumps of
// this ProtocolVersion and the sigstore version.
// Plugin authors may choose to be backwards compatible with older versions.
// TODO: change this to be semver compatible, like v1, or v1.0.0.
ProtocolVersion = "1"
ProtocolVersion = "v1"
DefaultAlgorithmMethodName = "defaultAlgorithm"
SupportedAlgorithmsMethodName = "supportedAlgorithms"
CreateKeyMethodName = "createKey"
Expand Down
117 changes: 111 additions & 6 deletions pkg/signature/kms/cliplugin/common/interface_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package common
import (
"crypto"
"encoding/json"
"strconv"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -71,7 +72,7 @@ func TestPluginArgsJSON(t *testing.T) {
want: `{
"initOptions": {
"ctxDeadline": "2025-04-01T02:47:00Z",
"protocolVersion": "1",
"protocolVersion": "v1",
"keyResourceID": "testkms://testkey",
"hashFunc": 17,
"rpcOptions": {
Expand All @@ -96,7 +97,7 @@ func TestPluginArgsJSON(t *testing.T) {
want: `{
"initOptions": {
"ctxDeadline": "2025-04-01T02:47:00Z",
"protocolVersion": "1",
"protocolVersion": "v1",
"keyResourceID": "testkms://testkey",
"hashFunc": 17,
"rpcOptions": {
Expand Down Expand Up @@ -124,7 +125,7 @@ func TestPluginArgsJSON(t *testing.T) {
want: `{
"initOptions": {
"ctxDeadline": "2025-04-01T02:47:00Z",
"protocolVersion": "1",
"protocolVersion": "v1",
"keyResourceID": "testkms://testkey",
"hashFunc": 17,
"rpcOptions": {
Expand Down Expand Up @@ -160,7 +161,7 @@ func TestPluginArgsJSON(t *testing.T) {
want: `{
"initOptions": {
"ctxDeadline": "2025-04-01T02:47:00Z",
"protocolVersion": "1",
"protocolVersion": "v1",
"keyResourceID": "testkms://testkey",
"hashFunc": 17,
"rpcOptions": {
Expand Down Expand Up @@ -205,7 +206,7 @@ func TestPluginArgsJSON(t *testing.T) {
want: `{
"initOptions": {
"ctxDeadline": "2025-04-01T02:47:00Z",
"protocolVersion": "1",
"protocolVersion": "v1",
"keyResourceID": "testkms://testkey",
"hashFunc": 17,
"rpcOptions": {
Expand Down Expand Up @@ -255,7 +256,7 @@ func TestPluginArgsJSON(t *testing.T) {
want: `{
"initOptions": {
"ctxDeadline": "2025-04-01T02:47:00Z",
"protocolVersion": "1",
"protocolVersion": "v1",
"keyResourceID": "testkms://testkey",
"hashFunc": 17,
"rpcOptions": {
Expand Down Expand Up @@ -416,3 +417,107 @@ func TestPluginRespJSON(t *testing.T) {
})
}
}

// TestHashFuncJSON ensures that some of our well-known hashfuncs consistently encode to known int values.
// just in case the order of thoe iota changes in the future. If this test fails, then we likely need a new protocol version.
// See iota values at https://pkg.go.dev/crypto@go1.23.5#Hash.
func TestHashFuncJSON(t *testing.T) {
t.Parallel()

tests := []struct {
hash crypto.Hash
wantInt int
}{
// all know crypto.HASH
{
crypto.MD4,
1,
},
{
crypto.MD5,
2,
},
{
crypto.SHA1,
3,
},
{
crypto.SHA224,
4,
},
{
crypto.SHA256,
5,
},
{
crypto.SHA384,
6,
},
{
crypto.SHA512,
7,
},
{
crypto.MD5SHA1,
8,
},
{
crypto.RIPEMD160,
9,
},
{
crypto.SHA3_224,
10,
},
{
crypto.SHA3_256,
11,
},
{
crypto.SHA3_384,
12,
},
{
crypto.SHA3_512,
13,
},
{
crypto.SHA512_224,
14,
},
{
crypto.SHA512_256,
15,
},
{
crypto.BLAKE2s_256,
16,
},
{
crypto.BLAKE2b_256,
17,
},
{
crypto.BLAKE2b_384,
18,
},
{
crypto.BLAKE2b_512,
19,
},
}
for _, tc := range tests {
t.Run(tc.hash.String(), func(t *testing.T) {
t.Parallel()

got, err := json.Marshal(tc.hash)
if err != nil {
t.Errorf("marshaling hash %s: %v", tc.hash.String(), err)
}
want := []byte(strconv.Itoa(tc.wantInt))
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("unexpected JSON (-want +got): \n%s", diff)
}
})
}
}
3 changes: 2 additions & 1 deletion test/cliplugin/localkms/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import (
"github.com/sigstore/sigstore/pkg/signature/kms/cliplugin/handler"
)

const expectedProtocolVersion = "1"
// See cliplugin.common.ProtocolVersion
const expectedProtocolVersion = "v1"

func main() {
// we log to stderr, not stdout. stdout is reserved for the plugin return value.
Expand Down

0 comments on commit 67bd820

Please sign in to comment.