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 }