openssl-custom 2.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/BSDL +22 -0
  3. data/CONTRIBUTING.md +132 -0
  4. data/History.md +485 -0
  5. data/LICENSE.txt +56 -0
  6. data/README.md +66 -0
  7. data/ext/openssl/extconf.rb +190 -0
  8. data/ext/openssl/openssl_missing.c +106 -0
  9. data/ext/openssl/openssl_missing.h +257 -0
  10. data/ext/openssl/ossl.c +1282 -0
  11. data/ext/openssl/ossl.h +181 -0
  12. data/ext/openssl/ossl_asn1.c +1878 -0
  13. data/ext/openssl/ossl_asn1.h +62 -0
  14. data/ext/openssl/ossl_bio.c +42 -0
  15. data/ext/openssl/ossl_bio.h +16 -0
  16. data/ext/openssl/ossl_bn.c +1270 -0
  17. data/ext/openssl/ossl_bn.h +26 -0
  18. data/ext/openssl/ossl_cipher.c +1075 -0
  19. data/ext/openssl/ossl_cipher.h +20 -0
  20. data/ext/openssl/ossl_config.c +89 -0
  21. data/ext/openssl/ossl_config.h +19 -0
  22. data/ext/openssl/ossl_digest.c +425 -0
  23. data/ext/openssl/ossl_digest.h +20 -0
  24. data/ext/openssl/ossl_engine.c +567 -0
  25. data/ext/openssl/ossl_engine.h +19 -0
  26. data/ext/openssl/ossl_hmac.c +389 -0
  27. data/ext/openssl/ossl_hmac.h +18 -0
  28. data/ext/openssl/ossl_kdf.c +303 -0
  29. data/ext/openssl/ossl_kdf.h +6 -0
  30. data/ext/openssl/ossl_ns_spki.c +405 -0
  31. data/ext/openssl/ossl_ns_spki.h +19 -0
  32. data/ext/openssl/ossl_ocsp.c +2013 -0
  33. data/ext/openssl/ossl_ocsp.h +23 -0
  34. data/ext/openssl/ossl_pkcs12.c +257 -0
  35. data/ext/openssl/ossl_pkcs12.h +13 -0
  36. data/ext/openssl/ossl_pkcs7.c +1098 -0
  37. data/ext/openssl/ossl_pkcs7.h +36 -0
  38. data/ext/openssl/ossl_pkey.c +673 -0
  39. data/ext/openssl/ossl_pkey.h +241 -0
  40. data/ext/openssl/ossl_pkey_dh.c +650 -0
  41. data/ext/openssl/ossl_pkey_dsa.c +664 -0
  42. data/ext/openssl/ossl_pkey_ec.c +1827 -0
  43. data/ext/openssl/ossl_pkey_rsa.c +966 -0
  44. data/ext/openssl/ossl_rand.c +200 -0
  45. data/ext/openssl/ossl_rand.h +18 -0
  46. data/ext/openssl/ossl_ssl.c +3080 -0
  47. data/ext/openssl/ossl_ssl.h +36 -0
  48. data/ext/openssl/ossl_ssl_session.c +332 -0
  49. data/ext/openssl/ossl_ts.c +1524 -0
  50. data/ext/openssl/ossl_ts.h +16 -0
  51. data/ext/openssl/ossl_x509.c +262 -0
  52. data/ext/openssl/ossl_x509.h +115 -0
  53. data/ext/openssl/ossl_x509attr.c +324 -0
  54. data/ext/openssl/ossl_x509cert.c +846 -0
  55. data/ext/openssl/ossl_x509crl.c +542 -0
  56. data/ext/openssl/ossl_x509ext.c +491 -0
  57. data/ext/openssl/ossl_x509name.c +590 -0
  58. data/ext/openssl/ossl_x509req.c +441 -0
  59. data/ext/openssl/ossl_x509revoked.c +300 -0
  60. data/ext/openssl/ossl_x509store.c +902 -0
  61. data/ext/openssl/ruby_missing.h +24 -0
  62. data/lib/openssl/bn.rb +40 -0
  63. data/lib/openssl/buffering.rb +478 -0
  64. data/lib/openssl/cipher.rb +67 -0
  65. data/lib/openssl/config.rb +501 -0
  66. data/lib/openssl/digest.rb +73 -0
  67. data/lib/openssl/hmac.rb +13 -0
  68. data/lib/openssl/marshal.rb +30 -0
  69. data/lib/openssl/pkcs5.rb +22 -0
  70. data/lib/openssl/pkey.rb +42 -0
  71. data/lib/openssl/ssl.rb +542 -0
  72. data/lib/openssl/version.rb +5 -0
  73. data/lib/openssl/x509.rb +369 -0
  74. data/lib/openssl.rb +38 -0
  75. metadata +196 -0
@@ -0,0 +1,1075 @@
1
+ /*
2
+ * 'OpenSSL for Ruby' project
3
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
4
+ * All rights reserved.
5
+ */
6
+ /*
7
+ * This program is licensed under the same licence as Ruby.
8
+ * (See the file 'LICENCE'.)
9
+ */
10
+ #include "ossl.h"
11
+
12
+ #define NewCipher(klass) \
13
+ TypedData_Wrap_Struct((klass), &ossl_cipher_type, 0)
14
+ #define AllocCipher(obj, ctx) do { \
15
+ (ctx) = EVP_CIPHER_CTX_new(); \
16
+ if (!(ctx)) \
17
+ ossl_raise(rb_eRuntimeError, NULL); \
18
+ RTYPEDDATA_DATA(obj) = (ctx); \
19
+ } while (0)
20
+ #define GetCipherInit(obj, ctx) do { \
21
+ TypedData_Get_Struct((obj), EVP_CIPHER_CTX, &ossl_cipher_type, (ctx)); \
22
+ } while (0)
23
+ #define GetCipher(obj, ctx) do { \
24
+ GetCipherInit((obj), (ctx)); \
25
+ if (!(ctx)) { \
26
+ ossl_raise(rb_eRuntimeError, "Cipher not initialized!"); \
27
+ } \
28
+ } while (0)
29
+
30
+ /*
31
+ * Classes
32
+ */
33
+ VALUE cCipher;
34
+ VALUE eCipherError;
35
+ static ID id_auth_tag_len, id_key_set;
36
+
37
+ static VALUE ossl_cipher_alloc(VALUE klass);
38
+ static void ossl_cipher_free(void *ptr);
39
+
40
+ static const rb_data_type_t ossl_cipher_type = {
41
+ "OpenSSL/Cipher",
42
+ {
43
+ 0, ossl_cipher_free,
44
+ },
45
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
46
+ };
47
+
48
+ /*
49
+ * PUBLIC
50
+ */
51
+ const EVP_CIPHER *
52
+ ossl_evp_get_cipherbyname(VALUE obj)
53
+ {
54
+ if (rb_obj_is_kind_of(obj, cCipher)) {
55
+ EVP_CIPHER_CTX *ctx;
56
+
57
+ GetCipher(obj, ctx);
58
+
59
+ return EVP_CIPHER_CTX_cipher(ctx);
60
+ }
61
+ else {
62
+ const EVP_CIPHER *cipher;
63
+
64
+ StringValueCStr(obj);
65
+ cipher = EVP_get_cipherbyname(RSTRING_PTR(obj));
66
+ if (!cipher)
67
+ ossl_raise(rb_eArgError,
68
+ "unsupported cipher algorithm: %"PRIsVALUE, obj);
69
+
70
+ return cipher;
71
+ }
72
+ }
73
+
74
+ VALUE
75
+ ossl_cipher_new(const EVP_CIPHER *cipher)
76
+ {
77
+ VALUE ret;
78
+ EVP_CIPHER_CTX *ctx;
79
+
80
+ ret = ossl_cipher_alloc(cCipher);
81
+ AllocCipher(ret, ctx);
82
+ if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1)
83
+ ossl_raise(eCipherError, NULL);
84
+
85
+ return ret;
86
+ }
87
+
88
+ /*
89
+ * PRIVATE
90
+ */
91
+ static void
92
+ ossl_cipher_free(void *ptr)
93
+ {
94
+ EVP_CIPHER_CTX_free(ptr);
95
+ }
96
+
97
+ static VALUE
98
+ ossl_cipher_alloc(VALUE klass)
99
+ {
100
+ return NewCipher(klass);
101
+ }
102
+
103
+ /*
104
+ * call-seq:
105
+ * Cipher.new(string) -> cipher
106
+ *
107
+ * The string must contain a valid cipher name like "AES-256-CBC".
108
+ *
109
+ * A list of cipher names is available by calling OpenSSL::Cipher.ciphers.
110
+ */
111
+ static VALUE
112
+ ossl_cipher_initialize(VALUE self, VALUE str)
113
+ {
114
+ EVP_CIPHER_CTX *ctx;
115
+ const EVP_CIPHER *cipher;
116
+ char *name;
117
+
118
+ name = StringValueCStr(str);
119
+ GetCipherInit(self, ctx);
120
+ if (ctx) {
121
+ ossl_raise(rb_eRuntimeError, "Cipher already initialized!");
122
+ }
123
+ AllocCipher(self, ctx);
124
+ if (!(cipher = EVP_get_cipherbyname(name))) {
125
+ ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%"PRIsVALUE")", str);
126
+ }
127
+ if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1)
128
+ ossl_raise(eCipherError, NULL);
129
+
130
+ return self;
131
+ }
132
+
133
+ static VALUE
134
+ ossl_cipher_copy(VALUE self, VALUE other)
135
+ {
136
+ EVP_CIPHER_CTX *ctx1, *ctx2;
137
+
138
+ rb_check_frozen(self);
139
+ if (self == other) return self;
140
+
141
+ GetCipherInit(self, ctx1);
142
+ if (!ctx1) {
143
+ AllocCipher(self, ctx1);
144
+ }
145
+ GetCipher(other, ctx2);
146
+ if (EVP_CIPHER_CTX_copy(ctx1, ctx2) != 1)
147
+ ossl_raise(eCipherError, NULL);
148
+
149
+ return self;
150
+ }
151
+
152
+ static void*
153
+ add_cipher_name_to_ary(const OBJ_NAME *name, VALUE ary)
154
+ {
155
+ rb_ary_push(ary, rb_str_new2(name->name));
156
+ return NULL;
157
+ }
158
+
159
+ /*
160
+ * call-seq:
161
+ * OpenSSL::Cipher.ciphers -> array[string...]
162
+ *
163
+ * Returns the names of all available ciphers in an array.
164
+ */
165
+ static VALUE
166
+ ossl_s_ciphers(VALUE self)
167
+ {
168
+ VALUE ary;
169
+
170
+ ary = rb_ary_new();
171
+ OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
172
+ (void(*)(const OBJ_NAME*,void*))add_cipher_name_to_ary,
173
+ (void*)ary);
174
+
175
+ return ary;
176
+ }
177
+
178
+ /*
179
+ * call-seq:
180
+ * cipher.reset -> self
181
+ *
182
+ * Fully resets the internal state of the Cipher. By using this, the same
183
+ * Cipher instance may be used several times for encryption or decryption tasks.
184
+ *
185
+ * Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1).
186
+ */
187
+ static VALUE
188
+ ossl_cipher_reset(VALUE self)
189
+ {
190
+ EVP_CIPHER_CTX *ctx;
191
+
192
+ GetCipher(self, ctx);
193
+ if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1) != 1)
194
+ ossl_raise(eCipherError, NULL);
195
+
196
+ return self;
197
+ }
198
+
199
+ static VALUE
200
+ ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode)
201
+ {
202
+ EVP_CIPHER_CTX *ctx;
203
+ unsigned char key[EVP_MAX_KEY_LENGTH], *p_key = NULL;
204
+ unsigned char iv[EVP_MAX_IV_LENGTH], *p_iv = NULL;
205
+ VALUE pass, init_v;
206
+
207
+ if(rb_scan_args(argc, argv, "02", &pass, &init_v) > 0){
208
+ /*
209
+ * oops. this code mistakes salt for IV.
210
+ * We deprecated the arguments for this method, but we decided
211
+ * keeping this behaviour for backward compatibility.
212
+ */
213
+ VALUE cname = rb_class_path(rb_obj_class(self));
214
+ rb_warn("arguments for %"PRIsVALUE"#encrypt and %"PRIsVALUE"#decrypt were deprecated; "
215
+ "use %"PRIsVALUE"#pkcs5_keyivgen to derive key and IV",
216
+ cname, cname, cname);
217
+ StringValue(pass);
218
+ GetCipher(self, ctx);
219
+ if (NIL_P(init_v)) memcpy(iv, "OpenSSL for Ruby rulez!", sizeof(iv));
220
+ else{
221
+ StringValue(init_v);
222
+ if (EVP_MAX_IV_LENGTH > RSTRING_LEN(init_v)) {
223
+ memset(iv, 0, EVP_MAX_IV_LENGTH);
224
+ memcpy(iv, RSTRING_PTR(init_v), RSTRING_LEN(init_v));
225
+ }
226
+ else memcpy(iv, RSTRING_PTR(init_v), sizeof(iv));
227
+ }
228
+ EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv,
229
+ (unsigned char *)RSTRING_PTR(pass), RSTRING_LENINT(pass), 1, key, NULL);
230
+ p_key = key;
231
+ p_iv = iv;
232
+ }
233
+ else {
234
+ GetCipher(self, ctx);
235
+ }
236
+ if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) {
237
+ ossl_raise(eCipherError, NULL);
238
+ }
239
+
240
+ rb_ivar_set(self, id_key_set, p_key ? Qtrue : Qfalse);
241
+
242
+ return self;
243
+ }
244
+
245
+ /*
246
+ * call-seq:
247
+ * cipher.encrypt -> self
248
+ *
249
+ * Initializes the Cipher for encryption.
250
+ *
251
+ * Make sure to call Cipher#encrypt or Cipher#decrypt before using any of the
252
+ * following methods:
253
+ * * [#key=, #iv=, #random_key, #random_iv, #pkcs5_keyivgen]
254
+ *
255
+ * Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 1).
256
+ */
257
+ static VALUE
258
+ ossl_cipher_encrypt(int argc, VALUE *argv, VALUE self)
259
+ {
260
+ return ossl_cipher_init(argc, argv, self, 1);
261
+ }
262
+
263
+ /*
264
+ * call-seq:
265
+ * cipher.decrypt -> self
266
+ *
267
+ * Initializes the Cipher for decryption.
268
+ *
269
+ * Make sure to call Cipher#encrypt or Cipher#decrypt before using any of the
270
+ * following methods:
271
+ * * [#key=, #iv=, #random_key, #random_iv, #pkcs5_keyivgen]
272
+ *
273
+ * Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 0).
274
+ */
275
+ static VALUE
276
+ ossl_cipher_decrypt(int argc, VALUE *argv, VALUE self)
277
+ {
278
+ return ossl_cipher_init(argc, argv, self, 0);
279
+ }
280
+
281
+ /*
282
+ * call-seq:
283
+ * cipher.pkcs5_keyivgen(pass, salt = nil, iterations = 2048, digest = "MD5") -> nil
284
+ *
285
+ * Generates and sets the key/IV based on a password.
286
+ *
287
+ * *WARNING*: This method is only PKCS5 v1.5 compliant when using RC2, RC4-40,
288
+ * or DES with MD5 or SHA1. Using anything else (like AES) will generate the
289
+ * key/iv using an OpenSSL specific method. This method is deprecated and
290
+ * should no longer be used. Use a PKCS5 v2 key generation method from
291
+ * OpenSSL::PKCS5 instead.
292
+ *
293
+ * === Parameters
294
+ * * _salt_ must be an 8 byte string if provided.
295
+ * * _iterations_ is an integer with a default of 2048.
296
+ * * _digest_ is a Digest object that defaults to 'MD5'
297
+ *
298
+ * A minimum of 1000 iterations is recommended.
299
+ *
300
+ */
301
+ static VALUE
302
+ ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self)
303
+ {
304
+ EVP_CIPHER_CTX *ctx;
305
+ const EVP_MD *digest;
306
+ VALUE vpass, vsalt, viter, vdigest;
307
+ unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH], *salt = NULL;
308
+ int iter;
309
+
310
+ rb_scan_args(argc, argv, "13", &vpass, &vsalt, &viter, &vdigest);
311
+ StringValue(vpass);
312
+ if(!NIL_P(vsalt)){
313
+ StringValue(vsalt);
314
+ if(RSTRING_LEN(vsalt) != PKCS5_SALT_LEN)
315
+ ossl_raise(eCipherError, "salt must be an 8-octet string");
316
+ salt = (unsigned char *)RSTRING_PTR(vsalt);
317
+ }
318
+ iter = NIL_P(viter) ? 2048 : NUM2INT(viter);
319
+ if (iter <= 0)
320
+ rb_raise(rb_eArgError, "iterations must be a positive integer");
321
+ digest = NIL_P(vdigest) ? EVP_md5() : ossl_evp_get_digestbyname(vdigest);
322
+ GetCipher(self, ctx);
323
+ EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt,
324
+ (unsigned char *)RSTRING_PTR(vpass), RSTRING_LENINT(vpass), iter, key, iv);
325
+ if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, -1) != 1)
326
+ ossl_raise(eCipherError, NULL);
327
+ OPENSSL_cleanse(key, sizeof key);
328
+ OPENSSL_cleanse(iv, sizeof iv);
329
+
330
+ rb_ivar_set(self, id_key_set, Qtrue);
331
+
332
+ return Qnil;
333
+ }
334
+
335
+ static int
336
+ ossl_cipher_update_long(EVP_CIPHER_CTX *ctx, unsigned char *out, long *out_len_ptr,
337
+ const unsigned char *in, long in_len)
338
+ {
339
+ int out_part_len;
340
+ int limit = INT_MAX / 2 + 1;
341
+ long out_len = 0;
342
+
343
+ do {
344
+ int in_part_len = in_len > limit ? limit : (int)in_len;
345
+
346
+ if (!EVP_CipherUpdate(ctx, out ? (out + out_len) : 0,
347
+ &out_part_len, in, in_part_len))
348
+ return 0;
349
+
350
+ out_len += out_part_len;
351
+ in += in_part_len;
352
+ } while ((in_len -= limit) > 0);
353
+
354
+ if (out_len_ptr)
355
+ *out_len_ptr = out_len;
356
+
357
+ return 1;
358
+ }
359
+
360
+ /*
361
+ * call-seq:
362
+ * cipher.update(data [, buffer]) -> string or buffer
363
+ *
364
+ * Encrypts data in a streaming fashion. Hand consecutive blocks of data
365
+ * to the #update method in order to encrypt it. Returns the encrypted
366
+ * data chunk. When done, the output of Cipher#final should be additionally
367
+ * added to the result.
368
+ *
369
+ * If _buffer_ is given, the encryption/decryption result will be written to
370
+ * it. _buffer_ will be resized automatically.
371
+ */
372
+ static VALUE
373
+ ossl_cipher_update(int argc, VALUE *argv, VALUE self)
374
+ {
375
+ EVP_CIPHER_CTX *ctx;
376
+ unsigned char *in;
377
+ long in_len, out_len;
378
+ VALUE data, str;
379
+
380
+ rb_scan_args(argc, argv, "11", &data, &str);
381
+
382
+ if (!RTEST(rb_attr_get(self, id_key_set)))
383
+ ossl_raise(eCipherError, "key not set");
384
+
385
+ StringValue(data);
386
+ in = (unsigned char *)RSTRING_PTR(data);
387
+ if ((in_len = RSTRING_LEN(data)) == 0)
388
+ ossl_raise(rb_eArgError, "data must not be empty");
389
+ GetCipher(self, ctx);
390
+ out_len = in_len+EVP_CIPHER_CTX_block_size(ctx);
391
+ if (out_len <= 0) {
392
+ ossl_raise(rb_eRangeError,
393
+ "data too big to make output buffer: %ld bytes", in_len);
394
+ }
395
+
396
+ if (NIL_P(str)) {
397
+ str = rb_str_new(0, out_len);
398
+ } else {
399
+ StringValue(str);
400
+ rb_str_resize(str, out_len);
401
+ }
402
+
403
+ if (!ossl_cipher_update_long(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len))
404
+ ossl_raise(eCipherError, NULL);
405
+ assert(out_len < RSTRING_LEN(str));
406
+ rb_str_set_len(str, out_len);
407
+
408
+ return str;
409
+ }
410
+
411
+ /*
412
+ * call-seq:
413
+ * cipher.final -> string
414
+ *
415
+ * Returns the remaining data held in the cipher object. Further calls to
416
+ * Cipher#update or Cipher#final will return garbage. This call should always
417
+ * be made as the last call of an encryption or decryption operation, after
418
+ * having fed the entire plaintext or ciphertext to the Cipher instance.
419
+ *
420
+ * If an authenticated cipher was used, a CipherError is raised if the tag
421
+ * could not be authenticated successfully. Only call this method after
422
+ * setting the authentication tag and passing the entire contents of the
423
+ * ciphertext into the cipher.
424
+ */
425
+ static VALUE
426
+ ossl_cipher_final(VALUE self)
427
+ {
428
+ EVP_CIPHER_CTX *ctx;
429
+ int out_len;
430
+ VALUE str;
431
+
432
+ GetCipher(self, ctx);
433
+ str = rb_str_new(0, EVP_CIPHER_CTX_block_size(ctx));
434
+ if (!EVP_CipherFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), &out_len))
435
+ ossl_raise(eCipherError, NULL);
436
+ assert(out_len <= RSTRING_LEN(str));
437
+ rb_str_set_len(str, out_len);
438
+
439
+ return str;
440
+ }
441
+
442
+ /*
443
+ * call-seq:
444
+ * cipher.name -> string
445
+ *
446
+ * Returns the name of the cipher which may differ slightly from the original
447
+ * name provided.
448
+ */
449
+ static VALUE
450
+ ossl_cipher_name(VALUE self)
451
+ {
452
+ EVP_CIPHER_CTX *ctx;
453
+
454
+ GetCipher(self, ctx);
455
+
456
+ return rb_str_new2(EVP_CIPHER_name(EVP_CIPHER_CTX_cipher(ctx)));
457
+ }
458
+
459
+ /*
460
+ * call-seq:
461
+ * cipher.key = string -> string
462
+ *
463
+ * Sets the cipher key. To generate a key, you should either use a secure
464
+ * random byte string or, if the key is to be derived from a password, you
465
+ * should rely on PBKDF2 functionality provided by OpenSSL::PKCS5. To
466
+ * generate a secure random-based key, Cipher#random_key may be used.
467
+ *
468
+ * Only call this method after calling Cipher#encrypt or Cipher#decrypt.
469
+ */
470
+ static VALUE
471
+ ossl_cipher_set_key(VALUE self, VALUE key)
472
+ {
473
+ EVP_CIPHER_CTX *ctx;
474
+ int key_len;
475
+
476
+ StringValue(key);
477
+ GetCipher(self, ctx);
478
+
479
+ key_len = EVP_CIPHER_CTX_key_length(ctx);
480
+ if (RSTRING_LEN(key) != key_len)
481
+ ossl_raise(rb_eArgError, "key must be %d bytes", key_len);
482
+
483
+ if (EVP_CipherInit_ex(ctx, NULL, NULL, (unsigned char *)RSTRING_PTR(key), NULL, -1) != 1)
484
+ ossl_raise(eCipherError, NULL);
485
+
486
+ rb_ivar_set(self, id_key_set, Qtrue);
487
+
488
+ return key;
489
+ }
490
+
491
+ /*
492
+ * call-seq:
493
+ * cipher.iv = string -> string
494
+ *
495
+ * Sets the cipher IV. Please note that since you should never be using ECB
496
+ * mode, an IV is always explicitly required and should be set prior to
497
+ * encryption. The IV itself can be safely transmitted in public, but it
498
+ * should be unpredictable to prevent certain kinds of attacks. You may use
499
+ * Cipher#random_iv to create a secure random IV.
500
+ *
501
+ * Only call this method after calling Cipher#encrypt or Cipher#decrypt.
502
+ */
503
+ static VALUE
504
+ ossl_cipher_set_iv(VALUE self, VALUE iv)
505
+ {
506
+ EVP_CIPHER_CTX *ctx;
507
+ int iv_len = 0;
508
+
509
+ StringValue(iv);
510
+ GetCipher(self, ctx);
511
+
512
+ if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)
513
+ iv_len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx);
514
+ if (!iv_len)
515
+ iv_len = EVP_CIPHER_CTX_iv_length(ctx);
516
+ if (RSTRING_LEN(iv) != iv_len)
517
+ ossl_raise(rb_eArgError, "iv must be %d bytes", iv_len);
518
+
519
+ if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, (unsigned char *)RSTRING_PTR(iv), -1) != 1)
520
+ ossl_raise(eCipherError, NULL);
521
+
522
+ return iv;
523
+ }
524
+
525
+ /*
526
+ * call-seq:
527
+ * cipher.authenticated? -> true | false
528
+ *
529
+ * Indicated whether this Cipher instance uses an Authenticated Encryption
530
+ * mode.
531
+ */
532
+ static VALUE
533
+ ossl_cipher_is_authenticated(VALUE self)
534
+ {
535
+ EVP_CIPHER_CTX *ctx;
536
+
537
+ GetCipher(self, ctx);
538
+
539
+ return (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER) ? Qtrue : Qfalse;
540
+ }
541
+
542
+ /*
543
+ * call-seq:
544
+ * cipher.auth_data = string -> string
545
+ *
546
+ * Sets the cipher's additional authenticated data. This field must be
547
+ * set when using AEAD cipher modes such as GCM or CCM. If no associated
548
+ * data shall be used, this method must *still* be called with a value of "".
549
+ * The contents of this field should be non-sensitive data which will be
550
+ * added to the ciphertext to generate the authentication tag which validates
551
+ * the contents of the ciphertext.
552
+ *
553
+ * The AAD must be set prior to encryption or decryption. In encryption mode,
554
+ * it must be set after calling Cipher#encrypt and setting Cipher#key= and
555
+ * Cipher#iv=. When decrypting, the authenticated data must be set after key,
556
+ * iv and especially *after* the authentication tag has been set. I.e. set it
557
+ * only after calling Cipher#decrypt, Cipher#key=, Cipher#iv= and
558
+ * Cipher#auth_tag= first.
559
+ */
560
+ static VALUE
561
+ ossl_cipher_set_auth_data(VALUE self, VALUE data)
562
+ {
563
+ EVP_CIPHER_CTX *ctx;
564
+ unsigned char *in;
565
+ long in_len, out_len;
566
+
567
+ StringValue(data);
568
+
569
+ in = (unsigned char *) RSTRING_PTR(data);
570
+ in_len = RSTRING_LEN(data);
571
+
572
+ GetCipher(self, ctx);
573
+ if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
574
+ ossl_raise(eCipherError, "AEAD not supported by this cipher");
575
+
576
+ if (!ossl_cipher_update_long(ctx, NULL, &out_len, in, in_len))
577
+ ossl_raise(eCipherError, "couldn't set additional authenticated data");
578
+
579
+ return data;
580
+ }
581
+
582
+ /*
583
+ * call-seq:
584
+ * cipher.auth_tag(tag_len = 16) -> String
585
+ *
586
+ * Gets the authentication tag generated by Authenticated Encryption Cipher
587
+ * modes (GCM for example). This tag may be stored along with the ciphertext,
588
+ * then set on the decryption cipher to authenticate the contents of the
589
+ * ciphertext against changes. If the optional integer parameter _tag_len_ is
590
+ * given, the returned tag will be _tag_len_ bytes long. If the parameter is
591
+ * omitted, the default length of 16 bytes or the length previously set by
592
+ * #auth_tag_len= will be used. For maximum security, the longest possible
593
+ * should be chosen.
594
+ *
595
+ * The tag may only be retrieved after calling Cipher#final.
596
+ */
597
+ static VALUE
598
+ ossl_cipher_get_auth_tag(int argc, VALUE *argv, VALUE self)
599
+ {
600
+ VALUE vtag_len, ret;
601
+ EVP_CIPHER_CTX *ctx;
602
+ int tag_len = 16;
603
+
604
+ rb_scan_args(argc, argv, "01", &vtag_len);
605
+ if (NIL_P(vtag_len))
606
+ vtag_len = rb_attr_get(self, id_auth_tag_len);
607
+ if (!NIL_P(vtag_len))
608
+ tag_len = NUM2INT(vtag_len);
609
+
610
+ GetCipher(self, ctx);
611
+
612
+ if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
613
+ ossl_raise(eCipherError, "authentication tag not supported by this cipher");
614
+
615
+ ret = rb_str_new(NULL, tag_len);
616
+ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, tag_len, RSTRING_PTR(ret)))
617
+ ossl_raise(eCipherError, "retrieving the authentication tag failed");
618
+
619
+ return ret;
620
+ }
621
+
622
+ /*
623
+ * call-seq:
624
+ * cipher.auth_tag = string -> string
625
+ *
626
+ * Sets the authentication tag to verify the integrity of the ciphertext.
627
+ * This can be called only when the cipher supports AE. The tag must be set
628
+ * after calling Cipher#decrypt, Cipher#key= and Cipher#iv=, but before
629
+ * calling Cipher#final. After all decryption is performed, the tag is
630
+ * verified automatically in the call to Cipher#final.
631
+ *
632
+ * For OCB mode, the tag length must be supplied with #auth_tag_len=
633
+ * beforehand.
634
+ */
635
+ static VALUE
636
+ ossl_cipher_set_auth_tag(VALUE self, VALUE vtag)
637
+ {
638
+ EVP_CIPHER_CTX *ctx;
639
+ unsigned char *tag;
640
+ int tag_len;
641
+
642
+ StringValue(vtag);
643
+ tag = (unsigned char *) RSTRING_PTR(vtag);
644
+ tag_len = RSTRING_LENINT(vtag);
645
+
646
+ GetCipher(self, ctx);
647
+ if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
648
+ ossl_raise(eCipherError, "authentication tag not supported by this cipher");
649
+
650
+ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, tag))
651
+ ossl_raise(eCipherError, "unable to set AEAD tag");
652
+
653
+ return vtag;
654
+ }
655
+
656
+ /*
657
+ * call-seq:
658
+ * cipher.auth_tag_len = Integer -> Integer
659
+ *
660
+ * Sets the length of the authentication tag to be generated or to be given for
661
+ * AEAD ciphers that requires it as in input parameter. Note that not all AEAD
662
+ * ciphers support this method.
663
+ *
664
+ * In OCB mode, the length must be supplied both when encrypting and when
665
+ * decrypting, and must be before specifying an IV.
666
+ */
667
+ static VALUE
668
+ ossl_cipher_set_auth_tag_len(VALUE self, VALUE vlen)
669
+ {
670
+ int tag_len = NUM2INT(vlen);
671
+ EVP_CIPHER_CTX *ctx;
672
+
673
+ GetCipher(self, ctx);
674
+ if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
675
+ ossl_raise(eCipherError, "AEAD not supported by this cipher");
676
+
677
+ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, NULL))
678
+ ossl_raise(eCipherError, "unable to set authentication tag length");
679
+
680
+ /* for #auth_tag */
681
+ rb_ivar_set(self, id_auth_tag_len, INT2NUM(tag_len));
682
+
683
+ return vlen;
684
+ }
685
+
686
+ /*
687
+ * call-seq:
688
+ * cipher.iv_len = integer -> integer
689
+ *
690
+ * Sets the IV/nonce length of the Cipher. Normally block ciphers don't allow
691
+ * changing the IV length, but some make use of IV for 'nonce'. You may need
692
+ * this for interoperability with other applications.
693
+ */
694
+ static VALUE
695
+ ossl_cipher_set_iv_length(VALUE self, VALUE iv_length)
696
+ {
697
+ int len = NUM2INT(iv_length);
698
+ EVP_CIPHER_CTX *ctx;
699
+
700
+ GetCipher(self, ctx);
701
+ if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER))
702
+ ossl_raise(eCipherError, "cipher does not support AEAD");
703
+
704
+ if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, len, NULL))
705
+ ossl_raise(eCipherError, "unable to set IV length");
706
+
707
+ /*
708
+ * EVP_CIPHER_CTX_iv_length() returns the default length. So we need to save
709
+ * the length somewhere. Luckily currently we aren't using app_data.
710
+ */
711
+ EVP_CIPHER_CTX_set_app_data(ctx, (void *)(VALUE)len);
712
+
713
+ return iv_length;
714
+ }
715
+
716
+ /*
717
+ * call-seq:
718
+ * cipher.key_len = integer -> integer
719
+ *
720
+ * Sets the key length of the cipher. If the cipher is a fixed length cipher
721
+ * then attempting to set the key length to any value other than the fixed
722
+ * value is an error.
723
+ *
724
+ * Under normal circumstances you do not need to call this method (and probably shouldn't).
725
+ *
726
+ * See EVP_CIPHER_CTX_set_key_length for further information.
727
+ */
728
+ static VALUE
729
+ ossl_cipher_set_key_length(VALUE self, VALUE key_length)
730
+ {
731
+ int len = NUM2INT(key_length);
732
+ EVP_CIPHER_CTX *ctx;
733
+
734
+ GetCipher(self, ctx);
735
+ if (EVP_CIPHER_CTX_set_key_length(ctx, len) != 1)
736
+ ossl_raise(eCipherError, NULL);
737
+
738
+ return key_length;
739
+ }
740
+
741
+ /*
742
+ * call-seq:
743
+ * cipher.padding = integer -> integer
744
+ *
745
+ * Enables or disables padding. By default encryption operations are padded using standard block padding and the
746
+ * padding is checked and removed when decrypting. If the pad parameter is zero then no padding is performed, the
747
+ * total amount of data encrypted or decrypted must then be a multiple of the block size or an error will occur.
748
+ *
749
+ * See EVP_CIPHER_CTX_set_padding for further information.
750
+ */
751
+ static VALUE
752
+ ossl_cipher_set_padding(VALUE self, VALUE padding)
753
+ {
754
+ EVP_CIPHER_CTX *ctx;
755
+ int pad = NUM2INT(padding);
756
+
757
+ GetCipher(self, ctx);
758
+ if (EVP_CIPHER_CTX_set_padding(ctx, pad) != 1)
759
+ ossl_raise(eCipherError, NULL);
760
+ return padding;
761
+ }
762
+
763
+ /*
764
+ * call-seq:
765
+ * cipher.key_len -> integer
766
+ *
767
+ * Returns the key length in bytes of the Cipher.
768
+ */
769
+ static VALUE
770
+ ossl_cipher_key_length(VALUE self)
771
+ {
772
+ EVP_CIPHER_CTX *ctx;
773
+
774
+ GetCipher(self, ctx);
775
+
776
+ return INT2NUM(EVP_CIPHER_CTX_key_length(ctx));
777
+ }
778
+
779
+ /*
780
+ * call-seq:
781
+ * cipher.iv_len -> integer
782
+ *
783
+ * Returns the expected length in bytes for an IV for this Cipher.
784
+ */
785
+ static VALUE
786
+ ossl_cipher_iv_length(VALUE self)
787
+ {
788
+ EVP_CIPHER_CTX *ctx;
789
+ int len = 0;
790
+
791
+ GetCipher(self, ctx);
792
+ if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)
793
+ len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx);
794
+ if (!len)
795
+ len = EVP_CIPHER_CTX_iv_length(ctx);
796
+
797
+ return INT2NUM(len);
798
+ }
799
+
800
+ /*
801
+ * call-seq:
802
+ * cipher.block_size -> integer
803
+ *
804
+ * Returns the size in bytes of the blocks on which this Cipher operates on.
805
+ */
806
+ static VALUE
807
+ ossl_cipher_block_size(VALUE self)
808
+ {
809
+ EVP_CIPHER_CTX *ctx;
810
+
811
+ GetCipher(self, ctx);
812
+
813
+ return INT2NUM(EVP_CIPHER_CTX_block_size(ctx));
814
+ }
815
+
816
+ /*
817
+ * call-seq:
818
+ * cipher.ccm_data_len = integer -> integer
819
+ *
820
+ * Sets the length of the plaintext / ciphertext message that will be
821
+ * processed in CCM mode. Make sure to call this method after #key= and
822
+ * #iv= have been set, and before #auth_data=.
823
+ *
824
+ * Only call this method after calling Cipher#encrypt or Cipher#decrypt.
825
+ */
826
+ static VALUE
827
+ ossl_cipher_set_ccm_data_len(VALUE self, VALUE data_len)
828
+ {
829
+ int in_len, out_len;
830
+ EVP_CIPHER_CTX *ctx;
831
+
832
+ in_len = NUM2INT(data_len);
833
+
834
+ GetCipher(self, ctx);
835
+ if (EVP_CipherUpdate(ctx, NULL, &out_len, NULL, in_len) != 1)
836
+ ossl_raise(eCipherError, NULL);
837
+
838
+ return data_len;
839
+ }
840
+
841
+ /*
842
+ * INIT
843
+ */
844
+ void
845
+ Init_ossl_cipher(void)
846
+ {
847
+ #if 0
848
+ mOSSL = rb_define_module("OpenSSL");
849
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
850
+ #endif
851
+
852
+ /* Document-class: OpenSSL::Cipher
853
+ *
854
+ * Provides symmetric algorithms for encryption and decryption. The
855
+ * algorithms that are available depend on the particular version
856
+ * of OpenSSL that is installed.
857
+ *
858
+ * === Listing all supported algorithms
859
+ *
860
+ * A list of supported algorithms can be obtained by
861
+ *
862
+ * puts OpenSSL::Cipher.ciphers
863
+ *
864
+ * === Instantiating a Cipher
865
+ *
866
+ * There are several ways to create a Cipher instance. Generally, a
867
+ * Cipher algorithm is categorized by its name, the key length in bits
868
+ * and the cipher mode to be used. The most generic way to create a
869
+ * Cipher is the following
870
+ *
871
+ * cipher = OpenSSL::Cipher.new('<name>-<key length>-<mode>')
872
+ *
873
+ * That is, a string consisting of the hyphenated concatenation of the
874
+ * individual components name, key length and mode. Either all uppercase
875
+ * or all lowercase strings may be used, for example:
876
+ *
877
+ * cipher = OpenSSL::Cipher.new('AES-128-CBC')
878
+ *
879
+ * === Choosing either encryption or decryption mode
880
+ *
881
+ * Encryption and decryption are often very similar operations for
882
+ * symmetric algorithms, this is reflected by not having to choose
883
+ * different classes for either operation, both can be done using the
884
+ * same class. Still, after obtaining a Cipher instance, we need to
885
+ * tell the instance what it is that we intend to do with it, so we
886
+ * need to call either
887
+ *
888
+ * cipher.encrypt
889
+ *
890
+ * or
891
+ *
892
+ * cipher.decrypt
893
+ *
894
+ * on the Cipher instance. This should be the first call after creating
895
+ * the instance, otherwise configuration that has already been set could
896
+ * get lost in the process.
897
+ *
898
+ * === Choosing a key
899
+ *
900
+ * Symmetric encryption requires a key that is the same for the encrypting
901
+ * and for the decrypting party and after initial key establishment should
902
+ * be kept as private information. There are a lot of ways to create
903
+ * insecure keys, the most notable is to simply take a password as the key
904
+ * without processing the password further. A simple and secure way to
905
+ * create a key for a particular Cipher is
906
+ *
907
+ * cipher = OpenSSL::Cipher.new('AES-256-CFB')
908
+ * cipher.encrypt
909
+ * key = cipher.random_key # also sets the generated key on the Cipher
910
+ *
911
+ * If you absolutely need to use passwords as encryption keys, you
912
+ * should use Password-Based Key Derivation Function 2 (PBKDF2) by
913
+ * generating the key with the help of the functionality provided by
914
+ * OpenSSL::PKCS5.pbkdf2_hmac_sha1 or OpenSSL::PKCS5.pbkdf2_hmac.
915
+ *
916
+ * Although there is Cipher#pkcs5_keyivgen, its use is deprecated and
917
+ * it should only be used in legacy applications because it does not use
918
+ * the newer PKCS#5 v2 algorithms.
919
+ *
920
+ * === Choosing an IV
921
+ *
922
+ * The cipher modes CBC, CFB, OFB and CTR all need an "initialization
923
+ * vector", or short, IV. ECB mode is the only mode that does not require
924
+ * an IV, but there is almost no legitimate use case for this mode
925
+ * because of the fact that it does not sufficiently hide plaintext
926
+ * patterns. Therefore
927
+ *
928
+ * <b>You should never use ECB mode unless you are absolutely sure that
929
+ * you absolutely need it</b>
930
+ *
931
+ * Because of this, you will end up with a mode that explicitly requires
932
+ * an IV in any case. Although the IV can be seen as public information,
933
+ * i.e. it may be transmitted in public once generated, it should still
934
+ * stay unpredictable to prevent certain kinds of attacks. Therefore,
935
+ * ideally
936
+ *
937
+ * <b>Always create a secure random IV for every encryption of your
938
+ * Cipher</b>
939
+ *
940
+ * A new, random IV should be created for every encryption of data. Think
941
+ * of the IV as a nonce (number used once) - it's public but random and
942
+ * unpredictable. A secure random IV can be created as follows
943
+ *
944
+ * cipher = ...
945
+ * cipher.encrypt
946
+ * key = cipher.random_key
947
+ * iv = cipher.random_iv # also sets the generated IV on the Cipher
948
+ *
949
+ * Although the key is generally a random value, too, it is a bad choice
950
+ * as an IV. There are elaborate ways how an attacker can take advantage
951
+ * of such an IV. As a general rule of thumb, exposing the key directly
952
+ * or indirectly should be avoided at all cost and exceptions only be
953
+ * made with good reason.
954
+ *
955
+ * === Calling Cipher#final
956
+ *
957
+ * ECB (which should not be used) and CBC are both block-based modes.
958
+ * This means that unlike for the other streaming-based modes, they
959
+ * operate on fixed-size blocks of data, and therefore they require a
960
+ * "finalization" step to produce or correctly decrypt the last block of
961
+ * data by appropriately handling some form of padding. Therefore it is
962
+ * essential to add the output of OpenSSL::Cipher#final to your
963
+ * encryption/decryption buffer or you will end up with decryption errors
964
+ * or truncated data.
965
+ *
966
+ * Although this is not really necessary for streaming-mode ciphers, it is
967
+ * still recommended to apply the same pattern of adding the output of
968
+ * Cipher#final there as well - it also enables you to switch between
969
+ * modes more easily in the future.
970
+ *
971
+ * === Encrypting and decrypting some data
972
+ *
973
+ * data = "Very, very confidential data"
974
+ *
975
+ * cipher = OpenSSL::Cipher.new('AES-128-CBC')
976
+ * cipher.encrypt
977
+ * key = cipher.random_key
978
+ * iv = cipher.random_iv
979
+ *
980
+ * encrypted = cipher.update(data) + cipher.final
981
+ * ...
982
+ * decipher = OpenSSL::Cipher.new('AES-128-CBC')
983
+ * decipher.decrypt
984
+ * decipher.key = key
985
+ * decipher.iv = iv
986
+ *
987
+ * plain = decipher.update(encrypted) + decipher.final
988
+ *
989
+ * puts data == plain #=> true
990
+ *
991
+ * === Authenticated Encryption and Associated Data (AEAD)
992
+ *
993
+ * If the OpenSSL version used supports it, an Authenticated Encryption
994
+ * mode (such as GCM or CCM) should always be preferred over any
995
+ * unauthenticated mode. Currently, OpenSSL supports AE only in combination
996
+ * with Associated Data (AEAD) where additional associated data is included
997
+ * in the encryption process to compute a tag at the end of the encryption.
998
+ * This tag will also be used in the decryption process and by verifying
999
+ * its validity, the authenticity of a given ciphertext is established.
1000
+ *
1001
+ * This is superior to unauthenticated modes in that it allows to detect
1002
+ * if somebody effectively changed the ciphertext after it had been
1003
+ * encrypted. This prevents malicious modifications of the ciphertext that
1004
+ * could otherwise be exploited to modify ciphertexts in ways beneficial to
1005
+ * potential attackers.
1006
+ *
1007
+ * An associated data is used where there is additional information, such as
1008
+ * headers or some metadata, that must be also authenticated but not
1009
+ * necessarily need to be encrypted. If no associated data is needed for
1010
+ * encryption and later decryption, the OpenSSL library still requires a
1011
+ * value to be set - "" may be used in case none is available.
1012
+ *
1013
+ * An example using the GCM (Galois/Counter Mode). You have 16 bytes _key_,
1014
+ * 12 bytes (96 bits) _nonce_ and the associated data _auth_data_. Be sure
1015
+ * not to reuse the _key_ and _nonce_ pair. Reusing an nonce ruins the
1016
+ * security guarantees of GCM mode.
1017
+ *
1018
+ * cipher = OpenSSL::Cipher.new('AES-128-GCM').encrypt
1019
+ * cipher.key = key
1020
+ * cipher.iv = nonce
1021
+ * cipher.auth_data = auth_data
1022
+ *
1023
+ * encrypted = cipher.update(data) + cipher.final
1024
+ * tag = cipher.auth_tag # produces 16 bytes tag by default
1025
+ *
1026
+ * Now you are the receiver. You know the _key_ and have received _nonce_,
1027
+ * _auth_data_, _encrypted_ and _tag_ through an untrusted network. Note
1028
+ * that GCM accepts an arbitrary length tag between 1 and 16 bytes. You may
1029
+ * additionally need to check that the received tag has the correct length,
1030
+ * or you allow attackers to forge a valid single byte tag for the tampered
1031
+ * ciphertext with a probability of 1/256.
1032
+ *
1033
+ * raise "tag is truncated!" unless tag.bytesize == 16
1034
+ * decipher = OpenSSL::Cipher.new('AES-128-GCM').decrypt
1035
+ * decipher.key = key
1036
+ * decipher.iv = nonce
1037
+ * decipher.auth_tag = tag
1038
+ * decipher.auth_data = auth_data
1039
+ *
1040
+ * decrypted = decipher.update(encrypted) + decipher.final
1041
+ *
1042
+ * puts data == decrypted #=> true
1043
+ */
1044
+ cCipher = rb_define_class_under(mOSSL, "Cipher", rb_cObject);
1045
+ eCipherError = rb_define_class_under(cCipher, "CipherError", eOSSLError);
1046
+
1047
+ rb_define_alloc_func(cCipher, ossl_cipher_alloc);
1048
+ rb_define_method(cCipher, "initialize_copy", ossl_cipher_copy, 1);
1049
+ rb_define_module_function(cCipher, "ciphers", ossl_s_ciphers, 0);
1050
+ rb_define_method(cCipher, "initialize", ossl_cipher_initialize, 1);
1051
+ rb_define_method(cCipher, "reset", ossl_cipher_reset, 0);
1052
+ rb_define_method(cCipher, "encrypt", ossl_cipher_encrypt, -1);
1053
+ rb_define_method(cCipher, "decrypt", ossl_cipher_decrypt, -1);
1054
+ rb_define_method(cCipher, "pkcs5_keyivgen", ossl_cipher_pkcs5_keyivgen, -1);
1055
+ rb_define_method(cCipher, "update", ossl_cipher_update, -1);
1056
+ rb_define_method(cCipher, "final", ossl_cipher_final, 0);
1057
+ rb_define_method(cCipher, "name", ossl_cipher_name, 0);
1058
+ rb_define_method(cCipher, "key=", ossl_cipher_set_key, 1);
1059
+ rb_define_method(cCipher, "auth_data=", ossl_cipher_set_auth_data, 1);
1060
+ rb_define_method(cCipher, "auth_tag=", ossl_cipher_set_auth_tag, 1);
1061
+ rb_define_method(cCipher, "auth_tag", ossl_cipher_get_auth_tag, -1);
1062
+ rb_define_method(cCipher, "auth_tag_len=", ossl_cipher_set_auth_tag_len, 1);
1063
+ rb_define_method(cCipher, "authenticated?", ossl_cipher_is_authenticated, 0);
1064
+ rb_define_method(cCipher, "key_len=", ossl_cipher_set_key_length, 1);
1065
+ rb_define_method(cCipher, "key_len", ossl_cipher_key_length, 0);
1066
+ rb_define_method(cCipher, "iv=", ossl_cipher_set_iv, 1);
1067
+ rb_define_method(cCipher, "iv_len=", ossl_cipher_set_iv_length, 1);
1068
+ rb_define_method(cCipher, "iv_len", ossl_cipher_iv_length, 0);
1069
+ rb_define_method(cCipher, "block_size", ossl_cipher_block_size, 0);
1070
+ rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1);
1071
+ rb_define_method(cCipher, "ccm_data_len=", ossl_cipher_set_ccm_data_len, 1);
1072
+
1073
+ id_auth_tag_len = rb_intern_const("auth_tag_len");
1074
+ id_key_set = rb_intern_const("key_set");
1075
+ }