Monorepo for Tangled
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: add tests for VerifySignature and SSHFingerprint

Signed-off-by: Matías Insaurralde <matias@insaurral.de>

authored by

Matías Insaurralde and committed by
Tangled
0c4cb06d 6cb52877

+134
+134
crypto/verify_test.go
··· 1 + package crypto 2 + 3 + import ( 4 + "bytes" 5 + "crypto/ed25519" 6 + "crypto/rand" 7 + "strings" 8 + "testing" 9 + 10 + "github.com/hiddeco/sshsig" 11 + "golang.org/x/crypto/ssh" 12 + ) 13 + 14 + // testKey generates an ephemeral ed25519 key pair and returns the ssh.Signer 15 + // and the public key in authorized_keys format. 16 + func testKey(t *testing.T) (ssh.Signer, []byte) { 17 + t.Helper() 18 + _, priv, err := ed25519.GenerateKey(rand.Reader) 19 + if err != nil { 20 + t.Fatalf("generate ed25519 key: %v", err) 21 + } 22 + signer, err := ssh.NewSignerFromKey(priv) 23 + if err != nil { 24 + t.Fatalf("create signer: %v", err) 25 + } 26 + return signer, ssh.MarshalAuthorizedKey(signer.PublicKey()) 27 + } 28 + 29 + // testSign signs payload with signer using the same parameters as VerifySignature 30 + // expects (SHA-512, "git" namespace) and returns the armored signature. 31 + func testSign(t *testing.T, signer ssh.Signer, payload []byte) []byte { 32 + t.Helper() 33 + sig, err := sshsig.Sign(bytes.NewReader(payload), signer, sshsig.HashSHA512, "git") 34 + if err != nil { 35 + t.Fatalf("sign payload: %v", err) 36 + } 37 + return sshsig.Armor(sig) 38 + } 39 + 40 + func TestSSHFingerprint(t *testing.T) { 41 + t.Run("valid key returns SHA256 fingerprint", func(t *testing.T) { 42 + _, pubKeyBytes := testKey(t) 43 + fp, err := SSHFingerprint(string(pubKeyBytes)) 44 + if err != nil { 45 + t.Fatalf("unexpected error: %v", err) 46 + } 47 + if !strings.HasPrefix(fp, "SHA256:") { 48 + t.Errorf("fingerprint %q does not start with SHA256:", fp) 49 + } 50 + }) 51 + 52 + t.Run("same key returns identical fingerprint", func(t *testing.T) { 53 + _, pubKeyBytes := testKey(t) 54 + fp1, _ := SSHFingerprint(string(pubKeyBytes)) 55 + fp2, _ := SSHFingerprint(string(pubKeyBytes)) 56 + if fp1 != fp2 { 57 + t.Errorf("fingerprint not deterministic: %q != %q", fp1, fp2) 58 + } 59 + }) 60 + 61 + t.Run("different keys return different fingerprints", func(t *testing.T) { 62 + _, pub1 := testKey(t) 63 + _, pub2 := testKey(t) 64 + fp1, _ := SSHFingerprint(string(pub1)) 65 + fp2, _ := SSHFingerprint(string(pub2)) 66 + if fp1 == fp2 { 67 + t.Error("different keys produced the same fingerprint") 68 + } 69 + }) 70 + 71 + t.Run("malformed key returns error", func(t *testing.T) { 72 + _, err := SSHFingerprint("not a valid ssh public key") 73 + if err == nil { 74 + t.Error("expected error for malformed key") 75 + } 76 + }) 77 + } 78 + 79 + func TestVerifySignature(t *testing.T) { 80 + signer, pubKeyBytes := testKey(t) 81 + payload := []byte("test payload") 82 + armoredSig := testSign(t, signer, payload) 83 + 84 + t.Run("valid signature verifies successfully", func(t *testing.T) { 85 + err, ok := VerifySignature(pubKeyBytes, armoredSig, payload) 86 + if err != nil { 87 + t.Errorf("unexpected error: %v", err) 88 + } 89 + if !ok { 90 + t.Error("expected ok=true for valid signature") 91 + } 92 + }) 93 + 94 + t.Run("malformed public key returns error", func(t *testing.T) { 95 + err, ok := VerifySignature([]byte("not a valid key"), armoredSig, payload) 96 + if err == nil { 97 + t.Error("expected error for malformed public key") 98 + } 99 + if ok { 100 + t.Error("expected ok=false") 101 + } 102 + }) 103 + 104 + t.Run("malformed signature returns error", func(t *testing.T) { 105 + err, ok := VerifySignature(pubKeyBytes, []byte("not a valid signature"), payload) 106 + if err == nil { 107 + t.Error("expected error for malformed signature") 108 + } 109 + if ok { 110 + t.Error("expected ok=false") 111 + } 112 + }) 113 + 114 + t.Run("tampered payload fails verification", func(t *testing.T) { 115 + err, ok := VerifySignature(pubKeyBytes, armoredSig, []byte("tampered")) 116 + if err == nil { 117 + t.Error("expected error for tampered payload") 118 + } 119 + if ok { 120 + t.Error("expected ok=false for tampered payload") 121 + } 122 + }) 123 + 124 + t.Run("wrong public key fails verification", func(t *testing.T) { 125 + _, otherPubKey := testKey(t) 126 + err, ok := VerifySignature(otherPubKey, armoredSig, payload) 127 + if err == nil { 128 + t.Error("expected error for wrong public key") 129 + } 130 + if ok { 131 + t.Error("expected ok=false for wrong public key") 132 + } 133 + }) 134 + }