self_crypto 0.0.8 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- }
@@ -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
- }
@@ -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
@@ -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