openssl 2.1.3 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +35 -45
  3. data/History.md +266 -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 +186 -329
  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");