self_crypto 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ #include "self_olm/pk.h"
2
+ #include "self_crypto.h"
3
+
4
+ void pk_encryption_init(VALUE cSelfCryptoPK);
5
+ void pk_decryption_init(VALUE cSelfCryptoPK);
6
+ void pk_signing_init(VALUE cSelfCryptoPK);
7
+
8
+ void pk_init(void) {
9
+ VALUE cSelfCrypto = rb_define_module("SelfCrypto");
10
+ VALUE cSelfCryptoPK = rb_define_module_under(cSelfCrypto, "PK");
11
+
12
+ pk_encryption_init(cSelfCryptoPK);
13
+ pk_decryption_init(cSelfCryptoPK);
14
+ pk_signing_init(cSelfCryptoPK);
15
+ }
@@ -0,0 +1,129 @@
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_decryption(ptr);
9
+ free(ptr);
10
+ }
11
+
12
+ static size_t _size(const void *ptr __attribute__((unused))) {
13
+ return olm_pk_decryption_size();
14
+ }
15
+
16
+ static const rb_data_type_t olm_pk_decryption_type = {
17
+ .wrap_struct_name = "olm_pk_decryption",
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_decryption_size());
30
+ return TypedData_Wrap_Struct(klass, &olm_pk_decryption_type, olm_pk_decryption(memory));
31
+ }
32
+
33
+ static VALUE initialize(int argc, VALUE *argv, VALUE self) {
34
+ OlmPkDecryption *this;
35
+ size_t publicKeyLen;
36
+ char *publicKeyPtr;
37
+ VALUE privateKey;
38
+ TypedData_Get_Struct(self, OlmPkDecryption, &olm_pk_decryption_type, this);
39
+
40
+ rb_scan_args(argc, argv, "01", &privateKey);
41
+
42
+ if (NIL_P(privateKey)) {
43
+ privateKey = get_random(olm_pk_private_key_length());
44
+ } else {
45
+ Check_Type(privateKey, T_STRING);
46
+ if (RSTRING_LEN(privateKey) != olm_pk_private_key_length()) {
47
+ rb_raise(rb_eval_string("ArgumentError"), "private_key has wrong size (must be %lu)", olm_pk_private_key_length());
48
+ }
49
+ }
50
+
51
+ publicKeyLen = olm_pk_key_length();
52
+ publicKeyPtr = malloc_or_raise(publicKeyLen);
53
+
54
+ if (olm_pk_key_from_private(this,
55
+ publicKeyPtr, publicKeyLen,
56
+ RSTRING_PTR(privateKey), RSTRING_LEN(privateKey)) == olm_error()) {
57
+ free(publicKeyPtr);
58
+ raise_olm_error(olm_pk_decryption_last_error(this));
59
+ }
60
+
61
+ rb_iv_set(self, "@public_key", rb_str_new(publicKeyPtr, publicKeyLen));
62
+ free(publicKeyPtr);
63
+
64
+ return self;
65
+ }
66
+
67
+ static VALUE pk_decrypt(VALUE self, VALUE pkMessage) {
68
+ OlmPkDecryption *this;
69
+ size_t plaintextLen;
70
+ char *plaintextPtr;
71
+ VALUE ephemeral, mac, ciphertext, retval;
72
+ TypedData_Get_Struct(self, OlmPkDecryption, &olm_pk_decryption_type, this);
73
+
74
+ ephemeral = rb_funcall(pkMessage, rb_intern("ephemeral_key"), 0);
75
+ Check_Type(ephemeral, T_STRING);
76
+ mac = rb_funcall(pkMessage, rb_intern("mac"), 0);
77
+ Check_Type(mac, T_STRING);
78
+ ciphertext = rb_funcall(pkMessage, rb_intern("cipher_text"), 0);
79
+ Check_Type(ciphertext, T_STRING);
80
+
81
+ plaintextLen = olm_pk_max_plaintext_length(this, RSTRING_LEN(ciphertext));
82
+ plaintextPtr = malloc_or_raise(plaintextLen);
83
+
84
+ plaintextLen = olm_pk_decrypt(this,
85
+ RSTRING_PTR(ephemeral), RSTRING_LEN(ephemeral),
86
+ RSTRING_PTR(mac), RSTRING_LEN(mac),
87
+ RSTRING_PTR(ciphertext), RSTRING_LEN(ciphertext),
88
+ plaintextPtr, plaintextLen);
89
+ if (plaintextLen == olm_error()) {
90
+ free(plaintextPtr);
91
+ raise_olm_error(olm_pk_decryption_last_error(this));
92
+ }
93
+
94
+ retval = rb_str_new(plaintextPtr, plaintextLen);
95
+ free(plaintextPtr);
96
+
97
+ return retval;
98
+ }
99
+
100
+ static VALUE private_key(VALUE self) {
101
+ OlmPkDecryption *this;
102
+ size_t privkeyLen;
103
+ char *privkeyPtr;
104
+ VALUE retval;
105
+ TypedData_Get_Struct(self, OlmPkDecryption, &olm_pk_decryption_type, this);
106
+
107
+ privkeyLen = olm_pk_private_key_length();
108
+ privkeyPtr = malloc_or_raise(privkeyLen);
109
+
110
+ if (olm_pk_get_private_key(this, privkeyPtr, privkeyLen) == olm_error()) {
111
+ free(privkeyPtr);
112
+ raise_olm_error(olm_pk_decryption_last_error(this));
113
+ }
114
+
115
+ retval = rb_str_new(privkeyPtr, privkeyLen);
116
+ free(privkeyPtr);
117
+ return retval;
118
+ }
119
+
120
+ void pk_decryption_init(VALUE cSelfCryptoPK) {
121
+ VALUE cDecryption = rb_define_class_under(cSelfCryptoPK, "Decryption", rb_cData);
122
+
123
+ rb_define_alloc_func(cDecryption, _alloc);
124
+
125
+ rb_define_attr(cDecryption, "public_key", 1, 0);
126
+ rb_define_method(cDecryption, "initialize", initialize, -1);
127
+ rb_define_method(cDecryption, "decrypt", pk_decrypt, 1);
128
+ rb_define_method(cDecryption, "private_key", private_key, 0);
129
+ }
@@ -0,0 +1,93 @@
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_encryption(ptr);
9
+ free(ptr);
10
+ }
11
+
12
+ static size_t _size(const void *ptr __attribute__((unused))) {
13
+ return olm_pk_encryption_size();
14
+ }
15
+
16
+ static const rb_data_type_t olm_pk_encryption_type = {
17
+ .wrap_struct_name = "olm_pk_encryption",
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_encryption_size());
30
+ return TypedData_Wrap_Struct(klass, &olm_pk_encryption_type, olm_pk_encryption(memory));
31
+ }
32
+
33
+ static VALUE initialize(VALUE self, VALUE recipientKey) {
34
+ OlmPkEncryption *this;
35
+ TypedData_Get_Struct(self, OlmPkEncryption, &olm_pk_encryption_type, this);
36
+ Check_Type(recipientKey, T_STRING);
37
+
38
+ if (olm_pk_encryption_set_recipient_key(this,
39
+ RSTRING_PTR(recipientKey), RSTRING_LEN(recipientKey)) == olm_error()) {
40
+ raise_olm_error(olm_pk_encryption_last_error(this));
41
+ }
42
+
43
+ return self;
44
+ }
45
+
46
+ static VALUE pk_encrypt(VALUE self, VALUE plaintext) {
47
+ OlmPkEncryption *this;
48
+ size_t ciphertextLen, macLen, ephemeralLen, randomLen;
49
+ char *ciphertextPtr, *macPtr, *ephemeralPtr;
50
+ VALUE retval;
51
+ TypedData_Get_Struct(self, OlmPkEncryption, &olm_pk_encryption_type, this);
52
+ Check_Type(plaintext, T_STRING);
53
+
54
+ ciphertextLen = olm_pk_ciphertext_length(this, RSTRING_LEN(plaintext));
55
+ ciphertextPtr = malloc_or_raise(ciphertextLen);
56
+ macLen = olm_pk_mac_length(this);
57
+ macPtr = malloc_or_raise(macLen);
58
+ ephemeralLen = olm_pk_key_length();
59
+ ephemeralPtr = malloc_or_raise(ephemeralLen);
60
+ randomLen = olm_pk_encrypt_random_length(this);
61
+
62
+ if (olm_pk_encrypt(this,
63
+ RSTRING_PTR(plaintext), RSTRING_LEN(plaintext),
64
+ ciphertextPtr, ciphertextLen,
65
+ macPtr, macLen,
66
+ ephemeralPtr, ephemeralLen,
67
+ RSTRING_PTR(get_random(randomLen)), randomLen) == olm_error()) {
68
+ free(ephemeralPtr);
69
+ free(macPtr);
70
+ free(ciphertextPtr);
71
+ raise_olm_error(olm_pk_encryption_last_error(this));
72
+ }
73
+
74
+ retval = rb_funcall(rb_eval_string("SelfCrypto::PK::Message"), rb_intern("new"), 3,
75
+ rb_str_new(ciphertextPtr, ciphertextLen),
76
+ rb_str_new(macPtr, macLen),
77
+ rb_str_new(ephemeralPtr, ephemeralLen));
78
+
79
+ free(ephemeralPtr);
80
+ free(macPtr);
81
+ free(ciphertextPtr);
82
+
83
+ return retval;
84
+ }
85
+
86
+ void pk_encryption_init(VALUE cSelfCryptoPK) {
87
+ VALUE cEncryption = rb_define_class_under(cSelfCryptoPK, "Encryption", rb_cData);
88
+
89
+ rb_define_alloc_func(cEncryption, _alloc);
90
+
91
+ rb_define_method(cEncryption, "initialize", initialize, 1);
92
+ rb_define_method(cEncryption, "encrypt", pk_encrypt, 1);
93
+ }
@@ -0,0 +1,102 @@
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
+ }
@@ -0,0 +1,190 @@
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
+ }