openssl 2.1.2 → 2.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a5ba46835caa91a77f80010c07b52e8532221c8a1b4726159584eb92a6ce204
4
- data.tar.gz: ca5ba9b87ceb945ac1f312e00ceadae32c868e2659e89677ed534a22ed145cf8
3
+ metadata.gz: 7698d18ecab870cfddfbc527123fb4e77cd8f993321440167feec83485828ea7
4
+ data.tar.gz: 1132a2cc147808d3e42ca9d3f726b24d635da93d3c8e62af31f4f9c8b5c51ce1
5
5
  SHA512:
6
- metadata.gz: 0eb54df27a2aa1455fb18b6e5e05c40598ba3f342ad933fd035342596b55a1e68c3b9607cede2b955961805150ca8eb7dcfa2a046600614da1d80dc9d17db17b
7
- data.tar.gz: 31ac63101df5218fa003477b130b07a32826f685e465c71cf43fc9db28d3ecbb275e5dcc4b685860f418ea893378c133009af92ff1a2293b3d91606a8055b70b
6
+ metadata.gz: 99bad919e464275130913d0ba39db26271d3d43f843a27cefc16b7777727715214e26810236227ef2c13588a7311f4cfef6954275f64e034724b21696ecf37e7
7
+ data.tar.gz: d44e451531531e45db6f86ecfd2eaa0099c5e4143e5dc1f7794ff85822ef6dc92ad10ac87e62faa1c8a227e2aed1089cde2a022fb71f5eba4b764f6ef7bade12
data/History.md CHANGED
@@ -1,3 +1,39 @@
1
+ Version 2.1.3
2
+ =============
3
+
4
+ Bug fixes
5
+ ---------
6
+
7
+ * Fix deprecation warnings on Ruby 3.0.
8
+ * Add ".include" directive support in `OpenSSL::Config`.
9
+ [[GitHub #216]](https://github.com/ruby/openssl/pull/216)
10
+ * Fix handling of IPv6 address SANs.
11
+ [[GitHub #185]](https://github.com/ruby/openssl/pull/185)
12
+ * Hostname verification failure with `OpenSSL::SSL::SSLContext#verify_hostname=`
13
+ sets a proper error code.
14
+ [[GitHub #350]](https://github.com/ruby/openssl/pull/350)
15
+ * Fix crash with `OpenSSL::BN.new(nil, 2)`.
16
+ [[Bug #15760]](https://bugs.ruby-lang.org/issues/15760)
17
+ * `OpenSSL::SSL::SSLSocket#sys{read,write}` prevent internal string buffers from
18
+ being modified by another thread.
19
+ [[GitHub #453]](https://github.com/ruby/openssl/pull/453)
20
+ * Fix misuse of input record separator in `OpenSSL::Buffering` where it was
21
+ for output.
22
+ * Fix wrong interger casting in `OpenSSL::PKey::EC#dsa_verify_asn1`.
23
+ [[GitHub #460]](https://github.com/ruby/openssl/pull/460)
24
+ * `extconf.rb` explicitly checks that OpenSSL's version number is 1.0.1 or
25
+ newer but also less than 3.0. Ruby/OpenSSL v2.1.x and v2.2.x will not support
26
+ OpenSSL 3.0 API.
27
+ [[GitHub #458]](https://github.com/ruby/openssl/pull/458)
28
+ * Activate `digest` gem correctly. `digest` library could go into an
29
+ inconsistent state if there are multiple versions of `digest` is installed
30
+ and `openssl` is `require`d before `digest`.
31
+ [[GitHub #463]](https://github.com/ruby/openssl/pull/463)
32
+ * Fix GC.compact compatibility.
33
+ [[GitHub #464]](https://github.com/ruby/openssl/issues/464)
34
+ [[GitHub #465]](https://github.com/ruby/openssl/pull/465)
35
+
36
+
1
37
  Version 2.1.2
2
38
  =============
3
39
 
@@ -3,7 +3,7 @@ module OpenSSL
3
3
  def self.deprecated_warning_flag
4
4
  unless flag = (@deprecated_warning_flag ||= nil)
5
5
  if try_compile("", flag = "-Werror=deprecated-declarations")
6
- $warnflags << " #{flag}"
6
+ $warnflags = "#{@warnflags = $warnflags}" #{flag}"
7
7
  else
8
8
  flag = ""
9
9
  end
@@ -12,6 +12,10 @@ module OpenSSL
12
12
  flag
13
13
  end
14
14
 
15
+ def self.restore_warning_flag
16
+ $warnflags = @warnflags
17
+ end
18
+
15
19
  def self.check_func(func, header)
16
20
  have_func(func, header, deprecated_warning_flag)
17
21
  end
@@ -19,7 +19,7 @@ dir_config("kerberos")
19
19
 
20
20
  Logging::message "=== OpenSSL for Ruby configurator ===\n"
21
21
 
22
- # Add -Werror=deprecated-declarations to $warnflags if available
22
+ # Check with -Werror=deprecated-declarations if available
23
23
  OpenSSL.deprecated_warning_flag
24
24
 
25
25
  ##
@@ -37,9 +37,6 @@ if $mswin || $mingw
37
37
  have_library("ws2_32")
38
38
  end
39
39
 
40
- Logging::message "=== Checking for required stuff... ===\n"
41
- result = pkg_config("openssl") && have_header("openssl/ssl.h")
42
-
43
40
  def find_openssl_library
44
41
  if $mswin || $mingw
45
42
  # required for static OpenSSL libraries
@@ -90,19 +87,33 @@ def find_openssl_library
90
87
  return false
91
88
  end
92
89
 
93
- unless result
94
- unless find_openssl_library
95
- Logging::message "=== Checking for required stuff failed. ===\n"
96
- Logging::message "Makefile wasn't created. Fix the errors above.\n"
97
- raise "OpenSSL library could not be found. You might want to use " \
98
- "--with-openssl-dir=<dir> option to specify the prefix where OpenSSL " \
99
- "is installed."
100
- end
90
+ Logging::message "=== Checking for required stuff... ===\n"
91
+ pkg_config_found = pkg_config("openssl") && have_header("openssl/ssl.h")
92
+
93
+ if !pkg_config_found && !find_openssl_library
94
+ Logging::message "=== Checking for required stuff failed. ===\n"
95
+ Logging::message "Makefile wasn't created. Fix the errors above.\n"
96
+ raise "OpenSSL library could not be found. You might want to use " \
97
+ "--with-openssl-dir=<dir> option to specify the prefix where OpenSSL " \
98
+ "is installed."
101
99
  end
102
100
 
103
- unless checking_for("OpenSSL version is 1.0.1 or later") {
104
- try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10001000L", "openssl/opensslv.h") }
105
- raise "OpenSSL >= 1.0.1 or LibreSSL is required"
101
+ version_ok = if have_macro("LIBRESSL_VERSION_NUMBER", "openssl/opensslv.h")
102
+ is_libressl = true
103
+ checking_for("LibreSSL version >= 2.5.0") {
104
+ try_static_assert("LIBRESSL_VERSION_NUMBER >= 0x20500000L", "openssl/opensslv.h") }
105
+ else
106
+ checking_for("OpenSSL version >= 1.0.1 and < 3.0.0") {
107
+ try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10001000L", "openssl/opensslv.h") &&
108
+ !try_static_assert("OPENSSL_VERSION_MAJOR >= 3", "openssl/opensslv.h") }
109
+ end
110
+ unless version_ok
111
+ raise "OpenSSL >= 1.0.1, < 3.0.0 or LibreSSL >= 2.5.0 is required"
112
+ end
113
+
114
+ # Prevent wincrypt.h from being included, which defines conflicting macro with openssl/x509.h
115
+ if is_libressl && ($mswin || $mingw)
116
+ $defs.push("-DNOCRYPT")
106
117
  end
107
118
 
108
119
  Logging::message "=== Checking for OpenSSL features... ===\n"
@@ -114,10 +125,6 @@ engines.each { |name|
114
125
  OpenSSL.check_func_or_macro("ENGINE_load_#{name}", "openssl/engine.h")
115
126
  }
116
127
 
117
- if ($mswin || $mingw) && have_macro("LIBRESSL_VERSION_NUMBER", "openssl/opensslv.h")
118
- $defs.push("-DNOCRYPT")
119
- end
120
-
121
128
  # added in 1.0.2
122
129
  have_func("EC_curve_nist2nid")
123
130
  have_func("X509_REVOKED_dup")
@@ -169,5 +176,6 @@ have_func("EVP_PBE_scrypt")
169
176
  Logging::message "=== Checking done. ===\n"
170
177
 
171
178
  create_header
179
+ OpenSSL.restore_warning_flag
172
180
  create_makefile("openssl")
173
181
  Logging::message "Done.\n"
@@ -185,7 +185,7 @@ IMPL_KEY_ACCESSOR3(DSA, pqg, p, q, g, (p == obj->p || q == obj->q || g == obj->g
185
185
  #if !defined(OPENSSL_NO_DH)
186
186
  IMPL_PKEY_GETTER(DH, dh)
187
187
  IMPL_KEY_ACCESSOR2(DH, key, pub_key, priv_key, (pub_key == obj->pub_key || (obj->priv_key && priv_key == obj->priv_key)))
188
- IMPL_KEY_ACCESSOR3(DH, pqg, p, q, g, (p == obj->p || obj->q && q == obj->q || g == obj->g))
188
+ IMPL_KEY_ACCESSOR3(DH, pqg, p, q, g, (p == obj->p || (obj->q && q == obj->q) || g == obj->g))
189
189
  static inline ENGINE *DH_get0_engine(DH *dh) { return dh->engine; }
190
190
  #endif
191
191
 
data/ext/openssl/ossl.c CHANGED
@@ -338,7 +338,7 @@ ossl_clear_error(void)
338
338
  * implementation.
339
339
  */
340
340
  VALUE
341
- ossl_get_errors(void)
341
+ ossl_get_errors(VALUE _)
342
342
  {
343
343
  VALUE ary;
344
344
  long e;
@@ -398,7 +398,7 @@ ossl_debug_set(VALUE self, VALUE val)
398
398
  }
399
399
 
400
400
  /*
401
- * call-seq
401
+ * call-seq:
402
402
  * OpenSSL.fips_mode -> true | false
403
403
  */
404
404
  static VALUE
data/ext/openssl/ossl.h CHANGED
@@ -13,8 +13,8 @@
13
13
  #include RUBY_EXTCONF_H
14
14
 
15
15
  #include <assert.h>
16
- #include <errno.h>
17
16
  #include <ruby.h>
17
+ #include <errno.h>
18
18
  #include <ruby/io.h>
19
19
  #include <ruby/thread.h>
20
20
  #include <openssl/opensslv.h>
@@ -1824,6 +1824,7 @@ do{\
1824
1824
  rb_define_method(cASN1EndOfContent, "to_der", ossl_asn1eoc_to_der, 0);
1825
1825
 
1826
1826
  class_tag_map = rb_hash_new();
1827
+ rb_gc_register_mark_object(class_tag_map);
1827
1828
  rb_hash_aset(class_tag_map, cASN1EndOfContent, INT2NUM(V_ASN1_EOC));
1828
1829
  rb_hash_aset(class_tag_map, cASN1Boolean, INT2NUM(V_ASN1_BOOLEAN));
1829
1830
  rb_hash_aset(class_tag_map, cASN1Integer, INT2NUM(V_ASN1_INTEGER));
@@ -1847,7 +1848,6 @@ do{\
1847
1848
  rb_hash_aset(class_tag_map, cASN1GeneralString, INT2NUM(V_ASN1_GENERALSTRING));
1848
1849
  rb_hash_aset(class_tag_map, cASN1UniversalString, INT2NUM(V_ASN1_UNIVERSALSTRING));
1849
1850
  rb_hash_aset(class_tag_map, cASN1BMPString, INT2NUM(V_ASN1_BMPSTRING));
1850
- rb_global_variable(&class_tag_map);
1851
1851
 
1852
1852
  id_each = rb_intern_const("each");
1853
1853
  }
@@ -187,6 +187,7 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
187
187
  BIGNUM *bn;
188
188
  VALUE str, bs;
189
189
  int base = 10;
190
+ char *ptr;
190
191
 
191
192
  if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) {
192
193
  base = NUM2INT(bs);
@@ -213,12 +214,14 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
213
214
  GetBN(self, bn);
214
215
  switch (base) {
215
216
  case 0:
216
- if (!BN_mpi2bn((unsigned char *)StringValuePtr(str), RSTRING_LENINT(str), bn)) {
217
+ ptr = StringValuePtr(str);
218
+ if (!BN_mpi2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
217
219
  ossl_raise(eBNError, NULL);
218
220
  }
219
221
  break;
220
222
  case 2:
221
- if (!BN_bin2bn((unsigned char *)StringValuePtr(str), RSTRING_LENINT(str), bn)) {
223
+ ptr = StringValuePtr(str);
224
+ if (!BN_bin2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
222
225
  ossl_raise(eBNError, NULL);
223
226
  }
224
227
  break;
@@ -397,7 +400,7 @@ ossl_bn_is_negative(VALUE self)
397
400
  if (!(result = BN_new())) { \
398
401
  ossl_raise(eBNError, NULL); \
399
402
  } \
400
- if (!BN_##func(result, bn, ossl_bn_ctx)) { \
403
+ if (BN_##func(result, bn, ossl_bn_ctx) <= 0) { \
401
404
  BN_free(result); \
402
405
  ossl_raise(eBNError, NULL); \
403
406
  } \
@@ -423,7 +426,7 @@ BIGNUM_1c(sqr)
423
426
  if (!(result = BN_new())) { \
424
427
  ossl_raise(eBNError, NULL); \
425
428
  } \
426
- if (!BN_##func(result, bn1, bn2)) { \
429
+ if (BN_##func(result, bn1, bn2) <= 0) { \
427
430
  BN_free(result); \
428
431
  ossl_raise(eBNError, NULL); \
429
432
  } \
@@ -456,7 +459,7 @@ BIGNUM_2(sub)
456
459
  if (!(result = BN_new())) { \
457
460
  ossl_raise(eBNError, NULL); \
458
461
  } \
459
- if (!BN_##func(result, bn1, bn2, ossl_bn_ctx)) { \
462
+ if (BN_##func(result, bn1, bn2, ossl_bn_ctx) <= 0) { \
460
463
  BN_free(result); \
461
464
  ossl_raise(eBNError, NULL); \
462
465
  } \
@@ -500,11 +503,21 @@ BIGNUM_2c(gcd)
500
503
  BIGNUM_2c(mod_sqr)
501
504
 
502
505
  /*
503
- * Document-method: OpenSSL::BN#mod_inverse
504
506
  * call-seq:
505
- * bn.mod_inverse(bn2) => aBN
507
+ * bn.mod_inverse(bn2) => aBN
506
508
  */
507
- BIGNUM_2c(mod_inverse)
509
+ static VALUE
510
+ ossl_bn_mod_inverse(VALUE self, VALUE other)
511
+ {
512
+ BIGNUM *bn1, *bn2 = GetBNPtr(other), *result;
513
+ VALUE obj;
514
+ GetBN(self, bn1);
515
+ obj = NewBN(rb_obj_class(self));
516
+ if (!(result = BN_mod_inverse(NULL, bn1, bn2, ossl_bn_ctx)))
517
+ ossl_raise(eBNError, "BN_mod_inverse");
518
+ SetBN(obj, result);
519
+ return obj;
520
+ }
508
521
 
509
522
  /*
510
523
  * call-seq:
@@ -553,7 +566,7 @@ ossl_bn_div(VALUE self, VALUE other)
553
566
  if (!(result = BN_new())) { \
554
567
  ossl_raise(eBNError, NULL); \
555
568
  } \
556
- if (!BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx)) { \
569
+ if (BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx) <= 0) { \
557
570
  BN_free(result); \
558
571
  ossl_raise(eBNError, NULL); \
559
572
  } \
@@ -595,7 +608,7 @@ BIGNUM_3c(mod_exp)
595
608
  { \
596
609
  BIGNUM *bn; \
597
610
  GetBN(self, bn); \
598
- if (!BN_##func(bn, NUM2INT(bit))) { \
611
+ if (BN_##func(bn, NUM2INT(bit)) <= 0) { \
599
612
  ossl_raise(eBNError, NULL); \
600
613
  } \
601
614
  return self; \
@@ -655,7 +668,7 @@ ossl_bn_is_bit_set(VALUE self, VALUE bit)
655
668
  if (!(result = BN_new())) { \
656
669
  ossl_raise(eBNError, NULL); \
657
670
  } \
658
- if (!BN_##func(result, bn, b)) { \
671
+ if (BN_##func(result, bn, b) <= 0) { \
659
672
  BN_free(result); \
660
673
  ossl_raise(eBNError, NULL); \
661
674
  } \
@@ -685,7 +698,7 @@ BIGNUM_SHIFT(rshift)
685
698
  int b; \
686
699
  b = NUM2INT(bits); \
687
700
  GetBN(self, bn); \
688
- if (!BN_##func(bn, bn, b)) \
701
+ if (BN_##func(bn, bn, b) <= 0) \
689
702
  ossl_raise(eBNError, NULL); \
690
703
  return self; \
691
704
  }
@@ -724,7 +737,7 @@ BIGNUM_SELF_SHIFT(rshift)
724
737
  if (!(result = BN_new())) { \
725
738
  ossl_raise(eBNError, NULL); \
726
739
  } \
727
- if (!BN_##func(result, b, top, bottom)) { \
740
+ if (BN_##func(result, b, top, bottom) <= 0) { \
728
741
  BN_free(result); \
729
742
  ossl_raise(eBNError, NULL); \
730
743
  } \
@@ -753,7 +766,7 @@ BIGNUM_RAND(pseudo_rand)
753
766
  if (!(result = BN_new())) { \
754
767
  ossl_raise(eBNError, NULL); \
755
768
  } \
756
- if (!BN_##func##_range(result, bn)) { \
769
+ if (BN_##func##_range(result, bn) <= 0) { \
757
770
  BN_free(result); \
758
771
  ossl_raise(eBNError, NULL); \
759
772
  } \
@@ -313,8 +313,6 @@ ossl_digest_block_length(VALUE self)
313
313
  void
314
314
  Init_ossl_digest(void)
315
315
  {
316
- rb_require("digest");
317
-
318
316
  #if 0
319
317
  mOSSL = rb_define_module("OpenSSL");
320
318
  eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
@@ -433,6 +431,12 @@ Init_ossl_digest(void)
433
431
  * digest2 = sha256.digest(data2)
434
432
  *
435
433
  */
434
+
435
+ /*
436
+ * Digest::Class is defined by the digest library. rb_require() cannot be
437
+ * used here because it bypasses RubyGems.
438
+ */
439
+ rb_funcall(Qnil, rb_intern_const("require"), 1, rb_str_new_cstr("digest"));
436
440
  cDigest = rb_define_class_under(mOSSL, "Digest", rb_path2class("Digest::Class"));
437
441
  /* Document-class: OpenSSL::Digest::DigestError
438
442
  *
@@ -133,9 +133,9 @@ static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2, VALU
133
133
  BIGNUM *bn3 = NULL, *orig_bn3 = NIL_P(v3) ? NULL : GetBNPtr(v3);\
134
134
  \
135
135
  Get##_type(self, obj); \
136
- if (orig_bn1 && !(bn1 = BN_dup(orig_bn1)) || \
137
- orig_bn2 && !(bn2 = BN_dup(orig_bn2)) || \
138
- orig_bn3 && !(bn3 = BN_dup(orig_bn3))) { \
136
+ if ((orig_bn1 && !(bn1 = BN_dup(orig_bn1))) || \
137
+ (orig_bn2 && !(bn2 = BN_dup(orig_bn2))) || \
138
+ (orig_bn3 && !(bn3 = BN_dup(orig_bn3)))) { \
139
139
  BN_clear_free(bn1); \
140
140
  BN_clear_free(bn2); \
141
141
  BN_clear_free(bn3); \
@@ -163,8 +163,8 @@ static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2) \
163
163
  BIGNUM *bn2 = NULL, *orig_bn2 = NIL_P(v2) ? NULL : GetBNPtr(v2);\
164
164
  \
165
165
  Get##_type(self, obj); \
166
- if (orig_bn1 && !(bn1 = BN_dup(orig_bn1)) || \
167
- orig_bn2 && !(bn2 = BN_dup(orig_bn2))) { \
166
+ if ((orig_bn1 && !(bn1 = BN_dup(orig_bn1))) || \
167
+ (orig_bn2 && !(bn2 = BN_dup(orig_bn2)))) { \
168
168
  BN_clear_free(bn1); \
169
169
  BN_clear_free(bn2); \
170
170
  ossl_raise(eBNError, NULL); \
@@ -262,7 +262,7 @@ ossl_dh_initialize_copy(VALUE self, VALUE other)
262
262
  BIGNUM *pub2 = BN_dup(pub);
263
263
  BIGNUM *priv2 = BN_dup(priv);
264
264
 
265
- if (!pub2 || priv && !priv2) {
265
+ if (!pub2 || (priv && !priv2)) {
266
266
  BN_clear_free(pub2);
267
267
  BN_clear_free(priv2);
268
268
  ossl_raise(eDHError, "BN_dup");
@@ -653,15 +653,15 @@ static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig)
653
653
  StringValue(data);
654
654
  StringValue(sig);
655
655
 
656
- switch (ECDSA_verify(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(sig), (int)RSTRING_LEN(sig), ec)) {
657
- case 1: return Qtrue;
658
- case 0: return Qfalse;
659
- default: break;
656
+ switch (ECDSA_verify(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
657
+ (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), ec)) {
658
+ case 1:
659
+ return Qtrue;
660
+ case 0:
661
+ return Qfalse;
662
+ default:
663
+ ossl_raise(eECError, "ECDSA_verify");
660
664
  }
661
-
662
- ossl_raise(eECError, "ECDSA_verify");
663
-
664
- UNREACHABLE;
665
665
  }
666
666
 
667
667
  /*
@@ -67,8 +67,6 @@ ossl_rand_add(VALUE self, VALUE str, VALUE entropy)
67
67
  static VALUE
68
68
  ossl_rand_load_file(VALUE self, VALUE filename)
69
69
  {
70
- rb_check_safe_obj(filename);
71
-
72
70
  if(!RAND_load_file(StringValueCStr(filename), -1)) {
73
71
  ossl_raise(eRandomError, NULL);
74
72
  }
@@ -86,8 +84,6 @@ ossl_rand_load_file(VALUE self, VALUE filename)
86
84
  static VALUE
87
85
  ossl_rand_write_file(VALUE self, VALUE filename)
88
86
  {
89
- rb_check_safe_obj(filename);
90
-
91
87
  if (RAND_write_file(StringValueCStr(filename)) == -1) {
92
88
  ossl_raise(eRandomError, NULL);
93
89
  }
@@ -164,8 +160,6 @@ ossl_rand_pseudo_bytes(VALUE self, VALUE len)
164
160
  static VALUE
165
161
  ossl_rand_egd(VALUE self, VALUE filename)
166
162
  {
167
- rb_check_safe_obj(filename);
168
-
169
163
  if (RAND_egd(StringValueCStr(filename)) == -1) {
170
164
  ossl_raise(eRandomError, NULL);
171
165
  }
@@ -186,8 +180,6 @@ ossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len)
186
180
  {
187
181
  int n = NUM2INT(len);
188
182
 
189
- rb_check_safe_obj(filename);
190
-
191
183
  if (RAND_egd_bytes(StringValueCStr(filename), n) == -1) {
192
184
  ossl_raise(eRandomError, NULL);
193
185
  }
@@ -13,6 +13,12 @@
13
13
 
14
14
  #define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
15
15
 
16
+ #if !defined(TLS1_3_VERSION) && \
17
+ defined(LIBRESSL_VERSION_NUMBER) && \
18
+ LIBRESSL_VERSION_NUMBER >= 0x3020000fL
19
+ # define TLS1_3_VERSION 0x0304
20
+ #endif
21
+
16
22
  #ifdef _WIN32
17
23
  # define TO_SOCKET(s) _get_osfhandle(s)
18
24
  #else
@@ -33,7 +39,7 @@ static VALUE eSSLErrorWaitReadable;
33
39
  static VALUE eSSLErrorWaitWritable;
34
40
 
35
41
  static ID id_call, ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback,
36
- id_npn_protocols_encoded;
42
+ id_npn_protocols_encoded, id_each;
37
43
  static VALUE sym_exception, sym_wait_readable, sym_wait_writable;
38
44
 
39
45
  static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
@@ -53,6 +59,13 @@ static int ossl_sslctx_ex_ptr_idx;
53
59
  static int ossl_sslctx_ex_store_p;
54
60
  #endif
55
61
 
62
+ static void
63
+ ossl_sslctx_mark(void *ptr)
64
+ {
65
+ SSL_CTX *ctx = ptr;
66
+ rb_gc_mark((VALUE)SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_ptr_idx));
67
+ }
68
+
56
69
  static void
57
70
  ossl_sslctx_free(void *ptr)
58
71
  {
@@ -67,7 +80,7 @@ ossl_sslctx_free(void *ptr)
67
80
  static const rb_data_type_t ossl_sslctx_type = {
68
81
  "OpenSSL/SSL/CTX",
69
82
  {
70
- 0, ossl_sslctx_free,
83
+ ossl_sslctx_mark, ossl_sslctx_free,
71
84
  },
72
85
  0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
73
86
  };
@@ -184,8 +197,10 @@ ossl_sslctx_set_minmax_proto_version(VALUE self, VALUE min_v, VALUE max_v)
184
197
 
185
198
  for (i = 0; i < numberof(options_map); i++) {
186
199
  sum |= options_map[i].opts;
187
- if (min && min > options_map[i].ver || max && max < options_map[i].ver)
200
+ if ((min && min > options_map[i].ver) ||
201
+ (max && max < options_map[i].ver)) {
188
202
  opts |= options_map[i].opts;
203
+ }
189
204
  }
190
205
  SSL_CTX_clear_options(ctx, sum);
191
206
  SSL_CTX_set_options(ctx, opts);
@@ -357,7 +372,14 @@ ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
357
372
  rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status));
358
373
  return 0;
359
374
  }
360
- preverify_ok = ret == Qtrue;
375
+ if (ret != Qtrue) {
376
+ preverify_ok = 0;
377
+ #if defined(X509_V_ERR_HOSTNAME_MISMATCH)
378
+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH);
379
+ #else
380
+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
381
+ #endif
382
+ }
361
383
  }
362
384
 
363
385
  return ossl_verify_cb_call(cb, preverify_ok, ctx);
@@ -378,7 +400,7 @@ ossl_call_session_get_cb(VALUE ary)
378
400
  }
379
401
 
380
402
  static SSL_SESSION *
381
- #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
403
+ #if (!defined(LIBRESSL_VERSION_NUMBER) ? OPENSSL_VERSION_NUMBER >= 0x10100000 : LIBRESSL_VERSION_NUMBER >= 0x2080000f)
382
404
  ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy)
383
405
  #else
384
406
  ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy)
@@ -590,7 +612,7 @@ ssl_renegotiation_cb(const SSL *ssl)
590
612
  #if !defined(OPENSSL_NO_NEXTPROTONEG) || \
591
613
  defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
592
614
  static VALUE
593
- ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded)
615
+ ssl_npn_encode_protocol_i(RB_BLOCK_CALL_FUNC_ARGLIST(cur, encoded))
594
616
  {
595
617
  int len = RSTRING_LENINT(cur);
596
618
  char len_byte;
@@ -607,7 +629,7 @@ static VALUE
607
629
  ssl_encode_npn_protocols(VALUE protocols)
608
630
  {
609
631
  VALUE encoded = rb_str_new(NULL, 0);
610
- rb_iterate(rb_each, protocols, ssl_npn_encode_protocol_i, encoded);
632
+ rb_block_call(protocols, id_each, 0, 0, ssl_npn_encode_protocol_i, encoded);
611
633
  return encoded;
612
634
  }
613
635
 
@@ -677,7 +699,7 @@ static int
677
699
  ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen,
678
700
  void *arg)
679
701
  {
680
- VALUE protocols = (VALUE)arg;
702
+ VALUE protocols = rb_attr_get((VALUE)arg, id_npn_protocols_encoded);
681
703
 
682
704
  *out = (const unsigned char *) RSTRING_PTR(protocols);
683
705
  *outlen = RSTRING_LENINT(protocols);
@@ -895,7 +917,7 @@ ossl_sslctx_setup(VALUE self)
895
917
  if (!NIL_P(val)) {
896
918
  VALUE encoded = ssl_encode_npn_protocols(val);
897
919
  rb_ivar_set(self, id_npn_protocols_encoded, encoded);
898
- SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)encoded);
920
+ SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self);
899
921
  OSSL_Debug("SSL NPN advertise callback added");
900
922
  }
901
923
  if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) {
@@ -1513,6 +1535,14 @@ ssl_started(SSL *ssl)
1513
1535
  return SSL_get_fd(ssl) >= 0;
1514
1536
  }
1515
1537
 
1538
+ static void
1539
+ ossl_ssl_mark(void *ptr)
1540
+ {
1541
+ SSL *ssl = ptr;
1542
+ rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx));
1543
+ rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx));
1544
+ }
1545
+
1516
1546
  static void
1517
1547
  ossl_ssl_free(void *ssl)
1518
1548
  {
@@ -1522,7 +1552,7 @@ ossl_ssl_free(void *ssl)
1522
1552
  const rb_data_type_t ossl_ssl_type = {
1523
1553
  "OpenSSL/SSL",
1524
1554
  {
1525
- 0, ossl_ssl_free,
1555
+ ossl_ssl_mark, ossl_ssl_free,
1526
1556
  },
1527
1557
  0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
1528
1558
  };
@@ -1678,6 +1708,11 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts)
1678
1708
  rb_io_wait_readable(fptr->fd);
1679
1709
  continue;
1680
1710
  case SSL_ERROR_SYSCALL:
1711
+ #ifdef __APPLE__
1712
+ /* See ossl_ssl_write_internal() */
1713
+ if (errno == EPROTOTYPE)
1714
+ continue;
1715
+ #endif
1681
1716
  if (errno) rb_sys_fail(funcname);
1682
1717
  ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl));
1683
1718
  #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
@@ -1826,7 +1861,6 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1826
1861
  else
1827
1862
  rb_str_modify_expand(str, ilen - RSTRING_LEN(str));
1828
1863
  }
1829
- OBJ_TAINT(str);
1830
1864
  rb_str_set_len(str, 0);
1831
1865
  if (ilen == 0)
1832
1866
  return str;
@@ -1835,26 +1869,36 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1835
1869
  io = rb_attr_get(self, id_i_io);
1836
1870
  GetOpenFile(io, fptr);
1837
1871
  if (ssl_started(ssl)) {
1838
- for (;;){
1872
+ rb_str_locktmp(str);
1873
+ for (;;) {
1839
1874
  nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
1840
1875
  switch(ssl_get_error(ssl, nread)){
1841
1876
  case SSL_ERROR_NONE:
1877
+ rb_str_unlocktmp(str);
1842
1878
  goto end;
1843
1879
  case SSL_ERROR_ZERO_RETURN:
1880
+ rb_str_unlocktmp(str);
1844
1881
  if (no_exception_p(opts)) { return Qnil; }
1845
1882
  rb_eof_error();
1846
1883
  case SSL_ERROR_WANT_WRITE:
1847
- if (no_exception_p(opts)) { return sym_wait_writable; }
1848
- write_would_block(nonblock);
1884
+ if (nonblock) {
1885
+ rb_str_unlocktmp(str);
1886
+ if (no_exception_p(opts)) { return sym_wait_writable; }
1887
+ write_would_block(nonblock);
1888
+ }
1849
1889
  rb_io_wait_writable(fptr->fd);
1850
1890
  continue;
1851
1891
  case SSL_ERROR_WANT_READ:
1852
- if (no_exception_p(opts)) { return sym_wait_readable; }
1853
- read_would_block(nonblock);
1892
+ if (nonblock) {
1893
+ rb_str_unlocktmp(str);
1894
+ if (no_exception_p(opts)) { return sym_wait_readable; }
1895
+ read_would_block(nonblock);
1896
+ }
1854
1897
  rb_io_wait_readable(fptr->fd);
1855
1898
  continue;
1856
1899
  case SSL_ERROR_SYSCALL:
1857
1900
  if (!ERR_peek_error()) {
1901
+ rb_str_unlocktmp(str);
1858
1902
  if (errno)
1859
1903
  rb_sys_fail(0);
1860
1904
  else {
@@ -1869,19 +1913,32 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1869
1913
  rb_eof_error();
1870
1914
  }
1871
1915
  }
1916
+ /* fall through */
1872
1917
  default:
1918
+ rb_str_unlocktmp(str);
1873
1919
  ossl_raise(eSSLError, "SSL_read");
1874
1920
  }
1875
1921
  }
1876
1922
  }
1877
1923
  else {
1878
- ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
1879
-
1880
- rb_warning("SSL session is not started yet.");
1881
- if (nonblock)
1882
- return rb_funcall(io, meth, 3, len, str, opts);
1883
- else
1884
- return rb_funcall(io, meth, 2, len, str);
1924
+ ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread");
1925
+
1926
+ rb_warning("SSL session is not started yet.");
1927
+ #if defined(RB_PASS_KEYWORDS)
1928
+ if (nonblock) {
1929
+ VALUE argv[3];
1930
+ argv[0] = len;
1931
+ argv[1] = str;
1932
+ argv[2] = opts;
1933
+ return rb_funcallv_kw(io, meth, 3, argv, RB_PASS_KEYWORDS);
1934
+ }
1935
+ #else
1936
+ if (nonblock) {
1937
+ return rb_funcall(io, meth, 3, len, str, opts);
1938
+ }
1939
+ #endif
1940
+ else
1941
+ return rb_funcall(io, meth, 2, len, str);
1885
1942
  }
1886
1943
 
1887
1944
  end:
@@ -1929,21 +1986,21 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
1929
1986
  int nwrite = 0;
1930
1987
  rb_io_t *fptr;
1931
1988
  int nonblock = opts != Qfalse;
1932
- VALUE io;
1989
+ VALUE tmp, io;
1933
1990
 
1934
- StringValue(str);
1991
+ tmp = rb_str_new_frozen(StringValue(str));
1935
1992
  GetSSL(self, ssl);
1936
1993
  io = rb_attr_get(self, id_i_io);
1937
1994
  GetOpenFile(io, fptr);
1938
1995
  if (ssl_started(ssl)) {
1939
- for (;;){
1940
- int num = RSTRING_LENINT(str);
1996
+ for (;;) {
1997
+ int num = RSTRING_LENINT(tmp);
1941
1998
 
1942
1999
  /* SSL_write(3ssl) manpage states num == 0 is undefined */
1943
2000
  if (num == 0)
1944
2001
  goto end;
1945
2002
 
1946
- nwrite = SSL_write(ssl, RSTRING_PTR(str), num);
2003
+ nwrite = SSL_write(ssl, RSTRING_PTR(tmp), num);
1947
2004
  switch(ssl_get_error(ssl, nwrite)){
1948
2005
  case SSL_ERROR_NONE:
1949
2006
  goto end;
@@ -1958,6 +2015,16 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
1958
2015
  rb_io_wait_readable(fptr->fd);
1959
2016
  continue;
1960
2017
  case SSL_ERROR_SYSCALL:
2018
+ #ifdef __APPLE__
2019
+ /*
2020
+ * It appears that send syscall can return EPROTOTYPE if the
2021
+ * socket is being torn down. Retry to get a proper errno to
2022
+ * make the error handling in line with the socket library.
2023
+ * [Bug #14713] https://bugs.ruby-lang.org/issues/14713
2024
+ */
2025
+ if (errno == EPROTOTYPE)
2026
+ continue;
2027
+ #endif
1961
2028
  if (errno) rb_sys_fail(0);
1962
2029
  default:
1963
2030
  ossl_raise(eSSLError, "SSL_write");
@@ -1968,11 +2035,21 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
1968
2035
  ID meth = nonblock ?
1969
2036
  rb_intern("write_nonblock") : rb_intern("syswrite");
1970
2037
 
1971
- rb_warning("SSL session is not started yet.");
1972
- if (nonblock)
1973
- return rb_funcall(io, meth, 2, str, opts);
1974
- else
1975
- return rb_funcall(io, meth, 1, str);
2038
+ rb_warning("SSL session is not started yet.");
2039
+ #if defined(RB_PASS_KEYWORDS)
2040
+ if (nonblock) {
2041
+ VALUE argv[2];
2042
+ argv[0] = str;
2043
+ argv[1] = opts;
2044
+ return rb_funcallv_kw(io, meth, 2, argv, RB_PASS_KEYWORDS);
2045
+ }
2046
+ #else
2047
+ if (nonblock) {
2048
+ return rb_funcall(io, meth, 2, str, opts);
2049
+ }
2050
+ #endif
2051
+ else
2052
+ return rb_funcall(io, meth, 1, str);
1976
2053
  }
1977
2054
 
1978
2055
  end:
@@ -2915,6 +2992,7 @@ Init_ossl_ssl(void)
2915
2992
  id_tmp_dh_callback = rb_intern("tmp_dh_callback");
2916
2993
  id_tmp_ecdh_callback = rb_intern("tmp_ecdh_callback");
2917
2994
  id_npn_protocols_encoded = rb_intern("npn_protocols_encoded");
2995
+ id_each = rb_intern_const("each");
2918
2996
 
2919
2997
  #define DefIVarID(name) do \
2920
2998
  id_i_##name = rb_intern("@"#name); while (0)
@@ -10,6 +10,6 @@
10
10
  #if !defined(_OSSL_VERSION_H_)
11
11
  #define _OSSL_VERSION_H_
12
12
 
13
- #define OSSL_VERSION "2.1.2"
13
+ #define OSSL_VERSION "2.1.3"
14
14
 
15
15
  #endif /* _OSSL_VERSION_H_ */
@@ -44,7 +44,13 @@ Init_ossl_x509(void)
44
44
  Init_ossl_x509revoked();
45
45
  Init_ossl_x509store();
46
46
 
47
+ /* Constants are up-to-date with 1.1.1. */
48
+
49
+ /* Certificate verification error code */
47
50
  DefX509Const(V_OK);
51
+ #if defined(X509_V_ERR_UNSPECIFIED) /* 1.0.1r, 1.0.2f, 1.1.0 */
52
+ DefX509Const(V_ERR_UNSPECIFIED);
53
+ #endif
48
54
  DefX509Const(V_ERR_UNABLE_TO_GET_ISSUER_CERT);
49
55
  DefX509Const(V_ERR_UNABLE_TO_GET_CRL);
50
56
  DefX509Const(V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE);
@@ -76,8 +82,73 @@ Init_ossl_x509(void)
76
82
  DefX509Const(V_ERR_AKID_SKID_MISMATCH);
77
83
  DefX509Const(V_ERR_AKID_ISSUER_SERIAL_MISMATCH);
78
84
  DefX509Const(V_ERR_KEYUSAGE_NO_CERTSIGN);
85
+ DefX509Const(V_ERR_UNABLE_TO_GET_CRL_ISSUER);
86
+ DefX509Const(V_ERR_UNHANDLED_CRITICAL_EXTENSION);
87
+ DefX509Const(V_ERR_KEYUSAGE_NO_CRL_SIGN);
88
+ DefX509Const(V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION);
89
+ DefX509Const(V_ERR_INVALID_NON_CA);
90
+ DefX509Const(V_ERR_PROXY_PATH_LENGTH_EXCEEDED);
91
+ DefX509Const(V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE);
92
+ DefX509Const(V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED);
93
+ DefX509Const(V_ERR_INVALID_EXTENSION);
94
+ DefX509Const(V_ERR_INVALID_POLICY_EXTENSION);
95
+ DefX509Const(V_ERR_NO_EXPLICIT_POLICY);
96
+ DefX509Const(V_ERR_DIFFERENT_CRL_SCOPE);
97
+ DefX509Const(V_ERR_UNSUPPORTED_EXTENSION_FEATURE);
98
+ DefX509Const(V_ERR_UNNESTED_RESOURCE);
99
+ DefX509Const(V_ERR_PERMITTED_VIOLATION);
100
+ DefX509Const(V_ERR_EXCLUDED_VIOLATION);
101
+ DefX509Const(V_ERR_SUBTREE_MINMAX);
79
102
  DefX509Const(V_ERR_APPLICATION_VERIFICATION);
103
+ DefX509Const(V_ERR_UNSUPPORTED_CONSTRAINT_TYPE);
104
+ DefX509Const(V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX);
105
+ DefX509Const(V_ERR_UNSUPPORTED_NAME_SYNTAX);
106
+ DefX509Const(V_ERR_CRL_PATH_VALIDATION_ERROR);
107
+ #if defined(X509_V_ERR_PATH_LOOP)
108
+ DefX509Const(V_ERR_PATH_LOOP);
109
+ #endif
110
+ #if defined(X509_V_ERR_SUITE_B_INVALID_VERSION)
111
+ DefX509Const(V_ERR_SUITE_B_INVALID_VERSION);
112
+ DefX509Const(V_ERR_SUITE_B_INVALID_ALGORITHM);
113
+ DefX509Const(V_ERR_SUITE_B_INVALID_CURVE);
114
+ DefX509Const(V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM);
115
+ DefX509Const(V_ERR_SUITE_B_LOS_NOT_ALLOWED);
116
+ DefX509Const(V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256);
117
+ #endif
118
+ #if defined(X509_V_ERR_HOSTNAME_MISMATCH)
119
+ DefX509Const(V_ERR_HOSTNAME_MISMATCH);
120
+ DefX509Const(V_ERR_EMAIL_MISMATCH);
121
+ DefX509Const(V_ERR_IP_ADDRESS_MISMATCH);
122
+ #endif
123
+ #if defined(X509_V_ERR_DANE_NO_MATCH)
124
+ DefX509Const(V_ERR_DANE_NO_MATCH);
125
+ #endif
126
+ #if defined(X509_V_ERR_EE_KEY_TOO_SMALL)
127
+ DefX509Const(V_ERR_EE_KEY_TOO_SMALL);
128
+ DefX509Const(V_ERR_CA_KEY_TOO_SMALL);
129
+ DefX509Const(V_ERR_CA_MD_TOO_WEAK);
130
+ #endif
131
+ #if defined(X509_V_ERR_INVALID_CALL)
132
+ DefX509Const(V_ERR_INVALID_CALL);
133
+ #endif
134
+ #if defined(X509_V_ERR_STORE_LOOKUP)
135
+ DefX509Const(V_ERR_STORE_LOOKUP);
136
+ #endif
137
+ #if defined(X509_V_ERR_NO_VALID_SCTS)
138
+ DefX509Const(V_ERR_NO_VALID_SCTS);
139
+ #endif
140
+ #if defined(X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION)
141
+ DefX509Const(V_ERR_PROXY_SUBJECT_NAME_VIOLATION);
142
+ #endif
143
+ #if defined(X509_V_ERR_OCSP_VERIFY_NEEDED)
144
+ DefX509Const(V_ERR_OCSP_VERIFY_NEEDED);
145
+ DefX509Const(V_ERR_OCSP_VERIFY_FAILED);
146
+ DefX509Const(V_ERR_OCSP_CERT_UNKNOWN);
147
+ #endif
80
148
 
149
+ /* Certificate verify flags */
150
+ /* Set by Store#flags= and StoreContext#flags=. */
151
+ DefX509Const(V_FLAG_USE_CHECK_TIME);
81
152
  /* Set by Store#flags= and StoreContext#flags=. Enables CRL checking for the
82
153
  * certificate chain leaf. */
83
154
  DefX509Const(V_FLAG_CRL_CHECK);
@@ -122,6 +193,26 @@ Init_ossl_x509(void)
122
193
  * Enabled by default in OpenSSL >= 1.1.0. */
123
194
  DefX509Const(V_FLAG_TRUSTED_FIRST);
124
195
  #endif
196
+ #if defined(X509_V_FLAG_SUITEB_128_LOS_ONLY)
197
+ /* Set by Store#flags= and StoreContext#flags=.
198
+ * Enables Suite B 128 bit only mode. */
199
+ DefX509Const(V_FLAG_SUITEB_128_LOS_ONLY);
200
+ #endif
201
+ #if defined(X509_V_FLAG_SUITEB_192_LOS)
202
+ /* Set by Store#flags= and StoreContext#flags=.
203
+ * Enables Suite B 192 bit only mode. */
204
+ DefX509Const(V_FLAG_SUITEB_192_LOS);
205
+ #endif
206
+ #if defined(X509_V_FLAG_SUITEB_128_LOS)
207
+ /* Set by Store#flags= and StoreContext#flags=.
208
+ * Enables Suite B 128 bit mode allowing 192 bit algorithms. */
209
+ DefX509Const(V_FLAG_SUITEB_128_LOS);
210
+ #endif
211
+ #if defined(X509_V_FLAG_PARTIAL_CHAIN)
212
+ /* Set by Store#flags= and StoreContext#flags=.
213
+ * Allows partial chains if at least one certificate is in trusted store. */
214
+ DefX509Const(V_FLAG_PARTIAL_CHAIN);
215
+ #endif
125
216
  #if defined(X509_V_FLAG_NO_ALT_CHAINS)
126
217
  /* Set by Store#flags= and StoreContext#flags=. Suppresses searching for
127
218
  * a alternative chain. No effect in OpenSSL >= 1.1.0. */
@@ -270,7 +270,7 @@ x509name_print(VALUE self, unsigned long iflag)
270
270
  if (!out)
271
271
  ossl_raise(eX509NameError, NULL);
272
272
  ret = X509_NAME_print_ex(out, name, 0, iflag);
273
- if (ret < 0 || iflag == XN_FLAG_COMPAT && ret == 0) {
273
+ if (ret < 0 || (iflag == XN_FLAG_COMPAT && ret == 0)) {
274
274
  BIO_free(out);
275
275
  ossl_raise(eX509NameError, "X509_NAME_print_ex");
276
276
  }
@@ -105,6 +105,13 @@ VALUE cX509Store;
105
105
  VALUE cX509StoreContext;
106
106
  VALUE eX509StoreError;
107
107
 
108
+ static void
109
+ ossl_x509store_mark(void *ptr)
110
+ {
111
+ X509_STORE *store = ptr;
112
+ rb_gc_mark((VALUE)X509_STORE_get_ex_data(store, store_ex_verify_cb_idx));
113
+ }
114
+
108
115
  static void
109
116
  ossl_x509store_free(void *ptr)
110
117
  {
@@ -114,7 +121,7 @@ ossl_x509store_free(void *ptr)
114
121
  static const rb_data_type_t ossl_x509store_type = {
115
122
  "OpenSSL/X509/STORE",
116
123
  {
117
- 0, ossl_x509store_free,
124
+ ossl_x509store_mark, ossl_x509store_free,
118
125
  },
119
126
  0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
120
127
  };
@@ -304,7 +311,6 @@ ossl_x509store_add_file(VALUE self, VALUE file)
304
311
  char *path = NULL;
305
312
 
306
313
  if(file != Qnil){
307
- rb_check_safe_obj(file);
308
314
  path = StringValueCStr(file);
309
315
  }
310
316
  GetX509Store(self, store);
@@ -340,7 +346,6 @@ ossl_x509store_add_path(VALUE self, VALUE dir)
340
346
  char *path = NULL;
341
347
 
342
348
  if(dir != Qnil){
343
- rb_check_safe_obj(dir);
344
349
  path = StringValueCStr(dir);
345
350
  }
346
351
  GetX509Store(self, store);
@@ -458,23 +463,16 @@ ossl_x509store_verify(int argc, VALUE *argv, VALUE self)
458
463
  return result;
459
464
  }
460
465
 
461
- /*
462
- * Public Functions
463
- */
464
- static void ossl_x509stctx_free(void*);
465
-
466
-
467
- static const rb_data_type_t ossl_x509stctx_type = {
468
- "OpenSSL/X509/STORE_CTX",
469
- {
470
- 0, ossl_x509stctx_free,
471
- },
472
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
473
- };
474
-
475
466
  /*
476
467
  * Private functions
477
468
  */
469
+ static void
470
+ ossl_x509stctx_mark(void *ptr)
471
+ {
472
+ X509_STORE_CTX *ctx = ptr;
473
+ rb_gc_mark((VALUE)X509_STORE_CTX_get_ex_data(ctx, stctx_ex_verify_cb_idx));
474
+ }
475
+
478
476
  static void
479
477
  ossl_x509stctx_free(void *ptr)
480
478
  {
@@ -486,6 +484,14 @@ ossl_x509stctx_free(void *ptr)
486
484
  X509_STORE_CTX_free(ctx);
487
485
  }
488
486
 
487
+ static const rb_data_type_t ossl_x509stctx_type = {
488
+ "OpenSSL/X509/STORE_CTX",
489
+ {
490
+ ossl_x509stctx_mark, ossl_x509stctx_free,
491
+ },
492
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
493
+ };
494
+
489
495
  static VALUE
490
496
  ossl_x509stctx_alloc(VALUE klass)
491
497
  {
@@ -519,7 +525,9 @@ static VALUE ossl_x509stctx_set_time(VALUE, VALUE);
519
525
 
520
526
  /*
521
527
  * call-seq:
522
- * StoreContext.new(store, cert = nil, chain = nil)
528
+ * StoreContext.new(store, cert = nil, untrusted = nil)
529
+ *
530
+ * Sets up a StoreContext for a verification of the X.509 certificate _cert_.
523
531
  */
524
532
  static VALUE
525
533
  ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
@@ -529,15 +537,24 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
529
537
  X509_STORE *x509st;
530
538
  X509 *x509 = NULL;
531
539
  STACK_OF(X509) *x509s = NULL;
540
+ int state;
532
541
 
533
542
  rb_scan_args(argc, argv, "12", &store, &cert, &chain);
534
543
  GetX509StCtx(self, ctx);
535
544
  GetX509Store(store, x509st);
536
- if(!NIL_P(cert)) x509 = DupX509CertPtr(cert); /* NEED TO DUP */
537
- if(!NIL_P(chain)) x509s = ossl_x509_ary2sk(chain);
538
- if(X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){
545
+ if (!NIL_P(cert))
546
+ x509 = DupX509CertPtr(cert); /* NEED TO DUP */
547
+ if (!NIL_P(chain)) {
548
+ x509s = ossl_protect_x509_ary2sk(chain, &state);
549
+ if (state) {
550
+ X509_free(x509);
551
+ rb_jump_tag(state);
552
+ }
553
+ }
554
+ if (X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){
555
+ X509_free(x509);
539
556
  sk_X509_pop_free(x509s, X509_free);
540
- ossl_raise(eX509StoreError, NULL);
557
+ ossl_raise(eX509StoreError, "X509_STORE_CTX_init");
541
558
  }
542
559
  if (!NIL_P(t = rb_iv_get(store, "@time")))
543
560
  ossl_x509stctx_set_time(self, t);
@@ -316,20 +316,15 @@ module OpenSSL::Buffering
316
316
  @wbuffer << s
317
317
  @wbuffer.force_encoding(Encoding::BINARY)
318
318
  @sync ||= false
319
- if @sync or @wbuffer.size > BLOCK_SIZE or idx = @wbuffer.rindex($/)
320
- remain = idx ? idx + $/.size : @wbuffer.length
321
- nwritten = 0
322
- while remain > 0
323
- str = @wbuffer[nwritten,remain]
319
+ if @sync or @wbuffer.size > BLOCK_SIZE
320
+ until @wbuffer.empty?
324
321
  begin
325
- nwrote = syswrite(str)
322
+ nwrote = syswrite(@wbuffer)
326
323
  rescue Errno::EAGAIN
327
324
  retry
328
325
  end
329
- remain -= nwrote
330
- nwritten += nwrote
326
+ @wbuffer[0, nwrote] = ""
331
327
  end
332
- @wbuffer[0,nwritten] = ""
333
328
  end
334
329
  end
335
330
 
@@ -409,9 +404,7 @@ module OpenSSL::Buffering
409
404
  end
410
405
  args.each{|arg|
411
406
  s << arg.to_s
412
- if $/ && /\n\z/ !~ s
413
- s << "\n"
414
- end
407
+ s.sub!(/(?<!\n)\z/, "\n")
415
408
  }
416
409
  do_write(s)
417
410
  nil
@@ -77,29 +77,44 @@ module OpenSSL
77
77
  def parse_config_lines(io)
78
78
  section = 'default'
79
79
  data = {section => {}}
80
- while definition = get_definition(io)
80
+ io_stack = [io]
81
+ while definition = get_definition(io_stack)
81
82
  definition = clear_comments(definition)
82
83
  next if definition.empty?
83
- if definition[0] == ?[
84
+ case definition
85
+ when /\A\[/
84
86
  if /\[([^\]]*)\]/ =~ definition
85
87
  section = $1.strip
86
88
  data[section] ||= {}
87
89
  else
88
90
  raise ConfigError, "missing close square bracket"
89
91
  end
90
- else
91
- if /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/ =~ definition
92
- if $2
93
- section = $1
94
- key = $2
95
- else
96
- key = $1
92
+ when /\A\.include (\s*=\s*)?(.+)\z/
93
+ path = $2
94
+ if File.directory?(path)
95
+ files = Dir.glob(File.join(path, "*.{cnf,conf}"), File::FNM_EXTGLOB)
96
+ else
97
+ files = [path]
98
+ end
99
+
100
+ files.each do |filename|
101
+ begin
102
+ io_stack << StringIO.new(File.read(filename))
103
+ rescue
104
+ raise ConfigError, "could not include file '%s'" % filename
97
105
  end
98
- value = unescape_value(data, section, $3)
99
- (data[section] ||= {})[key] = value.strip
106
+ end
107
+ when /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/
108
+ if $2
109
+ section = $1
110
+ key = $2
100
111
  else
101
- raise ConfigError, "missing equal sign"
112
+ key = $1
102
113
  end
114
+ value = unescape_value(data, section, $3)
115
+ (data[section] ||= {})[key] = value.strip
116
+ else
117
+ raise ConfigError, "missing equal sign"
103
118
  end
104
119
  end
105
120
  data
@@ -212,10 +227,10 @@ module OpenSSL
212
227
  scanned.join
213
228
  end
214
229
 
215
- def get_definition(io)
216
- if line = get_line(io)
230
+ def get_definition(io_stack)
231
+ if line = get_line(io_stack)
217
232
  while /[^\\]\\\z/ =~ line
218
- if extra = get_line(io)
233
+ if extra = get_line(io_stack)
219
234
  line += extra
220
235
  else
221
236
  break
@@ -225,9 +240,12 @@ module OpenSSL
225
240
  end
226
241
  end
227
242
 
228
- def get_line(io)
229
- if line = io.gets
230
- line.gsub(/[\r\n]*/, '')
243
+ def get_line(io_stack)
244
+ while io = io_stack.last
245
+ if line = io.gets
246
+ return line.gsub(/[\r\n]*/, '')
247
+ end
248
+ io_stack.pop
231
249
  end
232
250
  end
233
251
  end
data/lib/openssl/ssl.rb CHANGED
@@ -12,6 +12,7 @@
12
12
 
13
13
  require "openssl/buffering"
14
14
  require "io/nonblock"
15
+ require "ipaddr"
15
16
 
16
17
  module OpenSSL
17
18
  module SSL
@@ -272,11 +273,11 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3
272
273
  return true if verify_hostname(hostname, san.value)
273
274
  when 7 # iPAddress in GeneralName (RFC5280)
274
275
  should_verify_common_name = false
275
- # follows GENERAL_NAME_print() in x509v3/v3_alt.c
276
- if san.value.size == 4
277
- return true if san.value.unpack('C*').join('.') == hostname
278
- elsif san.value.size == 16
279
- return true if san.value.unpack('n*').map { |e| sprintf("%X", e) }.join(':') == hostname
276
+ if san.value.size == 4 || san.value.size == 16
277
+ begin
278
+ return true if san.value == IPAddr.new(hostname).hton
279
+ rescue IPAddr::InvalidAddressError
280
+ end
280
281
  end
281
282
  end
282
283
  }
metadata CHANGED
@@ -1,18 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openssl
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 2.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Bosslet
8
8
  - SHIBATA Hiroshi
9
9
  - Zachary Scott
10
10
  - Kazuki Yamaguchi
11
- autorequire:
11
+ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2018-10-18 00:00:00.000000000 Z
14
+ date: 2021-10-16 00:00:00.000000000 Z
15
15
  dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: ipaddr
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
16
30
  - !ruby/object:Gem::Dependency
17
31
  name: rake
18
32
  requirement: !ruby/object:Gem::Requirement
@@ -155,7 +169,7 @@ licenses:
155
169
  - Ruby
156
170
  metadata:
157
171
  msys2_mingw_dependencies: openssl
158
- post_install_message:
172
+ post_install_message:
159
173
  rdoc_options:
160
174
  - "--main"
161
175
  - README.md
@@ -172,9 +186,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
172
186
  - !ruby/object:Gem::Version
173
187
  version: '0'
174
188
  requirements: []
175
- rubyforge_project:
176
- rubygems_version: 2.7.6
177
- signing_key:
189
+ rubygems_version: 3.3.0.dev
190
+ signing_key:
178
191
  specification_version: 4
179
192
  summary: OpenSSL provides SSL, TLS and general purpose cryptography.
180
193
  test_files: []