Skip to content

Commit

Permalink
Add public key hash check in Signed Note verification (#2214)
Browse files Browse the repository at this point in the history
* Update Verify method to perform PK hash check

Signed-off-by: Jang <hjjang501@gmail.com>

* Update unit test file

Update existing tests and ensure they work as expected and add a unit test case
to check for public key mismatch.

Signed-off-by: Jang <hjjang501@gmail.com>

* Make getPublicKeyHash an unexported function

Signed-off-by: Jang <hjjang501@gmail.com>

---------

Signed-off-by: Jang <hjjang501@gmail.com>
  • Loading branch information
hojoungjang authored Aug 27, 2024
1 parent f5fe610 commit ab3e6b4
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 9 deletions.
21 changes: 19 additions & 2 deletions pkg/util/checkpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,8 @@ func TestSigningRoundtripCheckpoint(t *testing.T) {

func TestInvalidSigVerification(t *testing.T) {
ecdsaKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
pubKeyHash, _ := getPublicKeyHash(ecdsaKey.Public())

for _, test := range []struct {
checkpoint Checkpoint
s []note.Signature
Expand Down Expand Up @@ -382,12 +384,27 @@ func TestInvalidSigVerification(t *testing.T) {
s: []note.Signature{
{
Name: "something",
Hash: 1234,
Hash: pubKeyHash,
Base64: "not_base 64 string",
},
},
expectedResult: false,
},
{
checkpoint: Checkpoint{
Origin: "Log Checkpoint v0 public key mismatch",
Size: 123,
Hash: []byte("bananas"),
},
pubKey: ecdsaKey.Public(),
s: []note.Signature{
{
Name: "something",
Hash: 123,
Base64: "bm90IGEgc2ln", // not a valid signature; public key mismatch happens first
},
},
},
{
checkpoint: Checkpoint{
Origin: "Log Checkpoint v0 invalid signature",
Expand All @@ -398,7 +415,7 @@ func TestInvalidSigVerification(t *testing.T) {
s: []note.Signature{
{
Name: "someone",
Hash: 142,
Hash: pubKeyHash,
Base64: "bm90IGEgc2ln", // valid base64, not a valid signature
},
},
Expand Down
33 changes: 26 additions & 7 deletions pkg/util/signed_note.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package util
import (
"bufio"
"bytes"
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
Expand Down Expand Up @@ -53,16 +54,14 @@ func (s *SignedNote) Sign(identity string, signer signature.Signer, opts signatu
if err != nil {
return nil, fmt.Errorf("retrieving public key: %w", err)
}
pubKeyBytes, err := x509.MarshalPKIXPublicKey(pk)
pkHash, err := getPublicKeyHash(pk)
if err != nil {
return nil, fmt.Errorf("marshalling public key: %w", err)
return nil, err
}

pkSha := sha256.Sum256(pubKeyBytes)

signature := note.Signature{
Name: identity,
Hash: binary.BigEndian.Uint32(pkSha[:]),
Hash: pkHash,
Base64: base64.StdEncoding.EncodeToString(sig),
}

Expand All @@ -80,15 +79,25 @@ func (s SignedNote) Verify(verifier signature.Verifier) bool {
msg := []byte(s.Note)
digest := sha256.Sum256(msg)

pk, err := verifier.PublicKey()
if err != nil {
return false
}
verifierPkHash, err := getPublicKeyHash(pk)
if err != nil {
return false
}

for _, s := range s.Signatures {
sigBytes, err := base64.StdEncoding.DecodeString(s.Base64)
if err != nil {
return false
}
pk, err := verifier.PublicKey()
if err != nil {

if s.Hash != verifierPkHash {
return false
}

opts := []signature.VerifyOption{}
switch pk.(type) {
case *rsa.PublicKey, *ecdsa.PublicKey:
Expand Down Expand Up @@ -190,3 +199,13 @@ func SignedNoteValidator(strToValidate string) bool {
s := SignedNote{}
return s.UnmarshalText([]byte(strToValidate)) == nil
}

func getPublicKeyHash(publicKey crypto.PublicKey) (uint32, error) {
pubKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
return 0, fmt.Errorf("marshalling public key: %w", err)
}
pkSha := sha256.Sum256(pubKeyBytes)
hash := binary.BigEndian.Uint32(pkSha[:])
return hash, nil
}

0 comments on commit ab3e6b4

Please sign in to comment.