openssl 3.0.2 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +1 -1
  3. data/History.md +76 -0
  4. data/README.md +36 -19
  5. data/ext/openssl/extconf.rb +89 -55
  6. data/ext/openssl/ossl.c +73 -195
  7. data/ext/openssl/ossl.h +11 -6
  8. data/ext/openssl/ossl_asn1.c +11 -10
  9. data/ext/openssl/ossl_bn.c +25 -13
  10. data/ext/openssl/ossl_cipher.c +2 -3
  11. data/ext/openssl/ossl_config.c +1 -1
  12. data/ext/openssl/ossl_digest.c +1 -1
  13. data/ext/openssl/ossl_engine.c +1 -1
  14. data/ext/openssl/ossl_hmac.c +1 -1
  15. data/ext/openssl/ossl_kdf.c +4 -4
  16. data/ext/openssl/ossl_ns_spki.c +1 -1
  17. data/ext/openssl/ossl_ocsp.c +8 -8
  18. data/ext/openssl/ossl_pkcs12.c +1 -1
  19. data/ext/openssl/ossl_pkcs7.c +3 -3
  20. data/ext/openssl/ossl_pkey.c +219 -46
  21. data/ext/openssl/ossl_pkey.h +1 -1
  22. data/ext/openssl/ossl_pkey_dh.c +28 -13
  23. data/ext/openssl/ossl_pkey_dsa.c +64 -15
  24. data/ext/openssl/ossl_pkey_ec.c +73 -17
  25. data/ext/openssl/ossl_pkey_rsa.c +74 -19
  26. data/ext/openssl/ossl_provider.c +211 -0
  27. data/ext/openssl/ossl_provider.h +5 -0
  28. data/ext/openssl/ossl_ssl.c +292 -113
  29. data/ext/openssl/ossl_ssl_session.c +5 -1
  30. data/ext/openssl/ossl_ts.c +3 -3
  31. data/ext/openssl/ossl_x509attr.c +1 -1
  32. data/ext/openssl/ossl_x509cert.c +1 -1
  33. data/ext/openssl/ossl_x509crl.c +1 -1
  34. data/ext/openssl/ossl_x509ext.c +13 -7
  35. data/ext/openssl/ossl_x509name.c +1 -1
  36. data/ext/openssl/ossl_x509req.c +1 -1
  37. data/ext/openssl/ossl_x509revoked.c +1 -1
  38. data/ext/openssl/ossl_x509store.c +12 -5
  39. data/lib/openssl/buffering.rb +2 -5
  40. data/lib/openssl/digest.rb +1 -5
  41. data/lib/openssl/pkey.rb +8 -4
  42. data/lib/openssl/ssl.rb +15 -10
  43. data/lib/openssl/version.rb +1 -1
  44. metadata +9 -6
data/ext/openssl/ossl.c CHANGED
@@ -207,7 +207,7 @@ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
207
207
 
208
208
  while (1) {
209
209
  /*
210
- * when the flag is nonzero, this passphrase
210
+ * when the flag is nonzero, this password
211
211
  * will be used to perform encryption; otherwise it will
212
212
  * be used to perform decryption.
213
213
  */
@@ -272,23 +272,28 @@ VALUE
272
272
  ossl_make_error(VALUE exc, VALUE str)
273
273
  {
274
274
  unsigned long e;
275
+ const char *data;
276
+ int flags;
275
277
 
276
- 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
277
286
  if (e) {
278
- const char *msg = ERR_reason_error_string(e);
287
+ const char *msg = ERR_reason_error_string(e);
279
288
 
280
- if (NIL_P(str)) {
281
- if (msg) str = rb_str_new_cstr(msg);
282
- }
283
- else {
284
- if (RSTRING_LEN(str)) rb_str_cat2(str, ": ");
285
- rb_str_cat2(str, msg ? msg : "(null)");
286
- }
287
- 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();
288
294
  }
289
295
 
290
- if (NIL_P(str)) str = rb_str_new(0, 0);
291
- return rb_exc_new3(exc, str);
296
+ return rb_exc_new_str(exc, str);
292
297
  }
293
298
 
294
299
  void
@@ -369,22 +374,6 @@ ossl_get_errors(VALUE _)
369
374
  */
370
375
  VALUE dOSSL;
371
376
 
372
- #if !defined(HAVE_VA_ARGS_MACRO)
373
- void
374
- ossl_debug(const char *fmt, ...)
375
- {
376
- va_list args;
377
-
378
- if (dOSSL == Qtrue) {
379
- fprintf(stderr, "OSSL_DEBUG: ");
380
- va_start(args, fmt);
381
- vfprintf(stderr, fmt, args);
382
- va_end(args);
383
- fprintf(stderr, " [CONTEXT N/A]\n");
384
- }
385
- }
386
- #endif
387
-
388
377
  /*
389
378
  * call-seq:
390
379
  * OpenSSL.debug -> true | false
@@ -418,7 +407,11 @@ static VALUE
418
407
  ossl_fips_mode_get(VALUE self)
419
408
  {
420
409
 
421
- #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)
422
415
  VALUE enabled;
423
416
  enabled = FIPS_mode() ? Qtrue : Qfalse;
424
417
  return enabled;
@@ -442,8 +435,18 @@ ossl_fips_mode_get(VALUE self)
442
435
  static VALUE
443
436
  ossl_fips_mode_set(VALUE self, VALUE enabled)
444
437
  {
445
-
446
- #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)
447
450
  if (RTEST(enabled)) {
448
451
  int mode = FIPS_mode();
449
452
  if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */
@@ -460,75 +463,6 @@ ossl_fips_mode_set(VALUE self, VALUE enabled)
460
463
  #endif
461
464
  }
462
465
 
463
- #if defined(OSSL_DEBUG)
464
- #if !defined(LIBRESSL_VERSION_NUMBER) && \
465
- (OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \
466
- defined(CRYPTO_malloc_debug_init))
467
- /*
468
- * call-seq:
469
- * OpenSSL.mem_check_start -> nil
470
- *
471
- * Calls CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON). Starts tracking memory
472
- * allocations. See also OpenSSL.print_mem_leaks.
473
- *
474
- * This is available only when built with a capable OpenSSL and --enable-debug
475
- * configure option.
476
- */
477
- static VALUE
478
- mem_check_start(VALUE self)
479
- {
480
- CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
481
- return Qnil;
482
- }
483
-
484
- /*
485
- * call-seq:
486
- * OpenSSL.print_mem_leaks -> true | false
487
- *
488
- * For debugging the Ruby/OpenSSL library. Calls CRYPTO_mem_leaks_fp(stderr).
489
- * Prints detected memory leaks to standard error. This cleans the global state
490
- * up thus you cannot use any methods of the library after calling this.
491
- *
492
- * Returns +true+ if leaks detected, +false+ otherwise.
493
- *
494
- * This is available only when built with a capable OpenSSL and --enable-debug
495
- * configure option.
496
- *
497
- * === Example
498
- * OpenSSL.mem_check_start
499
- * NOT_GCED = OpenSSL::PKey::RSA.new(256)
500
- *
501
- * END {
502
- * GC.start
503
- * OpenSSL.print_mem_leaks # will print the leakage
504
- * }
505
- */
506
- static VALUE
507
- print_mem_leaks(VALUE self)
508
- {
509
- #if OPENSSL_VERSION_NUMBER >= 0x10100000
510
- int ret;
511
- #endif
512
-
513
- #ifndef HAVE_RB_EXT_RACTOR_SAFE
514
- // for Ruby 2.x
515
- void ossl_bn_ctx_free(void); // ossl_bn.c
516
- ossl_bn_ctx_free();
517
- #endif
518
-
519
- #if OPENSSL_VERSION_NUMBER >= 0x10100000
520
- ret = CRYPTO_mem_leaks_fp(stderr);
521
- if (ret < 0)
522
- ossl_raise(eOSSLError, "CRYPTO_mem_leaks_fp");
523
- return ret ? Qfalse : Qtrue;
524
- #else
525
- CRYPTO_mem_leaks_fp(stderr);
526
- return Qnil;
527
- #endif
528
- }
529
- #endif
530
- #endif
531
-
532
466
  #if !defined(HAVE_OPENSSL_110_THREADING_API)
533
467
  /**
534
468
  * Stores locks needed for OpenSSL thread safety
@@ -671,23 +605,21 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
671
605
  *
672
606
  * key = OpenSSL::PKey::RSA.new 2048
673
607
  *
674
- * open 'private_key.pem', 'w' do |io| io.write key.to_pem end
675
- * 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
676
610
  *
677
611
  * === Exporting a Key
678
612
  *
679
613
  * Keys saved to disk without encryption are not secure as anyone who gets
680
614
  * ahold of the key may use it unless it is encrypted. In order to securely
681
- * export a key you may export it with a pass phrase.
615
+ * export a key you may export it with a password.
682
616
  *
683
617
  * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
684
- * pass_phrase = 'my secure pass phrase goes here'
618
+ * password = 'my secure password goes here'
685
619
  *
686
- * key_secure = key.export cipher, pass_phrase
620
+ * key_secure = key.private_to_pem cipher, password
687
621
  *
688
- * open 'private.secure.pem', 'w' do |io|
689
- * io.write key_secure
690
- * end
622
+ * File.write 'private.secure.pem', key_secure
691
623
  *
692
624
  * OpenSSL::Cipher.ciphers returns a list of available ciphers.
693
625
  *
@@ -707,13 +639,13 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
707
639
  *
708
640
  * === Loading an Encrypted Key
709
641
  *
710
- * OpenSSL will prompt you for your pass phrase when loading an encrypted key.
711
- * 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
712
644
  * loading the key:
713
645
  *
714
646
  * key4_pem = File.read 'private.secure.pem'
715
- * pass_phrase = 'my secure pass phrase goes here'
716
- * key4 = OpenSSL::PKey.read key4_pem, pass_phrase
647
+ * password = 'my secure password goes here'
648
+ * key4 = OpenSSL::PKey.read key4_pem, password
717
649
  *
718
650
  * == RSA Encryption
719
651
  *
@@ -829,45 +761,6 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
829
761
  * decrypted = cipher.update encrypted
830
762
  * decrypted << cipher.final
831
763
  *
832
- * == PKCS #5 Password-based Encryption
833
- *
834
- * PKCS #5 is a password-based encryption standard documented at
835
- * RFC2898[http://www.ietf.org/rfc/rfc2898.txt]. It allows a short password or
836
- * passphrase to be used to create a secure encryption key. If possible, PBKDF2
837
- * as described above should be used if the circumstances allow it.
838
- *
839
- * PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption
840
- * key.
841
- *
842
- * pass_phrase = 'my secure pass phrase goes here'
843
- * salt = '8 octets'
844
- *
845
- * === Encryption
846
- *
847
- * First set up the cipher for encryption
848
- *
849
- * encryptor = OpenSSL::Cipher.new 'aes-256-cbc'
850
- * encryptor.encrypt
851
- * encryptor.pkcs5_keyivgen pass_phrase, salt
852
- *
853
- * Then pass the data you want to encrypt through
854
- *
855
- * encrypted = encryptor.update 'top secret document'
856
- * encrypted << encryptor.final
857
- *
858
- * === Decryption
859
- *
860
- * Use a new Cipher instance set up for decryption
861
- *
862
- * decryptor = OpenSSL::Cipher.new 'aes-256-cbc'
863
- * decryptor.decrypt
864
- * decryptor.pkcs5_keyivgen pass_phrase, salt
865
- *
866
- * Then pass the data you want to decrypt through
867
- *
868
- * plain = decryptor.update encrypted
869
- * plain << decryptor.final
870
- *
871
764
  * == X509 Certificates
872
765
  *
873
766
  * === Creating a Certificate
@@ -945,12 +838,12 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
945
838
  * not readable by other users.
946
839
  *
947
840
  * ca_key = OpenSSL::PKey::RSA.new 2048
948
- * pass_phrase = 'my secure pass phrase goes here'
841
+ * password = 'my secure password goes here'
949
842
  *
950
- * cipher = OpenSSL::Cipher.new 'aes-256-cbc'
843
+ * cipher = 'aes-256-cbc'
951
844
  *
952
845
  * open 'ca_key.pem', 'w', 0400 do |io|
953
- * io.write ca_key.export(cipher, pass_phrase)
846
+ * io.write ca_key.private_to_pem(cipher, password)
954
847
  * end
955
848
  *
956
849
  * === CA Certificate
@@ -1170,8 +1063,8 @@ Init_openssl(void)
1170
1063
  /*
1171
1064
  * Init main module
1172
1065
  */
1173
- mOSSL = rb_define_module("OpenSSL");
1174
1066
  rb_global_variable(&mOSSL);
1067
+ mOSSL = rb_define_module("OpenSSL");
1175
1068
  rb_define_singleton_method(mOSSL, "fixed_length_secure_compare", ossl_crypto_fixed_length_secure_compare, 2);
1176
1069
 
1177
1070
  /*
@@ -1190,15 +1083,35 @@ Init_openssl(void)
1190
1083
 
1191
1084
  /*
1192
1085
  * Version number of OpenSSL the ruby OpenSSL extension was built with
1193
- * (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).
1194
1093
  */
1195
1094
  rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));
1196
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
+
1197
1107
  /*
1198
1108
  * Boolean indicating whether OpenSSL is FIPS-capable or not
1199
1109
  */
1200
1110
  rb_define_const(mOSSL, "OPENSSL_FIPS",
1201
- #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)
1202
1115
  Qtrue
1203
1116
  #else
1204
1117
  Qfalse
@@ -1208,12 +1121,12 @@ Init_openssl(void)
1208
1121
  rb_define_module_function(mOSSL, "fips_mode", ossl_fips_mode_get, 0);
1209
1122
  rb_define_module_function(mOSSL, "fips_mode=", ossl_fips_mode_set, 1);
1210
1123
 
1124
+ rb_global_variable(&eOSSLError);
1211
1125
  /*
1212
1126
  * Generic error,
1213
1127
  * common for all classes under OpenSSL module
1214
1128
  */
1215
1129
  eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);
1216
- rb_global_variable(&eOSSLError);
1217
1130
 
1218
1131
  /*
1219
1132
  * Init debug core
@@ -1254,42 +1167,7 @@ Init_openssl(void)
1254
1167
  Init_ossl_x509();
1255
1168
  Init_ossl_ocsp();
1256
1169
  Init_ossl_engine();
1170
+ Init_ossl_provider();
1257
1171
  Init_ossl_asn1();
1258
1172
  Init_ossl_kdf();
1259
-
1260
- #if defined(OSSL_DEBUG)
1261
- /*
1262
- * For debugging Ruby/OpenSSL. Enable only when built with --enable-debug
1263
- */
1264
- #if !defined(LIBRESSL_VERSION_NUMBER) && \
1265
- (OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \
1266
- defined(CRYPTO_malloc_debug_init))
1267
- rb_define_module_function(mOSSL, "mem_check_start", mem_check_start, 0);
1268
- rb_define_module_function(mOSSL, "print_mem_leaks", print_mem_leaks, 0);
1269
-
1270
- #if defined(CRYPTO_malloc_debug_init) /* <= 1.0.2 */
1271
- CRYPTO_malloc_debug_init();
1272
- #endif
1273
-
1274
- #if defined(V_CRYPTO_MDEBUG_ALL) /* <= 1.0.2 */
1275
- CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
1276
- #endif
1277
-
1278
- #if OPENSSL_VERSION_NUMBER < 0x10100000 /* <= 1.0.2 */
1279
- {
1280
- int i;
1281
- /*
1282
- * See crypto/ex_data.c; call def_get_class() immediately to avoid
1283
- * allocations. 15 is the maximum number that is used as the class index
1284
- * in OpenSSL 1.0.2.
1285
- */
1286
- for (i = 0; i <= 15; i++) {
1287
- if (CRYPTO_get_ex_new_index(i, 0, (void *)"ossl-mdebug-dummy", 0, 0, 0) < 0)
1288
- rb_raise(rb_eRuntimeError, "CRYPTO_get_ex_new_index for "
1289
- "class index %d failed", i);
1290
- }
1291
- }
1292
- #endif
1293
- #endif
1294
- #endif
1295
1173
  }
data/ext/openssl/ossl.h CHANGED
@@ -52,10 +52,20 @@
52
52
  (LIBRESSL_VERSION_NUMBER >= ((maj << 28) | (min << 20) | (pat << 12)))
53
53
  #endif
54
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
+
55
61
  #if !defined(OPENSSL_NO_ENGINE) && !OSSL_OPENSSL_PREREQ(3, 0, 0)
56
62
  # define OSSL_USE_ENGINE
57
63
  #endif
58
64
 
65
+ #if OSSL_OPENSSL_PREREQ(3, 0, 0)
66
+ # define OSSL_USE_PROVIDER
67
+ #endif
68
+
59
69
  /*
60
70
  * Common Module
61
71
  */
@@ -151,7 +161,6 @@ VALUE ossl_to_der_if_possible(VALUE);
151
161
  */
152
162
  extern VALUE dOSSL;
153
163
 
154
- #if defined(HAVE_VA_ARGS_MACRO)
155
164
  #define OSSL_Debug(...) do { \
156
165
  if (dOSSL == Qtrue) { \
157
166
  fprintf(stderr, "OSSL_DEBUG: "); \
@@ -160,11 +169,6 @@ extern VALUE dOSSL;
160
169
  } \
161
170
  } while (0)
162
171
 
163
- #else
164
- void ossl_debug(const char *, ...);
165
- #define OSSL_Debug ossl_debug
166
- #endif
167
-
168
172
  /*
169
173
  * Include all parts
170
174
  */
@@ -188,6 +192,7 @@ void ossl_debug(const char *, ...);
188
192
  #endif
189
193
  #include "ossl_x509.h"
190
194
  #include "ossl_engine.h"
195
+ #include "ossl_provider.h"
191
196
  #include "ossl_kdf.h"
192
197
 
193
198
  void Init_openssl(void);
@@ -509,7 +509,8 @@ ossl_asn1_get_asn1type(VALUE obj)
509
509
  ASN1_TYPE *ret;
510
510
  VALUE value, rflag;
511
511
  void *ptr;
512
- void (*free_func)();
512
+ typedef void free_func_type(void *);
513
+ free_func_type *free_func;
513
514
  int tag;
514
515
 
515
516
  tag = ossl_asn1_default_tag(obj);
@@ -522,16 +523,16 @@ ossl_asn1_get_asn1type(VALUE obj)
522
523
  case V_ASN1_INTEGER: /* FALLTHROUGH */
523
524
  case V_ASN1_ENUMERATED:
524
525
  ptr = obj_to_asn1int(value);
525
- free_func = ASN1_INTEGER_free;
526
+ free_func = (free_func_type *)ASN1_INTEGER_free;
526
527
  break;
527
528
  case V_ASN1_BIT_STRING:
528
529
  rflag = rb_attr_get(obj, sivUNUSED_BITS);
529
530
  ptr = obj_to_asn1bstr(value, NUM2INT(rflag));
530
- free_func = ASN1_BIT_STRING_free;
531
+ free_func = (free_func_type *)ASN1_BIT_STRING_free;
531
532
  break;
532
533
  case V_ASN1_NULL:
533
534
  ptr = obj_to_asn1null(value);
534
- free_func = ASN1_NULL_free;
535
+ free_func = (free_func_type *)ASN1_NULL_free;
535
536
  break;
536
537
  case V_ASN1_OCTET_STRING: /* FALLTHROUGH */
537
538
  case V_ASN1_UTF8STRING: /* FALLTHROUGH */
@@ -546,24 +547,24 @@ ossl_asn1_get_asn1type(VALUE obj)
546
547
  case V_ASN1_UNIVERSALSTRING: /* FALLTHROUGH */
547
548
  case V_ASN1_BMPSTRING:
548
549
  ptr = obj_to_asn1str(value);
549
- free_func = ASN1_STRING_free;
550
+ free_func = (free_func_type *)ASN1_STRING_free;
550
551
  break;
551
552
  case V_ASN1_OBJECT:
552
553
  ptr = obj_to_asn1obj(value);
553
- free_func = ASN1_OBJECT_free;
554
+ free_func = (free_func_type *)ASN1_OBJECT_free;
554
555
  break;
555
556
  case V_ASN1_UTCTIME:
556
557
  ptr = obj_to_asn1utime(value);
557
- free_func = ASN1_TIME_free;
558
+ free_func = (free_func_type *)ASN1_TIME_free;
558
559
  break;
559
560
  case V_ASN1_GENERALIZEDTIME:
560
561
  ptr = obj_to_asn1gtime(value);
561
- free_func = ASN1_TIME_free;
562
+ free_func = (free_func_type *)ASN1_TIME_free;
562
563
  break;
563
564
  case V_ASN1_SET: /* FALLTHROUGH */
564
565
  case V_ASN1_SEQUENCE:
565
566
  ptr = obj_to_asn1derstr(obj);
566
- free_func = ASN1_STRING_free;
567
+ free_func = (free_func_type *)ASN1_STRING_free;
567
568
  break;
568
569
  default:
569
570
  ossl_raise(eASN1Error, "unsupported ASN.1 type");
@@ -1522,7 +1523,7 @@ Init_ossl_asn1(void)
1522
1523
  *
1523
1524
  * An Array that stores the name of a given tag number. These names are
1524
1525
  * the same as the name of the tag constant that is additionally defined,
1525
- * e.g. +UNIVERSAL_TAG_NAME[2] = "INTEGER"+ and +OpenSSL::ASN1::INTEGER = 2+.
1526
+ * e.g. <tt>UNIVERSAL_TAG_NAME[2] = "INTEGER"</tt> and <tt>OpenSSL::ASN1::INTEGER = 2</tt>.
1526
1527
  *
1527
1528
  * == Example usage
1528
1529
  *
@@ -41,7 +41,7 @@ static const rb_data_type_t ossl_bn_type = {
41
41
  {
42
42
  0, ossl_bn_free,
43
43
  },
44
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
44
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
45
45
  };
46
46
 
47
47
  /*
@@ -577,22 +577,33 @@ BIGNUM_2c(gcd)
577
577
  */
578
578
  BIGNUM_2c(mod_sqr)
579
579
 
580
+ #define BIGNUM_2cr(func) \
581
+ static VALUE \
582
+ ossl_bn_##func(VALUE self, VALUE other) \
583
+ { \
584
+ BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
585
+ VALUE obj; \
586
+ GetBN(self, bn1); \
587
+ obj = NewBN(rb_obj_class(self)); \
588
+ if (!(result = BN_##func(NULL, bn1, bn2, ossl_bn_ctx))) \
589
+ ossl_raise(eBNError, NULL); \
590
+ SetBN(obj, result); \
591
+ return obj; \
592
+ }
593
+
580
594
  /*
595
+ * Document-method: OpenSSL::BN#mod_sqrt
596
+ * call-seq:
597
+ * bn.mod_sqrt(bn2) => aBN
598
+ */
599
+ BIGNUM_2cr(mod_sqrt)
600
+
601
+ /*
602
+ * Document-method: OpenSSL::BN#mod_inverse
581
603
  * call-seq:
582
604
  * bn.mod_inverse(bn2) => aBN
583
605
  */
584
- static VALUE
585
- ossl_bn_mod_inverse(VALUE self, VALUE other)
586
- {
587
- BIGNUM *bn1, *bn2 = GetBNPtr(other), *result;
588
- VALUE obj;
589
- GetBN(self, bn1);
590
- obj = NewBN(rb_obj_class(self));
591
- if (!(result = BN_mod_inverse(NULL, bn1, bn2, ossl_bn_ctx)))
592
- ossl_raise(eBNError, "BN_mod_inverse");
593
- SetBN(obj, result);
594
- return obj;
595
- }
606
+ BIGNUM_2cr(mod_inverse)
596
607
 
597
608
  /*
598
609
  * call-seq:
@@ -1234,6 +1245,7 @@ Init_ossl_bn(void)
1234
1245
  rb_define_method(cBN, "mod_sub", ossl_bn_mod_sub, 2);
1235
1246
  rb_define_method(cBN, "mod_mul", ossl_bn_mod_mul, 2);
1236
1247
  rb_define_method(cBN, "mod_sqr", ossl_bn_mod_sqr, 1);
1248
+ rb_define_method(cBN, "mod_sqrt", ossl_bn_mod_sqrt, 1);
1237
1249
  rb_define_method(cBN, "**", ossl_bn_exp, 1);
1238
1250
  rb_define_method(cBN, "mod_exp", ossl_bn_mod_exp, 2);
1239
1251
  rb_define_method(cBN, "gcd", ossl_bn_gcd, 1);
@@ -42,7 +42,7 @@ static const rb_data_type_t ossl_cipher_type = {
42
42
  {
43
43
  0, ossl_cipher_free,
44
44
  },
45
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
45
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
46
46
  };
47
47
 
48
48
  /*
@@ -384,8 +384,7 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self)
384
384
 
385
385
  StringValue(data);
386
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");
387
+ in_len = RSTRING_LEN(data);
389
388
  GetCipher(self, ctx);
390
389
  out_len = in_len+EVP_CIPHER_CTX_block_size(ctx);
391
390
  if (out_len <= 0) {
@@ -22,7 +22,7 @@ static const rb_data_type_t ossl_config_type = {
22
22
  {
23
23
  0, nconf_free,
24
24
  },
25
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
25
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
26
26
  };
27
27
 
28
28
  CONF *
@@ -35,7 +35,7 @@ static const rb_data_type_t ossl_digest_type = {
35
35
  {
36
36
  0, ossl_digest_free,
37
37
  },
38
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
38
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
39
39
  };
40
40
 
41
41
  /*
@@ -78,7 +78,7 @@ static const rb_data_type_t ossl_engine_type = {
78
78
  {
79
79
  0, ossl_engine_free,
80
80
  },
81
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
81
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
82
82
  };
83
83
 
84
84
  /*
@@ -42,7 +42,7 @@ static const rb_data_type_t ossl_hmac_type = {
42
42
  {
43
43
  0, ossl_hmac_free,
44
44
  },
45
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
45
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
46
46
  };
47
47
 
48
48
  static VALUE
@@ -3,7 +3,7 @@
3
3
  * Copyright (C) 2007, 2017 Ruby/OpenSSL Project Authors
4
4
  */
5
5
  #include "ossl.h"
6
- #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
6
+ #if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_LIBRESSL_PREREQ(3, 6, 0)
7
7
  # include <openssl/kdf.h>
8
8
  #endif
9
9
 
@@ -21,7 +21,7 @@ static VALUE mKDF, eKDF;
21
21
  * (https://tools.ietf.org/html/rfc2898#section-5.2).
22
22
  *
23
23
  * === Parameters
24
- * pass :: The passphrase.
24
+ * pass :: The password.
25
25
  * salt :: The salt. Salts prevent attacks based on dictionaries of common
26
26
  * passwords and attacks based on rainbow tables. It is a public
27
27
  * value that can be safely stored along with the password (e.g.
@@ -141,7 +141,7 @@ kdf_scrypt(int argc, VALUE *argv, VALUE self)
141
141
  }
142
142
  #endif
143
143
 
144
- #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
144
+ #if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_LIBRESSL_PREREQ(3, 6, 0)
145
145
  /*
146
146
  * call-seq:
147
147
  * KDF.hkdf(ikm, salt:, info:, length:, hash:) -> String
@@ -305,7 +305,7 @@ Init_ossl_kdf(void)
305
305
  #if defined(HAVE_EVP_PBE_SCRYPT)
306
306
  rb_define_module_function(mKDF, "scrypt", kdf_scrypt, -1);
307
307
  #endif
308
- #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
308
+ #if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_LIBRESSL_PREREQ(3, 6, 0)
309
309
  rb_define_module_function(mKDF, "hkdf", kdf_hkdf, -1);
310
310
  #endif
311
311
  }
@@ -50,7 +50,7 @@ static const rb_data_type_t ossl_netscape_spki_type = {
50
50
  {
51
51
  0, ossl_netscape_spki_free,
52
52
  },
53
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
53
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
54
54
  };
55
55
 
56
56
  static VALUE