self_crypto 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/self_crypto/account.c +126 -120
- data/ext/self_crypto/extconf.rb +2 -4
- data/ext/self_crypto/omemo.c +40 -49
- data/ext/self_crypto/self_crypto.c +9 -40
- data/ext/self_crypto/session.c +71 -219
- data/ext/self_crypto/utility.c +73 -110
- data/lib/self_crypto/session.rb +0 -2
- data/lib/self_crypto/version.rb +1 -1
- data/lib/self_crypto.rb +0 -1
- data/test/spec/test_account.rb +0 -28
- metadata +8 -19
- data/ext/self_crypto/pk.c +0 -15
- data/ext/self_crypto/pk_decryption.c +0 -129
- data/ext/self_crypto/pk_encryption.c +0 -93
- data/ext/self_crypto/pk_signing.c +0 -102
- data/ext/self_crypto/sas.c +0 -190
- data/lib/self_crypto/sas.rb +0 -28
- data/lib/self_crypto/sas_data.rb +0 -71
- data/test/examples/test_bob_no_answer.rb +0 -62
- data/test/examples/test_exchange.rb +0 -60
@@ -1,102 +0,0 @@
|
|
1
|
-
#include <ruby.h>
|
2
|
-
#include <stdlib.h>
|
3
|
-
#include <self_olm/pk.h>
|
4
|
-
#include <self_olm/olm.h>
|
5
|
-
#include "self_crypto.h"
|
6
|
-
|
7
|
-
static void _free(void *ptr) {
|
8
|
-
olm_clear_pk_signing(ptr);
|
9
|
-
free(ptr);
|
10
|
-
}
|
11
|
-
|
12
|
-
static size_t _size(const void *ptr __attribute__((unused))) {
|
13
|
-
return olm_pk_signing_size();
|
14
|
-
}
|
15
|
-
|
16
|
-
static const rb_data_type_t olm_pk_signing_type = {
|
17
|
-
.wrap_struct_name = "olm_pk_signing",
|
18
|
-
.function = {
|
19
|
-
.dmark = NULL,
|
20
|
-
.dfree = _free,
|
21
|
-
.dsize = _size,
|
22
|
-
.reserved = {NULL}
|
23
|
-
},
|
24
|
-
.data = NULL,
|
25
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
26
|
-
};
|
27
|
-
|
28
|
-
static VALUE _alloc(VALUE klass) {
|
29
|
-
void *memory = malloc_or_raise(olm_pk_signing_size());
|
30
|
-
return TypedData_Wrap_Struct(klass, &olm_pk_signing_type, olm_pk_signing(memory));
|
31
|
-
}
|
32
|
-
|
33
|
-
static VALUE initialize(int argc, VALUE *argv, VALUE self) {
|
34
|
-
OlmPkSigning *this;
|
35
|
-
size_t publicKeyLen;
|
36
|
-
char *publicKeyPtr;
|
37
|
-
VALUE privateKey;
|
38
|
-
TypedData_Get_Struct(self, OlmPkSigning, &olm_pk_signing_type, this);
|
39
|
-
|
40
|
-
rb_scan_args(argc, argv, "01", &privateKey);
|
41
|
-
|
42
|
-
if (NIL_P(privateKey)) {
|
43
|
-
privateKey = get_random(olm_pk_signing_seed_length());
|
44
|
-
} else {
|
45
|
-
Check_Type(privateKey, T_STRING);
|
46
|
-
if (RSTRING_LEN(privateKey) != olm_pk_signing_seed_length()) {
|
47
|
-
rb_raise(rb_eval_string("ArgumentError"), "private_key has wrong size (must be %lu)", olm_pk_signing_seed_length());
|
48
|
-
}
|
49
|
-
}
|
50
|
-
|
51
|
-
publicKeyLen = olm_pk_signing_public_key_length();
|
52
|
-
publicKeyPtr = malloc_or_raise(publicKeyLen);
|
53
|
-
|
54
|
-
if (olm_pk_signing_key_from_seed(this,
|
55
|
-
publicKeyPtr, publicKeyLen,
|
56
|
-
RSTRING_PTR(privateKey), RSTRING_LEN(privateKey)) == olm_error()) {
|
57
|
-
free(publicKeyPtr);
|
58
|
-
raise_olm_error(olm_pk_signing_last_error(this));
|
59
|
-
}
|
60
|
-
|
61
|
-
rb_iv_set(self, "@public_key", rb_str_new(publicKeyPtr, publicKeyLen));
|
62
|
-
rb_iv_set(self, "@private_key", privateKey);
|
63
|
-
free(publicKeyPtr);
|
64
|
-
|
65
|
-
return self;
|
66
|
-
}
|
67
|
-
|
68
|
-
static VALUE sign(VALUE self, VALUE message) {
|
69
|
-
OlmPkSigning *this;
|
70
|
-
size_t signatureLen;
|
71
|
-
char *signaturePtr;
|
72
|
-
VALUE retval;
|
73
|
-
TypedData_Get_Struct(self, OlmPkSigning, &olm_pk_signing_type, this);
|
74
|
-
|
75
|
-
Check_Type(message, T_STRING);
|
76
|
-
|
77
|
-
signatureLen = olm_pk_signature_length();
|
78
|
-
signaturePtr = malloc_or_raise(signatureLen);
|
79
|
-
|
80
|
-
if (olm_pk_sign(this,
|
81
|
-
RSTRING_PTR(message), RSTRING_LEN(message),
|
82
|
-
signaturePtr, signatureLen) == olm_error()) {
|
83
|
-
free(signaturePtr);
|
84
|
-
raise_olm_error(olm_pk_signing_last_error(this));
|
85
|
-
}
|
86
|
-
|
87
|
-
retval = rb_str_new(signaturePtr, signatureLen);
|
88
|
-
free(signaturePtr);
|
89
|
-
return retval;
|
90
|
-
}
|
91
|
-
|
92
|
-
void pk_signing_init(VALUE cSelfCryptoPK) {
|
93
|
-
VALUE cSigning = rb_define_class_under(cSelfCryptoPK, "Signing", rb_cData);
|
94
|
-
|
95
|
-
rb_define_alloc_func(cSigning, _alloc);
|
96
|
-
|
97
|
-
rb_define_attr(cSigning, "public_key", 1, 0);
|
98
|
-
rb_define_attr(cSigning, "private_key", 1, 0);
|
99
|
-
|
100
|
-
rb_define_method(cSigning, "initialize", initialize, -1);
|
101
|
-
rb_define_method(cSigning, "sign", sign, 1);
|
102
|
-
}
|
data/ext/self_crypto/sas.c
DELETED
@@ -1,190 +0,0 @@
|
|
1
|
-
#include <ruby.h>
|
2
|
-
#include <stdlib.h>
|
3
|
-
#include <self_olm/olm.h>
|
4
|
-
#include <self_olm/sas.h>
|
5
|
-
#include "self_crypto.h"
|
6
|
-
|
7
|
-
static VALUE set_other_pubkey(VALUE self, VALUE other_public_key);
|
8
|
-
|
9
|
-
static void _free(void *ptr) {
|
10
|
-
olm_clear_sas(ptr);
|
11
|
-
free(ptr);
|
12
|
-
}
|
13
|
-
|
14
|
-
static size_t _size(const void *ptr __attribute__((unused))) {
|
15
|
-
return olm_sas_size();
|
16
|
-
}
|
17
|
-
|
18
|
-
static const rb_data_type_t olm_sas_type = {
|
19
|
-
.wrap_struct_name = "olm_sas",
|
20
|
-
.function = {
|
21
|
-
.dmark = NULL,
|
22
|
-
.dfree = _free,
|
23
|
-
.dsize = _size,
|
24
|
-
.reserved = {NULL}
|
25
|
-
},
|
26
|
-
.data = NULL,
|
27
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
28
|
-
};
|
29
|
-
|
30
|
-
static VALUE _alloc(VALUE klass) {
|
31
|
-
void *memory = malloc_or_raise(olm_sas_size());
|
32
|
-
return TypedData_Wrap_Struct(klass, &olm_sas_type, olm_sas(memory));
|
33
|
-
}
|
34
|
-
|
35
|
-
static void _ensure_other_pubkey(VALUE self) {
|
36
|
-
if (NIL_P(rb_iv_get(self, "@other_public_key"))) {
|
37
|
-
rb_raise(rb_eRuntimeError, "other_public_key must be set");
|
38
|
-
}
|
39
|
-
}
|
40
|
-
|
41
|
-
static VALUE initialize(int argc, VALUE *argv, VALUE self) {
|
42
|
-
OlmSAS *this;
|
43
|
-
VALUE random;
|
44
|
-
VALUE other_pubkey;
|
45
|
-
TypedData_Get_Struct(self, OlmSAS, &olm_sas_type, this);
|
46
|
-
|
47
|
-
rb_scan_args(argc, argv, "01", &other_pubkey);
|
48
|
-
|
49
|
-
random = get_random(olm_create_sas_random_length(this));
|
50
|
-
if (olm_create_sas(this, RSTRING_PTR(random), RSTRING_LEN(random)) == olm_error()) {
|
51
|
-
raise_olm_error(olm_sas_last_error(this));
|
52
|
-
}
|
53
|
-
|
54
|
-
// Make sure @other_public_key is set
|
55
|
-
rb_iv_set(self, "@other_public_key", Qnil);
|
56
|
-
|
57
|
-
if (!NIL_P(other_pubkey)) {
|
58
|
-
set_other_pubkey(self, other_pubkey);
|
59
|
-
}
|
60
|
-
|
61
|
-
return self;
|
62
|
-
}
|
63
|
-
|
64
|
-
static VALUE set_other_pubkey(VALUE self, VALUE other_public_key) {
|
65
|
-
OlmSAS *this;
|
66
|
-
TypedData_Get_Struct(self, OlmSAS, &olm_sas_type, this);
|
67
|
-
Check_Type(other_public_key, T_STRING);
|
68
|
-
|
69
|
-
if (RSTRING_LEN(other_public_key) != olm_sas_pubkey_length(this)) {
|
70
|
-
rb_raise(rb_eval_string("ArgumentError"), "other_public_key has wrong size (must be %lu)", olm_sas_pubkey_length(this));
|
71
|
-
}
|
72
|
-
|
73
|
-
// olm_sas_set_their_key trashes other_public_key, and rb_str_dup only creates a shallow copy.
|
74
|
-
VALUE other_public_key_dup = rb_str_new(RSTRING_PTR(other_public_key), RSTRING_LEN(other_public_key));
|
75
|
-
if (olm_sas_set_their_key(this, RSTRING_PTR(other_public_key_dup), RSTRING_LEN(other_public_key_dup)) == olm_error()) {
|
76
|
-
raise_olm_error(olm_sas_last_error(this));
|
77
|
-
}
|
78
|
-
|
79
|
-
rb_iv_set(self, "@other_public_key", other_public_key);
|
80
|
-
return other_public_key;
|
81
|
-
}
|
82
|
-
|
83
|
-
static VALUE get_public_key(VALUE self) {
|
84
|
-
OlmSAS *this;
|
85
|
-
size_t public_key_len;
|
86
|
-
char *public_key;
|
87
|
-
VALUE retval;
|
88
|
-
TypedData_Get_Struct(self, OlmSAS, &olm_sas_type, this);
|
89
|
-
|
90
|
-
public_key_len = olm_sas_pubkey_length(this);
|
91
|
-
public_key = malloc_or_raise(public_key_len);
|
92
|
-
|
93
|
-
if (olm_sas_get_pubkey(this, public_key, public_key_len) == olm_error()) {
|
94
|
-
free(public_key);
|
95
|
-
raise_olm_error(olm_sas_last_error(this));
|
96
|
-
}
|
97
|
-
|
98
|
-
retval = rb_str_new(public_key, public_key_len);
|
99
|
-
free(public_key);
|
100
|
-
return retval;
|
101
|
-
}
|
102
|
-
|
103
|
-
static VALUE generate_bytes(VALUE self, VALUE count, VALUE info) {
|
104
|
-
OlmSAS *this;
|
105
|
-
size_t output_len;
|
106
|
-
char *output;
|
107
|
-
VALUE retval;
|
108
|
-
TypedData_Get_Struct(self, OlmSAS, &olm_sas_type, this);
|
109
|
-
Check_Type(count, T_FIXNUM);
|
110
|
-
Check_Type(info, T_STRING);
|
111
|
-
|
112
|
-
output_len = NUM2ULONG(count);
|
113
|
-
output = malloc_or_raise(output_len);
|
114
|
-
|
115
|
-
if (olm_sas_generate_bytes(this, RSTRING_PTR(info), RSTRING_LEN(info), output, output_len) == olm_error()) {
|
116
|
-
free(output);
|
117
|
-
raise_olm_error(olm_sas_last_error(this));
|
118
|
-
}
|
119
|
-
|
120
|
-
retval = rb_str_new(output, output_len);
|
121
|
-
free(output);
|
122
|
-
// Return raw byte string here, higher abstraction in Ruby
|
123
|
-
return retval;
|
124
|
-
}
|
125
|
-
|
126
|
-
static VALUE calculate_mac(VALUE self, VALUE message, VALUE info) {
|
127
|
-
OlmSAS *this;
|
128
|
-
size_t mac_len;
|
129
|
-
char *mac;
|
130
|
-
VALUE retval;
|
131
|
-
TypedData_Get_Struct(self, OlmSAS, &olm_sas_type, this);
|
132
|
-
Check_Type(message, T_STRING);
|
133
|
-
Check_Type(info, T_STRING);
|
134
|
-
|
135
|
-
mac_len = olm_sas_mac_length(this);
|
136
|
-
mac = malloc_or_raise(mac_len);
|
137
|
-
|
138
|
-
if (olm_sas_calculate_mac(this,
|
139
|
-
RSTRING_PTR(message), RSTRING_LEN(message),
|
140
|
-
RSTRING_PTR(info), RSTRING_LEN(info),
|
141
|
-
mac, mac_len) == olm_error()) {
|
142
|
-
free(mac);
|
143
|
-
raise_olm_error(olm_sas_last_error(this));
|
144
|
-
}
|
145
|
-
|
146
|
-
retval = rb_str_new(mac, mac_len);
|
147
|
-
free(mac);
|
148
|
-
return retval;
|
149
|
-
}
|
150
|
-
|
151
|
-
static VALUE calculate_mac_long_kdf(VALUE self, VALUE message, VALUE info) {
|
152
|
-
OlmSAS *this;
|
153
|
-
size_t mac_len;
|
154
|
-
char *mac;
|
155
|
-
VALUE retval;
|
156
|
-
TypedData_Get_Struct(self, OlmSAS, &olm_sas_type, this);
|
157
|
-
Check_Type(message, T_STRING);
|
158
|
-
Check_Type(info, T_STRING);
|
159
|
-
|
160
|
-
mac_len = olm_sas_mac_length(this);
|
161
|
-
mac = malloc_or_raise(mac_len);
|
162
|
-
|
163
|
-
if (olm_sas_calculate_mac_long_kdf(this,
|
164
|
-
RSTRING_PTR(message), RSTRING_LEN(message),
|
165
|
-
RSTRING_PTR(info), RSTRING_LEN(info),
|
166
|
-
mac, mac_len) == olm_error()) {
|
167
|
-
free(mac);
|
168
|
-
raise_olm_error(olm_sas_last_error(this));
|
169
|
-
}
|
170
|
-
|
171
|
-
retval = rb_str_new(mac, mac_len);
|
172
|
-
free(mac);
|
173
|
-
return retval;
|
174
|
-
}
|
175
|
-
|
176
|
-
void sas_init(void) {
|
177
|
-
VALUE cSelfCrypto = rb_define_module("SelfCrypto");
|
178
|
-
VALUE cSAS = rb_define_class_under(cSelfCrypto, "SAS", rb_cData);
|
179
|
-
|
180
|
-
rb_define_alloc_func(cSAS, _alloc);
|
181
|
-
|
182
|
-
rb_define_attr(cSAS, "other_public_key", 1, 0);
|
183
|
-
rb_define_method(cSAS, "other_public_key=", set_other_pubkey, 1);
|
184
|
-
|
185
|
-
rb_define_method(cSAS, "initialize", initialize, -1);
|
186
|
-
rb_define_method(cSAS, "public_key", get_public_key, 0);
|
187
|
-
rb_define_method(cSAS, "generate_bytes", generate_bytes, 2);
|
188
|
-
rb_define_method(cSAS, "calculate_mac", calculate_mac, 2);
|
189
|
-
rb_define_method(cSAS, "calculate_mac_long_kdf", calculate_mac_long_kdf, 2);
|
190
|
-
}
|
data/lib/self_crypto/sas.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require_relative './sas_data'
|
2
|
-
|
3
|
-
class SelfCrypto::SAS
|
4
|
-
METHODS = %i[decimal emoji]
|
5
|
-
|
6
|
-
def generate(method, info)
|
7
|
-
method = method.to_sym
|
8
|
-
raise ArgumentError, "Unknown SAS method: #{method}" unless METHODS.include? method
|
9
|
-
|
10
|
-
send method, info
|
11
|
-
end
|
12
|
-
|
13
|
-
protected
|
14
|
-
|
15
|
-
def decimal(info)
|
16
|
-
bytes = generate_bytes(5, info)
|
17
|
-
bits = bytes.unpack1('B39')
|
18
|
-
grouped = bits.chars.each_slice(13).map &:join
|
19
|
-
grouped.map {|s| s.to_i(2) + 1000}
|
20
|
-
end
|
21
|
-
|
22
|
-
def emoji(info)
|
23
|
-
bytes = generate_bytes(6, info)
|
24
|
-
bits = bytes.unpack1('B42')
|
25
|
-
grouped = bits.chars.each_slice(6).map &:join
|
26
|
-
grouped.map {|s| EMOJI_TABLE[s.to_i(2)]}.join
|
27
|
-
end
|
28
|
-
end
|
data/lib/self_crypto/sas_data.rb
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
class SelfCrypto::SAS
|
5
|
-
EMOJI_TABLE = {
|
6
|
-
0 => '🐶',
|
7
|
-
1 => '🐱',
|
8
|
-
2 => '🦁',
|
9
|
-
3 => '🐎',
|
10
|
-
4 => '🦄',
|
11
|
-
5 => '🐷',
|
12
|
-
6 => '🐘',
|
13
|
-
7 => '🐰',
|
14
|
-
8 => '🐼',
|
15
|
-
9 => '🐓',
|
16
|
-
10 => '🐧',
|
17
|
-
11 => '🐢',
|
18
|
-
12 => '🐟',
|
19
|
-
13 => '🐙',
|
20
|
-
14 => '🦋',
|
21
|
-
15 => '🌷',
|
22
|
-
16 => '🌳',
|
23
|
-
17 => '🌵',
|
24
|
-
18 => '🍄',
|
25
|
-
19 => '🌏',
|
26
|
-
20 => '🌙',
|
27
|
-
21 => '☁',
|
28
|
-
22 => '🔥',
|
29
|
-
23 => '🍌',
|
30
|
-
24 => '🍎',
|
31
|
-
25 => '🍓',
|
32
|
-
26 => '🌽',
|
33
|
-
27 => '🍕',
|
34
|
-
28 => '🎂',
|
35
|
-
29 => '❤',
|
36
|
-
30 => '😀',
|
37
|
-
31 => '🤖',
|
38
|
-
32 => '🎩',
|
39
|
-
33 => '👓',
|
40
|
-
34 => '🔧',
|
41
|
-
35 => '🎅',
|
42
|
-
36 => '👍',
|
43
|
-
37 => '☂',
|
44
|
-
38 => '⌛',
|
45
|
-
39 => '⏰',
|
46
|
-
40 => '🎁',
|
47
|
-
41 => '💡',
|
48
|
-
42 => '📕',
|
49
|
-
43 => '✏',
|
50
|
-
44 => '📎',
|
51
|
-
45 => '✂',
|
52
|
-
46 => '🔒',
|
53
|
-
47 => '🔑',
|
54
|
-
48 => '🔨',
|
55
|
-
49 => '☎',
|
56
|
-
50 => '🏁',
|
57
|
-
51 => '🚂',
|
58
|
-
52 => '🚲',
|
59
|
-
53 => '✈',
|
60
|
-
54 => '🚀',
|
61
|
-
55 => '🏆',
|
62
|
-
56 => '⚽',
|
63
|
-
57 => '🎸',
|
64
|
-
58 => '🎺',
|
65
|
-
59 => '🔔',
|
66
|
-
60 => '⚓',
|
67
|
-
61 => '🎧',
|
68
|
-
62 => '📁',
|
69
|
-
63 => '📌'
|
70
|
-
}
|
71
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
require 'minitest/autorun'
|
2
|
-
require 'self_crypto'
|
3
|
-
|
4
|
-
class TestExchange < Minitest::Test
|
5
|
-
|
6
|
-
include SelfCrypto
|
7
|
-
|
8
|
-
# Alice -> Bob
|
9
|
-
# Alice -> Bob
|
10
|
-
#
|
11
|
-
def test_bob_no_answer
|
12
|
-
|
13
|
-
alice = Account.new
|
14
|
-
bob = Account.new
|
15
|
-
|
16
|
-
# Alice wants to send a message to Bob
|
17
|
-
alice_msg = "hi bob"
|
18
|
-
|
19
|
-
# Bob generates a one-time-key
|
20
|
-
bob.gen_otk
|
21
|
-
|
22
|
-
# Alice must have Bob's identity and one-time-key to make a session
|
23
|
-
alice_session = alice.outbound_session(bob.ik['curve25519'], bob.otk['curve25519'].values.first)
|
24
|
-
|
25
|
-
# Bob marks all one-time-keys as published
|
26
|
-
bob.mark_otk
|
27
|
-
|
28
|
-
# Alice can encrypt
|
29
|
-
encrypted = alice_session.encrypt(alice_msg)
|
30
|
-
assert_instance_of PreKeyMessage, encrypted
|
31
|
-
|
32
|
-
# Bob can create a session from this first message
|
33
|
-
bob_session = bob.inbound_session(encrypted)
|
34
|
-
|
35
|
-
# Bob can now update his list of marked otk (since he knows one has been used)
|
36
|
-
bob.update_otk(bob_session)
|
37
|
-
|
38
|
-
# Bob can decrypt Alice's message
|
39
|
-
bob_msg = bob_session.decrypt(encrypted)
|
40
|
-
|
41
|
-
assert_equal alice_msg, bob_msg
|
42
|
-
|
43
|
-
# At this point Bob has received but Alice hasn't
|
44
|
-
assert bob_session.has_received?
|
45
|
-
refute alice_session.has_received?
|
46
|
-
|
47
|
-
###
|
48
|
-
|
49
|
-
# Alice sends another message before reply from Bob
|
50
|
-
alice_msg = "BOB!"
|
51
|
-
|
52
|
-
encrypted = alice_session.encrypt(alice_msg)
|
53
|
-
assert_instance_of PreKeyMessage, encrypted
|
54
|
-
|
55
|
-
# Bob needs to check if this is the same session or a new one
|
56
|
-
same_session = bob_session.will_receive? encrypted
|
57
|
-
|
58
|
-
assert same_session
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'minitest/autorun'
|
2
|
-
require 'self_crypto'
|
3
|
-
|
4
|
-
class TestExchange < Minitest::Test
|
5
|
-
|
6
|
-
include SelfCrypto
|
7
|
-
|
8
|
-
# Alice -> Bob
|
9
|
-
# Alice <- Bob
|
10
|
-
def test_exchange
|
11
|
-
|
12
|
-
alice = Account.new
|
13
|
-
bob = Account.new
|
14
|
-
|
15
|
-
# Alice wants to send a message to Bob
|
16
|
-
alice_msg = "hi bob"
|
17
|
-
|
18
|
-
# Bob generates a one-time-key
|
19
|
-
bob.gen_otk
|
20
|
-
|
21
|
-
# Alice must have Bob's identity and one-time-key to make a session
|
22
|
-
alice_session = alice.outbound_session(bob.ik['curve25519'], bob.otk['curve25519'].values.first)
|
23
|
-
|
24
|
-
# Bob marks all one-time-keys as published
|
25
|
-
bob.mark_otk
|
26
|
-
|
27
|
-
# Alice can encrypt
|
28
|
-
encrypted = alice_session.encrypt(alice_msg)
|
29
|
-
assert_instance_of PreKeyMessage, encrypted
|
30
|
-
|
31
|
-
# Bob can create a session from this first message
|
32
|
-
bob_session = bob.inbound_session(encrypted)
|
33
|
-
|
34
|
-
# Bob can now update his list of marked otk (since he knows one has been used)
|
35
|
-
bob.update_otk(bob_session)
|
36
|
-
|
37
|
-
# Bob can decrypt Alice's message
|
38
|
-
bob_msg = bob_session.decrypt(encrypted)
|
39
|
-
|
40
|
-
assert_equal alice_msg, bob_msg
|
41
|
-
|
42
|
-
# At this point Bob has received but Alice hasn't
|
43
|
-
assert bob_session.has_received?
|
44
|
-
refute alice_session.has_received?
|
45
|
-
|
46
|
-
####
|
47
|
-
|
48
|
-
# Bob can send messages back to Alice
|
49
|
-
bob_msg = "hi alice"
|
50
|
-
|
51
|
-
encrypted = bob_session.encrypt(bob_msg)
|
52
|
-
assert_instance_of Message, encrypted
|
53
|
-
|
54
|
-
alice_msg = alice_session.decrypt(encrypted)
|
55
|
-
|
56
|
-
assert_equal alice_msg, bob_msg
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|