ruby-libstorj 0.0.0
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/.gitignore +10 -0
- data/.gitmodules +3 -0
- data/.rspec +1 -0
- data/Gemfile +23 -0
- data/Gemfile.lock +111 -0
- data/Guardfile +21 -0
- data/LICENSE +502 -0
- data/README.md +262 -0
- data/Rakefile +76 -0
- data/ext/libstorj/.gitignore +47 -0
- data/ext/libstorj/.travis.yml +27 -0
- data/ext/libstorj/Doxyfile +2427 -0
- data/ext/libstorj/LICENSE +502 -0
- data/ext/libstorj/Makefile.am +6 -0
- data/ext/libstorj/README.md +198 -0
- data/ext/libstorj/autogen.sh +3 -0
- data/ext/libstorj/configure.ac +64 -0
- data/ext/libstorj/depends/Makefile +153 -0
- data/ext/libstorj/depends/config.guess +1462 -0
- data/ext/libstorj/depends/config.sub +1823 -0
- data/ext/libstorj/depends/extract-osx-sdk.sh +33 -0
- data/ext/libstorj/depends/packages/cctools.mk +7 -0
- data/ext/libstorj/depends/packages/clang.mk +7 -0
- data/ext/libstorj/depends/packages/gmp.mk +23 -0
- data/ext/libstorj/depends/packages/gnutls.mk +25 -0
- data/ext/libstorj/depends/packages/json-c.mk +7 -0
- data/ext/libstorj/depends/packages/libcurl.mk +39 -0
- data/ext/libstorj/depends/packages/libmicrohttpd.mk +7 -0
- data/ext/libstorj/depends/packages/libuv.mk +7 -0
- data/ext/libstorj/depends/packages/nettle.mk +30 -0
- data/ext/libstorj/libstorj.pc.in +11 -0
- data/ext/libstorj/src/Makefile.am +23 -0
- data/ext/libstorj/src/bip39.c +233 -0
- data/ext/libstorj/src/bip39.h +64 -0
- data/ext/libstorj/src/bip39_english.h +2074 -0
- data/ext/libstorj/src/cli.c +1494 -0
- data/ext/libstorj/src/crypto.c +525 -0
- data/ext/libstorj/src/crypto.h +178 -0
- data/ext/libstorj/src/downloader.c +1923 -0
- data/ext/libstorj/src/downloader.h +163 -0
- data/ext/libstorj/src/http.c +688 -0
- data/ext/libstorj/src/http.h +175 -0
- data/ext/libstorj/src/rs.c +962 -0
- data/ext/libstorj/src/rs.h +99 -0
- data/ext/libstorj/src/storj.c +1523 -0
- data/ext/libstorj/src/storj.h +1014 -0
- data/ext/libstorj/src/uploader.c +2736 -0
- data/ext/libstorj/src/uploader.h +181 -0
- data/ext/libstorj/src/utils.c +336 -0
- data/ext/libstorj/src/utils.h +65 -0
- data/ext/libstorj/test/Makefile.am +27 -0
- data/ext/libstorj/test/mockbridge.c +260 -0
- data/ext/libstorj/test/mockbridge.json +687 -0
- data/ext/libstorj/test/mockbridgeinfo.json +1836 -0
- data/ext/libstorj/test/mockfarmer.c +358 -0
- data/ext/libstorj/test/storjtests.h +41 -0
- data/ext/libstorj/test/tests.c +1617 -0
- data/ext/libstorj/test/tests_rs.c +869 -0
- data/ext/ruby-libstorj/extconf.rb +8 -0
- data/ext/ruby-libstorj/ruby-libstorj.cc +17 -0
- data/lib/ruby-libstorj.rb +1 -0
- data/lib/ruby-libstorj/arg_forwarding_task.rb +58 -0
- data/lib/ruby-libstorj/env.rb +178 -0
- data/lib/ruby-libstorj/ext/bucket.rb +71 -0
- data/lib/ruby-libstorj/ext/create_bucket_request.rb +53 -0
- data/lib/ruby-libstorj/ext/curl_code.rb +139 -0
- data/lib/ruby-libstorj/ext/ext.rb +71 -0
- data/lib/ruby-libstorj/ext/file.rb +84 -0
- data/lib/ruby-libstorj/ext/get_bucket_request.rb +45 -0
- data/lib/ruby-libstorj/ext/json_request.rb +51 -0
- data/lib/ruby-libstorj/ext/list_files_request.rb +63 -0
- data/lib/ruby-libstorj/ext/types.rb +226 -0
- data/lib/ruby-libstorj/ext/upload_options.rb +38 -0
- data/lib/ruby-libstorj/libstorj.rb +22 -0
- data/lib/ruby-libstorj/mixins/storj.rb +27 -0
- data/lib/ruby-libstorj/struct.rb +42 -0
- data/ruby-libstorj.gemspec +57 -0
- data/spec/helpers/options.yml.example +22 -0
- data/spec/helpers/shared_rake_examples.rb +132 -0
- data/spec/helpers/storj_options.rb +96 -0
- data/spec/helpers/upload.data +3 -0
- data/spec/helpers/upload.data.sha256 +1 -0
- data/spec/libstorj_spec.rb +0 -0
- data/spec/ruby-libstorj/arg_forwarding_task_spec.rb +311 -0
- data/spec/ruby-libstorj/env_spec.rb +353 -0
- data/spec/ruby-libstorj/ext_spec.rb +75 -0
- data/spec/ruby-libstorj/json_request_spec.rb +13 -0
- data/spec/ruby-libstorj/libstorj_spec.rb +81 -0
- data/spec/ruby-libstorj/struct_spec.rb +64 -0
- data/spec/spec_helper.rb +113 -0
- metadata +136 -0
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
#include "crypto.h"
|
|
2
|
+
|
|
3
|
+
int ripemd160sha256_as_string(uint8_t *data, uint64_t data_size, char *digest)
|
|
4
|
+
{
|
|
5
|
+
uint8_t *ripemd160_digest = calloc(RIPEMD160_DIGEST_SIZE, sizeof(char));
|
|
6
|
+
if (!ripemd160_digest) {
|
|
7
|
+
return 1;
|
|
8
|
+
}
|
|
9
|
+
ripemd160sha256(data, data_size, ripemd160_digest);
|
|
10
|
+
|
|
11
|
+
// Convert ripemd160 hex to character array
|
|
12
|
+
char *ripemd160_str = hex2str(RIPEMD160_DIGEST_SIZE, ripemd160_digest);
|
|
13
|
+
if (!ripemd160_str) {
|
|
14
|
+
return 1;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//Copy the result into buffer
|
|
18
|
+
memcpy(digest, ripemd160_str, RIPEMD160_DIGEST_SIZE * 2);
|
|
19
|
+
|
|
20
|
+
free(ripemd160_digest);
|
|
21
|
+
free(ripemd160_str);
|
|
22
|
+
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
int ripemd160sha256(uint8_t *data, uint64_t data_size, uint8_t *digest)
|
|
27
|
+
{
|
|
28
|
+
// Get the sha256 of the data
|
|
29
|
+
uint8_t sha256_digest[SHA256_DIGEST_SIZE];
|
|
30
|
+
sha256_of_str(data, data_size, sha256_digest);
|
|
31
|
+
|
|
32
|
+
// Get the ripemd160 of the sha256
|
|
33
|
+
uint8_t ripemd160_digest[RIPEMD160_DIGEST_SIZE];
|
|
34
|
+
ripemd160_of_str(sha256_digest, SHA256_DIGEST_SIZE, ripemd160_digest);
|
|
35
|
+
|
|
36
|
+
//Copy the result into buffer
|
|
37
|
+
memcpy(digest, ripemd160_digest, RIPEMD160_DIGEST_SIZE);
|
|
38
|
+
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
int double_ripemd160sha256(uint8_t *data, uint64_t data_size, uint8_t *digest)
|
|
43
|
+
{
|
|
44
|
+
uint8_t *first_ripemd160_digest = calloc(RIPEMD160_DIGEST_SIZE, sizeof(char));
|
|
45
|
+
if (!first_ripemd160_digest) {
|
|
46
|
+
return 1;
|
|
47
|
+
}
|
|
48
|
+
ripemd160sha256(data, data_size, first_ripemd160_digest);
|
|
49
|
+
|
|
50
|
+
uint8_t *second_ripemd160_digest = calloc(RIPEMD160_DIGEST_SIZE, sizeof(char));
|
|
51
|
+
if (!second_ripemd160_digest) {
|
|
52
|
+
return 1;
|
|
53
|
+
}
|
|
54
|
+
ripemd160sha256(first_ripemd160_digest, RIPEMD160_DIGEST_SIZE,
|
|
55
|
+
second_ripemd160_digest);
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
//Copy the result into buffer
|
|
59
|
+
memcpy(digest, second_ripemd160_digest, RIPEMD160_DIGEST_SIZE);
|
|
60
|
+
|
|
61
|
+
free(first_ripemd160_digest);
|
|
62
|
+
free(second_ripemd160_digest);
|
|
63
|
+
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
int double_ripemd160sha256_as_string(uint8_t *data, uint64_t data_size,
|
|
68
|
+
char **digest)
|
|
69
|
+
{
|
|
70
|
+
uint8_t *ripemd160_digest = calloc(RIPEMD160_DIGEST_SIZE, sizeof(char));
|
|
71
|
+
if (!ripemd160_digest) {
|
|
72
|
+
return 1;
|
|
73
|
+
}
|
|
74
|
+
if (double_ripemd160sha256(data, data_size, ripemd160_digest)) {
|
|
75
|
+
return 1;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Convert ripemd160 hex to character array
|
|
79
|
+
char *ripemd160_str = hex2str(RIPEMD160_DIGEST_SIZE, ripemd160_digest);
|
|
80
|
+
if (!ripemd160_str) {
|
|
81
|
+
return 1;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
//Copy the result into buffer
|
|
85
|
+
memcpy(*digest, ripemd160_str, RIPEMD160_DIGEST_SIZE * 2);
|
|
86
|
+
|
|
87
|
+
free(ripemd160_digest);
|
|
88
|
+
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
int generate_bucket_key(const char *mnemonic, const char *bucket_id,
|
|
93
|
+
char **bucket_key)
|
|
94
|
+
{
|
|
95
|
+
int status = 0;
|
|
96
|
+
char *seed = calloc(128 + 1, sizeof(char));
|
|
97
|
+
if (!seed) {
|
|
98
|
+
status = 1;
|
|
99
|
+
goto cleanup;
|
|
100
|
+
}
|
|
101
|
+
mnemonic_to_seed(mnemonic, "", &seed);
|
|
102
|
+
seed[128] = '\0';
|
|
103
|
+
|
|
104
|
+
status = get_deterministic_key(seed, 128, bucket_id, bucket_key);
|
|
105
|
+
|
|
106
|
+
cleanup:
|
|
107
|
+
|
|
108
|
+
if (seed) {
|
|
109
|
+
memset_zero(seed, 128 + 1);
|
|
110
|
+
free(seed);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return status;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
int generate_file_key(const char *mnemonic, const char *bucket_id,
|
|
117
|
+
const char *index, char **file_key)
|
|
118
|
+
{
|
|
119
|
+
int status = 0;
|
|
120
|
+
char *bucket_key = calloc(DETERMINISTIC_KEY_SIZE + 1, sizeof(char));
|
|
121
|
+
if (!bucket_key) {
|
|
122
|
+
status = 1;
|
|
123
|
+
goto cleanup;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
status = generate_bucket_key(mnemonic, bucket_id, &bucket_key);
|
|
127
|
+
if (status) {
|
|
128
|
+
goto cleanup;
|
|
129
|
+
}
|
|
130
|
+
bucket_key[DETERMINISTIC_KEY_SIZE] = '\0';
|
|
131
|
+
|
|
132
|
+
get_deterministic_key(bucket_key, 64, index, file_key);
|
|
133
|
+
|
|
134
|
+
cleanup:
|
|
135
|
+
|
|
136
|
+
if (bucket_key) {
|
|
137
|
+
memset_zero(bucket_key, DETERMINISTIC_KEY_SIZE + 1);
|
|
138
|
+
free(bucket_key);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return status;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
int get_deterministic_key(const char *key, int key_len,
|
|
145
|
+
const char *id, char **buffer)
|
|
146
|
+
{
|
|
147
|
+
int input_len = key_len + strlen(id);
|
|
148
|
+
char *sha512input = calloc(input_len + 1, sizeof(char));
|
|
149
|
+
if (!sha512input) {
|
|
150
|
+
return 1;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Combine key and id
|
|
154
|
+
memcpy(sha512input, key, key_len);
|
|
155
|
+
memcpy(sha512input + key_len, id, strlen(id));
|
|
156
|
+
sha512input[input_len] = '\0';
|
|
157
|
+
|
|
158
|
+
// Convert input to hexdata
|
|
159
|
+
uint8_t *sha512input_as_hex = str2hex(input_len, sha512input);
|
|
160
|
+
if (!sha512input_as_hex) {
|
|
161
|
+
return 2;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Sha512 of hexdata
|
|
165
|
+
uint8_t sha512_digest[SHA512_DIGEST_SIZE];
|
|
166
|
+
sha512_of_str(sha512input_as_hex, input_len / 2, sha512_digest);
|
|
167
|
+
|
|
168
|
+
// Convert Sha512 hex to character array
|
|
169
|
+
char *sha512_str = hex2str(SHA512_DIGEST_SIZE, sha512_digest);
|
|
170
|
+
if (!sha512_str) {
|
|
171
|
+
return 2;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
//First 64 bytes of sha512
|
|
175
|
+
memcpy(*buffer, sha512_str, DETERMINISTIC_KEY_SIZE);
|
|
176
|
+
|
|
177
|
+
memset_zero(sha512_str, SHA512_DIGEST_SIZE * 2 + 1);
|
|
178
|
+
memset_zero(sha512_digest, SHA512_DIGEST_SIZE);
|
|
179
|
+
memset_zero(sha512input_as_hex, input_len / 2 + 1);
|
|
180
|
+
memset_zero(sha512input, input_len + 1);
|
|
181
|
+
|
|
182
|
+
free(sha512input);
|
|
183
|
+
free(sha512input_as_hex);
|
|
184
|
+
free(sha512_str);
|
|
185
|
+
|
|
186
|
+
return 0;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
int sha256_of_str(const uint8_t *str, int str_len, uint8_t *digest)
|
|
190
|
+
{
|
|
191
|
+
struct sha256_ctx ctx;
|
|
192
|
+
sha256_init(&ctx);
|
|
193
|
+
sha256_update(&ctx, str_len, str);
|
|
194
|
+
sha256_digest(&ctx, SHA256_DIGEST_SIZE, digest);
|
|
195
|
+
|
|
196
|
+
return 0;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
int ripemd160_of_str(const uint8_t *str, int str_len, uint8_t *digest)
|
|
200
|
+
{
|
|
201
|
+
struct ripemd160_ctx ctx;
|
|
202
|
+
ripemd160_init(&ctx);
|
|
203
|
+
ripemd160_update(&ctx, str_len, str);
|
|
204
|
+
ripemd160_digest(&ctx, RIPEMD160_DIGEST_SIZE, digest);
|
|
205
|
+
|
|
206
|
+
return 0;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
int sha512_of_str(const uint8_t *str, int str_len, uint8_t *digest)
|
|
210
|
+
{
|
|
211
|
+
struct sha512_ctx ctx;
|
|
212
|
+
sha512_init(&ctx);
|
|
213
|
+
sha512_update(&ctx, str_len, str);
|
|
214
|
+
sha512_digest(&ctx, SHA512_DIGEST_SIZE, digest);
|
|
215
|
+
|
|
216
|
+
return 0;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
void pbkdf2_hmac_sha512 (
|
|
220
|
+
unsigned key_length,
|
|
221
|
+
const uint8_t *key,
|
|
222
|
+
unsigned iterations,
|
|
223
|
+
unsigned salt_length, const uint8_t *salt,
|
|
224
|
+
unsigned length, uint8_t *dst)
|
|
225
|
+
{
|
|
226
|
+
struct hmac_sha512_ctx sha512ctx;
|
|
227
|
+
|
|
228
|
+
hmac_sha512_set_key (&sha512ctx, key_length, key);
|
|
229
|
+
PBKDF2 (&sha512ctx, hmac_sha512_update, hmac_sha512_digest,
|
|
230
|
+
SHA512_DIGEST_SIZE, iterations, salt_length, salt, length, dst);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
int increment_ctr_aes_iv(uint8_t *iv, uint64_t bytes_position)
|
|
234
|
+
{
|
|
235
|
+
if (bytes_position % AES_BLOCK_SIZE != 0) {
|
|
236
|
+
return 1;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
uint64_t times = bytes_position / AES_BLOCK_SIZE;
|
|
240
|
+
|
|
241
|
+
while (times) {
|
|
242
|
+
unsigned int i = AES_BLOCK_SIZE - 1;
|
|
243
|
+
if (++(iv)[i] == 0) {
|
|
244
|
+
while (i > 0 && ++(iv)[--i] == 0);
|
|
245
|
+
}
|
|
246
|
+
times--;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return 0;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
uint8_t *key_from_passphrase(const char *passphrase, const char *salt)
|
|
253
|
+
{
|
|
254
|
+
uint8_t passphrase_len = strlen(passphrase);
|
|
255
|
+
uint8_t salt_len = strlen(salt);
|
|
256
|
+
uint8_t *key = calloc(SHA256_DIGEST_SIZE + 1, sizeof(uint8_t));
|
|
257
|
+
if (!key) {
|
|
258
|
+
return NULL;
|
|
259
|
+
}
|
|
260
|
+
int rounds = 200000;
|
|
261
|
+
pbkdf2_hmac_sha256(passphrase_len, (uint8_t *)passphrase, rounds, salt_len,
|
|
262
|
+
(uint8_t *)salt, SHA256_DIGEST_SIZE, key);
|
|
263
|
+
|
|
264
|
+
return key;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
int decrypt_data(const char *passphrase, const char *salt, const char *data,
|
|
268
|
+
char **result)
|
|
269
|
+
{
|
|
270
|
+
|
|
271
|
+
uint8_t *key = key_from_passphrase(passphrase, salt);
|
|
272
|
+
if (!key) {
|
|
273
|
+
return 1;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Convert from hex string
|
|
277
|
+
int len = strlen(data);
|
|
278
|
+
if (len / 2 < GCM_DIGEST_SIZE + SHA256_DIGEST_SIZE + 1) {
|
|
279
|
+
free(key);
|
|
280
|
+
return 1;
|
|
281
|
+
}
|
|
282
|
+
int enc_len = len / 2;
|
|
283
|
+
int data_size = enc_len - GCM_DIGEST_SIZE - SHA256_DIGEST_SIZE;
|
|
284
|
+
uint8_t *enc = str2hex(len, (char *)data);
|
|
285
|
+
if (!enc) {
|
|
286
|
+
free(key);
|
|
287
|
+
return 1;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Get the expected digest and iv
|
|
291
|
+
uint8_t digest[GCM_DIGEST_SIZE];
|
|
292
|
+
uint8_t data_iv[SHA256_DIGEST_SIZE];
|
|
293
|
+
uint8_t cipher_text[data_size];
|
|
294
|
+
memcpy(&digest, enc, GCM_DIGEST_SIZE);
|
|
295
|
+
memcpy(&data_iv, enc + GCM_DIGEST_SIZE, SHA256_DIGEST_SIZE);
|
|
296
|
+
memcpy(&cipher_text, enc + GCM_DIGEST_SIZE + SHA256_DIGEST_SIZE, data_size);
|
|
297
|
+
|
|
298
|
+
free(enc);
|
|
299
|
+
|
|
300
|
+
struct gcm_aes256_ctx gcm_ctx;
|
|
301
|
+
gcm_aes256_set_key(&gcm_ctx, key);
|
|
302
|
+
gcm_aes256_set_iv(&gcm_ctx, SHA256_DIGEST_SIZE, data_iv);
|
|
303
|
+
free(key);
|
|
304
|
+
|
|
305
|
+
// Decrypt the data
|
|
306
|
+
*result = calloc(data_size + 1, sizeof(char));
|
|
307
|
+
int pos = 0;
|
|
308
|
+
size_t remain = data_size;
|
|
309
|
+
while (pos < data_size) {
|
|
310
|
+
int len = AES_BLOCK_SIZE;
|
|
311
|
+
if (remain < AES_BLOCK_SIZE) {
|
|
312
|
+
len = remain;
|
|
313
|
+
}
|
|
314
|
+
gcm_aes256_decrypt(&gcm_ctx, len, (uint8_t *)*result + pos,
|
|
315
|
+
cipher_text + pos);
|
|
316
|
+
pos += AES_BLOCK_SIZE;
|
|
317
|
+
remain -= AES_BLOCK_SIZE;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
uint8_t actual_digest[GCM_DIGEST_SIZE];
|
|
321
|
+
gcm_aes256_digest(&gcm_ctx, GCM_DIGEST_SIZE, actual_digest);
|
|
322
|
+
|
|
323
|
+
int digest_match = memcmp(actual_digest, digest, GCM_DIGEST_SIZE);
|
|
324
|
+
if (digest_match != 0) {
|
|
325
|
+
return 1;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return 0;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
int encrypt_data(const char *passphrase, const char *salt, const char *data,
|
|
332
|
+
char **result)
|
|
333
|
+
{
|
|
334
|
+
uint8_t *key = key_from_passphrase(passphrase, salt);
|
|
335
|
+
if (!key) {
|
|
336
|
+
return 1;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
uint8_t data_size = strlen(data);
|
|
340
|
+
if (data_size <= 0) {
|
|
341
|
+
return 1;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Generate synthetic iv with first half of sha512 hmac of data
|
|
345
|
+
struct hmac_sha512_ctx hmac_ctx;
|
|
346
|
+
hmac_sha512_set_key(&hmac_ctx, SHA256_DIGEST_SIZE, key);
|
|
347
|
+
hmac_sha512_update(&hmac_ctx, data_size, (uint8_t *)data);
|
|
348
|
+
uint8_t data_iv[SHA256_DIGEST_SIZE];
|
|
349
|
+
hmac_sha512_digest(&hmac_ctx, SHA256_DIGEST_SIZE, data_iv);
|
|
350
|
+
|
|
351
|
+
// Encrypt the data
|
|
352
|
+
struct gcm_aes256_ctx gcm_ctx;
|
|
353
|
+
gcm_aes256_set_key(&gcm_ctx, key);
|
|
354
|
+
gcm_aes256_set_iv(&gcm_ctx, SHA256_DIGEST_SIZE, data_iv);
|
|
355
|
+
free(key);
|
|
356
|
+
|
|
357
|
+
int pos = 0;
|
|
358
|
+
size_t remain = data_size;
|
|
359
|
+
uint8_t cipher_text[data_size];
|
|
360
|
+
while (pos < data_size) {
|
|
361
|
+
int len = AES_BLOCK_SIZE;
|
|
362
|
+
if (remain < AES_BLOCK_SIZE) {
|
|
363
|
+
len = remain;
|
|
364
|
+
}
|
|
365
|
+
gcm_aes256_encrypt(&gcm_ctx, len, cipher_text + pos,
|
|
366
|
+
(uint8_t *)data + pos);
|
|
367
|
+
pos += AES_BLOCK_SIZE;
|
|
368
|
+
remain -= AES_BLOCK_SIZE;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// Get the digest
|
|
372
|
+
uint8_t digest[GCM_DIGEST_SIZE];
|
|
373
|
+
gcm_aes256_digest(&gcm_ctx, GCM_DIGEST_SIZE, digest);
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
// Copy the digest, iv and cipher text to a buffer
|
|
377
|
+
int buffer_size = GCM_DIGEST_SIZE + (SHA512_DIGEST_SIZE / 2) + data_size;
|
|
378
|
+
uint8_t *buffer = calloc(buffer_size, sizeof(char));
|
|
379
|
+
if (!buffer) {
|
|
380
|
+
return 1;
|
|
381
|
+
}
|
|
382
|
+
memcpy(buffer, digest, GCM_DIGEST_SIZE);
|
|
383
|
+
memcpy(buffer + GCM_DIGEST_SIZE, data_iv, SHA256_DIGEST_SIZE);
|
|
384
|
+
memcpy(buffer + GCM_DIGEST_SIZE + SHA256_DIGEST_SIZE,
|
|
385
|
+
&cipher_text, data_size);
|
|
386
|
+
|
|
387
|
+
// Convert to hex string
|
|
388
|
+
*result = hex2str(buffer_size, buffer);
|
|
389
|
+
if (!*result) {
|
|
390
|
+
return 1;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
free(buffer);
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
return 0;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
int encrypt_meta(const char *filemeta,
|
|
400
|
+
uint8_t *encrypt_key,
|
|
401
|
+
uint8_t *encrypt_iv,
|
|
402
|
+
char **buffer_base64)
|
|
403
|
+
{
|
|
404
|
+
struct gcm_aes256_ctx ctx2;
|
|
405
|
+
gcm_aes256_set_key(&ctx2, encrypt_key);
|
|
406
|
+
gcm_aes256_set_iv(&ctx2, SHA256_DIGEST_SIZE, encrypt_iv);
|
|
407
|
+
|
|
408
|
+
int pos = 0;
|
|
409
|
+
size_t length = strlen(filemeta);
|
|
410
|
+
size_t remain = length;
|
|
411
|
+
uint8_t cipher_text[length];
|
|
412
|
+
while (pos < length) {
|
|
413
|
+
int len = AES_BLOCK_SIZE;
|
|
414
|
+
if (remain < AES_BLOCK_SIZE) {
|
|
415
|
+
len = remain;
|
|
416
|
+
}
|
|
417
|
+
gcm_aes256_encrypt(&ctx2, len, cipher_text + pos,
|
|
418
|
+
(uint8_t *)filemeta + pos);
|
|
419
|
+
pos += AES_BLOCK_SIZE;
|
|
420
|
+
remain -= AES_BLOCK_SIZE;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
uint8_t digest[GCM_DIGEST_SIZE];
|
|
424
|
+
gcm_aes256_digest(&ctx2, GCM_DIGEST_SIZE, digest);
|
|
425
|
+
|
|
426
|
+
uint32_t buf_len = GCM_DIGEST_SIZE + SHA256_DIGEST_SIZE + length;
|
|
427
|
+
uint8_t buf[buf_len];
|
|
428
|
+
memcpy(buf, digest, GCM_DIGEST_SIZE);
|
|
429
|
+
memcpy(buf + GCM_DIGEST_SIZE, encrypt_iv, SHA256_DIGEST_SIZE);
|
|
430
|
+
memcpy(buf + GCM_DIGEST_SIZE + SHA256_DIGEST_SIZE, &cipher_text, length);
|
|
431
|
+
|
|
432
|
+
size_t base64_len = BASE64_ENCODE_LENGTH(buf_len);
|
|
433
|
+
*buffer_base64 = calloc(base64_len + 3, sizeof(uint8_t));
|
|
434
|
+
if (!*buffer_base64) {
|
|
435
|
+
//STORJ_MEMORY_ERROR
|
|
436
|
+
return 1;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
struct base64_encode_ctx ctx3;
|
|
440
|
+
base64_encode_init(&ctx3);
|
|
441
|
+
size_t out_len = base64_encode_update(&ctx3, (uint8_t *)*buffer_base64,
|
|
442
|
+
buf_len, buf);
|
|
443
|
+
out_len += base64_encode_final(&ctx3, (uint8_t *)*buffer_base64 + out_len);
|
|
444
|
+
|
|
445
|
+
return 0;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
int decrypt_meta(const char *buffer_base64,
|
|
449
|
+
uint8_t *decrypt_key,
|
|
450
|
+
char **filemeta)
|
|
451
|
+
{
|
|
452
|
+
uint32_t buffer_len = BASE64_DECODE_LENGTH(strlen(buffer_base64));
|
|
453
|
+
uint8_t *buffer = calloc(buffer_len, sizeof(uint8_t));
|
|
454
|
+
if (!buffer) {
|
|
455
|
+
//STORJ_MEMORY_ERROR
|
|
456
|
+
return 1;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
size_t decode_len = 0;
|
|
460
|
+
struct base64_decode_ctx ctx3;
|
|
461
|
+
base64_decode_init(&ctx3);
|
|
462
|
+
if (!base64_decode_update(&ctx3, &decode_len, buffer,
|
|
463
|
+
strlen(buffer_base64), (uint8_t *)buffer_base64)) {
|
|
464
|
+
free(buffer);
|
|
465
|
+
return 1;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
if (!base64_decode_final(&ctx3)) {
|
|
469
|
+
free(buffer);
|
|
470
|
+
return 1;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
if (GCM_DIGEST_SIZE + SHA256_DIGEST_SIZE + 1 > decode_len) {
|
|
474
|
+
free(buffer);
|
|
475
|
+
//STORJ_META_DECRYPTION_ERROR
|
|
476
|
+
return 1;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
size_t length = decode_len - GCM_DIGEST_SIZE - SHA256_DIGEST_SIZE;
|
|
480
|
+
|
|
481
|
+
uint8_t digest[GCM_DIGEST_SIZE];
|
|
482
|
+
uint8_t iv[SHA256_DIGEST_SIZE];
|
|
483
|
+
uint8_t cipher_text[length];
|
|
484
|
+
uint8_t clear_text[length];
|
|
485
|
+
|
|
486
|
+
memcpy(&digest, buffer, GCM_DIGEST_SIZE);
|
|
487
|
+
memcpy(&iv, buffer + GCM_DIGEST_SIZE, SHA256_DIGEST_SIZE);
|
|
488
|
+
memcpy(&cipher_text, buffer + GCM_DIGEST_SIZE + SHA256_DIGEST_SIZE, length);
|
|
489
|
+
|
|
490
|
+
free(buffer);
|
|
491
|
+
|
|
492
|
+
struct gcm_aes256_ctx ctx2;
|
|
493
|
+
gcm_aes256_set_key(&ctx2, decrypt_key);
|
|
494
|
+
gcm_aes256_set_iv(&ctx2, SHA256_DIGEST_SIZE, iv);
|
|
495
|
+
|
|
496
|
+
int pos = 0;
|
|
497
|
+
size_t remain = length;
|
|
498
|
+
while (pos < length) {
|
|
499
|
+
int len = AES_BLOCK_SIZE;
|
|
500
|
+
if (remain < AES_BLOCK_SIZE) {
|
|
501
|
+
len = remain;
|
|
502
|
+
}
|
|
503
|
+
gcm_aes256_decrypt(&ctx2, len, clear_text + pos, cipher_text + pos);
|
|
504
|
+
pos += AES_BLOCK_SIZE;
|
|
505
|
+
remain -= AES_BLOCK_SIZE;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
uint8_t actual_digest[GCM_DIGEST_SIZE];
|
|
509
|
+
gcm_aes256_digest(&ctx2, GCM_DIGEST_SIZE, actual_digest);
|
|
510
|
+
|
|
511
|
+
int digest_match = memcmp(actual_digest, digest, GCM_DIGEST_SIZE);
|
|
512
|
+
if (digest_match != 0) {
|
|
513
|
+
//STORJ_META_DECRYPTION_ERROR
|
|
514
|
+
return 1;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
*filemeta = calloc(length + 1, sizeof(char));
|
|
518
|
+
if (!*filemeta) {
|
|
519
|
+
//STORJ_MEMORY_ERROR
|
|
520
|
+
return 1;
|
|
521
|
+
}
|
|
522
|
+
memcpy(*filemeta, &clear_text, length);
|
|
523
|
+
|
|
524
|
+
return 0;
|
|
525
|
+
}
|