-
Notifications
You must be signed in to change notification settings - Fork 31
/
e3x_exchange.c
105 lines (93 loc) · 3.01 KB
/
e3x_exchange.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include "e3x.h"
#include "util.h"
#include "unit_test.h"
int main(int argc, char **argv)
{
fail_unless(e3x_init(NULL) == 0);
// create A
lob_t idA = e3x_generate();
fail_unless(idA);
printf("idA key %.*s secret %.*s\n",(int)lob_linked(idA)->head_len,lob_linked(idA)->head,(int)idA->head_len,idA->head);
e3x_self_t selfA = e3x_self_new(idA,NULL);
fail_unless(selfA);
char *cshex = strdup(lob_get_index(idA,0));
fail_unless(cshex);
uint8_t csid = 0;
util_unhex(cshex,2,&csid);
fail_unless(csid);
lob_t keyA = lob_get_base32(lob_linked(idA),cshex);
fail_unless(keyA);
lob_free(idA);
// create B and an exchange A->B
lob_t idB = e3x_generate();
e3x_self_t selfB = e3x_self_new(idB,NULL);
lob_t keyB = lob_get_base32(lob_linked(idB),cshex);
fail_unless(keyB);
e3x_exchange_t xAB = e3x_exchange_new(selfA, csid, keyB);
fail_unless(xAB);
fail_unless(xAB->csid == csid);
fail_unless(e3x_exchange_out(xAB,1));
fail_unless(xAB->order == xAB->out);
lob_free(idB);
free(cshex);
// create message from A->B
lob_t innerAB = lob_new();
lob_set(innerAB,"te","st");
lob_t msgAB = e3x_exchange_message(xAB, innerAB);
fail_unless(msgAB);
fail_unless(msgAB->head_len == 1);
fail_unless(msgAB->head[0] == csid);
fail_unless(msgAB->body_len >= 42);
// decrypt
lob_t innerAB2 = e3x_self_decrypt(selfB,msgAB);
fail_unless(innerAB2);
fail_unless(util_cmp(lob_get(innerAB,"te"),"st") == 0);
lob_free(innerAB2);
lob_free(innerAB);
// create exchange B->A and verify message
e3x_exchange_t xBA = e3x_exchange_new(selfB, csid, keyA);
fail_unless(xBA);
fail_unless(e3x_exchange_out(xBA,1));
fail_unless(e3x_exchange_verify(xBA,msgAB) == 0);
lob_free(msgAB);
// generate handshake
fail_unless(e3x_exchange_out(xAB,3));
lob_t hsAB = e3x_exchange_handshake(xAB, NULL);
fail_unless(hsAB);
fail_unless(hsAB->head_len == 1);
fail_unless(hsAB->head[0] == csid);
fail_unless(hsAB->body_len >= 60);
// sync w/ handshake both ways
lob_t inAB = e3x_self_decrypt(selfB,hsAB);
fail_unless(inAB);
fail_unless(e3x_exchange_verify(xBA,hsAB) == 0);
fail_unless(e3x_exchange_sync(xBA,hsAB));
lob_t hsBA = e3x_exchange_handshake(xBA, NULL);
lob_t inBA = e3x_self_decrypt(selfA,hsBA);
fail_unless(inBA);
fail_unless(e3x_exchange_verify(xAB,hsBA) == 0);
fail_unless(e3x_exchange_sync(xAB,hsBA));
lob_free(inAB);
lob_free(hsAB);
lob_free(inBA);
lob_free(hsBA);
lob_free(keyA);
lob_free(keyB);
// send/receive channel packet
lob_t chanAB = lob_new();
lob_set_int(chanAB,"c",e3x_exchange_cid(xAB, NULL));
fail_unless(e3x_exchange_cid(xBA, chanAB)); // verify incoming
lob_t coutAB = e3x_exchange_send(xAB,chanAB);
fail_unless(coutAB);
fail_unless(coutAB->body_len >= 33);
lob_t cinAB = e3x_exchange_receive(xBA,coutAB);
fail_unless(cinAB);
fail_unless(lob_get_int(cinAB,"c") == lob_get_int(chanAB,"c"));
lob_free(cinAB);
lob_free(coutAB);
e3x_exchange_free(xAB);
e3x_exchange_free(xBA);
e3x_self_free(selfA);
e3x_self_free(selfB);
return 0;
}