openssl 2.1.3 → 3.0.1

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +237 -1
  4. data/README.md +2 -2
  5. data/ext/openssl/extconf.rb +46 -38
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +59 -43
  8. data/ext/openssl/ossl.c +110 -64
  9. data/ext/openssl/ossl.h +27 -10
  10. data/ext/openssl/ossl_asn1.c +41 -4
  11. data/ext/openssl/ossl_bn.c +251 -134
  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 +25 -60
  17. data/ext/openssl/ossl_engine.c +18 -27
  18. data/ext/openssl/ossl_hmac.c +60 -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 +1295 -178
  27. data/ext/openssl/ossl_pkey.h +35 -72
  28. data/ext/openssl/ossl_pkey_dh.c +124 -334
  29. data/ext/openssl/ossl_pkey_dsa.c +93 -398
  30. data/ext/openssl/ossl_pkey_ec.c +159 -318
  31. data/ext/openssl/ossl_pkey_rsa.c +105 -484
  32. data/ext/openssl/ossl_rand.c +2 -32
  33. data/ext/openssl/ossl_ssl.c +347 -394
  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 +0 -6
  38. data/ext/openssl/ossl_x509cert.c +169 -13
  39. data/ext/openssl/ossl_x509crl.c +13 -10
  40. data/ext/openssl/ossl_x509ext.c +15 -2
  41. data/ext/openssl/ossl_x509name.c +15 -4
  42. data/ext/openssl/ossl_x509req.c +13 -10
  43. data/ext/openssl/ossl_x509revoked.c +3 -3
  44. data/ext/openssl/ossl_x509store.c +154 -70
  45. data/lib/openssl/bn.rb +1 -1
  46. data/lib/openssl/buffering.rb +37 -5
  47. data/lib/openssl/cipher.rb +1 -1
  48. data/lib/openssl/digest.rb +10 -12
  49. data/lib/openssl/hmac.rb +78 -0
  50. data/lib/openssl/marshal.rb +30 -0
  51. data/lib/openssl/pkcs5.rb +1 -1
  52. data/lib/openssl/pkey.rb +443 -1
  53. data/lib/openssl/ssl.rb +47 -9
  54. data/lib/openssl/version.rb +5 -0
  55. data/lib/openssl/x509.rb +177 -1
  56. data/lib/openssl.rb +24 -9
  57. metadata +10 -79
  58. data/ext/openssl/deprecation.rb +0 -27
  59. data/ext/openssl/ossl_version.h +0 -15
  60. data/ext/openssl/ruby_missing.h +0 -24
  61. data/lib/openssl/config.rb +0 -492
@@ -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)
@@ -193,6 +259,10 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
193
259
  base = NUM2INT(bs);
194
260
  }
195
261
 
262
+ if (NIL_P(str)) {
263
+ ossl_raise(rb_eArgError, "invalid argument");
264
+ }
265
+
196
266
  if (RB_INTEGER_TYPE_P(str)) {
197
267
  GetBN(self, bn);
198
268
  integer_to_bnptr(str, bn);
@@ -243,16 +313,21 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
243
313
 
244
314
  /*
245
315
  * call-seq:
246
- * bn.to_s => string
247
- * bn.to_s(base) => string
316
+ * bn.to_s(base = 10) -> string
248
317
  *
249
- * === Parameters
250
- * * _base_ - Integer
251
- * Valid values:
252
- * * 0 - MPI
253
- * * 2 - binary
254
- * * 10 - the default
255
- * * 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.
256
331
  */
257
332
  static VALUE
258
333
  ossl_bn_to_s(int argc, VALUE *argv, VALUE self)
@@ -717,78 +792,64 @@ BIGNUM_SELF_SHIFT(lshift)
717
792
  */
718
793
  BIGNUM_SELF_SHIFT(rshift)
719
794
 
720
- #define BIGNUM_RAND(func) \
721
- static VALUE \
722
- ossl_bn_s_##func(int argc, VALUE *argv, VALUE klass) \
723
- { \
724
- BIGNUM *result; \
725
- int bottom = 0, top = 0, b; \
726
- VALUE bits, fill, odd, obj; \
727
- \
728
- switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) { \
729
- case 3: \
730
- bottom = (odd == Qtrue) ? 1 : 0; \
731
- /* FALLTHROUGH */ \
732
- case 2: \
733
- top = NUM2INT(fill); \
734
- } \
735
- b = NUM2INT(bits); \
736
- obj = NewBN(klass); \
737
- if (!(result = BN_new())) { \
738
- ossl_raise(eBNError, NULL); \
739
- } \
740
- if (BN_##func(result, b, top, bottom) <= 0) { \
741
- BN_free(result); \
742
- ossl_raise(eBNError, NULL); \
743
- } \
744
- SetBN(obj, result); \
745
- return obj; \
746
- }
747
-
748
- /*
749
- * Document-method: OpenSSL::BN.rand
750
- * BN.rand(bits [, fill [, odd]]) -> aBN
751
- */
752
- BIGNUM_RAND(rand)
753
-
754
- /*
755
- * Document-method: OpenSSL::BN.pseudo_rand
756
- * BN.pseudo_rand(bits [, fill [, odd]]) -> aBN
757
- */
758
- BIGNUM_RAND(pseudo_rand)
759
-
760
- #define BIGNUM_RAND_RANGE(func) \
761
- static VALUE \
762
- ossl_bn_s_##func##_range(VALUE klass, VALUE range) \
763
- { \
764
- BIGNUM *bn = GetBNPtr(range), *result; \
765
- VALUE obj = NewBN(klass); \
766
- if (!(result = BN_new())) { \
767
- ossl_raise(eBNError, NULL); \
768
- } \
769
- if (BN_##func##_range(result, bn) <= 0) { \
770
- BN_free(result); \
771
- ossl_raise(eBNError, NULL); \
772
- } \
773
- SetBN(obj, result); \
774
- return obj; \
775
- }
776
-
777
795
  /*
778
- * Document-method: OpenSSL::BN.rand_range
779
796
  * call-seq:
780
- * BN.rand_range(range) -> aBN
797
+ * BN.rand(bits [, fill [, odd]]) -> aBN
781
798
  *
799
+ * Generates a cryptographically strong pseudo-random number of +bits+.
800
+ *
801
+ * See also the man page BN_rand(3).
782
802
  */
783
- 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
+ }
784
829
 
785
830
  /*
786
- * Document-method: OpenSSL::BN.pseudo_rand_range
787
831
  * call-seq:
788
- * 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+.
789
836
  *
837
+ * See also the man page BN_rand_range(3).
790
838
  */
791
- 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
+ }
792
853
 
793
854
  /*
794
855
  * call-seq:
@@ -883,7 +944,17 @@ ossl_bn_copy(VALUE self, VALUE other)
883
944
  static VALUE
884
945
  ossl_bn_uplus(VALUE self)
885
946
  {
886
- 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;
887
958
  }
888
959
 
889
960
  /*
@@ -907,6 +978,24 @@ ossl_bn_uminus(VALUE self)
907
978
  return obj;
908
979
  }
909
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
+
910
999
  #define BIGNUM_CMP(func) \
911
1000
  static VALUE \
912
1001
  ossl_bn_##func(VALUE self, VALUE other) \
@@ -1015,34 +1104,29 @@ ossl_bn_hash(VALUE self)
1015
1104
  * bn.prime? => true | false
1016
1105
  * bn.prime?(checks) => true | false
1017
1106
  *
1018
- * Performs a Miller-Rabin probabilistic primality test with _checks_
1019
- * iterations. If _checks_ is not specified, a number of iterations is used
1020
- * that yields a false positive rate of at most 2^-80 for random input.
1107
+ * Performs a Miller-Rabin probabilistic primality test for +bn+.
1021
1108
  *
1022
- * === Parameters
1023
- * * _checks_ - integer
1109
+ * <b>+checks+ parameter is deprecated in version 3.0.</b> It has no effect.
1024
1110
  */
1025
1111
  static VALUE
1026
1112
  ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
1027
1113
  {
1028
1114
  BIGNUM *bn;
1029
- VALUE vchecks;
1030
- int checks = BN_prime_checks;
1115
+ int ret;
1031
1116
 
1032
- if (rb_scan_args(argc, argv, "01", &vchecks) == 1) {
1033
- checks = NUM2INT(vchecks);
1034
- }
1117
+ rb_check_arity(argc, 0, 1);
1035
1118
  GetBN(self, bn);
1036
- switch (BN_is_prime_ex(bn, checks, ossl_bn_ctx, NULL)) {
1037
- case 1:
1038
- return Qtrue;
1039
- case 0:
1040
- return Qfalse;
1041
- default:
1042
- ossl_raise(eBNError, NULL);
1043
- }
1044
- /* not reachable */
1045
- 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;
1046
1130
  }
1047
1131
 
1048
1132
  /*
@@ -1051,39 +1135,52 @@ ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
1051
1135
  * bn.prime_fasttest?(checks) => true | false
1052
1136
  * bn.prime_fasttest?(checks, trial_div) => true | false
1053
1137
  *
1054
- * Performs a Miller-Rabin primality test. This is same as #prime? except this
1055
- * first attempts trial divisions with some small primes.
1138
+ * Performs a Miller-Rabin probabilistic primality test for +bn+.
1056
1139
  *
1057
- * === Parameters
1058
- * * _checks_ - integer
1059
- * * _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.
1060
1143
  */
1061
1144
  static VALUE
1062
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)
1063
1163
  {
1064
1164
  BIGNUM *bn;
1065
- VALUE vchecks, vtrivdiv;
1066
- int checks = BN_prime_checks, do_trial_division = 1;
1165
+ GetBN(self, bn);
1067
1166
 
1068
- rb_scan_args(argc, argv, "02", &vchecks, &vtrivdiv);
1167
+ return INT2NUM(BN_get_flags(bn, NUM2INT(arg)));
1168
+ }
1069
1169
 
1070
- if (!NIL_P(vchecks)) {
1071
- checks = NUM2INT(vchecks);
1072
- }
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;
1073
1181
  GetBN(self, bn);
1074
- /* handle true/false */
1075
- if (vtrivdiv == Qfalse) {
1076
- do_trial_division = 0;
1077
- }
1078
- switch (BN_is_prime_fasttest_ex(bn, checks, ossl_bn_ctx, do_trial_division, NULL)) {
1079
- case 1:
1080
- return Qtrue;
1081
- case 0:
1082
- return Qfalse;
1083
- default:
1084
- ossl_raise(eBNError, NULL);
1085
- }
1086
- /* not reachable */
1182
+
1183
+ BN_set_flags(bn, NUM2INT(arg));
1087
1184
  return Qnil;
1088
1185
  }
1089
1186
 
@@ -1099,9 +1196,11 @@ Init_ossl_bn(void)
1099
1196
  eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
1100
1197
  #endif
1101
1198
 
1102
- if (!(ossl_bn_ctx = BN_CTX_new())) {
1103
- ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
1104
- }
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
1105
1204
 
1106
1205
  eBNError = rb_define_class_under(mOSSL, "BNError", eOSSLError);
1107
1206
 
@@ -1121,6 +1220,7 @@ Init_ossl_bn(void)
1121
1220
 
1122
1221
  rb_define_method(cBN, "+@", ossl_bn_uplus, 0);
1123
1222
  rb_define_method(cBN, "-@", ossl_bn_uminus, 0);
1223
+ rb_define_method(cBN, "abs", ossl_bn_abs, 0);
1124
1224
 
1125
1225
  rb_define_method(cBN, "+", ossl_bn_add, 1);
1126
1226
  rb_define_method(cBN, "-", ossl_bn_sub, 1);
@@ -1164,9 +1264,9 @@ Init_ossl_bn(void)
1164
1264
  * get_word */
1165
1265
 
1166
1266
  rb_define_singleton_method(cBN, "rand", ossl_bn_s_rand, -1);
1167
- rb_define_singleton_method(cBN, "pseudo_rand", ossl_bn_s_pseudo_rand, -1);
1168
1267
  rb_define_singleton_method(cBN, "rand_range", ossl_bn_s_rand_range, 1);
1169
- 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");
1170
1270
 
1171
1271
  rb_define_singleton_method(cBN, "generate_prime", ossl_bn_s_generate_prime, -1);
1172
1272
  rb_define_method(cBN, "prime?", ossl_bn_is_prime, -1);
@@ -1183,6 +1283,23 @@ Init_ossl_bn(void)
1183
1283
  /* lshift1 - DON'T IMPL. */
1184
1284
  /* rshift1 - DON'T IMPL. */
1185
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
+
1186
1303
  /*
1187
1304
  * bn2bin
1188
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
 
@@ -104,7 +104,7 @@ ossl_cipher_alloc(VALUE klass)
104
104
  * call-seq:
105
105
  * Cipher.new(string) -> cipher
106
106
  *
107
- * The string must be a valid cipher name like "AES-128-CBC" or "3DES".
107
+ * The string must contain a valid cipher name like "aes-256-cbc".
108
108
  *
109
109
  * A list of cipher names is available by calling OpenSSL::Cipher.ciphers.
110
110
  */
@@ -149,11 +149,11 @@ ossl_cipher_copy(VALUE self, VALUE other)
149
149
  return self;
150
150
  }
151
151
 
152
- static void*
153
- add_cipher_name_to_ary(const OBJ_NAME *name, VALUE ary)
152
+ static void
153
+ add_cipher_name_to_ary(const OBJ_NAME *name, void *arg)
154
154
  {
155
+ VALUE ary = (VALUE)arg;
155
156
  rb_ary_push(ary, rb_str_new2(name->name));
156
- return NULL;
157
157
  }
158
158
 
159
159
  /*
@@ -169,7 +169,7 @@ ossl_s_ciphers(VALUE self)
169
169
 
170
170
  ary = rb_ary_new();
171
171
  OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
172
- (void(*)(const OBJ_NAME*,void*))add_cipher_name_to_ary,
172
+ add_cipher_name_to_ary,
173
173
  (void*)ary);
174
174
 
175
175
  return ary;
@@ -237,8 +237,7 @@ ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode)
237
237
  ossl_raise(eCipherError, NULL);
238
238
  }
239
239
 
240
- if (p_key)
241
- rb_ivar_set(self, id_key_set, Qtrue);
240
+ rb_ivar_set(self, id_key_set, p_key ? Qtrue : Qfalse);
242
241
 
243
242
  return self;
244
243
  }
@@ -814,6 +813,31 @@ ossl_cipher_block_size(VALUE self)
814
813
  return INT2NUM(EVP_CIPHER_CTX_block_size(ctx));
815
814
  }
816
815
 
816
+ /*
817
+ * call-seq:
818
+ * cipher.ccm_data_len = integer -> integer
819
+ *
820
+ * Sets the length of the plaintext / ciphertext message that will be
821
+ * processed in CCM mode. Make sure to call this method after #key= and
822
+ * #iv= have been set, and before #auth_data=.
823
+ *
824
+ * Only call this method after calling Cipher#encrypt or Cipher#decrypt.
825
+ */
826
+ static VALUE
827
+ ossl_cipher_set_ccm_data_len(VALUE self, VALUE data_len)
828
+ {
829
+ int in_len, out_len;
830
+ EVP_CIPHER_CTX *ctx;
831
+
832
+ in_len = NUM2INT(data_len);
833
+
834
+ GetCipher(self, ctx);
835
+ if (EVP_CipherUpdate(ctx, NULL, &out_len, NULL, in_len) != 1)
836
+ ossl_raise(eCipherError, NULL);
837
+
838
+ return data_len;
839
+ }
840
+
817
841
  /*
818
842
  * INIT
819
843
  */
@@ -850,23 +874,7 @@ Init_ossl_cipher(void)
850
874
  * individual components name, key length and mode. Either all uppercase
851
875
  * or all lowercase strings may be used, for example:
852
876
  *
853
- * cipher = OpenSSL::Cipher.new('AES-128-CBC')
854
- *
855
- * For each algorithm supported, there is a class defined under the
856
- * Cipher class that goes by the name of the cipher, e.g. to obtain an
857
- * instance of AES, you could also use
858
- *
859
- * # these are equivalent
860
- * cipher = OpenSSL::Cipher::AES.new(128, :CBC)
861
- * cipher = OpenSSL::Cipher::AES.new(128, 'CBC')
862
- * cipher = OpenSSL::Cipher::AES.new('128-CBC')
863
- *
864
- * Finally, due to its wide-spread use, there are also extra classes
865
- * defined for the different key sizes of AES
866
- *
867
- * cipher = OpenSSL::Cipher::AES128.new(:CBC)
868
- * cipher = OpenSSL::Cipher::AES192.new(:CBC)
869
- * cipher = OpenSSL::Cipher::AES256.new(:CBC)
877
+ * cipher = OpenSSL::Cipher.new('aes-128-cbc')
870
878
  *
871
879
  * === Choosing either encryption or decryption mode
872
880
  *
@@ -896,7 +904,7 @@ Init_ossl_cipher(void)
896
904
  * without processing the password further. A simple and secure way to
897
905
  * create a key for a particular Cipher is
898
906
  *
899
- * cipher = OpenSSL::AES256.new(:CFB)
907
+ * cipher = OpenSSL::Cipher.new('aes-256-cfb')
900
908
  * cipher.encrypt
901
909
  * key = cipher.random_key # also sets the generated key on the Cipher
902
910
  *
@@ -964,14 +972,14 @@ Init_ossl_cipher(void)
964
972
  *
965
973
  * data = "Very, very confidential data"
966
974
  *
967
- * cipher = OpenSSL::Cipher::AES.new(128, :CBC)
975
+ * cipher = OpenSSL::Cipher.new('aes-128-cbc')
968
976
  * cipher.encrypt
969
977
  * key = cipher.random_key
970
978
  * iv = cipher.random_iv
971
979
  *
972
980
  * encrypted = cipher.update(data) + cipher.final
973
981
  * ...
974
- * decipher = OpenSSL::Cipher::AES.new(128, :CBC)
982
+ * decipher = OpenSSL::Cipher.new('aes-128-cbc')
975
983
  * decipher.decrypt
976
984
  * decipher.key = key
977
985
  * decipher.iv = iv
@@ -1007,7 +1015,7 @@ Init_ossl_cipher(void)
1007
1015
  * not to reuse the _key_ and _nonce_ pair. Reusing an nonce ruins the
1008
1016
  * security guarantees of GCM mode.
1009
1017
  *
1010
- * cipher = OpenSSL::Cipher::AES.new(128, :GCM).encrypt
1018
+ * cipher = OpenSSL::Cipher.new('aes-128-gcm').encrypt
1011
1019
  * cipher.key = key
1012
1020
  * cipher.iv = nonce
1013
1021
  * cipher.auth_data = auth_data
@@ -1023,7 +1031,7 @@ Init_ossl_cipher(void)
1023
1031
  * ciphertext with a probability of 1/256.
1024
1032
  *
1025
1033
  * raise "tag is truncated!" unless tag.bytesize == 16
1026
- * decipher = OpenSSL::Cipher::AES.new(128, :GCM).decrypt
1034
+ * decipher = OpenSSL::Cipher.new('aes-128-gcm').decrypt
1027
1035
  * decipher.key = key
1028
1036
  * decipher.iv = nonce
1029
1037
  * decipher.auth_tag = tag
@@ -1060,6 +1068,7 @@ Init_ossl_cipher(void)
1060
1068
  rb_define_method(cCipher, "iv_len", ossl_cipher_iv_length, 0);
1061
1069
  rb_define_method(cCipher, "block_size", ossl_cipher_block_size, 0);
1062
1070
  rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1);
1071
+ rb_define_method(cCipher, "ccm_data_len=", ossl_cipher_set_ccm_data_len, 1);
1063
1072
 
1064
1073
  id_auth_tag_len = rb_intern_const("auth_tag_len");
1065
1074
  id_key_set = rb_intern_const("key_set");