This commit is contained in:
@@ -1,44 +0,0 @@
|
|||||||
-----BEGIN PGP MESSAGE-----
|
|
||||||
Comment: https://gopenpgp.org
|
|
||||||
Version: GopenPGP 2.8.3
|
|
||||||
|
|
||||||
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
|
|
||||||
=C05v
|
|
||||||
-----END PGP MESSAGE-----
|
|
||||||
@@ -8,10 +8,12 @@ import (
|
|||||||
"forge.redroom.link/yves/meowlib"
|
"forge.redroom.link/yves/meowlib"
|
||||||
"forge.redroom.link/yves/meowlib/client"
|
"forge.redroom.link/yves/meowlib/client"
|
||||||
"forge.redroom.link/yves/meowlib/client/invitation/messages"
|
"forge.redroom.link/yves/meowlib/client/invitation/messages"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Step2ReadAndAnswer reads an InvitationInitPayload from a .mwiv file, creates the
|
// Step2ReadAndAnswer reads an InvitationInitPayload from a .mwiv file, creates the
|
||||||
// invitee's peer entry, and writes the invitee's ContactCard response to a .mwiv file.
|
// invitee's peer entry, and writes the encrypted ContactCard (PackedUserMessage) to a
|
||||||
|
// .mwiv file for the initiator to pick up and process in step 3.
|
||||||
func Step2ReadAndAnswer(invitationFile string, nickname string, myNickname string, serverUids []string) error {
|
func Step2ReadAndAnswer(invitationFile string, nickname string, myNickname string, serverUids []string) error {
|
||||||
if _, err := os.Stat(invitationFile); os.IsNotExist(err) {
|
if _, err := os.Stat(invitationFile); os.IsNotExist(err) {
|
||||||
return err
|
return err
|
||||||
@@ -33,12 +35,29 @@ func Step2ReadAndAnswer(invitationFile string, nickname string, myNickname strin
|
|||||||
mynick = client.GetConfig().GetIdentity().Nickname
|
mynick = client.GetConfig().GetIdentity().Nickname
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := messages.Step2InviteeCreatesInitiatorAndEncryptedContactCard(payload, nickname, mynick, serverUids)
|
packed, peer, err := messages.Step2InviteeCreatesInitiatorAndEncryptedContactCard(payload, nickname, mynick, serverUids)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap the PackedUserMessage in an Invitation so the initiator (step3) has the
|
||||||
|
// invitee's public key available for signature verification without an extra file.
|
||||||
|
packedBytes, err := proto.Marshal(packed)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
invitation := &meowlib.Invitation{
|
||||||
|
Uuid: peer.InvitationId,
|
||||||
|
Step: 2,
|
||||||
|
From: peer.MyIdentity.Public,
|
||||||
|
Payload: packedBytes,
|
||||||
|
}
|
||||||
|
out, err := proto.Marshal(invitation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
c := client.GetConfig()
|
c := client.GetConfig()
|
||||||
filename := c.StoragePath + string(os.PathSeparator) + mynick + "-" + nickname + ".mwiv"
|
filename := c.StoragePath + string(os.PathSeparator) + mynick + "-" + nickname + ".mwiv"
|
||||||
return response.GetMyContact().WriteCompressed(filename)
|
return os.WriteFile(filename, out, 0600)
|
||||||
}
|
}
|
||||||
|
|||||||
142
client/invitation/messages/flow_test.go
Normal file
142
client/invitation/messages/flow_test.go
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
package messages_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"forge.redroom.link/yves/meowlib"
|
||||||
|
"forge.redroom.link/yves/meowlib/client"
|
||||||
|
"forge.redroom.link/yves/meowlib/client/invitation/messages"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
// setupIdentity creates a fresh identity and sets it as the active config identity.
|
||||||
|
// Returns the identity and a cleanup function.
|
||||||
|
func setupIdentity(t *testing.T, nickname string) (*client.Identity, func()) {
|
||||||
|
t.Helper()
|
||||||
|
cfg := client.GetConfig()
|
||||||
|
cfg.SetMemPass("testpass") //nolint:errcheck
|
||||||
|
|
||||||
|
id, err := client.CreateIdentity(nickname)
|
||||||
|
require.NoError(t, err)
|
||||||
|
cfg.SetIdentity(id)
|
||||||
|
|
||||||
|
cleanup := func() {
|
||||||
|
os.RemoveAll(cfg.StoragePath + "/" + id.Uuid)
|
||||||
|
}
|
||||||
|
return id, cleanup
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestStep2ProducesPackedUserMessage verifies that Step2 returns a PackedUserMessage
|
||||||
|
// (not just a peer) and that the message is encrypted with the initiator's temp key
|
||||||
|
// so Step3 can decrypt it.
|
||||||
|
func TestStep2ProducesPackedUserMessage(t *testing.T) {
|
||||||
|
cfg := client.GetConfig()
|
||||||
|
cfg.SetMemPass("testpass") //nolint:errcheck
|
||||||
|
|
||||||
|
// --- STEP 1: initiator creates temp keypair and payload ---
|
||||||
|
initiator, cleanInit := setupIdentity(t, "alice")
|
||||||
|
defer cleanInit()
|
||||||
|
|
||||||
|
payload, initPeer, err := messages.Step1InitiatorCreatesInviteeAndTempKey("Bob", "Alice", "Hello!", nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, payload)
|
||||||
|
require.NotNil(t, initPeer)
|
||||||
|
// Initiator has only the temp keypair at this stage.
|
||||||
|
assert.Nil(t, initPeer.MyIdentity)
|
||||||
|
assert.NotNil(t, initPeer.InvitationKp)
|
||||||
|
|
||||||
|
// --- STEP 2: invitee receives payload, creates peer, returns packed message ---
|
||||||
|
_, cleanInvitee := setupIdentity(t, "bob")
|
||||||
|
defer cleanInvitee()
|
||||||
|
|
||||||
|
packed, inviteePeer, err := messages.Step2InviteeCreatesInitiatorAndEncryptedContactCard(
|
||||||
|
payload, "Alice", "Bob", nil,
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, packed, "step2 must return a PackedUserMessage, not just a peer")
|
||||||
|
require.NotNil(t, inviteePeer)
|
||||||
|
|
||||||
|
// The packed message destination is the initiator's temp key (used as lookup key).
|
||||||
|
assert.Equal(t, payload.PublicKey, packed.Destination)
|
||||||
|
|
||||||
|
// The invitee peer has full keypairs now.
|
||||||
|
assert.NotNil(t, inviteePeer.MyIdentity)
|
||||||
|
assert.NotNil(t, inviteePeer.MyEncryptionKp)
|
||||||
|
assert.NotNil(t, inviteePeer.MyLookupKp)
|
||||||
|
|
||||||
|
// --- STEP 3: initiator decrypts invitee's packed message and finalises ---
|
||||||
|
cfg.SetIdentity(initiator)
|
||||||
|
|
||||||
|
// Simulate how the server delivers the step-2 answer: marshal the PackedUserMessage
|
||||||
|
// into an Invitation.Payload.
|
||||||
|
packedBytes, err := proto.Marshal(packed)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
invitation := &meowlib.Invitation{
|
||||||
|
Uuid: payload.Uuid,
|
||||||
|
Step: 2,
|
||||||
|
From: inviteePeer.MyIdentity.Public,
|
||||||
|
Payload: packedBytes,
|
||||||
|
}
|
||||||
|
|
||||||
|
peer, myCC, err := messages.Step3InitiatorFinalizesInviteeAndCreatesContactCard(invitation)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, peer)
|
||||||
|
require.NotNil(t, myCC, "step3 must produce the initiator's ContactCard to send to invitee")
|
||||||
|
|
||||||
|
// Initiator's peer must now hold invitee's real keys.
|
||||||
|
assert.Equal(t, inviteePeer.MyIdentity.Public, peer.ContactPublicKey)
|
||||||
|
assert.Equal(t, inviteePeer.MyEncryptionKp.Public, peer.ContactEncryption)
|
||||||
|
assert.Equal(t, inviteePeer.MyLookupKp.Public, peer.ContactLookupKey)
|
||||||
|
assert.Nil(t, peer.InvitationKp, "temp keypair must be cleared after step3")
|
||||||
|
assert.NotEmpty(t, myCC.DrRootKey)
|
||||||
|
assert.NotEmpty(t, myCC.DrPublicKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestStep2Step3RoundTripPayload verifies that the PackedUserMessage produced by step2
|
||||||
|
// actually carries the invitee's ContactCard when decrypted by the initiator.
|
||||||
|
func TestStep2Step3RoundTripPayload(t *testing.T) {
|
||||||
|
cfg := client.GetConfig()
|
||||||
|
cfg.SetMemPass("testpass") //nolint:errcheck
|
||||||
|
|
||||||
|
initiator, cleanInit := setupIdentity(t, "alice2")
|
||||||
|
defer cleanInit()
|
||||||
|
|
||||||
|
payload, _, err := messages.Step1InitiatorCreatesInviteeAndTempKey("Bob", "Alice", "", nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
_, cleanInvitee := setupIdentity(t, "bob2")
|
||||||
|
defer cleanInvitee()
|
||||||
|
|
||||||
|
packed, inviteePeer, err := messages.Step2InviteeCreatesInitiatorAndEncryptedContactCard(payload, "Alice", "Bob", nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Confirm the message serialises cleanly (transport simulation).
|
||||||
|
packedBytes, err := proto.Marshal(packed)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.NotEmpty(t, packedBytes)
|
||||||
|
|
||||||
|
// Switch back to initiator and run step3.
|
||||||
|
cfg.SetIdentity(initiator)
|
||||||
|
|
||||||
|
var roundTripped meowlib.PackedUserMessage
|
||||||
|
require.NoError(t, proto.Unmarshal(packedBytes, &roundTripped))
|
||||||
|
|
||||||
|
invitation := &meowlib.Invitation{
|
||||||
|
Uuid: payload.Uuid,
|
||||||
|
Step: 2,
|
||||||
|
From: inviteePeer.MyIdentity.Public,
|
||||||
|
Payload: packedBytes,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, myCC, err := messages.Step3InitiatorFinalizesInviteeAndCreatesContactCard(invitation)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, myCC)
|
||||||
|
|
||||||
|
// The initiator's CC must reference the invitee's invitation ID so the invitee
|
||||||
|
// can match it when step4 arrives.
|
||||||
|
assert.Equal(t, payload.Uuid, myCC.InvitationId)
|
||||||
|
}
|
||||||
@@ -6,17 +6,28 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Step2InviteeCreatesInitiatorAndEncryptedContactCard creates the invitee's peer entry
|
// Step2InviteeCreatesInitiatorAndEncryptedContactCard creates the invitee's peer entry
|
||||||
// from an InvitationInitPayload and generates the encrypted ContactCard to be sent back
|
// from an InvitationInitPayload, then builds the invitee's ContactCard and returns it
|
||||||
// to the initiator via any transport.
|
// as a PackedUserMessage asymmetrically encrypted with the initiator's temporary public
|
||||||
func Step2InviteeCreatesInitiatorAndEncryptedContactCard(payload *meowlib.InvitationInitPayload, nickname string, myNickname string, serverUids []string) (*client.Peer, error) {
|
// key. The packed message is ready to be transmitted to the initiator via any transport
|
||||||
|
// (file, QR, server…); Step3InitiatorFinalizesInviteeAndCreatesContactCard on the
|
||||||
|
// initiator side will decrypt and process it.
|
||||||
|
func Step2InviteeCreatesInitiatorAndEncryptedContactCard(payload *meowlib.InvitationInitPayload, nickname string, myNickname string, serverUids []string) (*meowlib.PackedUserMessage, *client.Peer, error) {
|
||||||
mynick := myNickname
|
mynick := myNickname
|
||||||
if mynick == "" {
|
if mynick == "" {
|
||||||
mynick = client.GetConfig().GetIdentity().Nickname
|
mynick = client.GetConfig().GetIdentity().Nickname
|
||||||
}
|
}
|
||||||
peer, err := client.GetConfig().GetIdentity().InvitationStep2(mynick, nickname, serverUids, payload)
|
peer, err := client.GetConfig().GetIdentity().InvitationStep2(mynick, nickname, serverUids, payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
usermsg, err := peer.BuildInvitationStep2Message(peer.GetMyContact())
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
packed, err := peer.ProcessOutboundUserMessage(usermsg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
client.GetConfig().GetIdentity().Save()
|
client.GetConfig().GetIdentity().Save()
|
||||||
return peer, nil
|
return packed, peer, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,29 +62,20 @@ func Step2ReadResponse(invitationData []byte, invitationServerUid string) (*meow
|
|||||||
return meowlib.NewInvitationInitPayloadFromCompressed(serverMsg.Invitation.Payload)
|
return meowlib.NewInvitationInitPayloadFromCompressed(serverMsg.Invitation.Payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step2PostAnswer builds and returns the packed server message that posts the
|
// Step2PostAnswer wraps the invitee's already-built PackedUserMessage into a server
|
||||||
// invitee's ContactCard (encrypted with the initiator's temp key) to the invitation server.
|
// message and posts it to the invitation server. The packed message is produced by
|
||||||
func Step2PostAnswer(invitationId string, invitationServerUid string, timeout int) ([]byte, error) {
|
// messages.Step2InviteeCreatesInitiatorAndEncryptedContactCard.
|
||||||
|
func Step2PostAnswer(invitationId string, packedMsg *meowlib.PackedUserMessage, invitationServerUid string, timeout int) ([]byte, error) {
|
||||||
peer := client.GetConfig().GetIdentity().Peers.GetFromInvitationId(invitationId)
|
peer := client.GetConfig().GetIdentity().Peers.GetFromInvitationId(invitationId)
|
||||||
if peer == nil {
|
if peer == nil {
|
||||||
return nil, errors.New("no peer with that invitation id")
|
return nil, errors.New("no peer with that invitation id")
|
||||||
}
|
}
|
||||||
|
|
||||||
answermsg, err := peer.BuildInvitationStep2Message(peer.GetMyContact())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
invitationServer, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(invitationServerUid)
|
invitationServer, err := client.GetConfig().GetIdentity().MessageServers.LoadServer(invitationServerUid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
packedMsg, err := peer.ProcessOutboundUserMessage(answermsg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
toServerMessage, err := invitationServer.BuildToServerMessageInvitationAnswer(packedMsg, peer.MyIdentity.Public, invitationId, timeout)
|
toServerMessage, err := invitationServer.BuildToServerMessageInvitationAnswer(packedMsg, peer.MyIdentity.Public, invitationId, timeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"forge.redroom.link/yves/meowlib"
|
"forge.redroom.link/yves/meowlib"
|
||||||
doubleratchet "github.com/status-im/doubleratchet"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
doubleratchet "github.com/status-im/doubleratchet"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ type Peer struct {
|
|||||||
// Invitation temporary keypair (step 1 only — discarded after step 3)
|
// Invitation temporary keypair (step 1 only — discarded after step 3)
|
||||||
InvitationKp *meowlib.KeyPair `json:"invitation_kp,omitempty"`
|
InvitationKp *meowlib.KeyPair `json:"invitation_kp,omitempty"`
|
||||||
// Double Ratchet state
|
// Double Ratchet state
|
||||||
DrKpPublic string `json:"dr_kp_public,omitempty"`
|
DrKpPublic string `json:"dr_kp_public,omitempty"`
|
||||||
DrKpPrivate string `json:"dr_kp_private,omitempty"`
|
DrKpPrivate string `json:"dr_kp_private,omitempty"`
|
||||||
DrRootKey string `json:"dr_root_key,omitempty"`
|
DrRootKey string `json:"dr_root_key,omitempty"`
|
||||||
DrInitiator bool `json:"dr_initiator,omitempty"`
|
DrInitiator bool `json:"dr_initiator,omitempty"`
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
-----BEGIN PGP MESSAGE-----
|
|
||||||
Comment: https://gopenpgp.org
|
|
||||||
Version: GopenPGP 2.8.3
|
|
||||||
|
|
||||||
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
|
|
||||||
=BI6k
|
|
||||||
-----END PGP MESSAGE-----
|
|
||||||
Reference in New Issue
Block a user