openssl 2.2.2 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +33 -45
  3. data/History.md +232 -1
  4. data/README.md +36 -19
  5. data/ext/openssl/extconf.rb +100 -67
  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);