dsfx/pkg/handshake/handshake_test.go

91 lines
1.8 KiB
Go
Raw Normal View History

2025-03-07 21:05:37 -05:00
package handshake_test
import (
"bytes"
"crypto/ecdsa"
"log"
"net"
"sync"
"testing"
"koti.casa/numenor-labs/dsfx/pkg/dcrypto"
"koti.casa/numenor-labs/dsfx/pkg/handshake"
)
func TestHandshake(t *testing.T) {
var wg sync.WaitGroup
client, server := net.Pipe()
defer client.Close()
defer server.Close()
alice := newActor()
bob := newActor()
var aliceSharedSecret []byte
var aliceErr error
var bobSharedSecret []byte
var bobErr error
wg.Add(2)
go func() {
aliceSharedSecret, aliceErr = handshake.InitiateHandshake(alice, client, &bob.IdentityKey().PublicKey)
wg.Done()
}()
go func() {
bobSharedSecret, bobErr = handshake.AcceptHandshake(bob, server)
wg.Done()
}()
wg.Wait()
if aliceErr != nil || bobErr != nil {
if aliceErr != nil {
t.Errorf("alice error: %v", aliceErr)
return
}
t.Errorf("bob error: %v", bobErr)
return
}
if aliceSharedSecret == nil || bobSharedSecret == nil {
t.Errorf("handshake failed: shared secret is nil")
return
}
if len(aliceSharedSecret) == 0 || len(bobSharedSecret) == 0 {
t.Errorf("handshake failed: shared secret is empty")
}
if !bytes.Equal(aliceSharedSecret, bobSharedSecret) {
t.Errorf("handshake failed: shared secrets do not match")
return
}
}
// An actor represents an entity that can participate in the handshake process.
type actor struct {
identity *ecdsa.PrivateKey
}
// newActor creates a new actor with a random identity key.
func newActor() *actor {
key, err := dcrypto.GenerateSigningKey()
if err != nil {
log.Fatal(err)
}
return &actor{
identity: key,
}
}
// IdentityKey ...
func (a *actor) IdentityKey() *ecdsa.PrivateKey {
return a.identity
}
// Address returns the address of the actor. This is used when listening for
// incoming connections, and when dialing out to other actors.
func (a *actor) Address() *net.TCPAddr {
return nil
}