From 47486c21d409b9562bb22ee4b040a236705db6db Mon Sep 17 00:00:00 2001
From: dlorenc <dlorenc@google.com>
Date: Wed, 22 Dec 2021 15:59:55 -0600
Subject: [PATCH] Fix a bug in minisign canonicalization. (#562)

We were previously stripping off the keyid/algorithm identifiers in minisign public keys.
These should be included in here to properly canonicalize/reconstruct the keys for verification.

Signed-off-by: Dan Lorenc <lorenc.d@gmail.com>
---
 pkg/pki/minisign/minisign.go      |  7 ++++++-
 pkg/pki/minisign/minisign_test.go | 10 ++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/pkg/pki/minisign/minisign.go b/pkg/pki/minisign/minisign.go
index 2026a33..995a18c 100644
--- a/pkg/pki/minisign/minisign.go
+++ b/pkg/pki/minisign/minisign.go
@@ -120,6 +120,7 @@ func NewPublicKey(r io.Reader) (*PublicKey, error) {
 	}
 
 	inputString := inputBuffer.String()
+
 	key, err := minisign.DecodePublicKey(inputString)
 	if err != nil {
 		// try as a standalone base64 string
@@ -139,7 +140,11 @@ func (k PublicKey) CanonicalValue() ([]byte, error) {
 		return nil, fmt.Errorf("minisign public key has not been initialized")
 	}
 
-	b64Key := base64.StdEncoding.EncodeToString(k.key.PublicKey[:])
+	bin := []byte{}
+	bin = append(bin, k.key.SignatureAlgorithm[:]...)
+	bin = append(bin, k.key.KeyId[:]...)
+	bin = append(bin, k.key.PublicKey[:]...)
+	b64Key := base64.StdEncoding.EncodeToString(bin)
 	return []byte(b64Key), nil
 }
 
diff --git a/pkg/pki/minisign/minisign_test.go b/pkg/pki/minisign/minisign_test.go
index a054aba..1570615 100644
--- a/pkg/pki/minisign/minisign_test.go
+++ b/pkg/pki/minisign/minisign_test.go
@@ -22,6 +22,7 @@ import (
 	"os"
 	"testing"
 
+	"github.com/google/go-cmp/cmp"
 	"go.uber.org/goleak"
 )
 
@@ -240,6 +241,15 @@ func TestCanonicalValuePublicKey(t *testing.T) {
 		if bytes.Equal(cvInput, cvOutput) != tc.match {
 			t.Errorf("%v: %v equality of canonical values of %v and %v was expected but not generated", tc.caseDesc, tc.match, tc.input, tc.output)
 		}
+
+		// The canonical values should be round-trippable
+		rt, err := NewPublicKey(bytes.NewReader(cvInput))
+		if err != nil {
+			t.Fatalf("error parsing canonicalized key: %v", err)
+		}
+		if diff := cmp.Diff(rt.key, inputKey.key); diff != "" {
+			t.Error(diff)
+		}
 	}
 }
 
-- 
GitLab