openssl 2.2.1 → 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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +33 -45
  3. data/History.md +248 -1
  4. data/README.md +36 -19
  5. data/ext/openssl/extconf.rb +101 -68
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +26 -45
  8. data/ext/openssl/ossl.c +128 -237
  9. data/ext/openssl/ossl.h +31 -12
  10. data/ext/openssl/ossl_asn1.c +26 -13
  11. data/ext/openssl/ossl_bn.c +213 -139
  12. data/ext/openssl/ossl_cipher.c +13 -14
  13. data/ext/openssl/ossl_config.c +412 -41
  14. data/ext/openssl/ossl_config.h +4 -7
  15. data/ext/openssl/ossl_digest.c +10 -10
  16. data/ext/openssl/ossl_engine.c +17 -16
  17. data/ext/openssl/ossl_hmac.c +57 -136
  18. data/ext/openssl/ossl_kdf.c +12 -4
  19. data/ext/openssl/ossl_ns_spki.c +1 -1
  20. data/ext/openssl/ossl_ocsp.c +11 -59
  21. data/ext/openssl/ossl_pkcs12.c +22 -4
  22. data/ext/openssl/ossl_pkcs7.c +45 -62
  23. data/ext/openssl/ossl_pkey.c +1320 -196
  24. data/ext/openssl/ossl_pkey.h +36 -73
  25. data/ext/openssl/ossl_pkey_dh.c +152 -347
  26. data/ext/openssl/ossl_pkey_dsa.c +157 -413
  27. data/ext/openssl/ossl_pkey_ec.c +227 -343
  28. data/ext/openssl/ossl_pkey_rsa.c +159 -491
  29. data/ext/openssl/ossl_provider.c +211 -0
  30. data/ext/openssl/ossl_provider.h +5 -0
  31. data/ext/openssl/ossl_ssl.c +530 -450
  32. data/ext/openssl/ossl_ssl_session.c +29 -30
  33. data/ext/openssl/ossl_ts.c +38 -23
  34. data/ext/openssl/ossl_x509.c +0 -6
  35. data/ext/openssl/ossl_x509attr.c +1 -1
  36. data/ext/openssl/ossl_x509cert.c +168 -12
  37. data/ext/openssl/ossl_x509crl.c +14 -11
  38. data/ext/openssl/ossl_x509ext.c +14 -9
  39. data/ext/openssl/ossl_x509name.c +10 -3
  40. data/ext/openssl/ossl_x509req.c +14 -11
  41. data/ext/openssl/ossl_x509revoked.c +4 -4
  42. data/ext/openssl/ossl_x509store.c +166 -75
  43. data/lib/openssl/buffering.rb +9 -3
  44. data/lib/openssl/digest.rb +1 -5
  45. data/lib/openssl/hmac.rb +65 -0
  46. data/lib/openssl/pkey.rb +429 -0
  47. data/lib/openssl/ssl.rb +22 -17
  48. data/lib/openssl/version.rb +1 -1
  49. data/lib/openssl/x509.rb +22 -0
  50. data/lib/openssl.rb +0 -1
  51. metadata +10 -79
  52. data/ext/openssl/ruby_missing.h +0 -24
  53. data/lib/openssl/config.rb +0 -501
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
 
@@ -356,22 +374,6 @@ ossl_get_errors(VALUE _)
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
@@ -405,7 +407,11 @@ 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,75 +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
- #ifndef HAVE_RB_EXT_RACTOR_SAFE
501
- // for Ruby 2.x
502
- void ossl_bn_ctx_free(void); // ossl_bn.c
503
- ossl_bn_ctx_free();
504
- #endif
505
-
506
- #if OPENSSL_VERSION_NUMBER >= 0x10100000
507
- ret = CRYPTO_mem_leaks_fp(stderr);
508
- if (ret < 0)
509
- ossl_raise(eOSSLError, "CRYPTO_mem_leaks_fp");
510
- return ret ? Qfalse : Qtrue;
511
- #else
512
- CRYPTO_mem_leaks_fp(stderr);
513
- return Qnil;
514
- #endif
515
- }
516
- #endif
517
- #endif
518
-
519
466
  #if !defined(HAVE_OPENSSL_110_THREADING_API)
520
467
  /**
521
468
  * Stores locks needed for OpenSSL thread safety
@@ -658,23 +605,21 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
658
605
  *
659
606
  * key = OpenSSL::PKey::RSA.new 2048
660
607
  *
661
- * open 'private_key.pem', 'w' do |io| io.write key.to_pem end
662
- * 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
663
610
  *
664
611
  * === Exporting a Key
665
612
  *
666
613
  * Keys saved to disk without encryption are not secure as anyone who gets
667
614
  * ahold of the key may use it unless it is encrypted. In order to securely
668
- * export a key you may export it with a pass phrase.
615
+ * export a key you may export it with a password.
669
616
  *
670
- * cipher = OpenSSL::Cipher.new 'AES-256-CBC'
671
- * pass_phrase = 'my secure pass phrase goes here'
617
+ * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
618
+ * password = 'my secure password goes here'
672
619
  *
673
- * key_secure = key.export cipher, pass_phrase
620
+ * key_secure = key.private_to_pem cipher, password
674
621
  *
675
- * open 'private.secure.pem', 'w' do |io|
676
- * io.write key_secure
677
- * end
622
+ * File.write 'private.secure.pem', key_secure
678
623
  *
679
624
  * OpenSSL::Cipher.ciphers returns a list of available ciphers.
680
625
  *
@@ -682,25 +627,25 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
682
627
  *
683
628
  * A key can also be loaded from a file.
684
629
  *
685
- * key2 = OpenSSL::PKey::RSA.new File.read 'private_key.pem'
630
+ * key2 = OpenSSL::PKey.read File.read 'private_key.pem'
686
631
  * key2.public? # => true
687
632
  * key2.private? # => true
688
633
  *
689
634
  * or
690
635
  *
691
- * key3 = OpenSSL::PKey::RSA.new File.read 'public_key.pem'
636
+ * key3 = OpenSSL::PKey.read File.read 'public_key.pem'
692
637
  * key3.public? # => true
693
638
  * key3.private? # => false
694
639
  *
695
640
  * === Loading an Encrypted Key
696
641
  *
697
- * OpenSSL will prompt you for your pass phrase when loading an encrypted key.
698
- * 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
699
644
  * loading the key:
700
645
  *
701
646
  * key4_pem = File.read 'private.secure.pem'
702
- * pass_phrase = 'my secure pass phrase goes here'
703
- * key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
647
+ * password = 'my secure password goes here'
648
+ * key4 = OpenSSL::PKey.read key4_pem, password
704
649
  *
705
650
  * == RSA Encryption
706
651
  *
@@ -775,7 +720,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
775
720
  * using PBKDF2. PKCS #5 v2.0 recommends at least 8 bytes for the salt,
776
721
  * the number of iterations largely depends on the hardware being used.
777
722
  *
778
- * cipher = OpenSSL::Cipher.new 'AES-256-CBC'
723
+ * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
779
724
  * cipher.encrypt
780
725
  * iv = cipher.random_iv
781
726
  *
@@ -798,7 +743,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
798
743
  * Use the same steps as before to derive the symmetric AES key, this time
799
744
  * setting the Cipher up for decryption.
800
745
  *
801
- * cipher = OpenSSL::Cipher.new 'AES-256-CBC'
746
+ * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
802
747
  * cipher.decrypt
803
748
  * cipher.iv = iv # the one generated with #random_iv
804
749
  *
@@ -816,45 +761,6 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
816
761
  * decrypted = cipher.update encrypted
817
762
  * decrypted << cipher.final
818
763
  *
819
- * == PKCS #5 Password-based Encryption
820
- *
821
- * PKCS #5 is a password-based encryption standard documented at
822
- * RFC2898[http://www.ietf.org/rfc/rfc2898.txt]. It allows a short password or
823
- * passphrase to be used to create a secure encryption key. If possible, PBKDF2
824
- * as described above should be used if the circumstances allow it.
825
- *
826
- * PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption
827
- * key.
828
- *
829
- * pass_phrase = 'my secure pass phrase goes here'
830
- * salt = '8 octets'
831
- *
832
- * === Encryption
833
- *
834
- * First set up the cipher for encryption
835
- *
836
- * encryptor = OpenSSL::Cipher.new 'AES-256-CBC'
837
- * encryptor.encrypt
838
- * encryptor.pkcs5_keyivgen pass_phrase, salt
839
- *
840
- * Then pass the data you want to encrypt through
841
- *
842
- * encrypted = encryptor.update 'top secret document'
843
- * encrypted << encryptor.final
844
- *
845
- * === Decryption
846
- *
847
- * Use a new Cipher instance set up for decryption
848
- *
849
- * decryptor = OpenSSL::Cipher.new 'AES-256-CBC'
850
- * decryptor.decrypt
851
- * decryptor.pkcs5_keyivgen pass_phrase, salt
852
- *
853
- * Then pass the data you want to decrypt through
854
- *
855
- * plain = decryptor.update encrypted
856
- * plain << decryptor.final
857
- *
858
764
  * == X509 Certificates
859
765
  *
860
766
  * === Creating a Certificate
@@ -932,12 +838,12 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
932
838
  * not readable by other users.
933
839
  *
934
840
  * ca_key = OpenSSL::PKey::RSA.new 2048
935
- * pass_phrase = 'my secure pass phrase goes here'
841
+ * password = 'my secure password goes here'
936
842
  *
937
- * cipher = OpenSSL::Cipher.new 'AES-256-CBC'
843
+ * cipher = 'aes-256-cbc'
938
844
  *
939
845
  * open 'ca_key.pem', 'w', 0400 do |io|
940
- * io.write ca_key.export(cipher, pass_phrase)
846
+ * io.write ca_key.private_to_pem(cipher, password)
941
847
  * end
942
848
  *
943
849
  * === CA Certificate
@@ -1072,13 +978,13 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
1072
978
  * loop do
1073
979
  * ssl_connection = ssl_server.accept
1074
980
  *
1075
- * data = connection.gets
981
+ * data = ssl_connection.gets
1076
982
  *
1077
983
  * response = "I got #{data.dump}"
1078
984
  * puts response
1079
985
  *
1080
- * connection.puts "I got #{data.dump}"
1081
- * connection.close
986
+ * ssl_connection.puts "I got #{data.dump}"
987
+ * ssl_connection.close
1082
988
  * end
1083
989
  *
1084
990
  * === SSL client
@@ -1129,7 +1035,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
1129
1035
  void
1130
1036
  Init_openssl(void)
1131
1037
  {
1132
- #if HAVE_RB_EXT_RACTOR_SAFE
1038
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
1133
1039
  rb_ext_ractor_safe(true);
1134
1040
  #endif
1135
1041
 
@@ -1157,8 +1063,8 @@ Init_openssl(void)
1157
1063
  /*
1158
1064
  * Init main module
1159
1065
  */
1160
- mOSSL = rb_define_module("OpenSSL");
1161
1066
  rb_global_variable(&mOSSL);
1067
+ mOSSL = rb_define_module("OpenSSL");
1162
1068
  rb_define_singleton_method(mOSSL, "fixed_length_secure_compare", ossl_crypto_fixed_length_secure_compare, 2);
1163
1069
 
1164
1070
  /*
@@ -1177,15 +1083,35 @@ Init_openssl(void)
1177
1083
 
1178
1084
  /*
1179
1085
  * Version number of OpenSSL the ruby OpenSSL extension was built with
1180
- * (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).
1181
1093
  */
1182
1094
  rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));
1183
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
+
1184
1107
  /*
1185
1108
  * Boolean indicating whether OpenSSL is FIPS-capable or not
1186
1109
  */
1187
1110
  rb_define_const(mOSSL, "OPENSSL_FIPS",
1188
- #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)
1189
1115
  Qtrue
1190
1116
  #else
1191
1117
  Qfalse
@@ -1195,12 +1121,12 @@ Init_openssl(void)
1195
1121
  rb_define_module_function(mOSSL, "fips_mode", ossl_fips_mode_get, 0);
1196
1122
  rb_define_module_function(mOSSL, "fips_mode=", ossl_fips_mode_set, 1);
1197
1123
 
1124
+ rb_global_variable(&eOSSLError);
1198
1125
  /*
1199
1126
  * Generic error,
1200
1127
  * common for all classes under OpenSSL module
1201
1128
  */
1202
1129
  eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);
1203
- rb_global_variable(&eOSSLError);
1204
1130
 
1205
1131
  /*
1206
1132
  * Init debug core
@@ -1241,42 +1167,7 @@ Init_openssl(void)
1241
1167
  Init_ossl_x509();
1242
1168
  Init_ossl_ocsp();
1243
1169
  Init_ossl_engine();
1170
+ Init_ossl_provider();
1244
1171
  Init_ossl_asn1();
1245
1172
  Init_ossl_kdf();
1246
-
1247
- #if defined(OSSL_DEBUG)
1248
- /*
1249
- * For debugging Ruby/OpenSSL. Enable only when built with --enable-debug
1250
- */
1251
- #if !defined(LIBRESSL_VERSION_NUMBER) && \
1252
- (OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \
1253
- defined(CRYPTO_malloc_debug_init))
1254
- rb_define_module_function(mOSSL, "mem_check_start", mem_check_start, 0);
1255
- rb_define_module_function(mOSSL, "print_mem_leaks", print_mem_leaks, 0);
1256
-
1257
- #if defined(CRYPTO_malloc_debug_init) /* <= 1.0.2 */
1258
- CRYPTO_malloc_debug_init();
1259
- #endif
1260
-
1261
- #if defined(V_CRYPTO_MDEBUG_ALL) /* <= 1.0.2 */
1262
- CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
1263
- #endif
1264
-
1265
- #if OPENSSL_VERSION_NUMBER < 0x10100000 /* <= 1.0.2 */
1266
- {
1267
- int i;
1268
- /*
1269
- * See crypto/ex_data.c; call def_get_class() immediately to avoid
1270
- * allocations. 15 is the maximum number that is used as the class index
1271
- * in OpenSSL 1.0.2.
1272
- */
1273
- for (i = 0; i <= 15; i++) {
1274
- if (CRYPTO_get_ex_new_index(i, 0, (void *)"ossl-mdebug-dummy", 0, 0, 0) < 0)
1275
- rb_raise(rb_eRuntimeError, "CRYPTO_get_ex_new_index for "
1276
- "class index %d failed", i);
1277
- }
1278
- }
1279
- #endif
1280
- #endif
1281
- #endif
1282
1173
  }
data/ext/openssl/ossl.h CHANGED
@@ -18,22 +18,19 @@
18
18
  #include <ruby/io.h>
19
19
  #include <ruby/thread.h>
20
20
  #include <openssl/opensslv.h>
21
+
21
22
  #include <openssl/err.h>
22
23
  #include <openssl/asn1.h>
23
24
  #include <openssl/x509v3.h>
24
25
  #include <openssl/ssl.h>
25
26
  #include <openssl/pkcs12.h>
26
27
  #include <openssl/pkcs7.h>
27
- #include <openssl/hmac.h>
28
28
  #include <openssl/rand.h>
29
29
  #include <openssl/conf.h>
30
30
  #ifndef OPENSSL_NO_TS
31
31
  #include <openssl/ts.h>
32
32
  #endif
33
33
  #include <openssl/crypto.h>
34
- #if !defined(OPENSSL_NO_ENGINE)
35
- # include <openssl/engine.h>
36
- #endif
37
34
  #if !defined(OPENSSL_NO_OCSP)
38
35
  # include <openssl/ocsp.h>
39
36
  #endif
@@ -43,6 +40,32 @@
43
40
  #include <openssl/evp.h>
44
41
  #include <openssl/dh.h>
45
42
 
43
+ #ifndef LIBRESSL_VERSION_NUMBER
44
+ # define OSSL_IS_LIBRESSL 0
45
+ # define OSSL_OPENSSL_PREREQ(maj, min, pat) \
46
+ (OPENSSL_VERSION_NUMBER >= ((maj << 28) | (min << 20) | (pat << 12)))
47
+ # define OSSL_LIBRESSL_PREREQ(maj, min, pat) 0
48
+ #else
49
+ # define OSSL_IS_LIBRESSL 1
50
+ # define OSSL_OPENSSL_PREREQ(maj, min, pat) 0
51
+ # define OSSL_LIBRESSL_PREREQ(maj, min, pat) \
52
+ (LIBRESSL_VERSION_NUMBER >= ((maj << 28) | (min << 20) | (pat << 12)))
53
+ #endif
54
+
55
+ #if OSSL_OPENSSL_PREREQ(3, 0, 0)
56
+ # define OSSL_3_const const
57
+ #else
58
+ # define OSSL_3_const /* const */
59
+ #endif
60
+
61
+ #if !defined(OPENSSL_NO_ENGINE) && !OSSL_OPENSSL_PREREQ(3, 0, 0)
62
+ # define OSSL_USE_ENGINE
63
+ #endif
64
+
65
+ #if OSSL_OPENSSL_PREREQ(3, 0, 0)
66
+ # define OSSL_USE_PROVIDER
67
+ #endif
68
+
46
69
  /*
47
70
  * Common Module
48
71
  */
@@ -121,7 +144,9 @@ int ossl_pem_passwd_cb(char *, int, int, void *);
121
144
  /*
122
145
  * ERRor messages
123
146
  */
124
- NORETURN(void ossl_raise(VALUE, const char *, ...));
147
+ PRINTF_ARGS(NORETURN(void ossl_raise(VALUE, const char *, ...)), 2, 3);
148
+ /* Make exception instance from str and OpenSSL error reason string. */
149
+ VALUE ossl_make_error(VALUE exc, VALUE str);
125
150
  /* Clear OpenSSL error queue. If dOSSL is set, rb_warn() them. */
126
151
  void ossl_clear_error(void);
127
152
 
@@ -136,7 +161,6 @@ VALUE ossl_to_der_if_possible(VALUE);
136
161
  */
137
162
  extern VALUE dOSSL;
138
163
 
139
- #if defined(HAVE_VA_ARGS_MACRO)
140
164
  #define OSSL_Debug(...) do { \
141
165
  if (dOSSL == Qtrue) { \
142
166
  fprintf(stderr, "OSSL_DEBUG: "); \
@@ -145,16 +169,10 @@ extern VALUE dOSSL;
145
169
  } \
146
170
  } while (0)
147
171
 
148
- #else
149
- void ossl_debug(const char *, ...);
150
- #define OSSL_Debug ossl_debug
151
- #endif
152
-
153
172
  /*
154
173
  * Include all parts
155
174
  */
156
175
  #include "openssl_missing.h"
157
- #include "ruby_missing.h"
158
176
  #include "ossl_asn1.h"
159
177
  #include "ossl_bio.h"
160
178
  #include "ossl_bn.h"
@@ -174,6 +192,7 @@ void ossl_debug(const char *, ...);
174
192
  #endif
175
193
  #include "ossl_x509.h"
176
194
  #include "ossl_engine.h"
195
+ #include "ossl_provider.h"
177
196
  #include "ossl_kdf.h"
178
197
 
179
198
  void Init_openssl(void);