blob: 3b61abe045c3d23d7b8d3d5ac58ffb0e022a7bfe [file] [log] [blame]
package cose
import (
"crypto/ed25519"
"crypto/rand"
"reflect"
"testing"
)
func generateTestEd25519Key(t *testing.T) (ed25519.PublicKey, ed25519.PrivateKey) {
vk, sk, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
t.Fatalf("ed25519.GenerateKey() error = %v", err)
}
return vk, sk
}
func Test_ed25519Signer(t *testing.T) {
// generate key
alg := AlgorithmEd25519
_, key := generateTestEd25519Key(t)
// set up signer
signer, err := NewSigner(alg, key)
if err != nil {
t.Fatalf("NewSigner() error = %v", err)
}
if _, ok := signer.(*ed25519Signer); !ok {
t.Fatalf("NewSigner() type = %v, want *ed25519Signer", reflect.TypeOf(signer))
}
if got := signer.Algorithm(); got != alg {
t.Fatalf("Algorithm() = %v, want %v", got, alg)
}
// sign / verify round trip
// see also conformance_test.go for strict tests.
digest, err := alg.computeHash([]byte("hello world"))
if err != nil {
t.Fatalf("Algorithm.computeHash() error = %v", err)
}
sig, err := signer.Sign(rand.Reader, digest)
if err != nil {
t.Fatalf("Sign() error = %v", err)
}
verifier, err := NewVerifier(alg, key.Public())
if err != nil {
t.Fatalf("NewVerifier() error = %v", err)
}
if err := verifier.Verify(digest, sig); err != nil {
t.Fatalf("Verifier.Verify() error = %v", err)
}
}
func Test_ed25519Verifier_Verify_Success(t *testing.T) {
// generate key
alg := AlgorithmEd25519
_, key := generateTestEd25519Key(t)
// generate a valid signature
digest, sig := signTestData(t, alg, key)
// set up verifier
verifier, err := NewVerifier(alg, key.Public())
if err != nil {
t.Fatalf("NewVerifier() error = %v", err)
}
if _, ok := verifier.(*ed25519Verifier); !ok {
t.Fatalf("NewVerifier() type = %v, want *ed25519Verifier", reflect.TypeOf(verifier))
}
if got := verifier.Algorithm(); got != alg {
t.Fatalf("Algorithm() = %v, want %v", got, alg)
}
// verify round trip
if err := verifier.Verify(digest, sig); err != nil {
t.Fatalf("ed25519Verifier.Verify() error = %v", err)
}
}
func Test_ed25519Verifier_Verify_KeyMismatch(t *testing.T) {
// generate key
alg := AlgorithmEd25519
_, key := generateTestEd25519Key(t)
// generate a valid signature
digest, sig := signTestData(t, alg, key)
// set up verifier with a different key / new key
vk, _ := generateTestEd25519Key(t)
verifier := &ed25519Verifier{
key: vk,
}
// verification should fail on key mismatch
if err := verifier.Verify(digest, sig); err != ErrVerification {
t.Fatalf("ed25519Verifier.Verify() error = %v, wantErr %v", err, ErrVerification)
}
}
func Test_ed25519Verifier_Verify_InvalidSignature(t *testing.T) {
// generate key
alg := AlgorithmEd25519
vk, sk := generateTestEd25519Key(t)
// generate a valid signature with a tampered one
digest, sig := signTestData(t, alg, sk)
tamperedSig := make([]byte, len(sig))
copy(tamperedSig, sig)
tamperedSig[0]++
// set up verifier with a different algorithm
verifier := &ed25519Verifier{
key: vk,
}
// verification should fail on invalid signature
tests := []struct {
name string
signature []byte
}{
{
name: "nil signature",
signature: nil,
},
{
name: "empty signature",
signature: []byte{},
},
{
name: "incomplete signature",
signature: sig[:len(sig)-2],
},
{
name: "tampered signature",
signature: tamperedSig,
},
{
name: "too many signature bytes",
signature: append(sig, 0),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := verifier.Verify(digest, tt.signature); err != ErrVerification {
t.Errorf("ed25519Verifier.Verify() error = %v, wantErr %v", err, ErrVerification)
}
})
}
}