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.
- checksums.yaml +7 -0
- data/Rakefile +19 -0
- data/ext/self_crypto/account.c +292 -0
- data/ext/self_crypto/extconf.rb +15 -0
- data/ext/self_crypto/omemo.c +170 -0
- data/ext/self_crypto/pk.c +15 -0
- data/ext/self_crypto/pk_decryption.c +129 -0
- data/ext/self_crypto/pk_encryption.c +93 -0
- data/ext/self_crypto/pk_signing.c +102 -0
- data/ext/self_crypto/sas.c +190 -0
- data/ext/self_crypto/self_crypto.c +68 -0
- data/ext/self_crypto/self_crypto.h +15 -0
- data/ext/self_crypto/session.c +363 -0
- data/ext/self_crypto/utility.c +143 -0
- data/lib/self_crypto.rb +14 -0
- data/lib/self_crypto/account.rb +30 -0
- data/lib/self_crypto/group_message.rb +34 -0
- data/lib/self_crypto/group_session.rb +8 -0
- data/lib/self_crypto/message.rb +6 -0
- data/lib/self_crypto/olm_error.rb +70 -0
- data/lib/self_crypto/olm_message.rb +25 -0
- data/lib/self_crypto/pre_key_message.rb +6 -0
- data/lib/self_crypto/sas.rb +28 -0
- data/lib/self_crypto/sas_data.rb +71 -0
- data/lib/self_crypto/session.rb +16 -0
- data/lib/self_crypto/utility.rb +7 -0
- data/lib/self_crypto/version.rb +5 -0
- data/test/examples/test_bob_no_answer.rb +62 -0
- data/test/examples/test_exchange.rb +60 -0
- data/test/spec/test_account.rb +100 -0
- data/test/unit/test_account_methods.rb +64 -0
- metadata +134 -0
@@ -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
|
+
}
|