openssl 2.1.2 → 3.0.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +232 -0
  4. data/README.md +2 -2
  5. data/ext/openssl/extconf.rb +61 -46
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +60 -44
  8. data/ext/openssl/ossl.c +112 -66
  9. data/ext/openssl/ossl.h +28 -11
  10. data/ext/openssl/ossl_asn1.c +42 -5
  11. data/ext/openssl/ossl_bn.c +276 -146
  12. data/ext/openssl/ossl_bn.h +2 -1
  13. data/ext/openssl/ossl_cipher.c +38 -29
  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 +31 -62
  17. data/ext/openssl/ossl_engine.c +18 -27
  18. data/ext/openssl/ossl_hmac.c +52 -145
  19. data/ext/openssl/ossl_kdf.c +11 -19
  20. data/ext/openssl/ossl_ns_spki.c +1 -1
  21. data/ext/openssl/ossl_ocsp.c +9 -62
  22. data/ext/openssl/ossl_ocsp.h +3 -3
  23. data/ext/openssl/ossl_pkcs12.c +21 -3
  24. data/ext/openssl/ossl_pkcs7.c +45 -78
  25. data/ext/openssl/ossl_pkcs7.h +16 -0
  26. data/ext/openssl/ossl_pkey.c +1255 -178
  27. data/ext/openssl/ossl_pkey.h +40 -77
  28. data/ext/openssl/ossl_pkey_dh.c +125 -335
  29. data/ext/openssl/ossl_pkey_dsa.c +93 -398
  30. data/ext/openssl/ossl_pkey_ec.c +155 -318
  31. data/ext/openssl/ossl_pkey_rsa.c +105 -484
  32. data/ext/openssl/ossl_rand.c +2 -40
  33. data/ext/openssl/ossl_ssl.c +395 -364
  34. data/ext/openssl/ossl_ssl_session.c +24 -29
  35. data/ext/openssl/ossl_ts.c +1539 -0
  36. data/ext/openssl/ossl_ts.h +16 -0
  37. data/ext/openssl/ossl_x509.c +86 -1
  38. data/ext/openssl/ossl_x509cert.c +166 -10
  39. data/ext/openssl/ossl_x509crl.c +10 -7
  40. data/ext/openssl/ossl_x509ext.c +15 -2
  41. data/ext/openssl/ossl_x509name.c +16 -5
  42. data/ext/openssl/ossl_x509req.c +10 -7
  43. data/ext/openssl/ossl_x509store.c +193 -92
  44. data/lib/openssl/bn.rb +1 -1
  45. data/lib/openssl/buffering.rb +42 -17
  46. data/lib/openssl/cipher.rb +1 -1
  47. data/lib/openssl/digest.rb +10 -12
  48. data/lib/openssl/hmac.rb +78 -0
  49. data/lib/openssl/marshal.rb +30 -0
  50. data/lib/openssl/pkcs5.rb +1 -1
  51. data/lib/openssl/pkey.rb +435 -1
  52. data/lib/openssl/ssl.rb +53 -14
  53. data/lib/openssl/version.rb +5 -0
  54. data/lib/openssl/x509.rb +177 -1
  55. data/lib/openssl.rb +24 -9
  56. metadata +13 -69
  57. data/ext/openssl/deprecation.rb +0 -23
  58. data/ext/openssl/ossl_version.h +0 -15
  59. data/ext/openssl/ruby_missing.h +0 -24
  60. 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 { \
@@ -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
  } \
@@ -500,11 +578,21 @@ BIGNUM_2c(gcd)
500
578
  BIGNUM_2c(mod_sqr)
501
579
 
502
580
  /*
503
- * Document-method: OpenSSL::BN#mod_inverse
504
581
  * call-seq:
505
- * bn.mod_inverse(bn2) => aBN
582
+ * bn.mod_inverse(bn2) => aBN
506
583
  */
507
- BIGNUM_2c(mod_inverse)
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
+ }
508
596
 
509
597
  /*
510
598
  * call-seq:
@@ -553,7 +641,7 @@ ossl_bn_div(VALUE self, VALUE other)
553
641
  if (!(result = BN_new())) { \
554
642
  ossl_raise(eBNError, NULL); \
555
643
  } \
556
- if (!BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx)) { \
644
+ if (BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx) <= 0) { \
557
645
  BN_free(result); \
558
646
  ossl_raise(eBNError, NULL); \
559
647
  } \
@@ -595,7 +683,7 @@ BIGNUM_3c(mod_exp)
595
683
  { \
596
684
  BIGNUM *bn; \
597
685
  GetBN(self, bn); \
598
- if (!BN_##func(bn, NUM2INT(bit))) { \
686
+ if (BN_##func(bn, NUM2INT(bit)) <= 0) { \
599
687
  ossl_raise(eBNError, NULL); \
600
688
  } \
601
689
  return self; \
@@ -655,7 +743,7 @@ ossl_bn_is_bit_set(VALUE self, VALUE bit)
655
743
  if (!(result = BN_new())) { \
656
744
  ossl_raise(eBNError, NULL); \
657
745
  } \
658
- if (!BN_##func(result, bn, b)) { \
746
+ if (BN_##func(result, bn, b) <= 0) { \
659
747
  BN_free(result); \
660
748
  ossl_raise(eBNError, NULL); \
661
749
  } \
@@ -685,7 +773,7 @@ BIGNUM_SHIFT(rshift)
685
773
  int b; \
686
774
  b = NUM2INT(bits); \
687
775
  GetBN(self, bn); \
688
- if (!BN_##func(bn, bn, b)) \
776
+ if (BN_##func(bn, bn, b) <= 0) \
689
777
  ossl_raise(eBNError, NULL); \
690
778
  return self; \
691
779
  }
@@ -704,78 +792,64 @@ BIGNUM_SELF_SHIFT(lshift)
704
792
  */
705
793
  BIGNUM_SELF_SHIFT(rshift)
706
794
 
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
- /*
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
795
  /*
765
- * Document-method: OpenSSL::BN.rand_range
766
796
  * call-seq:
767
- * BN.rand_range(range) -> aBN
797
+ * BN.rand(bits [, fill [, odd]]) -> aBN
768
798
  *
799
+ * Generates a cryptographically strong pseudo-random number of +bits+.
800
+ *
801
+ * See also the man page BN_rand(3).
769
802
  */
770
- BIGNUM_RAND_RANGE(rand)
803
+ static VALUE
804
+ ossl_bn_s_rand(int argc, VALUE *argv, VALUE klass)
805
+ {
806
+ BIGNUM *result;
807
+ int bottom = 0, top = 0, b;
808
+ VALUE bits, fill, odd, obj;
809
+
810
+ switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) {
811
+ case 3:
812
+ bottom = (odd == Qtrue) ? 1 : 0;
813
+ /* FALLTHROUGH */
814
+ case 2:
815
+ top = NUM2INT(fill);
816
+ }
817
+ b = NUM2INT(bits);
818
+ obj = NewBN(klass);
819
+ if (!(result = BN_new())) {
820
+ ossl_raise(eBNError, "BN_new");
821
+ }
822
+ if (BN_rand(result, b, top, bottom) <= 0) {
823
+ BN_free(result);
824
+ ossl_raise(eBNError, "BN_rand");
825
+ }
826
+ SetBN(obj, result);
827
+ return obj;
828
+ }
771
829
 
772
830
  /*
773
- * Document-method: OpenSSL::BN.pseudo_rand_range
774
831
  * call-seq:
775
- * BN.pseudo_rand_range(range) -> aBN
832
+ * BN.rand_range(range) -> aBN
833
+ *
834
+ * Generates a cryptographically strong pseudo-random number in the range
835
+ * 0...+range+.
776
836
  *
837
+ * See also the man page BN_rand_range(3).
777
838
  */
778
- BIGNUM_RAND_RANGE(pseudo_rand)
839
+ static VALUE
840
+ ossl_bn_s_rand_range(VALUE klass, VALUE range)
841
+ {
842
+ BIGNUM *bn = GetBNPtr(range), *result;
843
+ VALUE obj = NewBN(klass);
844
+ if (!(result = BN_new()))
845
+ ossl_raise(eBNError, "BN_new");
846
+ if (BN_rand_range(result, bn) <= 0) {
847
+ BN_free(result);
848
+ ossl_raise(eBNError, "BN_rand_range");
849
+ }
850
+ SetBN(obj, result);
851
+ return obj;
852
+ }
779
853
 
780
854
  /*
781
855
  * call-seq:
@@ -870,7 +944,17 @@ ossl_bn_copy(VALUE self, VALUE other)
870
944
  static VALUE
871
945
  ossl_bn_uplus(VALUE self)
872
946
  {
873
- return self;
947
+ VALUE obj;
948
+ BIGNUM *bn1, *bn2;
949
+
950
+ GetBN(self, bn1);
951
+ obj = NewBN(cBN);
952
+ bn2 = BN_dup(bn1);
953
+ if (!bn2)
954
+ ossl_raise(eBNError, "BN_dup");
955
+ SetBN(obj, bn2);
956
+
957
+ return obj;
874
958
  }
875
959
 
876
960
  /*
@@ -894,6 +978,24 @@ ossl_bn_uminus(VALUE self)
894
978
  return obj;
895
979
  }
896
980
 
981
+ /*
982
+ * call-seq:
983
+ * bn.abs -> aBN
984
+ */
985
+ static VALUE
986
+ ossl_bn_abs(VALUE self)
987
+ {
988
+ BIGNUM *bn1;
989
+
990
+ GetBN(self, bn1);
991
+ if (BN_is_negative(bn1)) {
992
+ return ossl_bn_uminus(self);
993
+ }
994
+ else {
995
+ return ossl_bn_uplus(self);
996
+ }
997
+ }
998
+
897
999
  #define BIGNUM_CMP(func) \
898
1000
  static VALUE \
899
1001
  ossl_bn_##func(VALUE self, VALUE other) \
@@ -1002,34 +1104,29 @@ ossl_bn_hash(VALUE self)
1002
1104
  * bn.prime? => true | false
1003
1105
  * bn.prime?(checks) => true | false
1004
1106
  *
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.
1107
+ * Performs a Miller-Rabin probabilistic primality test for +bn+.
1008
1108
  *
1009
- * === Parameters
1010
- * * _checks_ - integer
1109
+ * <b>+checks+ parameter is deprecated in version 3.0.</b> It has no effect.
1011
1110
  */
1012
1111
  static VALUE
1013
1112
  ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
1014
1113
  {
1015
1114
  BIGNUM *bn;
1016
- VALUE vchecks;
1017
- int checks = BN_prime_checks;
1115
+ int ret;
1018
1116
 
1019
- if (rb_scan_args(argc, argv, "01", &vchecks) == 1) {
1020
- checks = NUM2INT(vchecks);
1021
- }
1117
+ rb_check_arity(argc, 0, 1);
1022
1118
  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;
1119
+
1120
+ #ifdef HAVE_BN_CHECK_PRIME
1121
+ ret = BN_check_prime(bn, ossl_bn_ctx, NULL);
1122
+ if (ret < 0)
1123
+ ossl_raise(eBNError, "BN_check_prime");
1124
+ #else
1125
+ ret = BN_is_prime_fasttest_ex(bn, BN_prime_checks, ossl_bn_ctx, 1, NULL);
1126
+ if (ret < 0)
1127
+ ossl_raise(eBNError, "BN_is_prime_fasttest_ex");
1128
+ #endif
1129
+ return ret ? Qtrue : Qfalse;
1033
1130
  }
1034
1131
 
1035
1132
  /*
@@ -1038,39 +1135,52 @@ ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
1038
1135
  * bn.prime_fasttest?(checks) => true | false
1039
1136
  * bn.prime_fasttest?(checks, trial_div) => true | false
1040
1137
  *
1041
- * Performs a Miller-Rabin primality test. This is same as #prime? except this
1042
- * first attempts trial divisions with some small primes.
1138
+ * Performs a Miller-Rabin probabilistic primality test for +bn+.
1043
1139
  *
1044
- * === Parameters
1045
- * * _checks_ - integer
1046
- * * _trial_div_ - boolean
1140
+ * <b>Deprecated in version 3.0.</b> Use #prime? instead.
1141
+ *
1142
+ * +checks+ and +trial_div+ parameters no longer have any effect.
1047
1143
  */
1048
1144
  static VALUE
1049
1145
  ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
1146
+ {
1147
+ rb_check_arity(argc, 0, 2);
1148
+ return ossl_bn_is_prime(0, argv, self);
1149
+ }
1150
+
1151
+ /*
1152
+ * call-seq:
1153
+ * bn.get_flags(flags) => flags
1154
+ *
1155
+ * Returns the flags on the BN object.
1156
+ * The argument is used as a bit mask.
1157
+ *
1158
+ * === Parameters
1159
+ * * _flags_ - integer
1160
+ */
1161
+ static VALUE
1162
+ ossl_bn_get_flags(VALUE self, VALUE arg)
1050
1163
  {
1051
1164
  BIGNUM *bn;
1052
- VALUE vchecks, vtrivdiv;
1053
- int checks = BN_prime_checks, do_trial_division = 1;
1165
+ GetBN(self, bn);
1054
1166
 
1055
- rb_scan_args(argc, argv, "02", &vchecks, &vtrivdiv);
1167
+ return INT2NUM(BN_get_flags(bn, NUM2INT(arg)));
1168
+ }
1056
1169
 
1057
- if (!NIL_P(vchecks)) {
1058
- checks = NUM2INT(vchecks);
1059
- }
1170
+ /*
1171
+ * call-seq:
1172
+ * bn.set_flags(flags) => nil
1173
+ *
1174
+ * Enables the flags on the BN object.
1175
+ * Currently, the flags argument can contain zero of OpenSSL::BN::CONSTTIME.
1176
+ */
1177
+ static VALUE
1178
+ ossl_bn_set_flags(VALUE self, VALUE arg)
1179
+ {
1180
+ BIGNUM *bn;
1060
1181
  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 */
1182
+
1183
+ BN_set_flags(bn, NUM2INT(arg));
1074
1184
  return Qnil;
1075
1185
  }
1076
1186
 
@@ -1086,9 +1196,11 @@ Init_ossl_bn(void)
1086
1196
  eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
1087
1197
  #endif
1088
1198
 
1089
- if (!(ossl_bn_ctx = BN_CTX_new())) {
1090
- ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
1091
- }
1199
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
1200
+ ossl_bn_ctx_key = rb_ractor_local_storage_ptr_newkey(&ossl_bn_ctx_key_type);
1201
+ #else
1202
+ ossl_bn_ctx_get();
1203
+ #endif
1092
1204
 
1093
1205
  eBNError = rb_define_class_under(mOSSL, "BNError", eOSSLError);
1094
1206
 
@@ -1108,6 +1220,7 @@ Init_ossl_bn(void)
1108
1220
 
1109
1221
  rb_define_method(cBN, "+@", ossl_bn_uplus, 0);
1110
1222
  rb_define_method(cBN, "-@", ossl_bn_uminus, 0);
1223
+ rb_define_method(cBN, "abs", ossl_bn_abs, 0);
1111
1224
 
1112
1225
  rb_define_method(cBN, "+", ossl_bn_add, 1);
1113
1226
  rb_define_method(cBN, "-", ossl_bn_sub, 1);
@@ -1151,9 +1264,9 @@ Init_ossl_bn(void)
1151
1264
  * get_word */
1152
1265
 
1153
1266
  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
1267
  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);
1268
+ rb_define_alias(rb_singleton_class(cBN), "pseudo_rand", "rand");
1269
+ rb_define_alias(rb_singleton_class(cBN), "pseudo_rand_range", "rand_range");
1157
1270
 
1158
1271
  rb_define_singleton_method(cBN, "generate_prime", ossl_bn_s_generate_prime, -1);
1159
1272
  rb_define_method(cBN, "prime?", ossl_bn_is_prime, -1);
@@ -1170,6 +1283,23 @@ Init_ossl_bn(void)
1170
1283
  /* lshift1 - DON'T IMPL. */
1171
1284
  /* rshift1 - DON'T IMPL. */
1172
1285
 
1286
+ rb_define_method(cBN, "get_flags", ossl_bn_get_flags, 1);
1287
+ rb_define_method(cBN, "set_flags", ossl_bn_set_flags, 1);
1288
+
1289
+ #ifdef BN_FLG_CONSTTIME
1290
+ rb_define_const(cBN, "CONSTTIME", INT2NUM(BN_FLG_CONSTTIME));
1291
+ #endif
1292
+ /* BN_FLG_MALLOCED and BN_FLG_STATIC_DATA seems for C programming.
1293
+ * Allowing them leads to memory leak.
1294
+ * So, for now, they are not exported
1295
+ #ifdef BN_FLG_MALLOCED
1296
+ rb_define_const(cBN, "MALLOCED", INT2NUM(BN_FLG_MALLOCED));
1297
+ #endif
1298
+ #ifdef BN_FLG_STATIC_DATA
1299
+ rb_define_const(cBN, "STATIC_DATA", INT2NUM(BN_FLG_STATIC_DATA));
1300
+ #endif
1301
+ */
1302
+
1173
1303
  /*
1174
1304
  * bn2bin
1175
1305
  * 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