openssl 2.1.0 → 3.2.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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +426 -0
  4. data/README.md +38 -21
  5. data/ext/openssl/extconf.rb +132 -72
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +62 -46
  8. data/ext/openssl/ossl.c +177 -252
  9. data/ext/openssl/ossl.h +39 -17
  10. data/ext/openssl/ossl_asn1.c +53 -14
  11. data/ext/openssl/ossl_bn.c +288 -146
  12. data/ext/openssl/ossl_bn.h +2 -1
  13. data/ext/openssl/ossl_cipher.c +42 -32
  14. data/ext/openssl/ossl_config.c +412 -41
  15. data/ext/openssl/ossl_config.h +4 -7
  16. data/ext/openssl/ossl_digest.c +32 -63
  17. data/ext/openssl/ossl_engine.c +19 -28
  18. data/ext/openssl/ossl_hmac.c +61 -146
  19. data/ext/openssl/ossl_kdf.c +15 -23
  20. data/ext/openssl/ossl_ns_spki.c +2 -2
  21. data/ext/openssl/ossl_ocsp.c +17 -70
  22. data/ext/openssl/ossl_ocsp.h +3 -3
  23. data/ext/openssl/ossl_pkcs12.c +23 -4
  24. data/ext/openssl/ossl_pkcs7.c +49 -81
  25. data/ext/openssl/ossl_pkcs7.h +16 -0
  26. data/ext/openssl/ossl_pkey.c +1508 -195
  27. data/ext/openssl/ossl_pkey.h +41 -78
  28. data/ext/openssl/ossl_pkey_dh.c +153 -348
  29. data/ext/openssl/ossl_pkey_dsa.c +157 -413
  30. data/ext/openssl/ossl_pkey_ec.c +257 -343
  31. data/ext/openssl/ossl_pkey_rsa.c +166 -490
  32. data/ext/openssl/ossl_provider.c +211 -0
  33. data/ext/openssl/ossl_provider.h +5 -0
  34. data/ext/openssl/ossl_rand.c +2 -40
  35. data/ext/openssl/ossl_ssl.c +666 -456
  36. data/ext/openssl/ossl_ssl_session.c +29 -30
  37. data/ext/openssl/ossl_ts.c +1539 -0
  38. data/ext/openssl/ossl_ts.h +16 -0
  39. data/ext/openssl/ossl_x509.c +86 -1
  40. data/ext/openssl/ossl_x509attr.c +1 -1
  41. data/ext/openssl/ossl_x509cert.c +170 -14
  42. data/ext/openssl/ossl_x509crl.c +14 -11
  43. data/ext/openssl/ossl_x509ext.c +29 -9
  44. data/ext/openssl/ossl_x509name.c +24 -12
  45. data/ext/openssl/ossl_x509req.c +14 -11
  46. data/ext/openssl/ossl_x509revoked.c +4 -4
  47. data/ext/openssl/ossl_x509store.c +205 -96
  48. data/lib/openssl/bn.rb +1 -1
  49. data/lib/openssl/buffering.rb +42 -20
  50. data/lib/openssl/cipher.rb +1 -1
  51. data/lib/openssl/digest.rb +10 -16
  52. data/lib/openssl/hmac.rb +78 -0
  53. data/lib/openssl/marshal.rb +30 -0
  54. data/lib/openssl/pkcs5.rb +1 -1
  55. data/lib/openssl/pkey.rb +447 -1
  56. data/lib/openssl/ssl.rb +68 -24
  57. data/lib/openssl/version.rb +5 -0
  58. data/lib/openssl/x509.rb +177 -1
  59. data/lib/openssl.rb +24 -9
  60. metadata +18 -71
  61. data/ext/openssl/deprecation.rb +0 -23
  62. data/ext/openssl/ossl_version.h +0 -15
  63. data/ext/openssl/ruby_missing.h +0 -24
  64. data/lib/openssl/config.rb +0 -474
data/ext/openssl/ossl.c CHANGED
@@ -9,13 +9,19 @@
9
9
  */
10
10
  #include "ossl.h"
11
11
  #include <stdarg.h> /* for ossl_raise */
12
- #include <ruby/thread_native.h> /* for OpenSSL < 1.1.0 locks */
12
+
13
+ /* OpenSSL >= 1.1.0 and LibreSSL >= 2.9.0 */
14
+ #if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000
15
+ # define HAVE_OPENSSL_110_THREADING_API
16
+ #else
17
+ # include <ruby/thread_native.h>
18
+ #endif
13
19
 
14
20
  /*
15
21
  * Data Conversion
16
22
  */
17
23
  #define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \
18
- STACK_OF(type) * \
24
+ VALUE \
19
25
  ossl_##name##_ary2sk0(VALUE ary) \
20
26
  { \
21
27
  STACK_OF(type) *sk; \
@@ -37,7 +43,7 @@ ossl_##name##_ary2sk0(VALUE ary) \
37
43
  x = dup(val); /* NEED TO DUP */ \
38
44
  sk_##type##_push(sk, x); \
39
45
  } \
40
- return sk; \
46
+ return (VALUE)sk; \
41
47
  } \
42
48
  \
43
49
  STACK_OF(type) * \
@@ -201,7 +207,7 @@ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
201
207
 
202
208
  while (1) {
203
209
  /*
204
- * when the flag is nonzero, this passphrase
210
+ * when the flag is nonzero, this password
205
211
  * will be used to perform encryption; otherwise it will
206
212
  * be used to perform decryption.
207
213
  */
@@ -262,31 +268,32 @@ ossl_to_der_if_possible(VALUE obj)
262
268
  /*
263
269
  * Errors
264
270
  */
265
- static VALUE
266
- ossl_make_error(VALUE exc, const char *fmt, va_list args)
271
+ VALUE
272
+ ossl_make_error(VALUE exc, VALUE str)
267
273
  {
268
- VALUE str = Qnil;
269
274
  unsigned long e;
275
+ const char *data;
276
+ int flags;
270
277
 
271
- if (fmt) {
272
- str = rb_vsprintf(fmt, args);
273
- }
274
- e = ERR_peek_last_error();
278
+ if (NIL_P(str))
279
+ str = rb_str_new(NULL, 0);
280
+
281
+ #ifdef HAVE_ERR_GET_ERROR_ALL
282
+ e = ERR_peek_last_error_all(NULL, NULL, NULL, &data, &flags);
283
+ #else
284
+ e = ERR_peek_last_error_line_data(NULL, NULL, &data, &flags);
285
+ #endif
275
286
  if (e) {
276
- const char *msg = ERR_reason_error_string(e);
287
+ const char *msg = ERR_reason_error_string(e);
277
288
 
278
- if (NIL_P(str)) {
279
- if (msg) str = rb_str_new_cstr(msg);
280
- }
281
- else {
282
- if (RSTRING_LEN(str)) rb_str_cat2(str, ": ");
283
- rb_str_cat2(str, msg ? msg : "(null)");
284
- }
285
- ossl_clear_error();
289
+ if (RSTRING_LEN(str)) rb_str_cat_cstr(str, ": ");
290
+ rb_str_cat_cstr(str, msg ? msg : "(null)");
291
+ if (flags & ERR_TXT_STRING && data)
292
+ rb_str_catf(str, " (%s)", data);
293
+ ossl_clear_error();
286
294
  }
287
295
 
288
- if (NIL_P(str)) str = rb_str_new(0, 0);
289
- return rb_exc_new3(exc, str);
296
+ return rb_exc_new_str(exc, str);
290
297
  }
291
298
 
292
299
  void
@@ -294,37 +301,48 @@ ossl_raise(VALUE exc, const char *fmt, ...)
294
301
  {
295
302
  va_list args;
296
303
  VALUE err;
297
- va_start(args, fmt);
298
- err = ossl_make_error(exc, fmt, args);
299
- va_end(args);
300
- rb_exc_raise(err);
304
+
305
+ if (fmt) {
306
+ va_start(args, fmt);
307
+ err = rb_vsprintf(fmt, args);
308
+ va_end(args);
309
+ }
310
+ else {
311
+ err = Qnil;
312
+ }
313
+
314
+ rb_exc_raise(ossl_make_error(exc, err));
301
315
  }
302
316
 
303
317
  void
304
318
  ossl_clear_error(void)
305
319
  {
306
320
  if (dOSSL == Qtrue) {
307
- unsigned long e;
308
- const char *file, *data, *errstr;
309
- int line, flags;
310
-
311
- while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) {
312
- errstr = ERR_error_string(e, NULL);
313
- if (!errstr)
314
- errstr = "(null)";
315
-
316
- if (flags & ERR_TXT_STRING) {
317
- if (!data)
318
- data = "(null)";
319
- rb_warn("error on stack: %s (%s)", errstr, data);
320
- }
321
- else {
322
- rb_warn("error on stack: %s", errstr);
323
- }
324
- }
321
+ unsigned long e;
322
+ const char *file, *data, *func, *lib, *reason;
323
+ char append[256] = "";
324
+ int line, flags;
325
+
326
+ #ifdef HAVE_ERR_GET_ERROR_ALL
327
+ while ((e = ERR_get_error_all(&file, &line, &func, &data, &flags))) {
328
+ #else
329
+ while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) {
330
+ func = ERR_func_error_string(e);
331
+ #endif
332
+ lib = ERR_lib_error_string(e);
333
+ reason = ERR_reason_error_string(e);
334
+
335
+ if (flags & ERR_TXT_STRING) {
336
+ if (!data)
337
+ data = "(null)";
338
+ snprintf(append, sizeof(append), " (%s)", data);
339
+ }
340
+ rb_warn("error on stack: error:%08lX:%s:%s:%s%s", e, lib ? lib : "",
341
+ func ? func : "", reason ? reason : "", append);
342
+ }
325
343
  }
326
344
  else {
327
- ERR_clear_error();
345
+ ERR_clear_error();
328
346
  }
329
347
  }
330
348
 
@@ -338,7 +356,7 @@ ossl_clear_error(void)
338
356
  * implementation.
339
357
  */
340
358
  VALUE
341
- ossl_get_errors(void)
359
+ ossl_get_errors(VALUE _)
342
360
  {
343
361
  VALUE ary;
344
362
  long e;
@@ -356,22 +374,6 @@ ossl_get_errors(void)
356
374
  */
357
375
  VALUE dOSSL;
358
376
 
359
- #if !defined(HAVE_VA_ARGS_MACRO)
360
- void
361
- ossl_debug(const char *fmt, ...)
362
- {
363
- va_list args;
364
-
365
- if (dOSSL == Qtrue) {
366
- fprintf(stderr, "OSSL_DEBUG: ");
367
- va_start(args, fmt);
368
- vfprintf(stderr, fmt, args);
369
- va_end(args);
370
- fprintf(stderr, " [CONTEXT N/A]\n");
371
- }
372
- }
373
- #endif
374
-
375
377
  /*
376
378
  * call-seq:
377
379
  * OpenSSL.debug -> true | false
@@ -386,7 +388,7 @@ ossl_debug_get(VALUE self)
386
388
  * call-seq:
387
389
  * OpenSSL.debug = boolean -> boolean
388
390
  *
389
- * Turns on or off debug mode. With debug mode, all erros added to the OpenSSL
391
+ * Turns on or off debug mode. With debug mode, all errors added to the OpenSSL
390
392
  * error queue will be printed to stderr.
391
393
  */
392
394
  static VALUE
@@ -398,14 +400,18 @@ ossl_debug_set(VALUE self, VALUE val)
398
400
  }
399
401
 
400
402
  /*
401
- * call-seq
403
+ * call-seq:
402
404
  * OpenSSL.fips_mode -> true | false
403
405
  */
404
406
  static VALUE
405
407
  ossl_fips_mode_get(VALUE self)
406
408
  {
407
409
 
408
- #ifdef OPENSSL_FIPS
410
+ #if OSSL_OPENSSL_PREREQ(3, 0, 0)
411
+ VALUE enabled;
412
+ enabled = EVP_default_properties_is_fips_enabled(NULL) ? Qtrue : Qfalse;
413
+ return enabled;
414
+ #elif defined(OPENSSL_FIPS)
409
415
  VALUE enabled;
410
416
  enabled = FIPS_mode() ? Qtrue : Qfalse;
411
417
  return enabled;
@@ -429,8 +435,18 @@ ossl_fips_mode_get(VALUE self)
429
435
  static VALUE
430
436
  ossl_fips_mode_set(VALUE self, VALUE enabled)
431
437
  {
432
-
433
- #ifdef OPENSSL_FIPS
438
+ #if OSSL_OPENSSL_PREREQ(3, 0, 0)
439
+ if (RTEST(enabled)) {
440
+ if (!EVP_default_properties_enable_fips(NULL, 1)) {
441
+ ossl_raise(eOSSLError, "Turning on FIPS mode failed");
442
+ }
443
+ } else {
444
+ if (!EVP_default_properties_enable_fips(NULL, 0)) {
445
+ ossl_raise(eOSSLError, "Turning off FIPS mode failed");
446
+ }
447
+ }
448
+ return enabled;
449
+ #elif defined(OPENSSL_FIPS)
434
450
  if (RTEST(enabled)) {
435
451
  int mode = FIPS_mode();
436
452
  if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */
@@ -447,72 +463,6 @@ ossl_fips_mode_set(VALUE self, VALUE enabled)
447
463
  #endif
448
464
  }
449
465
 
450
- #if defined(OSSL_DEBUG)
451
- #if !defined(LIBRESSL_VERSION_NUMBER) && \
452
- (OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \
453
- defined(CRYPTO_malloc_debug_init))
454
- /*
455
- * call-seq:
456
- * OpenSSL.mem_check_start -> nil
457
- *
458
- * Calls CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON). Starts tracking memory
459
- * allocations. See also OpenSSL.print_mem_leaks.
460
- *
461
- * This is available only when built with a capable OpenSSL and --enable-debug
462
- * configure option.
463
- */
464
- static VALUE
465
- mem_check_start(VALUE self)
466
- {
467
- CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
468
- return Qnil;
469
- }
470
-
471
- /*
472
- * call-seq:
473
- * OpenSSL.print_mem_leaks -> true | false
474
- *
475
- * For debugging the Ruby/OpenSSL library. Calls CRYPTO_mem_leaks_fp(stderr).
476
- * Prints detected memory leaks to standard error. This cleans the global state
477
- * up thus you cannot use any methods of the library after calling this.
478
- *
479
- * Returns +true+ if leaks detected, +false+ otherwise.
480
- *
481
- * This is available only when built with a capable OpenSSL and --enable-debug
482
- * configure option.
483
- *
484
- * === Example
485
- * OpenSSL.mem_check_start
486
- * NOT_GCED = OpenSSL::PKey::RSA.new(256)
487
- *
488
- * END {
489
- * GC.start
490
- * OpenSSL.print_mem_leaks # will print the leakage
491
- * }
492
- */
493
- static VALUE
494
- print_mem_leaks(VALUE self)
495
- {
496
- #if OPENSSL_VERSION_NUMBER >= 0x10100000
497
- int ret;
498
- #endif
499
-
500
- BN_CTX_free(ossl_bn_ctx);
501
- ossl_bn_ctx = NULL;
502
-
503
- #if OPENSSL_VERSION_NUMBER >= 0x10100000
504
- ret = CRYPTO_mem_leaks_fp(stderr);
505
- if (ret < 0)
506
- ossl_raise(eOSSLError, "CRYPTO_mem_leaks_fp");
507
- return ret ? Qfalse : Qtrue;
508
- #else
509
- CRYPTO_mem_leaks_fp(stderr);
510
- return Qnil;
511
- #endif
512
- }
513
- #endif
514
- #endif
515
-
516
466
  #if !defined(HAVE_OPENSSL_110_THREADING_API)
517
467
  /**
518
468
  * Stores locks needed for OpenSSL thread safety
@@ -604,6 +554,35 @@ static void Init_ossl_locks(void)
604
554
  }
605
555
  #endif /* !HAVE_OPENSSL_110_THREADING_API */
606
556
 
557
+ /*
558
+ * call-seq:
559
+ * OpenSSL.fixed_length_secure_compare(string, string) -> boolean
560
+ *
561
+ * Constant time memory comparison for fixed length strings, such as results
562
+ * of HMAC calculations.
563
+ *
564
+ * Returns +true+ if the strings are identical, +false+ if they are of the same
565
+ * length but not identical. If the length is different, +ArgumentError+ is
566
+ * raised.
567
+ */
568
+ static VALUE
569
+ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
570
+ {
571
+ const unsigned char *p1 = (const unsigned char *)StringValuePtr(str1);
572
+ const unsigned char *p2 = (const unsigned char *)StringValuePtr(str2);
573
+ long len1 = RSTRING_LEN(str1);
574
+ long len2 = RSTRING_LEN(str2);
575
+
576
+ if (len1 != len2) {
577
+ ossl_raise(rb_eArgError, "inputs must be of equal length");
578
+ }
579
+
580
+ switch (CRYPTO_memcmp(p1, p2, len1)) {
581
+ case 0: return Qtrue;
582
+ default: return Qfalse;
583
+ }
584
+ }
585
+
607
586
  /*
608
587
  * OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
609
588
  * OpenSSL[https://www.openssl.org/] library.
@@ -626,23 +605,21 @@ static void Init_ossl_locks(void)
626
605
  *
627
606
  * key = OpenSSL::PKey::RSA.new 2048
628
607
  *
629
- * open 'private_key.pem', 'w' do |io| io.write key.to_pem end
630
- * open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end
608
+ * File.write 'private_key.pem', key.private_to_pem
609
+ * File.write 'public_key.pem', key.public_to_pem
631
610
  *
632
611
  * === Exporting a Key
633
612
  *
634
613
  * Keys saved to disk without encryption are not secure as anyone who gets
635
614
  * ahold of the key may use it unless it is encrypted. In order to securely
636
- * export a key you may export it with a pass phrase.
615
+ * export a key you may export it with a password.
637
616
  *
638
- * cipher = OpenSSL::Cipher.new 'AES-128-CBC'
639
- * pass_phrase = 'my secure pass phrase goes here'
617
+ * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
618
+ * password = 'my secure password goes here'
640
619
  *
641
- * key_secure = key.export cipher, pass_phrase
620
+ * key_secure = key.private_to_pem cipher, password
642
621
  *
643
- * open 'private.secure.pem', 'w' do |io|
644
- * io.write key_secure
645
- * end
622
+ * File.write 'private.secure.pem', key_secure
646
623
  *
647
624
  * OpenSSL::Cipher.ciphers returns a list of available ciphers.
648
625
  *
@@ -650,25 +627,25 @@ static void Init_ossl_locks(void)
650
627
  *
651
628
  * A key can also be loaded from a file.
652
629
  *
653
- * key2 = OpenSSL::PKey::RSA.new File.read 'private_key.pem'
630
+ * key2 = OpenSSL::PKey.read File.read 'private_key.pem'
654
631
  * key2.public? # => true
655
632
  * key2.private? # => true
656
633
  *
657
634
  * or
658
635
  *
659
- * key3 = OpenSSL::PKey::RSA.new File.read 'public_key.pem'
636
+ * key3 = OpenSSL::PKey.read File.read 'public_key.pem'
660
637
  * key3.public? # => true
661
638
  * key3.private? # => false
662
639
  *
663
640
  * === Loading an Encrypted Key
664
641
  *
665
- * OpenSSL will prompt you for your pass phrase when loading an encrypted key.
666
- * If you will not be able to type in the pass phrase you may provide it when
642
+ * OpenSSL will prompt you for your password when loading an encrypted key.
643
+ * If you will not be able to type in the password you may provide it when
667
644
  * loading the key:
668
645
  *
669
646
  * key4_pem = File.read 'private.secure.pem'
670
- * pass_phrase = 'my secure pass phrase goes here'
671
- * key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
647
+ * password = 'my secure password goes here'
648
+ * key4 = OpenSSL::PKey.read key4_pem, password
672
649
  *
673
650
  * == RSA Encryption
674
651
  *
@@ -710,16 +687,14 @@ static void Init_ossl_locks(void)
710
687
  * To sign a document, a cryptographically secure hash of the document is
711
688
  * computed first, which is then signed using the private key.
712
689
  *
713
- * digest = OpenSSL::Digest::SHA256.new
714
- * signature = key.sign digest, document
690
+ * signature = key.sign 'SHA256', document
715
691
  *
716
692
  * To validate the signature, again a hash of the document is computed and
717
693
  * the signature is decrypted using the public key. The result is then
718
694
  * compared to the hash just computed, if they are equal the signature was
719
695
  * valid.
720
696
  *
721
- * digest = OpenSSL::Digest::SHA256.new
722
- * if key.verify digest, signature, document
697
+ * if key.verify 'SHA256', signature, document
723
698
  * puts 'Valid'
724
699
  * else
725
700
  * puts 'Invalid'
@@ -745,7 +720,7 @@ static void Init_ossl_locks(void)
745
720
  * using PBKDF2. PKCS #5 v2.0 recommends at least 8 bytes for the salt,
746
721
  * the number of iterations largely depends on the hardware being used.
747
722
  *
748
- * cipher = OpenSSL::Cipher.new 'AES-128-CBC'
723
+ * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
749
724
  * cipher.encrypt
750
725
  * iv = cipher.random_iv
751
726
  *
@@ -753,7 +728,7 @@ static void Init_ossl_locks(void)
753
728
  * salt = OpenSSL::Random.random_bytes 16
754
729
  * iter = 20000
755
730
  * key_len = cipher.key_len
756
- * digest = OpenSSL::Digest::SHA256.new
731
+ * digest = OpenSSL::Digest.new('SHA256')
757
732
  *
758
733
  * key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
759
734
  * cipher.key = key
@@ -768,7 +743,7 @@ static void Init_ossl_locks(void)
768
743
  * Use the same steps as before to derive the symmetric AES key, this time
769
744
  * setting the Cipher up for decryption.
770
745
  *
771
- * cipher = OpenSSL::Cipher.new 'AES-128-CBC'
746
+ * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
772
747
  * cipher.decrypt
773
748
  * cipher.iv = iv # the one generated with #random_iv
774
749
  *
@@ -776,7 +751,7 @@ static void Init_ossl_locks(void)
776
751
  * salt = ... # the one generated above
777
752
  * iter = 20000
778
753
  * key_len = cipher.key_len
779
- * digest = OpenSSL::Digest::SHA256.new
754
+ * digest = OpenSSL::Digest.new('SHA256')
780
755
  *
781
756
  * key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
782
757
  * cipher.key = key
@@ -786,45 +761,6 @@ static void Init_ossl_locks(void)
786
761
  * decrypted = cipher.update encrypted
787
762
  * decrypted << cipher.final
788
763
  *
789
- * == PKCS #5 Password-based Encryption
790
- *
791
- * PKCS #5 is a password-based encryption standard documented at
792
- * RFC2898[http://www.ietf.org/rfc/rfc2898.txt]. It allows a short password or
793
- * passphrase to be used to create a secure encryption key. If possible, PBKDF2
794
- * as described above should be used if the circumstances allow it.
795
- *
796
- * PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption
797
- * key.
798
- *
799
- * pass_phrase = 'my secure pass phrase goes here'
800
- * salt = '8 octets'
801
- *
802
- * === Encryption
803
- *
804
- * First set up the cipher for encryption
805
- *
806
- * encryptor = OpenSSL::Cipher.new 'AES-128-CBC'
807
- * encryptor.encrypt
808
- * encryptor.pkcs5_keyivgen pass_phrase, salt
809
- *
810
- * Then pass the data you want to encrypt through
811
- *
812
- * encrypted = encryptor.update 'top secret document'
813
- * encrypted << encryptor.final
814
- *
815
- * === Decryption
816
- *
817
- * Use a new Cipher instance set up for decryption
818
- *
819
- * decryptor = OpenSSL::Cipher.new 'AES-128-CBC'
820
- * decryptor.decrypt
821
- * decryptor.pkcs5_keyivgen pass_phrase, salt
822
- *
823
- * Then pass the data you want to decrypt through
824
- *
825
- * plain = decryptor.update encrypted
826
- * plain << decryptor.final
827
- *
828
764
  * == X509 Certificates
829
765
  *
830
766
  * === Creating a Certificate
@@ -833,7 +769,7 @@ static void Init_ossl_locks(void)
833
769
  * signature.
834
770
  *
835
771
  * key = OpenSSL::PKey::RSA.new 2048
836
- * name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
772
+ * name = OpenSSL::X509::Name.parse '/CN=nobody/DC=example'
837
773
  *
838
774
  * cert = OpenSSL::X509::Certificate.new
839
775
  * cert.version = 2
@@ -872,7 +808,7 @@ static void Init_ossl_locks(void)
872
808
  * certificate.
873
809
  *
874
810
  * cert.issuer = name
875
- * cert.sign key, OpenSSL::Digest::SHA1.new
811
+ * cert.sign key, OpenSSL::Digest.new('SHA1')
876
812
  *
877
813
  * open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
878
814
  *
@@ -902,12 +838,12 @@ static void Init_ossl_locks(void)
902
838
  * not readable by other users.
903
839
  *
904
840
  * ca_key = OpenSSL::PKey::RSA.new 2048
905
- * pass_phrase = 'my secure pass phrase goes here'
841
+ * password = 'my secure password goes here'
906
842
  *
907
- * cipher = OpenSSL::Cipher.new 'AES-128-CBC'
843
+ * cipher = 'aes-256-cbc'
908
844
  *
909
845
  * open 'ca_key.pem', 'w', 0400 do |io|
910
- * io.write ca_key.export(cipher, pass_phrase)
846
+ * io.write ca_key.private_to_pem(cipher, password)
911
847
  * end
912
848
  *
913
849
  * === CA Certificate
@@ -915,7 +851,7 @@ static void Init_ossl_locks(void)
915
851
  * A CA certificate is created the same way we created a certificate above, but
916
852
  * with different extensions.
917
853
  *
918
- * ca_name = OpenSSL::X509::Name.parse 'CN=ca/DC=example'
854
+ * ca_name = OpenSSL::X509::Name.parse '/CN=ca/DC=example'
919
855
  *
920
856
  * ca_cert = OpenSSL::X509::Certificate.new
921
857
  * ca_cert.serial = 0
@@ -948,7 +884,7 @@ static void Init_ossl_locks(void)
948
884
  *
949
885
  * Root CA certificates are self-signed.
950
886
  *
951
- * ca_cert.sign ca_key, OpenSSL::Digest::SHA1.new
887
+ * ca_cert.sign ca_key, OpenSSL::Digest.new('SHA1')
952
888
  *
953
889
  * The CA certificate is saved to disk so it may be distributed to all the
954
890
  * users of the keys this CA will sign.
@@ -966,7 +902,7 @@ static void Init_ossl_locks(void)
966
902
  * csr.version = 0
967
903
  * csr.subject = name
968
904
  * csr.public_key = key.public_key
969
- * csr.sign key, OpenSSL::Digest::SHA1.new
905
+ * csr.sign key, OpenSSL::Digest.new('SHA1')
970
906
  *
971
907
  * A CSR is saved to disk and sent to the CA for signing.
972
908
  *
@@ -1010,7 +946,7 @@ static void Init_ossl_locks(void)
1010
946
  * csr_cert.add_extension \
1011
947
  * extension_factory.create_extension('subjectKeyIdentifier', 'hash')
1012
948
  *
1013
- * csr_cert.sign ca_key, OpenSSL::Digest::SHA1.new
949
+ * csr_cert.sign ca_key, OpenSSL::Digest.new('SHA1')
1014
950
  *
1015
951
  * open 'csr_cert.pem', 'w' do |io|
1016
952
  * io.write csr_cert.to_pem
@@ -1042,13 +978,13 @@ static void Init_ossl_locks(void)
1042
978
  * loop do
1043
979
  * ssl_connection = ssl_server.accept
1044
980
  *
1045
- * data = connection.gets
981
+ * data = ssl_connection.gets
1046
982
  *
1047
983
  * response = "I got #{data.dump}"
1048
984
  * puts response
1049
985
  *
1050
- * connection.puts "I got #{data.dump}"
1051
- * connection.close
986
+ * ssl_connection.puts "I got #{data.dump}"
987
+ * ssl_connection.close
1052
988
  * end
1053
989
  *
1054
990
  * === SSL client
@@ -1099,6 +1035,11 @@ static void Init_ossl_locks(void)
1099
1035
  void
1100
1036
  Init_openssl(void)
1101
1037
  {
1038
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
1039
+ rb_ext_ractor_safe(true);
1040
+ #endif
1041
+
1042
+ #undef rb_intern
1102
1043
  /*
1103
1044
  * Init timezone info
1104
1045
  */
@@ -1122,13 +1063,9 @@ Init_openssl(void)
1122
1063
  /*
1123
1064
  * Init main module
1124
1065
  */
1125
- mOSSL = rb_define_module("OpenSSL");
1126
1066
  rb_global_variable(&mOSSL);
1127
-
1128
- /*
1129
- * OpenSSL ruby extension version
1130
- */
1131
- rb_define_const(mOSSL, "VERSION", rb_str_new2(OSSL_VERSION));
1067
+ mOSSL = rb_define_module("OpenSSL");
1068
+ rb_define_singleton_method(mOSSL, "fixed_length_secure_compare", ossl_crypto_fixed_length_secure_compare, 2);
1132
1069
 
1133
1070
  /*
1134
1071
  * Version of OpenSSL the ruby OpenSSL extension was built with
@@ -1146,15 +1083,35 @@ Init_openssl(void)
1146
1083
 
1147
1084
  /*
1148
1085
  * Version number of OpenSSL the ruby OpenSSL extension was built with
1149
- * (base 16)
1086
+ * (base 16). The formats are below.
1087
+ *
1088
+ * [OpenSSL 3] <tt>0xMNN00PP0 (major minor 00 patch 0)</tt>
1089
+ * [OpenSSL before 3] <tt>0xMNNFFPPS (major minor fix patch status)</tt>
1090
+ * [LibreSSL] <tt>0x20000000 (fixed value)</tt>
1091
+ *
1092
+ * See also the man page OPENSSL_VERSION_NUMBER(3).
1150
1093
  */
1151
1094
  rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));
1152
1095
 
1096
+ #if defined(LIBRESSL_VERSION_NUMBER)
1097
+ /*
1098
+ * Version number of LibreSSL the ruby OpenSSL extension was built with
1099
+ * (base 16). The format is <tt>0xMNNFF00f (major minor fix 00
1100
+ * status)</tt>. This constant is only defined in LibreSSL cases.
1101
+ *
1102
+ * See also the man page LIBRESSL_VERSION_NUMBER(3).
1103
+ */
1104
+ rb_define_const(mOSSL, "LIBRESSL_VERSION_NUMBER", INT2NUM(LIBRESSL_VERSION_NUMBER));
1105
+ #endif
1106
+
1153
1107
  /*
1154
1108
  * Boolean indicating whether OpenSSL is FIPS-capable or not
1155
1109
  */
1156
1110
  rb_define_const(mOSSL, "OPENSSL_FIPS",
1157
- #ifdef OPENSSL_FIPS
1111
+ /* OpenSSL 3 is FIPS-capable even when it is installed without fips option */
1112
+ #if OSSL_OPENSSL_PREREQ(3, 0, 0)
1113
+ Qtrue
1114
+ #elif defined(OPENSSL_FIPS)
1158
1115
  Qtrue
1159
1116
  #else
1160
1117
  Qfalse
@@ -1164,12 +1121,12 @@ Init_openssl(void)
1164
1121
  rb_define_module_function(mOSSL, "fips_mode", ossl_fips_mode_get, 0);
1165
1122
  rb_define_module_function(mOSSL, "fips_mode=", ossl_fips_mode_set, 1);
1166
1123
 
1124
+ rb_global_variable(&eOSSLError);
1167
1125
  /*
1168
1126
  * Generic error,
1169
1127
  * common for all classes under OpenSSL module
1170
1128
  */
1171
1129
  eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);
1172
- rb_global_variable(&eOSSLError);
1173
1130
 
1174
1131
  /*
1175
1132
  * Init debug core
@@ -1204,45 +1161,13 @@ Init_openssl(void)
1204
1161
  Init_ossl_pkey();
1205
1162
  Init_ossl_rand();
1206
1163
  Init_ossl_ssl();
1164
+ #ifndef OPENSSL_NO_TS
1165
+ Init_ossl_ts();
1166
+ #endif
1207
1167
  Init_ossl_x509();
1208
1168
  Init_ossl_ocsp();
1209
1169
  Init_ossl_engine();
1170
+ Init_ossl_provider();
1210
1171
  Init_ossl_asn1();
1211
1172
  Init_ossl_kdf();
1212
-
1213
- #if defined(OSSL_DEBUG)
1214
- /*
1215
- * For debugging Ruby/OpenSSL. Enable only when built with --enable-debug
1216
- */
1217
- #if !defined(LIBRESSL_VERSION_NUMBER) && \
1218
- (OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \
1219
- defined(CRYPTO_malloc_debug_init))
1220
- rb_define_module_function(mOSSL, "mem_check_start", mem_check_start, 0);
1221
- rb_define_module_function(mOSSL, "print_mem_leaks", print_mem_leaks, 0);
1222
-
1223
- #if defined(CRYPTO_malloc_debug_init) /* <= 1.0.2 */
1224
- CRYPTO_malloc_debug_init();
1225
- #endif
1226
-
1227
- #if defined(V_CRYPTO_MDEBUG_ALL) /* <= 1.0.2 */
1228
- CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
1229
- #endif
1230
-
1231
- #if OPENSSL_VERSION_NUMBER < 0x10100000 /* <= 1.0.2 */
1232
- {
1233
- int i;
1234
- /*
1235
- * See crypto/ex_data.c; call def_get_class() immediately to avoid
1236
- * allocations. 15 is the maximum number that is used as the class index
1237
- * in OpenSSL 1.0.2.
1238
- */
1239
- for (i = 0; i <= 15; i++) {
1240
- if (CRYPTO_get_ex_new_index(i, 0, (void *)"ossl-mdebug-dummy", 0, 0, 0) < 0)
1241
- rb_raise(rb_eRuntimeError, "CRYPTO_get_ex_new_index for "
1242
- "class index %d failed", i);
1243
- }
1244
- }
1245
- #endif
1246
- #endif
1247
- #endif
1248
1173
  }