openssl 3.2.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +180 -29
- data/History.md +114 -1
- data/README.md +11 -7
- data/ext/openssl/extconf.rb +7 -9
- data/ext/openssl/openssl_missing.c +1 -1
- data/ext/openssl/openssl_missing.h +1 -1
- data/ext/openssl/ossl.c +7 -9
- data/ext/openssl/ossl.h +12 -8
- data/ext/openssl/ossl_asn1.c +65 -261
- data/ext/openssl/ossl_asn1.h +1 -19
- data/ext/openssl/ossl_bio.c +1 -1
- data/ext/openssl/ossl_bio.h +1 -1
- data/ext/openssl/ossl_bn.c +12 -12
- data/ext/openssl/ossl_bn.h +1 -2
- data/ext/openssl/ossl_cipher.c +24 -9
- data/ext/openssl/ossl_cipher.h +1 -4
- data/ext/openssl/ossl_config.c +10 -9
- data/ext/openssl/ossl_config.h +1 -1
- data/ext/openssl/ossl_digest.c +39 -20
- data/ext/openssl/ossl_digest.h +1 -4
- data/ext/openssl/ossl_engine.c +3 -3
- data/ext/openssl/ossl_engine.h +1 -4
- data/ext/openssl/ossl_hmac.c +3 -3
- data/ext/openssl/ossl_hmac.h +1 -4
- data/ext/openssl/ossl_kdf.c +5 -5
- data/ext/openssl/ossl_ns_spki.c +8 -8
- data/ext/openssl/ossl_ns_spki.h +1 -5
- data/ext/openssl/ossl_ocsp.c +8 -8
- data/ext/openssl/ossl_ocsp.h +1 -8
- data/ext/openssl/ossl_pkcs12.c +54 -3
- data/ext/openssl/ossl_pkcs12.h +1 -4
- data/ext/openssl/ossl_pkcs7.c +79 -22
- data/ext/openssl/ossl_pkcs7.h +2 -22
- data/ext/openssl/ossl_pkey.c +1 -1
- data/ext/openssl/ossl_pkey.h +3 -14
- data/ext/openssl/ossl_pkey_dh.c +2 -2
- data/ext/openssl/ossl_pkey_dsa.c +2 -2
- data/ext/openssl/ossl_pkey_ec.c +6 -6
- data/ext/openssl/ossl_pkey_rsa.c +2 -2
- data/ext/openssl/ossl_provider.c +1 -1
- data/ext/openssl/ossl_rand.c +3 -3
- data/ext/openssl/ossl_rand.h +1 -4
- data/ext/openssl/ossl_ssl.c +71 -52
- data/ext/openssl/ossl_ssl.h +1 -1
- data/ext/openssl/ossl_ts.c +73 -15
- data/ext/openssl/ossl_ts.h +1 -1
- data/ext/openssl/ossl_x509.c +1 -1
- data/ext/openssl/ossl_x509.h +1 -20
- data/ext/openssl/ossl_x509attr.c +25 -26
- data/ext/openssl/ossl_x509cert.c +42 -3
- data/ext/openssl/ossl_x509crl.c +8 -4
- data/ext/openssl/ossl_x509ext.c +3 -3
- data/ext/openssl/ossl_x509name.c +3 -3
- data/ext/openssl/ossl_x509req.c +8 -4
- data/ext/openssl/ossl_x509revoked.c +2 -2
- data/ext/openssl/ossl_x509store.c +16 -11
- data/lib/openssl/asn1.rb +188 -0
- data/lib/openssl/bn.rb +1 -1
- data/lib/openssl/buffering.rb +24 -9
- data/lib/openssl/cipher.rb +1 -1
- data/lib/openssl/digest.rb +1 -1
- data/lib/openssl/marshal.rb +1 -1
- data/lib/openssl/ssl.rb +67 -4
- data/lib/openssl/version.rb +1 -1
- data/lib/openssl/x509.rb +6 -6
- data/lib/openssl.rb +2 -1
- metadata +6 -4
- /data/{LICENSE.txt → COPYING} +0 -0
data/ext/openssl/ossl_pkcs7.c
CHANGED
@@ -5,10 +5,25 @@
|
|
5
5
|
*/
|
6
6
|
/*
|
7
7
|
* This program is licensed under the same licence as Ruby.
|
8
|
-
* (See the file '
|
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
|
{
|
@@ -165,7 +194,13 @@ ossl_pkcs7_s_read_smime(VALUE klass, VALUE arg)
|
|
165
194
|
out = NULL;
|
166
195
|
pkcs7 = SMIME_read_PKCS7(in, &out);
|
167
196
|
BIO_free(in);
|
168
|
-
if(!pkcs7)
|
197
|
+
if (!pkcs7)
|
198
|
+
ossl_raise(ePKCS7Error, "Could not parse the PKCS7");
|
199
|
+
if (!pkcs7->d.ptr) {
|
200
|
+
PKCS7_free(pkcs7);
|
201
|
+
ossl_raise(ePKCS7Error, "No content in PKCS7");
|
202
|
+
}
|
203
|
+
|
169
204
|
data = out ? ossl_membio2str(out) : Qnil;
|
170
205
|
SetPKCS7(ret, pkcs7);
|
171
206
|
ossl_pkcs7_set_data(ret, data);
|
@@ -255,7 +290,14 @@ ossl_pkcs7_s_sign(int argc, VALUE *argv, VALUE klass)
|
|
255
290
|
|
256
291
|
/*
|
257
292
|
* call-seq:
|
258
|
-
* PKCS7.encrypt(certs, data,
|
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).
|
259
301
|
*/
|
260
302
|
static VALUE
|
261
303
|
ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass)
|
@@ -269,21 +311,12 @@ ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass)
|
|
269
311
|
PKCS7 *p7;
|
270
312
|
|
271
313
|
rb_scan_args(argc, argv, "22", &certs, &data, &cipher, &flags);
|
272
|
-
if(NIL_P(cipher)){
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
ciph = EVP_des_ede3_cbc();
|
277
|
-
#elif !defined(OPENSSL_NO_RC2)
|
278
|
-
ciph = EVP_rc2_40_cbc();
|
279
|
-
#elif !defined(OPENSSL_NO_AES)
|
280
|
-
ciph = EVP_EVP_aes_128_cbc();
|
281
|
-
#else
|
282
|
-
ossl_raise(ePKCS7Error, "Must specify cipher");
|
283
|
-
#endif
|
284
|
-
|
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.");
|
285
318
|
}
|
286
|
-
|
319
|
+
ciph = ossl_evp_get_cipherbyname(cipher);
|
287
320
|
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
|
288
321
|
ret = NewPKCS7(cPKCS7);
|
289
322
|
in = ossl_obj2bio(&data);
|
@@ -346,6 +379,10 @@ ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
|
|
346
379
|
BIO_free(in);
|
347
380
|
if (!p7)
|
348
381
|
ossl_raise(rb_eArgError, "Could not parse the PKCS7");
|
382
|
+
if (!p7->d.ptr) {
|
383
|
+
PKCS7_free(p7);
|
384
|
+
ossl_raise(rb_eArgError, "No content in PKCS7");
|
385
|
+
}
|
349
386
|
|
350
387
|
RTYPEDDATA_DATA(self) = p7;
|
351
388
|
PKCS7_free(p7_orig);
|
@@ -841,6 +878,25 @@ ossl_pkcs7_to_der(VALUE self)
|
|
841
878
|
return str;
|
842
879
|
}
|
843
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
|
+
|
844
900
|
static VALUE
|
845
901
|
ossl_pkcs7_to_pem(VALUE self)
|
846
902
|
{
|
@@ -1050,6 +1106,7 @@ Init_ossl_pkcs7(void)
|
|
1050
1106
|
rb_define_method(cPKCS7, "to_pem", ossl_pkcs7_to_pem, 0);
|
1051
1107
|
rb_define_alias(cPKCS7, "to_s", "to_pem");
|
1052
1108
|
rb_define_method(cPKCS7, "to_der", ossl_pkcs7_to_der, 0);
|
1109
|
+
rb_define_method(cPKCS7, "to_text", ossl_pkcs7_to_text, 0);
|
1053
1110
|
|
1054
1111
|
cPKCS7Signer = rb_define_class_under(cPKCS7, "SignerInfo", rb_cObject);
|
1055
1112
|
rb_define_const(cPKCS7, "Signer", cPKCS7Signer);
|
data/ext/openssl/ossl_pkcs7.h
CHANGED
@@ -5,32 +5,12 @@
|
|
5
5
|
*/
|
6
6
|
/*
|
7
7
|
* This program is licensed under the same licence as Ruby.
|
8
|
-
* (See the file '
|
8
|
+
* (See the file 'COPYING'.)
|
9
9
|
*/
|
10
10
|
#if !defined(_OSSL_PKCS7_H_)
|
11
11
|
#define _OSSL_PKCS7_H_
|
12
12
|
|
13
|
-
|
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_ */
|
data/ext/openssl/ossl_pkey.c
CHANGED
data/ext/openssl/ossl_pkey.h
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
*/
|
6
6
|
/*
|
7
7
|
* This program is licensed under the same licence as Ruby.
|
8
|
-
* (See the file '
|
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(
|
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(
|
156
|
+
ossl_raise(ePKeyError, "BN_dup"); \
|
168
157
|
} \
|
169
158
|
\
|
170
159
|
if (!_type##_set0_##_group(obj, bn1, bn2)) { \
|
data/ext/openssl/ossl_pkey_dh.c
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
*/
|
6
6
|
/*
|
7
7
|
* This program is licensed under the same licence as Ruby.
|
8
|
-
* (See the file '
|
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
|
data/ext/openssl/ossl_pkey_dsa.c
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
*/
|
6
6
|
/*
|
7
7
|
* This program is licensed under the same licence as Ruby.
|
8
|
-
* (See the file '
|
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
|
data/ext/openssl/ossl_pkey_ec.c
CHANGED
@@ -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(
|
177
|
+
rb_raise(eECError, "incorrect pkey type: %s", OBJ_nid2sn(type));
|
178
178
|
}
|
179
179
|
RTYPEDDATA_DATA(self) = pkey;
|
180
180
|
return self;
|
data/ext/openssl/ossl_pkey_rsa.c
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
*/
|
6
6
|
/*
|
7
7
|
* This program is licensed under the same licence as Ruby.
|
8
|
-
* (See the file '
|
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
|
data/ext/openssl/ossl_provider.c
CHANGED
data/ext/openssl/ossl_rand.c
CHANGED
@@ -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 '
|
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:
|
data/ext/openssl/ossl_rand.h
CHANGED
@@ -5,14 +5,11 @@
|
|
5
5
|
*/
|
6
6
|
/*
|
7
7
|
* This program is licensed under the same licence as Ruby.
|
8
|
-
* (See the file '
|
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_ */
|
data/ext/openssl/ossl_ssl.c
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
*/
|
8
8
|
/*
|
9
9
|
* This program is licensed under the same licence as Ruby.
|
10
|
-
* (See the file '
|
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
|
560
|
+
ossl_call_servername_cb(VALUE arg)
|
562
561
|
{
|
563
|
-
|
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
|
-
|
566
|
-
|
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
|
-
|
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
|
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
|
-
|
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,
|
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
|
-
*
|
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
|
-
*
|
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
|
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
|
-
|
1951
|
-
if (ilen == 0)
|
1952
|
-
|
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");
|