openssl 3.2.1 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +180 -29
  3. data/History.md +76 -0
  4. data/README.md +11 -7
  5. data/ext/openssl/extconf.rb +7 -9
  6. data/ext/openssl/openssl_missing.c +1 -1
  7. data/ext/openssl/openssl_missing.h +1 -1
  8. data/ext/openssl/ossl.c +7 -9
  9. data/ext/openssl/ossl.h +12 -8
  10. data/ext/openssl/ossl_asn1.c +46 -237
  11. data/ext/openssl/ossl_asn1.h +1 -19
  12. data/ext/openssl/ossl_bio.c +1 -1
  13. data/ext/openssl/ossl_bio.h +1 -1
  14. data/ext/openssl/ossl_bn.c +12 -12
  15. data/ext/openssl/ossl_bn.h +1 -2
  16. data/ext/openssl/ossl_cipher.c +5 -5
  17. data/ext/openssl/ossl_cipher.h +1 -4
  18. data/ext/openssl/ossl_config.c +10 -9
  19. data/ext/openssl/ossl_config.h +1 -1
  20. data/ext/openssl/ossl_digest.c +39 -21
  21. data/ext/openssl/ossl_digest.h +1 -4
  22. data/ext/openssl/ossl_engine.c +3 -3
  23. data/ext/openssl/ossl_engine.h +1 -4
  24. data/ext/openssl/ossl_hmac.c +3 -3
  25. data/ext/openssl/ossl_hmac.h +1 -4
  26. data/ext/openssl/ossl_kdf.c +5 -5
  27. data/ext/openssl/ossl_ns_spki.c +8 -8
  28. data/ext/openssl/ossl_ns_spki.h +1 -5
  29. data/ext/openssl/ossl_ocsp.c +8 -8
  30. data/ext/openssl/ossl_ocsp.h +1 -8
  31. data/ext/openssl/ossl_pkcs12.c +54 -3
  32. data/ext/openssl/ossl_pkcs12.h +1 -4
  33. data/ext/openssl/ossl_pkcs7.c +68 -21
  34. data/ext/openssl/ossl_pkcs7.h +2 -22
  35. data/ext/openssl/ossl_pkey.c +1 -1
  36. data/ext/openssl/ossl_pkey.h +3 -14
  37. data/ext/openssl/ossl_pkey_dh.c +2 -2
  38. data/ext/openssl/ossl_pkey_dsa.c +2 -2
  39. data/ext/openssl/ossl_pkey_ec.c +6 -6
  40. data/ext/openssl/ossl_pkey_rsa.c +2 -2
  41. data/ext/openssl/ossl_provider.c +1 -1
  42. data/ext/openssl/ossl_rand.c +3 -3
  43. data/ext/openssl/ossl_rand.h +1 -4
  44. data/ext/openssl/ossl_ssl.c +71 -52
  45. data/ext/openssl/ossl_ssl.h +1 -1
  46. data/ext/openssl/ossl_ts.c +73 -15
  47. data/ext/openssl/ossl_ts.h +1 -1
  48. data/ext/openssl/ossl_x509.c +1 -1
  49. data/ext/openssl/ossl_x509.h +1 -20
  50. data/ext/openssl/ossl_x509attr.c +25 -26
  51. data/ext/openssl/ossl_x509cert.c +42 -3
  52. data/ext/openssl/ossl_x509crl.c +8 -4
  53. data/ext/openssl/ossl_x509ext.c +3 -3
  54. data/ext/openssl/ossl_x509name.c +3 -3
  55. data/ext/openssl/ossl_x509req.c +8 -4
  56. data/ext/openssl/ossl_x509revoked.c +2 -2
  57. data/ext/openssl/ossl_x509store.c +16 -11
  58. data/lib/openssl/asn1.rb +188 -0
  59. data/lib/openssl/bn.rb +1 -1
  60. data/lib/openssl/buffering.rb +13 -3
  61. data/lib/openssl/cipher.rb +1 -1
  62. data/lib/openssl/digest.rb +1 -1
  63. data/lib/openssl/marshal.rb +1 -1
  64. data/lib/openssl/ssl.rb +67 -4
  65. data/lib/openssl/version.rb +1 -1
  66. data/lib/openssl/x509.rb +1 -1
  67. data/lib/openssl.rb +2 -1
  68. metadata +5 -3
  69. /data/{LICENSE.txt → COPYING} +0 -0
@@ -5,10 +5,25 @@
5
5
  */
6
6
  /*
7
7
  * This program is licensed under the same licence as Ruby.
8
- * (See the file 'LICENCE'.)
8
+ * (See the file 'COPYING'.)
9
9
  */
10
10
  #include "ossl.h"
11
11
 
12
+ #define NewPKCS7(klass) \
13
+ TypedData_Wrap_Struct((klass), &ossl_pkcs7_type, 0)
14
+ #define SetPKCS7(obj, pkcs7) do { \
15
+ if (!(pkcs7)) { \
16
+ ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
17
+ } \
18
+ RTYPEDDATA_DATA(obj) = (pkcs7); \
19
+ } while (0)
20
+ #define GetPKCS7(obj, pkcs7) do { \
21
+ TypedData_Get_Struct((obj), PKCS7, &ossl_pkcs7_type, (pkcs7)); \
22
+ if (!(pkcs7)) { \
23
+ ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
24
+ } \
25
+ } while (0)
26
+
12
27
  #define NewPKCS7si(klass) \
13
28
  TypedData_Wrap_Struct((klass), &ossl_pkcs7_signer_info_type, 0)
14
29
  #define SetPKCS7si(obj, p7si) do { \
@@ -49,10 +64,10 @@
49
64
  /*
50
65
  * Classes
51
66
  */
52
- VALUE cPKCS7;
53
- VALUE cPKCS7Signer;
54
- VALUE cPKCS7Recipient;
55
- VALUE ePKCS7Error;
67
+ static VALUE cPKCS7;
68
+ static VALUE cPKCS7Signer;
69
+ static VALUE cPKCS7Recipient;
70
+ static VALUE ePKCS7Error;
56
71
 
57
72
  static void
58
73
  ossl_pkcs7_free(void *ptr)
@@ -60,7 +75,7 @@ ossl_pkcs7_free(void *ptr)
60
75
  PKCS7_free(ptr);
61
76
  }
62
77
 
63
- const rb_data_type_t ossl_pkcs7_type = {
78
+ static const rb_data_type_t ossl_pkcs7_type = {
64
79
  "OpenSSL/PKCS7",
65
80
  {
66
81
  0, ossl_pkcs7_free,
@@ -68,6 +83,20 @@ const rb_data_type_t ossl_pkcs7_type = {
68
83
  0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
69
84
  };
70
85
 
86
+ VALUE
87
+ ossl_pkcs7_new(PKCS7 *p7)
88
+ {
89
+ PKCS7 *new;
90
+ VALUE obj = NewPKCS7(cPKCS7);
91
+
92
+ new = PKCS7_dup(p7);
93
+ if (!new)
94
+ ossl_raise(ePKCS7Error, "PKCS7_dup");
95
+ SetPKCS7(obj, new);
96
+
97
+ return obj;
98
+ }
99
+
71
100
  static void
72
101
  ossl_pkcs7_signer_info_free(void *ptr)
73
102
  {
@@ -261,7 +290,14 @@ ossl_pkcs7_s_sign(int argc, VALUE *argv, VALUE klass)
261
290
 
262
291
  /*
263
292
  * call-seq:
264
- * PKCS7.encrypt(certs, data, [, cipher [, flags]]) => pkcs7
293
+ * PKCS7.encrypt(certs, data, cipher, flags = 0) => pkcs7
294
+ *
295
+ * Creates a PKCS #7 enveloped-data structure.
296
+ *
297
+ * Before version 3.3.0, +cipher+ was optional and defaulted to
298
+ * <tt>"RC2-40-CBC"</tt>.
299
+ *
300
+ * See also the man page PKCS7_encrypt(3).
265
301
  */
266
302
  static VALUE
267
303
  ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass)
@@ -275,21 +311,12 @@ ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass)
275
311
  PKCS7 *p7;
276
312
 
277
313
  rb_scan_args(argc, argv, "22", &certs, &data, &cipher, &flags);
278
- if(NIL_P(cipher)){
279
- #if !defined(OPENSSL_NO_RC2)
280
- ciph = EVP_rc2_40_cbc();
281
- #elif !defined(OPENSSL_NO_DES)
282
- ciph = EVP_des_ede3_cbc();
283
- #elif !defined(OPENSSL_NO_RC2)
284
- ciph = EVP_rc2_40_cbc();
285
- #elif !defined(OPENSSL_NO_AES)
286
- ciph = EVP_EVP_aes_128_cbc();
287
- #else
288
- ossl_raise(ePKCS7Error, "Must specify cipher");
289
- #endif
290
-
314
+ if (NIL_P(cipher)) {
315
+ rb_raise(rb_eArgError,
316
+ "cipher must be specified. Before version 3.3, " \
317
+ "the default cipher was RC2-40-CBC.");
291
318
  }
292
- else ciph = ossl_evp_get_cipherbyname(cipher);
319
+ ciph = ossl_evp_get_cipherbyname(cipher);
293
320
  flg = NIL_P(flags) ? 0 : NUM2INT(flags);
294
321
  ret = NewPKCS7(cPKCS7);
295
322
  in = ossl_obj2bio(&data);
@@ -851,6 +878,25 @@ ossl_pkcs7_to_der(VALUE self)
851
878
  return str;
852
879
  }
853
880
 
881
+ static VALUE
882
+ ossl_pkcs7_to_text(VALUE self)
883
+ {
884
+ PKCS7 *pkcs7;
885
+ BIO *out;
886
+ VALUE str;
887
+
888
+ GetPKCS7(self, pkcs7);
889
+ if(!(out = BIO_new(BIO_s_mem())))
890
+ ossl_raise(ePKCS7Error, NULL);
891
+ if(!PKCS7_print_ctx(out, pkcs7, 0, NULL)) {
892
+ BIO_free(out);
893
+ ossl_raise(ePKCS7Error, NULL);
894
+ }
895
+ str = ossl_membio2str(out);
896
+
897
+ return str;
898
+ }
899
+
854
900
  static VALUE
855
901
  ossl_pkcs7_to_pem(VALUE self)
856
902
  {
@@ -1060,6 +1106,7 @@ Init_ossl_pkcs7(void)
1060
1106
  rb_define_method(cPKCS7, "to_pem", ossl_pkcs7_to_pem, 0);
1061
1107
  rb_define_alias(cPKCS7, "to_s", "to_pem");
1062
1108
  rb_define_method(cPKCS7, "to_der", ossl_pkcs7_to_der, 0);
1109
+ rb_define_method(cPKCS7, "to_text", ossl_pkcs7_to_text, 0);
1063
1110
 
1064
1111
  cPKCS7Signer = rb_define_class_under(cPKCS7, "SignerInfo", rb_cObject);
1065
1112
  rb_define_const(cPKCS7, "Signer", cPKCS7Signer);
@@ -5,32 +5,12 @@
5
5
  */
6
6
  /*
7
7
  * This program is licensed under the same licence as Ruby.
8
- * (See the file 'LICENCE'.)
8
+ * (See the file 'COPYING'.)
9
9
  */
10
10
  #if !defined(_OSSL_PKCS7_H_)
11
11
  #define _OSSL_PKCS7_H_
12
12
 
13
- #define NewPKCS7(klass) \
14
- TypedData_Wrap_Struct((klass), &ossl_pkcs7_type, 0)
15
- #define SetPKCS7(obj, pkcs7) do { \
16
- if (!(pkcs7)) { \
17
- ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
18
- } \
19
- RTYPEDDATA_DATA(obj) = (pkcs7); \
20
- } while (0)
21
- #define GetPKCS7(obj, pkcs7) do { \
22
- TypedData_Get_Struct((obj), PKCS7, &ossl_pkcs7_type, (pkcs7)); \
23
- if (!(pkcs7)) { \
24
- ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
25
- } \
26
- } while (0)
27
-
28
- extern const rb_data_type_t ossl_pkcs7_type;
29
- extern VALUE cPKCS7;
30
- extern VALUE cPKCS7Signer;
31
- extern VALUE cPKCS7Recipient;
32
- extern VALUE ePKCS7Error;
33
-
13
+ VALUE ossl_pkcs7_new(PKCS7 *p7);
34
14
  void Init_ossl_pkcs7(void);
35
15
 
36
16
  #endif /* _OSSL_PKCS7_H_ */
@@ -5,7 +5,7 @@
5
5
  */
6
6
  /*
7
7
  * This program is licensed under the same licence as Ruby.
8
- * (See the file 'LICENCE'.)
8
+ * (See the file 'COPYING'.)
9
9
  */
10
10
  #include "ossl.h"
11
11
 
@@ -5,7 +5,7 @@
5
5
  */
6
6
  /*
7
7
  * This program is licensed under the same licence as Ruby.
8
- * (See the file 'LICENCE'.)
8
+ * (See the file 'COPYING'.)
9
9
  */
10
10
  #if !defined(OSSL_PKEY_H)
11
11
  #define OSSL_PKEY_H
@@ -53,35 +53,24 @@ void Init_ossl_pkey(void);
53
53
  * RSA
54
54
  */
55
55
  extern VALUE cRSA;
56
- extern VALUE eRSAError;
57
-
58
56
  void Init_ossl_rsa(void);
59
57
 
60
58
  /*
61
59
  * DSA
62
60
  */
63
61
  extern VALUE cDSA;
64
- extern VALUE eDSAError;
65
-
66
62
  void Init_ossl_dsa(void);
67
63
 
68
64
  /*
69
65
  * DH
70
66
  */
71
67
  extern VALUE cDH;
72
- extern VALUE eDHError;
73
-
74
68
  void Init_ossl_dh(void);
75
69
 
76
70
  /*
77
71
  * EC
78
72
  */
79
73
  extern VALUE cEC;
80
- extern VALUE eECError;
81
- extern VALUE cEC_GROUP;
82
- extern VALUE eEC_GROUP;
83
- extern VALUE cEC_POINT;
84
- extern VALUE eEC_POINT;
85
74
  VALUE ossl_ec_new(EVP_PKEY *);
86
75
  void Init_ossl_ec(void);
87
76
 
@@ -136,7 +125,7 @@ static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2, VALU
136
125
  BN_clear_free(bn1); \
137
126
  BN_clear_free(bn2); \
138
127
  BN_clear_free(bn3); \
139
- ossl_raise(eBNError, NULL); \
128
+ ossl_raise(ePKeyError, "BN_dup"); \
140
129
  } \
141
130
  \
142
131
  if (!_type##_set0_##_group(obj, bn1, bn2, bn3)) { \
@@ -164,7 +153,7 @@ static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2) \
164
153
  (orig_bn2 && !(bn2 = BN_dup(orig_bn2)))) { \
165
154
  BN_clear_free(bn1); \
166
155
  BN_clear_free(bn2); \
167
- ossl_raise(eBNError, NULL); \
156
+ ossl_raise(ePKeyError, "BN_dup"); \
168
157
  } \
169
158
  \
170
159
  if (!_type##_set0_##_group(obj, bn1, bn2)) { \
@@ -5,7 +5,7 @@
5
5
  */
6
6
  /*
7
7
  * This program is licensed under the same licence as Ruby.
8
- * (See the file 'LICENCE'.)
8
+ * (See the file 'COPYING'.)
9
9
  */
10
10
  #include "ossl.h"
11
11
 
@@ -27,7 +27,7 @@
27
27
  * Classes
28
28
  */
29
29
  VALUE cDH;
30
- VALUE eDHError;
30
+ static VALUE eDHError;
31
31
 
32
32
  /*
33
33
  * Private
@@ -5,7 +5,7 @@
5
5
  */
6
6
  /*
7
7
  * This program is licensed under the same licence as Ruby.
8
- * (See the file 'LICENCE'.)
8
+ * (See the file 'COPYING'.)
9
9
  */
10
10
  #include "ossl.h"
11
11
 
@@ -41,7 +41,7 @@ DSA_PRIVATE(VALUE obj, OSSL_3_const DSA *dsa)
41
41
  * Classes
42
42
  */
43
43
  VALUE cDSA;
44
- VALUE eDSAError;
44
+ static VALUE eDSAError;
45
45
 
46
46
  /*
47
47
  * Private
@@ -41,11 +41,11 @@ static const rb_data_type_t ossl_ec_point_type;
41
41
  } while (0)
42
42
 
43
43
  VALUE cEC;
44
- VALUE eECError;
45
- VALUE cEC_GROUP;
46
- VALUE eEC_GROUP;
47
- VALUE cEC_POINT;
48
- VALUE eEC_POINT;
44
+ static VALUE eECError;
45
+ static VALUE cEC_GROUP;
46
+ static VALUE eEC_GROUP;
47
+ static VALUE cEC_POINT;
48
+ static VALUE eEC_POINT;
49
49
 
50
50
  static ID s_GFp, s_GF2m;
51
51
 
@@ -174,7 +174,7 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
174
174
  type = EVP_PKEY_base_id(pkey);
175
175
  if (type != EVP_PKEY_EC) {
176
176
  EVP_PKEY_free(pkey);
177
- rb_raise(eDSAError, "incorrect pkey type: %s", OBJ_nid2sn(type));
177
+ rb_raise(eECError, "incorrect pkey type: %s", OBJ_nid2sn(type));
178
178
  }
179
179
  RTYPEDDATA_DATA(self) = pkey;
180
180
  return self;
@@ -5,7 +5,7 @@
5
5
  */
6
6
  /*
7
7
  * This program is licensed under the same licence as Ruby.
8
- * (See the file 'LICENCE'.)
8
+ * (See the file 'COPYING'.)
9
9
  */
10
10
  #include "ossl.h"
11
11
 
@@ -42,7 +42,7 @@ RSA_PRIVATE(VALUE obj, OSSL_3_const RSA *rsa)
42
42
  * Classes
43
43
  */
44
44
  VALUE cRSA;
45
- VALUE eRSAError;
45
+ static VALUE eRSAError;
46
46
 
47
47
  /*
48
48
  * Private
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * This program is licensed under the same licence as Ruby.
3
- * (See the file 'LICENCE'.)
3
+ * (See the file 'COPYING'.)
4
4
  */
5
5
  #include "ossl.h"
6
6
 
@@ -5,12 +5,12 @@
5
5
  * All rights reserved.
6
6
  *
7
7
  * This program is licensed under the same licence as Ruby.
8
- * (See the file 'LICENCE'.)
8
+ * (See the file 'COPYING'.)
9
9
  */
10
10
  #include "ossl.h"
11
11
 
12
- VALUE mRandom;
13
- VALUE eRandomError;
12
+ static VALUE mRandom;
13
+ static VALUE eRandomError;
14
14
 
15
15
  /*
16
16
  * call-seq:
@@ -5,14 +5,11 @@
5
5
  */
6
6
  /*
7
7
  * This program is licensed under the same licence as Ruby.
8
- * (See the file 'LICENCE'.)
8
+ * (See the file 'COPYING'.)
9
9
  */
10
10
  #if !defined(_OSSL_RAND_H_)
11
11
  #define _OSSL_RAND_H_
12
12
 
13
- extern VALUE mRandom;
14
- extern VALUE eRandomError;
15
-
16
13
  void Init_ossl_rand(void);
17
14
 
18
15
  #endif /* _OSSL_RAND_H_ */
@@ -7,7 +7,7 @@
7
7
  */
8
8
  /*
9
9
  * This program is licensed under the same licence as Ruby.
10
- * (See the file 'LICENCE'.)
10
+ * (See the file 'COPYING'.)
11
11
  */
12
12
  #include "ossl.h"
13
13
 
@@ -35,7 +35,7 @@
35
35
 
36
36
  VALUE mSSL;
37
37
  static VALUE eSSLError;
38
- VALUE cSSLContext;
38
+ static VALUE cSSLContext;
39
39
  VALUE cSSLSocket;
40
40
 
41
41
  static VALUE eSSLErrorWaitReadable;
@@ -55,7 +55,6 @@ static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
55
55
  id_i_verify_hostname, id_i_keylog_cb;
56
56
  static ID id_i_io, id_i_context, id_i_hostname;
57
57
 
58
- static int ossl_ssl_ex_vcb_idx;
59
58
  static int ossl_ssl_ex_ptr_idx;
60
59
  static int ossl_sslctx_ex_ptr_idx;
61
60
 
@@ -327,9 +326,9 @@ ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
327
326
  int status;
328
327
 
329
328
  ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
330
- cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx);
331
329
  ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
332
330
  sslctx_obj = rb_attr_get(ssl_obj, id_i_context);
331
+ cb = rb_attr_get(sslctx_obj, id_i_verify_callback);
333
332
  verify_hostname = rb_attr_get(sslctx_obj, id_i_verify_hostname);
334
333
 
335
334
  if (preverify_ok && RTEST(verify_hostname) && !SSL_is_server(ssl) &&
@@ -558,52 +557,42 @@ ossl_sslctx_add_extra_chain_cert_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg))
558
557
  static VALUE ossl_sslctx_setup(VALUE self);
559
558
 
560
559
  static VALUE
561
- ossl_call_servername_cb(VALUE ary)
560
+ ossl_call_servername_cb(VALUE arg)
562
561
  {
563
- VALUE ssl_obj, sslctx_obj, cb, ret_obj;
562
+ SSL *ssl = (void *)arg;
563
+ const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
564
+ if (!servername)
565
+ return Qnil;
564
566
 
565
- Check_Type(ary, T_ARRAY);
566
- ssl_obj = rb_ary_entry(ary, 0);
567
+ VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
568
+ VALUE sslctx_obj = rb_attr_get(ssl_obj, id_i_context);
569
+ VALUE cb = rb_attr_get(sslctx_obj, id_i_servername_cb);
570
+ VALUE ary = rb_assoc_new(ssl_obj, rb_str_new_cstr(servername));
567
571
 
568
- sslctx_obj = rb_attr_get(ssl_obj, id_i_context);
569
- cb = rb_attr_get(sslctx_obj, id_i_servername_cb);
570
- if (NIL_P(cb)) return Qnil;
571
-
572
- ret_obj = rb_funcallv(cb, id_call, 1, &ary);
572
+ VALUE ret_obj = rb_funcallv(cb, id_call, 1, &ary);
573
573
  if (rb_obj_is_kind_of(ret_obj, cSSLContext)) {
574
- SSL *ssl;
575
574
  SSL_CTX *ctx2;
576
-
577
575
  ossl_sslctx_setup(ret_obj);
578
- GetSSL(ssl_obj, ssl);
579
576
  GetSSLCTX(ret_obj, ctx2);
580
- SSL_set_SSL_CTX(ssl, ctx2);
577
+ if (!SSL_set_SSL_CTX(ssl, ctx2))
578
+ ossl_raise(eSSLError, "SSL_set_SSL_CTX");
581
579
  rb_ivar_set(ssl_obj, id_i_context, ret_obj);
582
580
  } else if (!NIL_P(ret_obj)) {
583
581
  ossl_raise(rb_eArgError, "servername_cb must return an "
584
582
  "OpenSSL::SSL::SSLContext object or nil");
585
583
  }
586
584
 
587
- return ret_obj;
585
+ return Qnil;
588
586
  }
589
587
 
590
588
  static int
591
589
  ssl_servername_cb(SSL *ssl, int *ad, void *arg)
592
590
  {
593
- VALUE ary, ssl_obj;
594
- int state = 0;
595
- const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
596
-
597
- if (!servername)
598
- return SSL_TLSEXT_ERR_OK;
599
-
600
- ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
601
- ary = rb_ary_new2(2);
602
- rb_ary_push(ary, ssl_obj);
603
- rb_ary_push(ary, rb_str_new2(servername));
591
+ int state;
604
592
 
605
- rb_protect(ossl_call_servername_cb, ary, &state);
593
+ rb_protect(ossl_call_servername_cb, (VALUE)ssl, &state);
606
594
  if (state) {
595
+ VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx);
607
596
  rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state));
608
597
  return SSL_TLSEXT_ERR_ALERT_FATAL;
609
598
  }
@@ -757,7 +746,10 @@ ssl_info_cb(const SSL *ssl, int where, int val)
757
746
  }
758
747
 
759
748
  /*
760
- * Gets various OpenSSL options.
749
+ * call-seq:
750
+ * ctx.options -> integer
751
+ *
752
+ * Gets various \OpenSSL options.
761
753
  */
762
754
  static VALUE
763
755
  ossl_sslctx_get_options(VALUE self)
@@ -772,7 +764,17 @@ ossl_sslctx_get_options(VALUE self)
772
764
  }
773
765
 
774
766
  /*
775
- * Sets various OpenSSL options.
767
+ * call-seq:
768
+ * ctx.options = integer
769
+ *
770
+ * Sets various \OpenSSL options. The options are a bit field and can be
771
+ * combined with the bitwise OR operator (<tt>|</tt>). Available options are
772
+ * defined as constants in OpenSSL::SSL that begin with +OP_+.
773
+ *
774
+ * For backwards compatibility, passing +nil+ has the same effect as passing
775
+ * OpenSSL::SSL::OP_ALL.
776
+ *
777
+ * See also man page SSL_CTX_set_options(3).
776
778
  */
777
779
  static VALUE
778
780
  ossl_sslctx_set_options(VALUE self, VALUE options)
@@ -1553,11 +1555,6 @@ ossl_ssl_mark(void *ptr)
1553
1555
  {
1554
1556
  SSL *ssl = ptr;
1555
1557
  rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx));
1556
-
1557
- // Note: this reference is stored as @verify_callback so we don't need to mark it.
1558
- // However we do need to ensure GC compaction won't move it, hence why
1559
- // we call rb_gc_mark here.
1560
- rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx));
1561
1558
  }
1562
1559
 
1563
1560
  static void
@@ -1622,7 +1619,7 @@ peeraddr_ip_str(VALUE self)
1622
1619
  static VALUE
1623
1620
  ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1624
1621
  {
1625
- VALUE io, v_ctx, verify_cb;
1622
+ VALUE io, v_ctx;
1626
1623
  SSL *ssl;
1627
1624
  SSL_CTX *ctx;
1628
1625
 
@@ -1649,10 +1646,6 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
1649
1646
 
1650
1647
  SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self);
1651
1648
  SSL_set_info_callback(ssl, ssl_info_cb);
1652
- verify_cb = rb_attr_get(v_ctx, id_i_verify_callback);
1653
- // We don't need to trigger a write barrier because it's already
1654
- // an instance variable of this object.
1655
- SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)verify_cb);
1656
1649
 
1657
1650
  rb_call_super(0, NULL);
1658
1651
 
@@ -1725,11 +1718,20 @@ no_exception_p(VALUE opts)
1725
1718
  #define RUBY_IO_TIMEOUT_DEFAULT Qnil
1726
1719
  #endif
1727
1720
 
1721
+ #ifdef HAVE_RB_IO_TIMEOUT
1722
+ #define IO_TIMEOUT_ERROR rb_eIOTimeoutError
1723
+ #else
1724
+ #define IO_TIMEOUT_ERROR rb_eIOError
1725
+ #endif
1726
+
1727
+
1728
1728
  static void
1729
1729
  io_wait_writable(VALUE io)
1730
1730
  {
1731
1731
  #ifdef HAVE_RB_IO_MAYBE_WAIT
1732
- rb_io_maybe_wait_writable(errno, io, RUBY_IO_TIMEOUT_DEFAULT);
1732
+ if (!rb_io_maybe_wait_writable(errno, io, RUBY_IO_TIMEOUT_DEFAULT)) {
1733
+ rb_raise(IO_TIMEOUT_ERROR, "Timed out while waiting to become writable!");
1734
+ }
1733
1735
  #else
1734
1736
  rb_io_t *fptr;
1735
1737
  GetOpenFile(io, fptr);
@@ -1741,7 +1743,9 @@ static void
1741
1743
  io_wait_readable(VALUE io)
1742
1744
  {
1743
1745
  #ifdef HAVE_RB_IO_MAYBE_WAIT
1744
- rb_io_maybe_wait_readable(errno, io, RUBY_IO_TIMEOUT_DEFAULT);
1746
+ if (!rb_io_maybe_wait_readable(errno, io, RUBY_IO_TIMEOUT_DEFAULT)) {
1747
+ rb_raise(IO_TIMEOUT_ERROR, "Timed out while waiting to become readable!");
1748
+ }
1745
1749
  #else
1746
1750
  rb_io_t *fptr;
1747
1751
  GetOpenFile(io, fptr);
@@ -1925,7 +1929,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1925
1929
  {
1926
1930
  SSL *ssl;
1927
1931
  int ilen;
1928
- VALUE len, str;
1932
+ VALUE len, str, cb_state;
1929
1933
  VALUE opts = Qnil;
1930
1934
 
1931
1935
  if (nonblock) {
@@ -1947,15 +1951,25 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock)
1947
1951
  else
1948
1952
  rb_str_modify_expand(str, ilen - RSTRING_LEN(str));
1949
1953
  }
1950
- rb_str_set_len(str, 0);
1951
- if (ilen == 0)
1952
- return str;
1954
+
1955
+ if (ilen == 0) {
1956
+ rb_str_set_len(str, 0);
1957
+ return str;
1958
+ }
1953
1959
 
1954
1960
  VALUE io = rb_attr_get(self, id_i_io);
1955
1961
 
1956
1962
  rb_str_locktmp(str);
1957
1963
  for (;;) {
1958
1964
  int nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
1965
+
1966
+ cb_state = rb_attr_get(self, ID_callback_state);
1967
+ if (!NIL_P(cb_state)) {
1968
+ rb_ivar_set(self, ID_callback_state, Qnil);
1969
+ ossl_clear_error();
1970
+ rb_jump_tag(NUM2INT(cb_state));
1971
+ }
1972
+
1959
1973
  switch (ssl_get_error(ssl, nread)) {
1960
1974
  case SSL_ERROR_NONE:
1961
1975
  rb_str_unlocktmp(str);
@@ -2045,7 +2059,7 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
2045
2059
  SSL *ssl;
2046
2060
  rb_io_t *fptr;
2047
2061
  int num, nonblock = opts != Qfalse;
2048
- VALUE tmp;
2062
+ VALUE tmp, cb_state;
2049
2063
 
2050
2064
  GetSSL(self, ssl);
2051
2065
  if (!ssl_started(ssl))
@@ -2062,6 +2076,14 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
2062
2076
 
2063
2077
  for (;;) {
2064
2078
  int nwritten = SSL_write(ssl, RSTRING_PTR(tmp), num);
2079
+
2080
+ cb_state = rb_attr_get(self, ID_callback_state);
2081
+ if (!NIL_P(cb_state)) {
2082
+ rb_ivar_set(self, ID_callback_state, Qnil);
2083
+ ossl_clear_error();
2084
+ rb_jump_tag(NUM2INT(cb_state));
2085
+ }
2086
+
2065
2087
  switch (ssl_get_error(ssl, nwritten)) {
2066
2088
  case SSL_ERROR_NONE:
2067
2089
  return INT2NUM(nwritten);
@@ -2590,9 +2612,6 @@ Init_ossl_ssl(void)
2590
2612
  id_call = rb_intern_const("call");
2591
2613
  ID_callback_state = rb_intern_const("callback_state");
2592
2614
 
2593
- ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_vcb_idx", 0, 0, 0);
2594
- if (ossl_ssl_ex_vcb_idx < 0)
2595
- ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index");
2596
2615
  ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_ptr_idx", 0, 0, 0);
2597
2616
  if (ossl_ssl_ex_ptr_idx < 0)
2598
2617
  ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index");
@@ -5,7 +5,7 @@
5
5
  */
6
6
  /*
7
7
  * This program is licensed under the same licence as Ruby.
8
- * (See the file 'LICENCE'.)
8
+ * (See the file 'COPYING'.)
9
9
  */
10
10
  #if !defined(_OSSL_SSL_H_)
11
11
  #define _OSSL_SSL_H_