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.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +1 -0
  5. data/Gemfile +23 -0
  6. data/Gemfile.lock +111 -0
  7. data/Guardfile +21 -0
  8. data/LICENSE +502 -0
  9. data/README.md +262 -0
  10. data/Rakefile +76 -0
  11. data/ext/libstorj/.gitignore +47 -0
  12. data/ext/libstorj/.travis.yml +27 -0
  13. data/ext/libstorj/Doxyfile +2427 -0
  14. data/ext/libstorj/LICENSE +502 -0
  15. data/ext/libstorj/Makefile.am +6 -0
  16. data/ext/libstorj/README.md +198 -0
  17. data/ext/libstorj/autogen.sh +3 -0
  18. data/ext/libstorj/configure.ac +64 -0
  19. data/ext/libstorj/depends/Makefile +153 -0
  20. data/ext/libstorj/depends/config.guess +1462 -0
  21. data/ext/libstorj/depends/config.sub +1823 -0
  22. data/ext/libstorj/depends/extract-osx-sdk.sh +33 -0
  23. data/ext/libstorj/depends/packages/cctools.mk +7 -0
  24. data/ext/libstorj/depends/packages/clang.mk +7 -0
  25. data/ext/libstorj/depends/packages/gmp.mk +23 -0
  26. data/ext/libstorj/depends/packages/gnutls.mk +25 -0
  27. data/ext/libstorj/depends/packages/json-c.mk +7 -0
  28. data/ext/libstorj/depends/packages/libcurl.mk +39 -0
  29. data/ext/libstorj/depends/packages/libmicrohttpd.mk +7 -0
  30. data/ext/libstorj/depends/packages/libuv.mk +7 -0
  31. data/ext/libstorj/depends/packages/nettle.mk +30 -0
  32. data/ext/libstorj/libstorj.pc.in +11 -0
  33. data/ext/libstorj/src/Makefile.am +23 -0
  34. data/ext/libstorj/src/bip39.c +233 -0
  35. data/ext/libstorj/src/bip39.h +64 -0
  36. data/ext/libstorj/src/bip39_english.h +2074 -0
  37. data/ext/libstorj/src/cli.c +1494 -0
  38. data/ext/libstorj/src/crypto.c +525 -0
  39. data/ext/libstorj/src/crypto.h +178 -0
  40. data/ext/libstorj/src/downloader.c +1923 -0
  41. data/ext/libstorj/src/downloader.h +163 -0
  42. data/ext/libstorj/src/http.c +688 -0
  43. data/ext/libstorj/src/http.h +175 -0
  44. data/ext/libstorj/src/rs.c +962 -0
  45. data/ext/libstorj/src/rs.h +99 -0
  46. data/ext/libstorj/src/storj.c +1523 -0
  47. data/ext/libstorj/src/storj.h +1014 -0
  48. data/ext/libstorj/src/uploader.c +2736 -0
  49. data/ext/libstorj/src/uploader.h +181 -0
  50. data/ext/libstorj/src/utils.c +336 -0
  51. data/ext/libstorj/src/utils.h +65 -0
  52. data/ext/libstorj/test/Makefile.am +27 -0
  53. data/ext/libstorj/test/mockbridge.c +260 -0
  54. data/ext/libstorj/test/mockbridge.json +687 -0
  55. data/ext/libstorj/test/mockbridgeinfo.json +1836 -0
  56. data/ext/libstorj/test/mockfarmer.c +358 -0
  57. data/ext/libstorj/test/storjtests.h +41 -0
  58. data/ext/libstorj/test/tests.c +1617 -0
  59. data/ext/libstorj/test/tests_rs.c +869 -0
  60. data/ext/ruby-libstorj/extconf.rb +8 -0
  61. data/ext/ruby-libstorj/ruby-libstorj.cc +17 -0
  62. data/lib/ruby-libstorj.rb +1 -0
  63. data/lib/ruby-libstorj/arg_forwarding_task.rb +58 -0
  64. data/lib/ruby-libstorj/env.rb +178 -0
  65. data/lib/ruby-libstorj/ext/bucket.rb +71 -0
  66. data/lib/ruby-libstorj/ext/create_bucket_request.rb +53 -0
  67. data/lib/ruby-libstorj/ext/curl_code.rb +139 -0
  68. data/lib/ruby-libstorj/ext/ext.rb +71 -0
  69. data/lib/ruby-libstorj/ext/file.rb +84 -0
  70. data/lib/ruby-libstorj/ext/get_bucket_request.rb +45 -0
  71. data/lib/ruby-libstorj/ext/json_request.rb +51 -0
  72. data/lib/ruby-libstorj/ext/list_files_request.rb +63 -0
  73. data/lib/ruby-libstorj/ext/types.rb +226 -0
  74. data/lib/ruby-libstorj/ext/upload_options.rb +38 -0
  75. data/lib/ruby-libstorj/libstorj.rb +22 -0
  76. data/lib/ruby-libstorj/mixins/storj.rb +27 -0
  77. data/lib/ruby-libstorj/struct.rb +42 -0
  78. data/ruby-libstorj.gemspec +57 -0
  79. data/spec/helpers/options.yml.example +22 -0
  80. data/spec/helpers/shared_rake_examples.rb +132 -0
  81. data/spec/helpers/storj_options.rb +96 -0
  82. data/spec/helpers/upload.data +3 -0
  83. data/spec/helpers/upload.data.sha256 +1 -0
  84. data/spec/libstorj_spec.rb +0 -0
  85. data/spec/ruby-libstorj/arg_forwarding_task_spec.rb +311 -0
  86. data/spec/ruby-libstorj/env_spec.rb +353 -0
  87. data/spec/ruby-libstorj/ext_spec.rb +75 -0
  88. data/spec/ruby-libstorj/json_request_spec.rb +13 -0
  89. data/spec/ruby-libstorj/libstorj_spec.rb +81 -0
  90. data/spec/ruby-libstorj/struct_spec.rb +64 -0
  91. data/spec/spec_helper.rb +113 -0
  92. 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
+ }