openssl 2.1.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
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