openssl 3.0.2 → 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 (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