Skip to content
Snippets Groups Projects
Unverified Commit 01ef8ffa authored by dlorenc's avatar dlorenc Committed by GitHub
Browse files

Enable parsing of incomplete minisign keys, to enable re-indexing. (#567)


Without this we can't properly re-run IndexKeys() on the log data because old minisign
keys were stripped to no longer contain the KeyID or Algorithm field.

Signed-off-by: default avatarDan Lorenc <lorenc.d@gmail.com>
parent 984255e0
No related branches found
No related tags found
No related merge requests found
......@@ -121,17 +121,30 @@ func NewPublicKey(r io.Reader) (*PublicKey, error) {
inputString := inputBuffer.String()
// There are three ways a minisign key can be stored.
// 1. The entire text key
// 2. A base64 encoded string
// 3. A legacy format we stored of just the key material (no key ID or Algorithm) due to bug fixed in https://github.com/sigstore/rekor/pull/562
key, err := minisign.DecodePublicKey(inputString)
if err != nil {
// try as a standalone base64 string
key, err = minisign.NewPublicKey(inputString)
if err != nil {
return nil, fmt.Errorf("unable to read minisign public key: %w", err)
}
if err == nil {
k.key = &key
return &k, nil
}
key, err = minisign.NewPublicKey(inputString)
if err == nil {
k.key = &key
return &k, nil
}
k.key = &key
return &k, nil
if len(inputString) == 32 {
k.key = &minisign.PublicKey{
SignatureAlgorithm: [2]byte{'E', 'd'},
KeyId: [8]byte{},
}
copy(k.key.PublicKey[:], inputBuffer.Bytes())
return &k, nil
}
return nil, fmt.Errorf("unable to read minisign public key: %w", err)
}
// CanonicalValue implements the pki.PublicKey interface
......
......@@ -32,26 +32,64 @@ func TestMain(m *testing.M) {
func TestReadPublicKey(t *testing.T) {
type test struct {
caseDesc string
inputFile string
errorFound bool
caseDesc string
inputFile string
}
tests := []test{
{caseDesc: "Not a valid public key file", inputFile: "testdata/hello_world.txt.minisig", errorFound: true},
{caseDesc: "Valid public key (minisign)", inputFile: "testdata/minisign.pub", errorFound: false},
{caseDesc: "Valid public key (signify)", inputFile: "testdata/signify.pub", errorFound: false},
{caseDesc: "Valid public key (minisign)", inputFile: "testdata/minisign.pub"},
{caseDesc: "Valid public key (signify)", inputFile: "testdata/signify.pub"},
}
for _, tc := range tests {
file, err := os.Open(tc.inputFile)
if err != nil {
t.Errorf("%v: cannot open %v", tc.caseDesc, tc.inputFile)
}
t.Run(tc.caseDesc, func(t *testing.T) {
file, err := os.Open(tc.inputFile)
if err != nil {
t.Fatalf("%v: cannot open %v", tc.caseDesc, tc.inputFile)
}
if got, err := NewPublicKey(file); ((got != nil) == tc.errorFound) || ((err != nil) != tc.errorFound) {
t.Errorf("%v: unexpected result testing %v: %v", tc.caseDesc, tc.inputFile, err)
}
got, err := NewPublicKey(file)
if err != nil {
t.Fatalf("unexpected error %v", err)
}
// Try to send just the raw public key bytes too
rawBytes := got.key.PublicKey[:]
rawGot, err := NewPublicKey(bytes.NewReader(rawBytes))
if err != nil {
t.Fatalf("unexpected error re-parsing public key: %v", err)
}
if !bytes.Equal(rawGot.key.PublicKey[:], rawBytes) {
t.Errorf("expected parsed keys to be equal, %v != %v", rawGot.key.PublicKey, rawBytes)
}
})
}
}
func TestReadPublicKeyErr(t *testing.T) {
type test struct {
caseDesc string
inputFile string
}
tests := []test{
{caseDesc: "Not a valid public key file", inputFile: "testdata/hello_world.txt.minisig"},
{caseDesc: "Wrong length", inputFile: "testdata/hello_world.txt"},
}
for _, tc := range tests {
t.Run(tc.caseDesc, func(t *testing.T) {
file, err := os.Open(tc.inputFile)
if err != nil {
t.Fatalf("%v: cannot open %v", tc.caseDesc, tc.inputFile)
}
got, err := NewPublicKey(file)
if err == nil {
t.Errorf("error expected, got nil error and %v", got)
}
})
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment