openssl 2.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +426 -0
  4. data/README.md +38 -21
  5. data/ext/openssl/extconf.rb +132 -72
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +62 -46
  8. data/ext/openssl/ossl.c +177 -252
  9. data/ext/openssl/ossl.h +39 -17
  10. data/ext/openssl/ossl_asn1.c +53 -14
  11. data/ext/openssl/ossl_bn.c +288 -146
  12. data/ext/openssl/ossl_bn.h +2 -1
  13. data/ext/openssl/ossl_cipher.c +42 -32
  14. data/ext/openssl/ossl_config.c +412 -41
  15. data/ext/openssl/ossl_config.h +4 -7
  16. data/ext/openssl/ossl_digest.c +32 -63
  17. data/ext/openssl/ossl_engine.c +19 -28
  18. data/ext/openssl/ossl_hmac.c +61 -146
  19. data/ext/openssl/ossl_kdf.c +15 -23
  20. data/ext/openssl/ossl_ns_spki.c +2 -2
  21. data/ext/openssl/ossl_ocsp.c +17 -70
  22. data/ext/openssl/ossl_ocsp.h +3 -3
  23. data/ext/openssl/ossl_pkcs12.c +23 -4
  24. data/ext/openssl/ossl_pkcs7.c +49 -81
  25. data/ext/openssl/ossl_pkcs7.h +16 -0
  26. data/ext/openssl/ossl_pkey.c +1508 -195
  27. data/ext/openssl/ossl_pkey.h +41 -78
  28. data/ext/openssl/ossl_pkey_dh.c +153 -348
  29. data/ext/openssl/ossl_pkey_dsa.c +157 -413
  30. data/ext/openssl/ossl_pkey_ec.c +257 -343
  31. data/ext/openssl/ossl_pkey_rsa.c +166 -490
  32. data/ext/openssl/ossl_provider.c +211 -0
  33. data/ext/openssl/ossl_provider.h +5 -0
  34. data/ext/openssl/ossl_rand.c +2 -40
  35. data/ext/openssl/ossl_ssl.c +666 -456
  36. data/ext/openssl/ossl_ssl_session.c +29 -30
  37. data/ext/openssl/ossl_ts.c +1539 -0
  38. data/ext/openssl/ossl_ts.h +16 -0
  39. data/ext/openssl/ossl_x509.c +86 -1
  40. data/ext/openssl/ossl_x509attr.c +1 -1
  41. data/ext/openssl/ossl_x509cert.c +170 -14
  42. data/ext/openssl/ossl_x509crl.c +14 -11
  43. data/ext/openssl/ossl_x509ext.c +29 -9
  44. data/ext/openssl/ossl_x509name.c +24 -12
  45. data/ext/openssl/ossl_x509req.c +14 -11
  46. data/ext/openssl/ossl_x509revoked.c +4 -4
  47. data/ext/openssl/ossl_x509store.c +205 -96
  48. data/lib/openssl/bn.rb +1 -1
  49. data/lib/openssl/buffering.rb +42 -20
  50. data/lib/openssl/cipher.rb +1 -1
  51. data/lib/openssl/digest.rb +10 -16
  52. data/lib/openssl/hmac.rb +78 -0
  53. data/lib/openssl/marshal.rb +30 -0
  54. data/lib/openssl/pkcs5.rb +1 -1
  55. data/lib/openssl/pkey.rb +447 -1
  56. data/lib/openssl/ssl.rb +68 -24
  57. data/lib/openssl/version.rb +5 -0
  58. data/lib/openssl/x509.rb +177 -1
  59. data/lib/openssl.rb +24 -9
  60. metadata +18 -71
  61. data/ext/openssl/deprecation.rb +0 -23
  62. data/ext/openssl/ossl_version.h +0 -15
  63. data/ext/openssl/ruby_missing.h +0 -24
  64. data/lib/openssl/config.rb +0 -474
@@ -10,6 +10,10 @@
10
10
  /* modified by Michal Rokos <m.rokos@sh.cvut.cz> */
11
11
  #include "ossl.h"
12
12
 
13
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
14
+ #include <ruby/ractor.h>
15
+ #endif
16
+
13
17
  #define NewBN(klass) \
14
18
  TypedData_Wrap_Struct((klass), &ossl_bn_type, 0)
15
19
  #define SetBN(obj, bn) do { \
@@ -37,7 +41,7 @@ static const rb_data_type_t ossl_bn_type = {
37
41
  {
38
42
  0, ossl_bn_free,
39
43
  },
40
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
44
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
41
45
  };
42
46
 
43
47
  /*
@@ -150,12 +154,58 @@ ossl_bn_value_ptr(volatile VALUE *ptr)
150
154
  /*
151
155
  * Private
152
156
  */
153
- /*
154
- * BN_CTX - is used in more difficult math. ops
155
- * (Why just 1? Because Ruby itself isn't thread safe,
156
- * we don't need to care about threads)
157
- */
158
- BN_CTX *ossl_bn_ctx;
157
+
158
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
159
+ void
160
+ ossl_bn_ctx_free(void *ptr)
161
+ {
162
+ BN_CTX *ctx = (BN_CTX *)ptr;
163
+ BN_CTX_free(ctx);
164
+ }
165
+
166
+ struct rb_ractor_local_storage_type ossl_bn_ctx_key_type = {
167
+ NULL, // mark
168
+ ossl_bn_ctx_free,
169
+ };
170
+
171
+ rb_ractor_local_key_t ossl_bn_ctx_key;
172
+
173
+ BN_CTX *
174
+ ossl_bn_ctx_get(void)
175
+ {
176
+ // stored in ractor local storage
177
+
178
+ BN_CTX *ctx = rb_ractor_local_storage_ptr(ossl_bn_ctx_key);
179
+ if (!ctx) {
180
+ if (!(ctx = BN_CTX_new())) {
181
+ ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
182
+ }
183
+ rb_ractor_local_storage_ptr_set(ossl_bn_ctx_key, ctx);
184
+ }
185
+ return ctx;
186
+ }
187
+ #else
188
+ // for ruby 2.x
189
+ static BN_CTX *gv_ossl_bn_ctx;
190
+
191
+ BN_CTX *
192
+ ossl_bn_ctx_get(void)
193
+ {
194
+ if (gv_ossl_bn_ctx == NULL) {
195
+ if (!(gv_ossl_bn_ctx = BN_CTX_new())) {
196
+ ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
197
+ }
198
+ }
199
+ return gv_ossl_bn_ctx;
200
+ }
201
+
202
+ void
203
+ ossl_bn_ctx_free(void)
204
+ {
205
+ BN_CTX_free(gv_ossl_bn_ctx);
206
+ gv_ossl_bn_ctx = NULL;
207
+ }
208
+ #endif
159
209
 
160
210
  static VALUE
161
211
  ossl_bn_alloc(VALUE klass)
@@ -173,13 +223,29 @@ ossl_bn_alloc(VALUE klass)
173
223
 
174
224
  /*
175
225
  * call-seq:
176
- * OpenSSL::BN.new => aBN
177
- * OpenSSL::BN.new(bn) => aBN
178
- * OpenSSL::BN.new(integer) => aBN
179
- * OpenSSL::BN.new(string) => aBN
180
- * OpenSSL::BN.new(string, 0 | 2 | 10 | 16) => aBN
226
+ * OpenSSL::BN.new(bn) -> aBN
227
+ * OpenSSL::BN.new(integer) -> aBN
228
+ * OpenSSL::BN.new(string, base = 10) -> aBN
229
+ *
230
+ * Construct a new \OpenSSL BIGNUM object.
181
231
  *
182
- * Construct a new OpenSSL BIGNUM object.
232
+ * If +bn+ is an Integer or OpenSSL::BN, a new instance of OpenSSL::BN
233
+ * representing the same value is returned. See also Integer#to_bn for the
234
+ * short-hand.
235
+ *
236
+ * If a String is given, the content will be parsed according to +base+.
237
+ *
238
+ * +string+::
239
+ * The string to be parsed.
240
+ * +base+::
241
+ * The format. Must be one of the following:
242
+ * - +0+ - MPI format. See the man page BN_mpi2bn(3) for details.
243
+ * - +2+ - Variable-length and big-endian binary encoding of a positive
244
+ * number.
245
+ * - +10+ - Decimal number representation, with a leading '-' for a negative
246
+ * number.
247
+ * - +16+ - Hexadeciaml number representation, with a leading '-' for a
248
+ * negative number.
183
249
  */
184
250
  static VALUE
185
251
  ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
@@ -187,11 +253,16 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
187
253
  BIGNUM *bn;
188
254
  VALUE str, bs;
189
255
  int base = 10;
256
+ char *ptr;
190
257
 
191
258
  if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) {
192
259
  base = NUM2INT(bs);
193
260
  }
194
261
 
262
+ if (NIL_P(str)) {
263
+ ossl_raise(rb_eArgError, "invalid argument");
264
+ }
265
+
195
266
  if (RB_INTEGER_TYPE_P(str)) {
196
267
  GetBN(self, bn);
197
268
  integer_to_bnptr(str, bn);
@@ -213,12 +284,14 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
213
284
  GetBN(self, bn);
214
285
  switch (base) {
215
286
  case 0:
216
- if (!BN_mpi2bn((unsigned char *)StringValuePtr(str), RSTRING_LENINT(str), bn)) {
287
+ ptr = StringValuePtr(str);
288
+ if (!BN_mpi2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
217
289
  ossl_raise(eBNError, NULL);
218
290
  }
219
291
  break;
220
292
  case 2:
221
- if (!BN_bin2bn((unsigned char *)StringValuePtr(str), RSTRING_LENINT(str), bn)) {
293
+ ptr = StringValuePtr(str);
294
+ if (!BN_bin2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
222
295
  ossl_raise(eBNError, NULL);
223
296
  }
224
297
  break;
@@ -240,16 +313,21 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
240
313
 
241
314
  /*
242
315
  * call-seq:
243
- * bn.to_s => string
244
- * bn.to_s(base) => string
316
+ * bn.to_s(base = 10) -> string
245
317
  *
246
- * === Parameters
247
- * * _base_ - Integer
248
- * Valid values:
249
- * * 0 - MPI
250
- * * 2 - binary
251
- * * 10 - the default
252
- * * 16 - hex
318
+ * Returns the string representation of the bignum.
319
+ *
320
+ * BN.new can parse the encoded string to convert back into an OpenSSL::BN.
321
+ *
322
+ * +base+::
323
+ * The format. Must be one of the following:
324
+ * - +0+ - MPI format. See the man page BN_bn2mpi(3) for details.
325
+ * - +2+ - Variable-length and big-endian binary encoding. The sign of
326
+ * the bignum is ignored.
327
+ * - +10+ - Decimal number representation, with a leading '-' for a negative
328
+ * bignum.
329
+ * - +16+ - Hexadeciaml number representation, with a leading '-' for a
330
+ * negative bignum.
253
331
  */
254
332
  static VALUE
255
333
  ossl_bn_to_s(int argc, VALUE *argv, VALUE self)
@@ -397,7 +475,7 @@ ossl_bn_is_negative(VALUE self)
397
475
  if (!(result = BN_new())) { \
398
476
  ossl_raise(eBNError, NULL); \
399
477
  } \
400
- if (!BN_##func(result, bn, ossl_bn_ctx)) { \
478
+ if (BN_##func(result, bn, ossl_bn_ctx) <= 0) { \
401
479
  BN_free(result); \
402
480
  ossl_raise(eBNError, NULL); \
403
481
  } \
@@ -423,7 +501,7 @@ BIGNUM_1c(sqr)
423
501
  if (!(result = BN_new())) { \
424
502
  ossl_raise(eBNError, NULL); \
425
503
  } \
426
- if (!BN_##func(result, bn1, bn2)) { \
504
+ if (BN_##func(result, bn1, bn2) <= 0) { \
427
505
  BN_free(result); \
428
506
  ossl_raise(eBNError, NULL); \
429
507
  } \
@@ -456,7 +534,7 @@ BIGNUM_2(sub)
456
534
  if (!(result = BN_new())) { \
457
535
  ossl_raise(eBNError, NULL); \
458
536
  } \
459
- if (!BN_##func(result, bn1, bn2, ossl_bn_ctx)) { \
537
+ if (BN_##func(result, bn1, bn2, ossl_bn_ctx) <= 0) { \
460
538
  BN_free(result); \
461
539
  ossl_raise(eBNError, NULL); \
462
540
  } \
@@ -499,12 +577,33 @@ BIGNUM_2c(gcd)
499
577
  */
500
578
  BIGNUM_2c(mod_sqr)
501
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
+
594
+ /*
595
+ * Document-method: OpenSSL::BN#mod_sqrt
596
+ * call-seq:
597
+ * bn.mod_sqrt(bn2) => aBN
598
+ */
599
+ BIGNUM_2cr(mod_sqrt)
600
+
502
601
  /*
503
602
  * Document-method: OpenSSL::BN#mod_inverse
504
603
  * call-seq:
505
- * bn.mod_inverse(bn2) => aBN
604
+ * bn.mod_inverse(bn2) => aBN
506
605
  */
507
- BIGNUM_2c(mod_inverse)
606
+ BIGNUM_2cr(mod_inverse)
508
607
 
509
608
  /*
510
609
  * call-seq:
@@ -553,7 +652,7 @@ ossl_bn_div(VALUE self, VALUE other)
553
652
  if (!(result = BN_new())) { \
554
653
  ossl_raise(eBNError, NULL); \
555
654
  } \
556
- if (!BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx)) { \
655
+ if (BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx) <= 0) { \
557
656
  BN_free(result); \
558
657
  ossl_raise(eBNError, NULL); \
559
658
  } \
@@ -595,7 +694,7 @@ BIGNUM_3c(mod_exp)
595
694
  { \
596
695
  BIGNUM *bn; \
597
696
  GetBN(self, bn); \
598
- if (!BN_##func(bn, NUM2INT(bit))) { \
697
+ if (BN_##func(bn, NUM2INT(bit)) <= 0) { \
599
698
  ossl_raise(eBNError, NULL); \
600
699
  } \
601
700
  return self; \
@@ -655,7 +754,7 @@ ossl_bn_is_bit_set(VALUE self, VALUE bit)
655
754
  if (!(result = BN_new())) { \
656
755
  ossl_raise(eBNError, NULL); \
657
756
  } \
658
- if (!BN_##func(result, bn, b)) { \
757
+ if (BN_##func(result, bn, b) <= 0) { \
659
758
  BN_free(result); \
660
759
  ossl_raise(eBNError, NULL); \
661
760
  } \
@@ -685,7 +784,7 @@ BIGNUM_SHIFT(rshift)
685
784
  int b; \
686
785
  b = NUM2INT(bits); \
687
786
  GetBN(self, bn); \
688
- if (!BN_##func(bn, bn, b)) \
787
+ if (BN_##func(bn, bn, b) <= 0) \
689
788
  ossl_raise(eBNError, NULL); \
690
789
  return self; \
691
790
  }
@@ -704,78 +803,64 @@ BIGNUM_SELF_SHIFT(lshift)
704
803
  */
705
804
  BIGNUM_SELF_SHIFT(rshift)
706
805
 
707
- #define BIGNUM_RAND(func) \
708
- static VALUE \
709
- ossl_bn_s_##func(int argc, VALUE *argv, VALUE klass) \
710
- { \
711
- BIGNUM *result; \
712
- int bottom = 0, top = 0, b; \
713
- VALUE bits, fill, odd, obj; \
714
- \
715
- switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) { \
716
- case 3: \
717
- bottom = (odd == Qtrue) ? 1 : 0; \
718
- /* FALLTHROUGH */ \
719
- case 2: \
720
- top = NUM2INT(fill); \
721
- } \
722
- b = NUM2INT(bits); \
723
- obj = NewBN(klass); \
724
- if (!(result = BN_new())) { \
725
- ossl_raise(eBNError, NULL); \
726
- } \
727
- if (!BN_##func(result, b, top, bottom)) { \
728
- BN_free(result); \
729
- ossl_raise(eBNError, NULL); \
730
- } \
731
- SetBN(obj, result); \
732
- return obj; \
733
- }
734
-
735
- /*
736
- * Document-method: OpenSSL::BN.rand
737
- * BN.rand(bits [, fill [, odd]]) -> aBN
738
- */
739
- BIGNUM_RAND(rand)
740
-
741
806
  /*
742
- * Document-method: OpenSSL::BN.pseudo_rand
743
- * BN.pseudo_rand(bits [, fill [, odd]]) -> aBN
744
- */
745
- BIGNUM_RAND(pseudo_rand)
746
-
747
- #define BIGNUM_RAND_RANGE(func) \
748
- static VALUE \
749
- ossl_bn_s_##func##_range(VALUE klass, VALUE range) \
750
- { \
751
- BIGNUM *bn = GetBNPtr(range), *result; \
752
- VALUE obj = NewBN(klass); \
753
- if (!(result = BN_new())) { \
754
- ossl_raise(eBNError, NULL); \
755
- } \
756
- if (!BN_##func##_range(result, bn)) { \
757
- BN_free(result); \
758
- ossl_raise(eBNError, NULL); \
759
- } \
760
- SetBN(obj, result); \
761
- return obj; \
762
- }
763
-
764
- /*
765
- * Document-method: OpenSSL::BN.rand_range
766
807
  * call-seq:
767
- * BN.rand_range(range) -> aBN
808
+ * BN.rand(bits [, fill [, odd]]) -> aBN
809
+ *
810
+ * Generates a cryptographically strong pseudo-random number of +bits+.
768
811
  *
812
+ * See also the man page BN_rand(3).
769
813
  */
770
- BIGNUM_RAND_RANGE(rand)
814
+ static VALUE
815
+ ossl_bn_s_rand(int argc, VALUE *argv, VALUE klass)
816
+ {
817
+ BIGNUM *result;
818
+ int bottom = 0, top = 0, b;
819
+ VALUE bits, fill, odd, obj;
820
+
821
+ switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) {
822
+ case 3:
823
+ bottom = (odd == Qtrue) ? 1 : 0;
824
+ /* FALLTHROUGH */
825
+ case 2:
826
+ top = NUM2INT(fill);
827
+ }
828
+ b = NUM2INT(bits);
829
+ obj = NewBN(klass);
830
+ if (!(result = BN_new())) {
831
+ ossl_raise(eBNError, "BN_new");
832
+ }
833
+ if (BN_rand(result, b, top, bottom) <= 0) {
834
+ BN_free(result);
835
+ ossl_raise(eBNError, "BN_rand");
836
+ }
837
+ SetBN(obj, result);
838
+ return obj;
839
+ }
771
840
 
772
841
  /*
773
- * Document-method: OpenSSL::BN.pseudo_rand_range
774
842
  * call-seq:
775
- * BN.pseudo_rand_range(range) -> aBN
843
+ * BN.rand_range(range) -> aBN
844
+ *
845
+ * Generates a cryptographically strong pseudo-random number in the range
846
+ * 0...+range+.
776
847
  *
848
+ * See also the man page BN_rand_range(3).
777
849
  */
778
- BIGNUM_RAND_RANGE(pseudo_rand)
850
+ static VALUE
851
+ ossl_bn_s_rand_range(VALUE klass, VALUE range)
852
+ {
853
+ BIGNUM *bn = GetBNPtr(range), *result;
854
+ VALUE obj = NewBN(klass);
855
+ if (!(result = BN_new()))
856
+ ossl_raise(eBNError, "BN_new");
857
+ if (BN_rand_range(result, bn) <= 0) {
858
+ BN_free(result);
859
+ ossl_raise(eBNError, "BN_rand_range");
860
+ }
861
+ SetBN(obj, result);
862
+ return obj;
863
+ }
779
864
 
780
865
  /*
781
866
  * call-seq:
@@ -870,7 +955,17 @@ ossl_bn_copy(VALUE self, VALUE other)
870
955
  static VALUE
871
956
  ossl_bn_uplus(VALUE self)
872
957
  {
873
- return self;
958
+ VALUE obj;
959
+ BIGNUM *bn1, *bn2;
960
+
961
+ GetBN(self, bn1);
962
+ obj = NewBN(cBN);
963
+ bn2 = BN_dup(bn1);
964
+ if (!bn2)
965
+ ossl_raise(eBNError, "BN_dup");
966
+ SetBN(obj, bn2);
967
+
968
+ return obj;
874
969
  }
875
970
 
876
971
  /*
@@ -894,6 +989,24 @@ ossl_bn_uminus(VALUE self)
894
989
  return obj;
895
990
  }
896
991
 
992
+ /*
993
+ * call-seq:
994
+ * bn.abs -> aBN
995
+ */
996
+ static VALUE
997
+ ossl_bn_abs(VALUE self)
998
+ {
999
+ BIGNUM *bn1;
1000
+
1001
+ GetBN(self, bn1);
1002
+ if (BN_is_negative(bn1)) {
1003
+ return ossl_bn_uminus(self);
1004
+ }
1005
+ else {
1006
+ return ossl_bn_uplus(self);
1007
+ }
1008
+ }
1009
+
897
1010
  #define BIGNUM_CMP(func) \
898
1011
  static VALUE \
899
1012
  ossl_bn_##func(VALUE self, VALUE other) \
@@ -1002,34 +1115,29 @@ ossl_bn_hash(VALUE self)
1002
1115
  * bn.prime? => true | false
1003
1116
  * bn.prime?(checks) => true | false
1004
1117
  *
1005
- * Performs a Miller-Rabin probabilistic primality test with _checks_
1006
- * iterations. If _checks_ is not specified, a number of iterations is used
1007
- * that yields a false positive rate of at most 2^-80 for random input.
1118
+ * Performs a Miller-Rabin probabilistic primality test for +bn+.
1008
1119
  *
1009
- * === Parameters
1010
- * * _checks_ - integer
1120
+ * <b>+checks+ parameter is deprecated in version 3.0.</b> It has no effect.
1011
1121
  */
1012
1122
  static VALUE
1013
1123
  ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
1014
1124
  {
1015
1125
  BIGNUM *bn;
1016
- VALUE vchecks;
1017
- int checks = BN_prime_checks;
1126
+ int ret;
1018
1127
 
1019
- if (rb_scan_args(argc, argv, "01", &vchecks) == 1) {
1020
- checks = NUM2INT(vchecks);
1021
- }
1128
+ rb_check_arity(argc, 0, 1);
1022
1129
  GetBN(self, bn);
1023
- switch (BN_is_prime_ex(bn, checks, ossl_bn_ctx, NULL)) {
1024
- case 1:
1025
- return Qtrue;
1026
- case 0:
1027
- return Qfalse;
1028
- default:
1029
- ossl_raise(eBNError, NULL);
1030
- }
1031
- /* not reachable */
1032
- return Qnil;
1130
+
1131
+ #ifdef HAVE_BN_CHECK_PRIME
1132
+ ret = BN_check_prime(bn, ossl_bn_ctx, NULL);
1133
+ if (ret < 0)
1134
+ ossl_raise(eBNError, "BN_check_prime");
1135
+ #else
1136
+ ret = BN_is_prime_fasttest_ex(bn, BN_prime_checks, ossl_bn_ctx, 1, NULL);
1137
+ if (ret < 0)
1138
+ ossl_raise(eBNError, "BN_is_prime_fasttest_ex");
1139
+ #endif
1140
+ return ret ? Qtrue : Qfalse;
1033
1141
  }
1034
1142
 
1035
1143
  /*
@@ -1038,39 +1146,52 @@ ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
1038
1146
  * bn.prime_fasttest?(checks) => true | false
1039
1147
  * bn.prime_fasttest?(checks, trial_div) => true | false
1040
1148
  *
1041
- * Performs a Miller-Rabin primality test. This is same as #prime? except this
1042
- * first attempts trial divisions with some small primes.
1149
+ * Performs a Miller-Rabin probabilistic primality test for +bn+.
1043
1150
  *
1044
- * === Parameters
1045
- * * _checks_ - integer
1046
- * * _trial_div_ - boolean
1151
+ * <b>Deprecated in version 3.0.</b> Use #prime? instead.
1152
+ *
1153
+ * +checks+ and +trial_div+ parameters no longer have any effect.
1047
1154
  */
1048
1155
  static VALUE
1049
1156
  ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
1157
+ {
1158
+ rb_check_arity(argc, 0, 2);
1159
+ return ossl_bn_is_prime(0, argv, self);
1160
+ }
1161
+
1162
+ /*
1163
+ * call-seq:
1164
+ * bn.get_flags(flags) => flags
1165
+ *
1166
+ * Returns the flags on the BN object.
1167
+ * The argument is used as a bit mask.
1168
+ *
1169
+ * === Parameters
1170
+ * * _flags_ - integer
1171
+ */
1172
+ static VALUE
1173
+ ossl_bn_get_flags(VALUE self, VALUE arg)
1050
1174
  {
1051
1175
  BIGNUM *bn;
1052
- VALUE vchecks, vtrivdiv;
1053
- int checks = BN_prime_checks, do_trial_division = 1;
1176
+ GetBN(self, bn);
1054
1177
 
1055
- rb_scan_args(argc, argv, "02", &vchecks, &vtrivdiv);
1178
+ return INT2NUM(BN_get_flags(bn, NUM2INT(arg)));
1179
+ }
1056
1180
 
1057
- if (!NIL_P(vchecks)) {
1058
- checks = NUM2INT(vchecks);
1059
- }
1181
+ /*
1182
+ * call-seq:
1183
+ * bn.set_flags(flags) => nil
1184
+ *
1185
+ * Enables the flags on the BN object.
1186
+ * Currently, the flags argument can contain zero of OpenSSL::BN::CONSTTIME.
1187
+ */
1188
+ static VALUE
1189
+ ossl_bn_set_flags(VALUE self, VALUE arg)
1190
+ {
1191
+ BIGNUM *bn;
1060
1192
  GetBN(self, bn);
1061
- /* handle true/false */
1062
- if (vtrivdiv == Qfalse) {
1063
- do_trial_division = 0;
1064
- }
1065
- switch (BN_is_prime_fasttest_ex(bn, checks, ossl_bn_ctx, do_trial_division, NULL)) {
1066
- case 1:
1067
- return Qtrue;
1068
- case 0:
1069
- return Qfalse;
1070
- default:
1071
- ossl_raise(eBNError, NULL);
1072
- }
1073
- /* not reachable */
1193
+
1194
+ BN_set_flags(bn, NUM2INT(arg));
1074
1195
  return Qnil;
1075
1196
  }
1076
1197
 
@@ -1086,9 +1207,11 @@ Init_ossl_bn(void)
1086
1207
  eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
1087
1208
  #endif
1088
1209
 
1089
- if (!(ossl_bn_ctx = BN_CTX_new())) {
1090
- ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
1091
- }
1210
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
1211
+ ossl_bn_ctx_key = rb_ractor_local_storage_ptr_newkey(&ossl_bn_ctx_key_type);
1212
+ #else
1213
+ ossl_bn_ctx_get();
1214
+ #endif
1092
1215
 
1093
1216
  eBNError = rb_define_class_under(mOSSL, "BNError", eOSSLError);
1094
1217
 
@@ -1108,6 +1231,7 @@ Init_ossl_bn(void)
1108
1231
 
1109
1232
  rb_define_method(cBN, "+@", ossl_bn_uplus, 0);
1110
1233
  rb_define_method(cBN, "-@", ossl_bn_uminus, 0);
1234
+ rb_define_method(cBN, "abs", ossl_bn_abs, 0);
1111
1235
 
1112
1236
  rb_define_method(cBN, "+", ossl_bn_add, 1);
1113
1237
  rb_define_method(cBN, "-", ossl_bn_sub, 1);
@@ -1121,6 +1245,7 @@ Init_ossl_bn(void)
1121
1245
  rb_define_method(cBN, "mod_sub", ossl_bn_mod_sub, 2);
1122
1246
  rb_define_method(cBN, "mod_mul", ossl_bn_mod_mul, 2);
1123
1247
  rb_define_method(cBN, "mod_sqr", ossl_bn_mod_sqr, 1);
1248
+ rb_define_method(cBN, "mod_sqrt", ossl_bn_mod_sqrt, 1);
1124
1249
  rb_define_method(cBN, "**", ossl_bn_exp, 1);
1125
1250
  rb_define_method(cBN, "mod_exp", ossl_bn_mod_exp, 2);
1126
1251
  rb_define_method(cBN, "gcd", ossl_bn_gcd, 1);
@@ -1151,9 +1276,9 @@ Init_ossl_bn(void)
1151
1276
  * get_word */
1152
1277
 
1153
1278
  rb_define_singleton_method(cBN, "rand", ossl_bn_s_rand, -1);
1154
- rb_define_singleton_method(cBN, "pseudo_rand", ossl_bn_s_pseudo_rand, -1);
1155
1279
  rb_define_singleton_method(cBN, "rand_range", ossl_bn_s_rand_range, 1);
1156
- rb_define_singleton_method(cBN, "pseudo_rand_range", ossl_bn_s_pseudo_rand_range, 1);
1280
+ rb_define_alias(rb_singleton_class(cBN), "pseudo_rand", "rand");
1281
+ rb_define_alias(rb_singleton_class(cBN), "pseudo_rand_range", "rand_range");
1157
1282
 
1158
1283
  rb_define_singleton_method(cBN, "generate_prime", ossl_bn_s_generate_prime, -1);
1159
1284
  rb_define_method(cBN, "prime?", ossl_bn_is_prime, -1);
@@ -1170,6 +1295,23 @@ Init_ossl_bn(void)
1170
1295
  /* lshift1 - DON'T IMPL. */
1171
1296
  /* rshift1 - DON'T IMPL. */
1172
1297
 
1298
+ rb_define_method(cBN, "get_flags", ossl_bn_get_flags, 1);
1299
+ rb_define_method(cBN, "set_flags", ossl_bn_set_flags, 1);
1300
+
1301
+ #ifdef BN_FLG_CONSTTIME
1302
+ rb_define_const(cBN, "CONSTTIME", INT2NUM(BN_FLG_CONSTTIME));
1303
+ #endif
1304
+ /* BN_FLG_MALLOCED and BN_FLG_STATIC_DATA seems for C programming.
1305
+ * Allowing them leads to memory leak.
1306
+ * So, for now, they are not exported
1307
+ #ifdef BN_FLG_MALLOCED
1308
+ rb_define_const(cBN, "MALLOCED", INT2NUM(BN_FLG_MALLOCED));
1309
+ #endif
1310
+ #ifdef BN_FLG_STATIC_DATA
1311
+ rb_define_const(cBN, "STATIC_DATA", INT2NUM(BN_FLG_STATIC_DATA));
1312
+ #endif
1313
+ */
1314
+
1173
1315
  /*
1174
1316
  * bn2bin
1175
1317
  * bin2bn
@@ -13,7 +13,8 @@
13
13
  extern VALUE cBN;
14
14
  extern VALUE eBNError;
15
15
 
16
- extern BN_CTX *ossl_bn_ctx;
16
+ BN_CTX *ossl_bn_ctx_get(void);
17
+ #define ossl_bn_ctx ossl_bn_ctx_get()
17
18
 
18
19
  #define GetBNPtr(obj) ossl_bn_value_ptr(&(obj))
19
20