Skip to content

Commit

Permalink
Join-by-Welcome active tests and supporting API/logic
Browse files Browse the repository at this point in the history
  • Loading branch information
bifurcation committed Mar 9, 2023
1 parent 82ad91f commit 02d5a62
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 37 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ go 1.16

require (
google.golang.org/grpc v1.36.0
google.golang.org/protobuf v1.28.1
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 // indirect
google.golang.org/protobuf v1.29.0
)
37 changes: 24 additions & 13 deletions interop/active_to_passive.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,12 @@ console.log(JSON.stringify(passiveTests, null, 2));
function activeToPassive(rawSteps, testCase, actor) {
// Identify where in the transcript we should look for relevant data
const steps = rawSteps.map((step, i) => { step.transcriptIndex = i; return step; });
const kp_steps = steps.filter(step => step.action == "createKeyPackage" && step.actor == actor);
const join_steps = steps.filter(step => step.action == "fullCommit" && step.joiners && step.joiners.includes(actor));
const commit_steps = steps.filter(step => step.action == "fullCommit" && step.members && step.members.includes(actor));
const kpSteps = steps.filter(step => step.action == "createKeyPackage" && step.actor == actor);
const pskSteps = steps.filter(step => step.action == "installExternalPSK" && step.clients && step.clients.includes(actor));
const joinSteps = steps.filter(step => step.action == "fullCommit" && step.joiners && step.joiners.includes(actor));
const commitSteps = steps.filter(step => step.action == "fullCommit" && step.members && step.members.includes(actor));

if (kp_steps.length == 0 || join_steps.length == 0) {
if (kpSteps.length == 0 || joinSteps.length == 0) {
console.warn("Actor did not join via Welcome", actor);
return;
}
Expand All @@ -73,24 +74,34 @@ function activeToPassive(rawSteps, testCase, actor) {
const transcript = testCase.transcript;

// Grab private state from createKeyPackage step in transcript
const kpTranscript = transcript[kp_steps[0].transcriptIndex];
const kpTranscript = transcript[kpSteps[0].transcriptIndex];
passiveTest.key_package = kpTranscript.key_package;
passiveTest.init_priv = kpTranscript.init_priv;
passiveTest.encryption_priv = kpTranscript.encryption_priv;
passiveTest.signature_priv = kpTranscript.signature_priv;

// Grab welcome and epoch authenticator from joinGroup
const commitTranscript = transcript[join_steps[0].transcriptIndex];
passiveTest.welcome = commitTranscript.welcome;
passiveTest.initial_epoch_authenticator = commitTranscript.epoch_authenticator;

// TODO Enable provisioning these fields
passiveTest.external_psks = [];
// Grab welcome, ratchet tree, and epoch authenticator from joinGroup
const joinTranscript = transcript[joinSteps[0].transcriptIndex];
passiveTest.welcome = joinTranscript.welcome;
passiveTest.initial_epoch_authenticator = joinTranscript.epoch_authenticator;

passiveTest.ratchet_tree = null;
if (joinTranscript.ratchet_tree.length > 0) {
passiveTest.ratchet_tree = joinTranscript.ratchet_tree;
}

// Grab any PSKs that were sent to this client
passiveTest.external_psks = pskSteps.map(step => transcript[step.transcriptIndex])
.map(txStep => {
return {
psk_id: txStep.psk_id,
psk: txStep.psk_secret,
};
});

// Grab Commits
passiveTest.epochs = [];
for (let step of commit_steps) {
for (let step of commitSteps) {
const commitTranscript = transcript[step.transcriptIndex];
const proposals = step.byReference.map(i => transcript[i].proposal);

Expand Down
33 changes: 33 additions & 0 deletions interop/configs/welcome_join.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"scripts": {
"no_path_secret": [
{"action": "createGroup", "actor": "alice"},
{"action": "createKeyPackage", "actor": "bob"},
{"action": "addProposal", "actor": "alice", "keyPackage": 1},
{"action": "fullCommit", "actor": "alice", "byReference": [2], "joiners": ["bob"]}
],

"with_path_secret": [
{"action": "createGroup", "actor": "alice"},
{"action": "createKeyPackage", "actor": "bob"},
{"action": "addProposal", "actor": "alice", "keyPackage": 1},
{"action": "fullCommit", "actor": "alice", "byReference": [2], "joiners": ["bob"], "force_path": true}
],

"with_psk": [
{"action": "createGroup", "actor": "alice"},
{"action": "createKeyPackage", "actor": "bob"},
{"action": "addProposal", "actor": "alice", "keyPackage": 1},
{"action": "installExternalPSK", "clients": ["alice", "bob"]},
{"action": "preSharedKeyProposal", "actor": "alice", "psk": 3},
{"action": "fullCommit", "actor": "alice", "byReference": [2, 4], "joiners": ["bob"]}
],

"with_external_tree": [
{"action": "createGroup", "actor": "alice"},
{"action": "createKeyPackage", "actor": "bob"},
{"action": "addProposal", "actor": "alice", "keyPackage": 1},
{"action": "fullCommit", "actor": "alice", "byReference": [2], "joiners": ["bob"], "external_tree": true}
]
}
}
8 changes: 6 additions & 2 deletions interop/proto/mls_client.proto
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ message JoinGroupRequest {
bytes welcome = 2;
bool encrypt_handshake = 3;
bytes identity = 4;
bytes ratchet_tree = 5;
}

message JoinGroupResponse {
Expand Down Expand Up @@ -155,9 +156,9 @@ message UnprotectResponse {

// rpc StorePSK
message StorePSKRequest {
uint32 state_id = 1;
uint32 state_or_transaction_id = 1;
bytes psk_id = 2;
bytes psk = 3;
bytes psk_secret = 3;
}

message StorePSKResponse {}
Expand Down Expand Up @@ -201,11 +202,14 @@ message CommitRequest {
uint32 state_id = 1;
repeated bytes by_reference = 2;
repeated bytes by_value = 3;
bool force_path = 4;
bool external_tree = 5;
}

message CommitResponse {
bytes commit = 1;
bytes welcome = 2;
bytes ratchet_tree = 3;
}

// rpc HandleCommit
Expand Down
118 changes: 97 additions & 21 deletions interop/test-runner/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,22 @@ const (
HandshakeModePrivate HandshakeMode = "private"
HandshakeModePublic HandshakeMode = "public"

ActionCreateGroup ScriptAction = "createGroup"
ActionCreateKeyPackage ScriptAction = "createKeyPackage"
ActionJoinGroup ScriptAction = "joinGroup"
ActionExternalJoin ScriptAction = "externalJoin"
ActionPublicGroupState ScriptAction = "publicGroupState"
ActionAddProposal ScriptAction = "addProposal"
ActionUpdateProposal ScriptAction = "updateProposal"
ActionRemoveProposal ScriptAction = "removeProposal"
ActionFullCommit ScriptAction = "fullCommit"
ActionCommit ScriptAction = "commit"
ActionHandleCommit ScriptAction = "handleCommit"
ActionHandlePendingCommit ScriptAction = "handlePendingCommit"
ActionProtect ScriptAction = "protect"
ActionUnprotect ScriptAction = "unprotect"
ActionCreateGroup ScriptAction = "createGroup"
ActionCreateKeyPackage ScriptAction = "createKeyPackage"
ActionJoinGroup ScriptAction = "joinGroup"
ActionExternalJoin ScriptAction = "externalJoin"
ActionInstallExternalPSK ScriptAction = "installExternalPSK"
ActionPublicGroupState ScriptAction = "publicGroupState"
ActionAddProposal ScriptAction = "addProposal"
ActionUpdateProposal ScriptAction = "updateProposal"
ActionRemoveProposal ScriptAction = "removeProposal"
ActionPreSharedKeyProposal ScriptAction = "preSharedKeyProposal"
ActionFullCommit ScriptAction = "fullCommit"
ActionCommit ScriptAction = "commit"
ActionHandleCommit ScriptAction = "handleCommit"
ActionHandlePendingCommit ScriptAction = "handlePendingCommit"
ActionProtect ScriptAction = "protect"
ActionUnprotect ScriptAction = "unprotect"

TimeoutSeconds = 120
)
Expand All @@ -66,6 +68,10 @@ type ExternalJoinStepParams struct {
PublicGroupState int `json:"publicGroupState"`
}

type InstallExternalPSKStepParams struct {
Clients []string `json:"clients"`
}

type AddProposalStepParams struct {
KeyPackage int `json:"keyPackage"`
}
Expand All @@ -74,11 +80,17 @@ type RemoveProposalStepParams struct {
Removed string `json:"removed"`
}

type PreSharedKeyProposalStepParams struct {
PSK int `json:"psk"`
}

type FullCommitStepParams struct {
ByReference []int `json:"byReference"`
ByValue []int `json:"byValue"`
Members []string `json:"members"`
Joiners []string `json:"joiners"`
ByReference []int `json:"byReference"`
ByValue []int `json:"byValue"`
Members []string `json:"members"`
Joiners []string `json:"joiners"`
ForcePath bool `json:"force_path"`
ExternalTree bool `json:"external_tree"`
}

type CommitStepParams struct {
Expand Down Expand Up @@ -406,6 +418,42 @@ func (config *ScriptActorConfig) RunStep(index int, step ScriptStep) error {
config.stateID[step.Actor] = resp.StateId
config.StoreMessage(index, "commit", resp.Commit)

case ActionInstallExternalPSK:
var params InstallExternalPSKStepParams
err := json.Unmarshal(step.Raw, &params)
if err != nil {
return err
}

pskID := make([]byte, 32)
rand.Read(pskID)
config.StoreMessage(index, "psk_id", pskID)

pskSecret := make([]byte, 32)
rand.Read(pskSecret)
config.StoreMessage(index, "psk_secret", pskSecret)

for _, clientName := range params.Clients {
client := config.ActorClients[clientName]

id := uint32(0)
if stateID, ok := config.stateID[clientName]; ok {
id = stateID
} else if txID, ok := config.transactionID[clientName]; ok {
id = txID
}

req := &pb.StorePSKRequest{
StateOrTransactionId: id,
PskId: pskID,
PskSecret: pskSecret,
}
_, err := client.rpc.StorePSK(ctx(), req)
if err != nil {
return err
}
}

case ActionPublicGroupState:
client := config.ActorClients[step.Actor]

Expand Down Expand Up @@ -480,6 +528,30 @@ func (config *ScriptActorConfig) RunStep(index int, step ScriptStep) error {

config.StoreMessage(index, "proposal", resp.Proposal)

case ActionPreSharedKeyProposal:
client := config.ActorClients[step.Actor]
var params PreSharedKeyProposalStepParams
err := json.Unmarshal(step.Raw, &params)
if err != nil {
return err
}

pskID, err := config.GetMessage(params.PSK, "psk_id")
if err != nil {
return err
}

req := &pb.PSKProposalRequest{
StateId: config.stateID[step.Actor],
PskId: pskID,
}
resp, err := client.rpc.PSKProposal(ctx(), req)
if err != nil {
return err
}

config.StoreMessage(index, "proposal", resp.Proposal)

case ActionFullCommit:
client := config.ActorClients[step.Actor]
var params FullCommitStepParams
Expand All @@ -506,9 +578,11 @@ func (config *ScriptActorConfig) RunStep(index int, step ScriptStep) error {
}

commitReq := &pb.CommitRequest{
StateId: config.stateID[step.Actor],
ByReference: byRef,
ByValue: byVal,
StateId: config.stateID[step.Actor],
ByReference: byRef,
ByValue: byVal,
ForcePath: params.ForcePath,
ExternalTree: params.ExternalTree,
}
commitResp, err := client.rpc.Commit(ctx(), commitReq)
if err != nil {
Expand All @@ -517,6 +591,7 @@ func (config *ScriptActorConfig) RunStep(index int, step ScriptStep) error {

config.StoreMessage(index, "welcome", commitResp.Welcome)
config.StoreMessage(index, "commit", commitResp.Commit)
config.StoreMessage(index, "ratchet_tree", commitResp.RatchetTree)

// Apply it at the committer [ActionHandlePendingCommit]
epochAuthenticator := []byte{}
Expand Down Expand Up @@ -568,6 +643,7 @@ func (config *ScriptActorConfig) RunStep(index int, step ScriptStep) error {
req := &pb.JoinGroupRequest{
TransactionId: txID,
Welcome: commitResp.Welcome,
RatchetTree: commitResp.RatchetTree,
EncryptHandshake: config.EncryptHandshake,
Identity: []byte(joiner),
}
Expand Down

0 comments on commit 02d5a62

Please sign in to comment.