self_crypto 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 34537603a575a2b32c468b332dd83e91ba2516c8c09984fb99d8f55910cdb680
4
+ data.tar.gz: 5e3a683e167fcdb4126bed5de9282d4d4e5c694ef54158d4dacd146b8d180d8e
5
+ SHA512:
6
+ metadata.gz: d0133166300cd4f784af606550459c670bdc0dde4a6db1a74e70fd0dcba36baae7a1e50604d923d0f0da25b3b59378d4418f0c671dadd1eb931faff780958be4
7
+ data.tar.gz: 498ad6f393d8683d9250ce56957d09d026283449a3964e3f5193a0ad1512bfce887eb67c75a99a8ded80768de075289b728328b18e494de4e15ac0d0ee248385
@@ -0,0 +1,19 @@
1
+ require 'rake/testtask'
2
+ require 'rake/extensiontask'
3
+
4
+ Rake::ExtensionTask.new do |ext|
5
+ ext.name = "self_crypto"
6
+ ext.ext_dir = "ext/self_crypto"
7
+ ext.lib_dir = "lib/self_crypto"
8
+ end
9
+
10
+ task :test => :compile
11
+
12
+ Rake::TestTask.new do |t|
13
+ t.name = :test
14
+ t.libs << "lib"
15
+ t.test_files = FileList["test/**/test_*.rb"]
16
+ t.verbose = true
17
+ end
18
+
19
+ task :default => :test
@@ -0,0 +1,292 @@
1
+ #include "sodium.h"
2
+ #include "self_olm/olm.h"
3
+ #include "self_crypto.h"
4
+
5
+ static VALUE last_error(VALUE self)
6
+ {
7
+ OlmAccount *this;
8
+ Data_Get_Struct(self, OlmAccount, this);
9
+
10
+ return rb_funcall(rb_eval_string("SelfCrypto::OlmError"), rb_intern("from_string"), 1, rb_str_new2(olm_account_last_error(this)));
11
+ }
12
+
13
+ static VALUE initialize(int argc, VALUE *argv, VALUE self)
14
+ {
15
+ VALUE pickle, password, seed, opts;
16
+ size_t size;
17
+ OlmAccount *this;
18
+ Data_Get_Struct(self, OlmAccount, this);
19
+
20
+ (void)rb_scan_args(argc, argv, "0:", &opts);
21
+
22
+ opts = (opts == Qnil) ? rb_hash_new(): opts;
23
+
24
+ pickle = rb_hash_aref(opts, ID2SYM(rb_intern("pickle")));
25
+ password = rb_hash_aref(opts, ID2SYM(rb_intern("password")));
26
+ seed = rb_hash_aref(opts, ID2SYM(rb_intern("seed")));
27
+
28
+ if(pickle != Qnil){
29
+
30
+ if(rb_obj_is_kind_of(pickle, rb_cString) != Qtrue){
31
+
32
+ rb_raise(rb_eTypeError, "pickle must be kind of String");
33
+ }
34
+ }
35
+
36
+ if(password != Qnil){
37
+
38
+ if(rb_obj_is_kind_of(password, rb_cString) != Qtrue){
39
+
40
+ rb_raise(rb_eTypeError, "password must be kind of String");
41
+ }
42
+ }
43
+ else{
44
+
45
+ password = rb_str_new2("");
46
+ }
47
+
48
+ if(pickle != Qnil){
49
+
50
+ if(olm_unpickle_account(this, RSTRING_PTR(password), RSTRING_LEN(password), RSTRING_PTR(dup_string(pickle)), RSTRING_LEN(pickle)) == olm_error()){
51
+
52
+ raise_olm_error(olm_account_last_error(this));
53
+ }
54
+ }
55
+ if(seed != Qnil){
56
+ if(olm_create_account_derrived_keys(this, RSTRING_PTR(seed), RSTRING_LEN(seed)) == olm_error()){
57
+
58
+ raise_olm_error(olm_account_last_error(this));
59
+ }
60
+ }
61
+ else{
62
+
63
+ size = olm_create_account_random_length(this);
64
+
65
+ if(olm_create_account(this, RSTRING_PTR(get_random(size)), size) == olm_error()){
66
+
67
+ raise_olm_error(olm_account_last_error(this));
68
+ }
69
+ }
70
+
71
+ return self;
72
+ }
73
+
74
+ static VALUE identity_keys(VALUE self)
75
+ {
76
+ OlmAccount *this;
77
+ size_t size;
78
+ Data_Get_Struct(self, OlmAccount, this);
79
+
80
+ size = olm_account_identity_keys_length(this);
81
+ uint8_t buf[size];
82
+
83
+ if(olm_account_identity_keys(this, buf, size) != size){
84
+
85
+ raise_olm_error(olm_account_last_error(this));
86
+ }
87
+
88
+ return rb_funcall(rb_eval_string("JSON"), rb_intern("parse"), 1, rb_str_new((char *)buf, size));
89
+ }
90
+
91
+ static VALUE generate_one_time_keys(VALUE self, VALUE number)
92
+ {
93
+ size_t size;
94
+ OlmAccount *this;
95
+ Data_Get_Struct(self, OlmAccount, this);
96
+
97
+ size = olm_account_generate_one_time_keys_random_length(this, NUM2SIZET(number));
98
+
99
+ if(olm_account_generate_one_time_keys(this, NUM2SIZET(number), RSTRING_PTR(get_random(size)), size) == olm_error()){
100
+
101
+ raise_olm_error(olm_account_last_error(this));
102
+ }
103
+
104
+ return self;
105
+ }
106
+
107
+ static VALUE one_time_keys_size(VALUE self)
108
+ {
109
+ OlmAccount *this;
110
+ Data_Get_Struct(self, OlmAccount, this);
111
+
112
+ return SIZET2NUM(olm_account_one_time_keys_length(this));
113
+ }
114
+
115
+ static VALUE one_time_keys(VALUE self)
116
+ {
117
+ VALUE retval;
118
+ size_t size;
119
+ void *ptr;
120
+ OlmAccount *this;
121
+ Data_Get_Struct(self, OlmAccount, this);
122
+
123
+ size = olm_account_one_time_keys_length(this);
124
+
125
+ // add an additional byte to stop this from overflowing
126
+ if((ptr = malloc(size+1)) == NULL){
127
+
128
+ rb_raise(rb_eNoMemError, "%s()", __FUNCTION__);
129
+ }
130
+
131
+ if(olm_account_one_time_keys(this, ptr, size) != size){
132
+
133
+ free(ptr);
134
+ raise_olm_error(olm_account_last_error(this));
135
+ }
136
+
137
+ retval = rb_funcall(rb_eval_string("JSON"), rb_intern("parse"), 1, rb_str_new(ptr, size));
138
+
139
+ free(ptr);
140
+
141
+ return retval;
142
+ }
143
+
144
+ static VALUE sign(VALUE self, VALUE message)
145
+ {
146
+ VALUE retval;
147
+ size_t size;
148
+ void *ptr;
149
+ OlmAccount *this;
150
+ Data_Get_Struct(self, OlmAccount, this);
151
+
152
+ size = olm_account_signature_length(this);
153
+
154
+ if((ptr = malloc(size)) == NULL){
155
+
156
+ rb_raise(rb_eNoMemError, "%s()", __FUNCTION__);
157
+ }
158
+
159
+ if(olm_account_sign(this, RSTRING_PTR(message), RSTRING_LEN(message), ptr, size) == olm_error()){
160
+
161
+ free(ptr);
162
+ raise_olm_error(olm_account_last_error(this));
163
+ }
164
+
165
+ retval = rb_str_new(ptr, size);
166
+
167
+ free(ptr);
168
+
169
+ return retval;
170
+ }
171
+
172
+ static VALUE mark_keys_as_published(VALUE self)
173
+ {
174
+ OlmAccount *this;
175
+ Data_Get_Struct(self, OlmAccount, this);
176
+
177
+ (void)olm_account_mark_keys_as_published(this);
178
+
179
+ return self;
180
+ }
181
+
182
+ static VALUE max_number_of_one_time_keys(VALUE self)
183
+ {
184
+ OlmAccount *this;
185
+ Data_Get_Struct(self, OlmAccount, this);
186
+
187
+ return SIZET2NUM(olm_account_max_number_of_one_time_keys(this));
188
+ }
189
+
190
+ static VALUE remove_one_time_keys(VALUE self, VALUE session)
191
+ {
192
+ OlmAccount *this;
193
+ Data_Get_Struct(self, OlmAccount, this);
194
+
195
+ OlmSession *s;
196
+ Data_Get_Struct(session, OlmSession, s);
197
+
198
+ if(olm_remove_one_time_keys(this, s) == olm_error()){
199
+
200
+ raise_olm_error(olm_account_last_error(this));
201
+ }
202
+
203
+ return self;
204
+ }
205
+
206
+ static VALUE outbound_session(VALUE self, VALUE identity_key, VALUE pre_key)
207
+ {
208
+ return rb_funcall(rb_eval_string("SelfCrypto::OutboundSession"), rb_intern("new"), 3, self, identity_key, pre_key);
209
+ }
210
+
211
+ static VALUE inbound_session(int argc, VALUE *argv, VALUE self)
212
+ {
213
+ VALUE args[] = {self, Qnil, Qnil};
214
+
215
+ (void)rb_scan_args(argc, argv, "11", &args[1], &args[2]);
216
+
217
+ return rb_class_new_instance(sizeof(args)/sizeof(*args), args, rb_eval_string("SelfCrypto::InboundSession"));
218
+ }
219
+
220
+ static VALUE to_pickle(int argc, VALUE *argv, VALUE self)
221
+ {
222
+ VALUE password, retval;
223
+ OlmAccount *this;
224
+ void *ptr;
225
+ size_t size;
226
+ Data_Get_Struct(self, OlmAccount, this);
227
+
228
+ (void)rb_scan_args(argc, argv, "01", &password);
229
+
230
+ password = (password == Qnil) ? rb_str_new2("") : password;
231
+
232
+ size = olm_pickle_account_length(this);
233
+
234
+ if((ptr = malloc(size)) == NULL){
235
+
236
+ rb_raise(rb_eNoMemError, "%s()", __FUNCTION__);
237
+ }
238
+
239
+ if(olm_pickle_account(this, RSTRING_PTR(password), RSTRING_LEN(password), ptr, size) != size){
240
+
241
+ free(ptr);
242
+ raise_olm_error(olm_account_last_error(this));
243
+ }
244
+
245
+ retval = rb_str_new(ptr, size);
246
+
247
+ free(ptr);
248
+
249
+ return retval;
250
+ }
251
+
252
+ static void _free(void *ptr)
253
+ {
254
+ olm_clear_account(ptr);
255
+ free(ptr);
256
+ }
257
+
258
+ static VALUE _alloc(VALUE klass)
259
+ {
260
+ OlmAccount *this;
261
+ VALUE self;
262
+
263
+ self = Data_Wrap_Struct(klass, 0, _free, calloc(1, olm_account_size()));
264
+
265
+ Data_Get_Struct(self, OlmAccount, this);
266
+
267
+ (void)olm_account((void *)this);
268
+
269
+ return self;
270
+ }
271
+
272
+ void account_init(void)
273
+ {
274
+ VALUE cRubyOLM = rb_define_module("SelfCrypto");
275
+ VALUE cAccount = rb_define_class_under(cRubyOLM, "Account", rb_cObject);
276
+
277
+ rb_define_alloc_func(cAccount, _alloc);
278
+
279
+ rb_define_method(cAccount, "initialize", initialize, -1);
280
+ rb_define_method(cAccount, "identity_keys", identity_keys, 0);
281
+ rb_define_method(cAccount, "one_time_keys", one_time_keys, 0);
282
+ rb_define_method(cAccount, "one_time_keys_size", one_time_keys_size, 0);
283
+ rb_define_method(cAccount, "generate_one_time_keys", generate_one_time_keys, 1);
284
+ rb_define_method(cAccount, "last_error", last_error, 0);
285
+ rb_define_method(cAccount, "sign", sign, 1);
286
+ rb_define_method(cAccount, "mark_keys_as_published", mark_keys_as_published, 0);
287
+ rb_define_method(cAccount, "max_number_of_one_time_keys", max_number_of_one_time_keys, 0);
288
+ rb_define_method(cAccount, "remove_one_time_keys", remove_one_time_keys, 1);
289
+ rb_define_method(cAccount, "outbound_session", outbound_session, 2);
290
+ rb_define_method(cAccount, "inbound_session", inbound_session, -1);
291
+ rb_define_method(cAccount, "to_pickle", to_pickle, -1);
292
+ }
@@ -0,0 +1,15 @@
1
+ require 'mkmf'
2
+
3
+ $CFLAGS = " -std=c99"
4
+
5
+ RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
6
+
7
+ pkg_config('self_olm')
8
+ pkg_config('self_omemo')
9
+ pkg_config("sodium")
10
+
11
+ abort "Missing sodium" unless have_library("sodium")
12
+ abort "Missing omemo" unless have_library("self_omemo")
13
+ abort "Missing olm" unless have_library("self_olm")
14
+
15
+ create_makefile('self_crypto/self_crypto')
@@ -0,0 +1,170 @@
1
+ #include "sodium.h"
2
+ #include "self_olm/olm.h"
3
+ #include "self_omemo.h"
4
+ #include "self_crypto.h"
5
+
6
+ static VALUE initialize(int argc, VALUE *argv, VALUE self)
7
+ {
8
+ VALUE identity;
9
+ GroupSession *this;
10
+
11
+ Data_Get_Struct(self, GroupSession, this);
12
+
13
+ (void)rb_scan_args(argc, argv, "1", &identity);
14
+
15
+ if(identity != Qnil){
16
+ if(rb_obj_is_kind_of(identity, rb_cString) != Qtrue){
17
+ rb_raise(rb_eTypeError, "identity must be kind of String");
18
+ }
19
+ }
20
+
21
+ omemo_set_identity(this, RSTRING_PTR(identity));
22
+
23
+ return self;
24
+ }
25
+
26
+ static VALUE add_participant(VALUE self, VALUE identity, VALUE session)
27
+ {
28
+ GroupSession *this;
29
+ OlmSession *s;
30
+
31
+ Data_Get_Struct(self, GroupSession, this);
32
+ Data_Get_Struct(session, OlmSession, s);
33
+
34
+ if(rb_obj_is_kind_of(identity, rb_eval_string("String")) != Qtrue){
35
+ rb_raise(rb_eTypeError, "identity must be kind of String");
36
+ }
37
+
38
+ if(
39
+ rb_obj_is_instance_of(session, rb_eval_string("SelfCrypto::Session")) != Qtrue &&
40
+ rb_obj_is_instance_of(session, rb_eval_string("SelfCrypto::InboundSession")) != Qtrue &&
41
+ rb_obj_is_instance_of(session, rb_eval_string("SelfCrypto::OutboundSession")) != Qtrue
42
+ ){
43
+ rb_raise(rb_eTypeError, "session must be an instance of SelfCrypto::Session, SelfCrypto::InboundSession or SelfCrypto::OutboundSession");
44
+ }
45
+
46
+ omemo_add_group_participant(this, RSTRING_PTR(identity), s);
47
+
48
+ return identity;
49
+ }
50
+
51
+ static VALUE encrypt(VALUE self, VALUE plaintext)
52
+ {
53
+ GroupSession *this;
54
+ VALUE ciphertext;
55
+ void *ptr;
56
+ size_t ciphertext_sz;
57
+
58
+ Data_Get_Struct(self, GroupSession, this);
59
+
60
+ if(rb_obj_is_kind_of(plaintext, rb_eval_string("String")) != Qtrue){
61
+ rb_raise(rb_eTypeError, "plaintext must be kind of String");
62
+ }
63
+
64
+ ciphertext_sz = omemo_encrypted_size(this, RSTRING_LEN(plaintext));
65
+
66
+ if (ciphertext_sz == 0) {
67
+ rb_raise(rb_eTypeError, "could not get size of encrypted message");
68
+ }
69
+
70
+ if((ptr = malloc(ciphertext_sz)) == NULL){
71
+ rb_raise(rb_eNoMemError, "%s()", __FUNCTION__);
72
+ }
73
+
74
+ ciphertext_sz = omemo_encrypt(
75
+ this,
76
+ RSTRING_PTR(plaintext),
77
+ RSTRING_LEN(plaintext),
78
+ ptr,
79
+ ciphertext_sz
80
+ );
81
+
82
+ if(ciphertext_sz == 0) {
83
+ free(ptr);
84
+ rb_raise(rb_eTypeError, "failed to encrypt");
85
+ }
86
+
87
+ ciphertext = rb_funcall(rb_eval_string("SelfCrypto::GroupMessage"), rb_intern("new"), 1, rb_str_new(ptr, ciphertext_sz));
88
+
89
+ free(ptr);
90
+
91
+ return ciphertext;
92
+ }
93
+
94
+ static VALUE decrypt(VALUE self, VALUE sender, VALUE ciphertext)
95
+ {
96
+ GroupSession *this;
97
+ VALUE plaintext;
98
+ void *ptr;
99
+ size_t plaintext_sz;
100
+
101
+ Data_Get_Struct(self, GroupSession, this);
102
+
103
+ if(rb_obj_is_kind_of(sender, rb_eval_string("String")) != Qtrue){
104
+ rb_raise(rb_eTypeError, "sender must be kind of String");
105
+ }
106
+
107
+ if(rb_obj_is_kind_of(ciphertext, rb_eval_string("String")) != Qtrue){
108
+ rb_raise(rb_eTypeError, "ciphertext must be kind of String");
109
+ }
110
+
111
+ plaintext_sz = omemo_decrypted_size(this, RSTRING_PTR(ciphertext), RSTRING_LEN(ciphertext));
112
+
113
+ if (plaintext_sz == 0) {
114
+ rb_raise(rb_eTypeError, "could not get size of decrypted message");
115
+ }
116
+
117
+ if((ptr = malloc(plaintext_sz)) == NULL){
118
+ rb_raise(rb_eNoMemError, "%s()", __FUNCTION__);
119
+ }
120
+
121
+ plaintext_sz = omemo_decrypt(
122
+ this,
123
+ RSTRING_PTR(sender),
124
+ ptr,
125
+ plaintext_sz,
126
+ RSTRING_PTR(ciphertext),
127
+ RSTRING_LEN(ciphertext)
128
+ );
129
+
130
+ if(plaintext_sz == 0) {
131
+ free(ptr);
132
+ rb_raise(rb_eTypeError, "failed to decrypt");
133
+ }
134
+
135
+ plaintext = rb_str_new(ptr, plaintext_sz);
136
+
137
+ free(ptr);
138
+
139
+ return plaintext;
140
+ }
141
+
142
+ static void _free(void *ptr)
143
+ {
144
+ omemo_destroy_group_session(ptr);
145
+ }
146
+
147
+ static VALUE _alloc(VALUE klass)
148
+ {
149
+ GroupSession *this;
150
+ VALUE self;
151
+
152
+ self = Data_Wrap_Struct(klass, 0, _free, omemo_create_group_session());
153
+
154
+ Data_Get_Struct(self, GroupSession, this);
155
+
156
+ return self;
157
+ }
158
+
159
+ void group_session_init()
160
+ {
161
+ VALUE cRubyOLM = rb_define_module("SelfCrypto");
162
+ VALUE cGroupSession = rb_define_class_under(cRubyOLM, "GroupSession", rb_cObject);
163
+
164
+ rb_define_alloc_func(cGroupSession, _alloc);
165
+
166
+ rb_define_method(cGroupSession, "initialize", initialize, -1);
167
+ rb_define_method(cGroupSession, "add_participant", add_participant, 2);
168
+ rb_define_method(cGroupSession, "encrypt", encrypt, 1);
169
+ rb_define_method(cGroupSession, "decrypt", decrypt, 2);
170
+ }