rubysl-openssl 2.10 → 2.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/ext/rubysl/openssl/deprecation.rb +7 -3
- data/ext/rubysl/openssl/extconf.rb +148 -103
- data/ext/rubysl/openssl/openssl_missing.c +94 -275
- data/ext/rubysl/openssl/openssl_missing.h +167 -98
- data/ext/rubysl/openssl/ossl.c +266 -212
- data/ext/rubysl/openssl/ossl.h +27 -89
- data/ext/rubysl/openssl/ossl_asn1.c +157 -221
- data/ext/rubysl/openssl/ossl_asn1.h +11 -3
- data/ext/rubysl/openssl/ossl_bio.c +10 -40
- data/ext/rubysl/openssl/ossl_bio.h +1 -2
- data/ext/rubysl/openssl/ossl_bn.c +144 -100
- data/ext/rubysl/openssl/ossl_bn.h +3 -1
- data/ext/rubysl/openssl/ossl_cipher.c +270 -195
- data/ext/rubysl/openssl/ossl_config.c +7 -1
- data/ext/rubysl/openssl/ossl_config.h +0 -1
- data/ext/rubysl/openssl/ossl_digest.c +40 -29
- data/ext/rubysl/openssl/ossl_engine.c +23 -62
- data/ext/rubysl/openssl/ossl_hmac.c +82 -55
- data/ext/rubysl/openssl/ossl_ns_spki.c +22 -22
- data/ext/rubysl/openssl/ossl_ocsp.c +894 -144
- data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
- data/ext/rubysl/openssl/ossl_pkcs12.c +47 -19
- data/ext/rubysl/openssl/ossl_pkcs5.c +7 -15
- data/ext/rubysl/openssl/ossl_pkcs7.c +38 -15
- data/ext/rubysl/openssl/ossl_pkey.c +151 -99
- data/ext/rubysl/openssl/ossl_pkey.h +123 -29
- data/ext/rubysl/openssl/ossl_pkey_dh.c +143 -92
- data/ext/rubysl/openssl/ossl_pkey_dsa.c +149 -104
- data/ext/rubysl/openssl/ossl_pkey_ec.c +646 -524
- data/ext/rubysl/openssl/ossl_pkey_rsa.c +180 -121
- data/ext/rubysl/openssl/ossl_rand.c +25 -21
- data/ext/rubysl/openssl/ossl_ssl.c +795 -413
- data/ext/rubysl/openssl/ossl_ssl.h +3 -0
- data/ext/rubysl/openssl/ossl_ssl_session.c +83 -77
- data/ext/rubysl/openssl/ossl_version.h +1 -1
- data/ext/rubysl/openssl/ossl_x509.c +92 -8
- data/ext/rubysl/openssl/ossl_x509.h +14 -5
- data/ext/rubysl/openssl/ossl_x509attr.c +77 -41
- data/ext/rubysl/openssl/ossl_x509cert.c +45 -46
- data/ext/rubysl/openssl/ossl_x509crl.c +51 -57
- data/ext/rubysl/openssl/ossl_x509ext.c +39 -33
- data/ext/rubysl/openssl/ossl_x509name.c +68 -45
- data/ext/rubysl/openssl/ossl_x509req.c +32 -38
- data/ext/rubysl/openssl/ossl_x509revoked.c +43 -9
- data/ext/rubysl/openssl/ossl_x509store.c +309 -104
- data/ext/rubysl/openssl/ruby_missing.h +8 -6
- data/lib/openssl/buffering.rb +11 -5
- data/lib/openssl/cipher.rb +23 -15
- data/lib/openssl/digest.rb +7 -10
- data/lib/openssl/pkey.rb +15 -8
- data/lib/openssl/ssl.rb +81 -105
- data/lib/rubysl/openssl.rb +1 -4
- data/lib/rubysl/openssl/version.rb +1 -1
- metadata +3 -4
@@ -10,187 +10,256 @@
|
|
10
10
|
#if !defined(_OSSL_OPENSSL_MISSING_H_)
|
11
11
|
#define _OSSL_OPENSSL_MISSING_H_
|
12
12
|
|
13
|
-
#
|
14
|
-
|
13
|
+
#include "ruby/config.h"
|
14
|
+
|
15
|
+
/* added in 0.9.8X */
|
16
|
+
#if !defined(HAVE_EVP_CIPHER_CTX_NEW)
|
17
|
+
EVP_CIPHER_CTX *ossl_EVP_CIPHER_CTX_new(void);
|
18
|
+
# define EVP_CIPHER_CTX_new ossl_EVP_CIPHER_CTX_new
|
15
19
|
#endif
|
16
20
|
|
17
|
-
#
|
18
|
-
|
21
|
+
#if !defined(HAVE_EVP_CIPHER_CTX_FREE)
|
22
|
+
void ossl_EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *);
|
23
|
+
# define EVP_CIPHER_CTX_free ossl_EVP_CIPHER_CTX_free
|
19
24
|
#endif
|
20
|
-
|
21
|
-
|
25
|
+
|
26
|
+
#if !defined(HAVE_SSL_CTX_CLEAR_OPTIONS)
|
27
|
+
# define SSL_CTX_clear_options(ctx, op) ((ctx)->options &= ~(op))
|
22
28
|
#endif
|
23
29
|
|
24
|
-
/*
|
25
|
-
|
26
|
-
|
30
|
+
/* added in 1.0.0 */
|
31
|
+
#if !defined(HAVE_EVP_PKEY_BASE_ID)
|
32
|
+
# define EVP_PKEY_base_id(pkey) EVP_PKEY_type((pkey)->type)
|
33
|
+
#endif
|
27
34
|
|
28
|
-
#if !defined(
|
29
|
-
|
30
|
-
|
35
|
+
#if !defined(HAVE_EVP_CIPHER_CTX_COPY)
|
36
|
+
int ossl_EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *, const EVP_CIPHER_CTX *);
|
37
|
+
# define EVP_CIPHER_CTX_copy ossl_EVP_CIPHER_CTX_copy
|
31
38
|
#endif
|
32
39
|
|
33
|
-
#if !defined(
|
34
|
-
|
35
|
-
|
36
|
-
PEM_STRING_DSA_PUBLIC,\
|
37
|
-
(bp),(char *)(x), NULL, NULL, 0, NULL, NULL)
|
40
|
+
#if !defined(HAVE_HMAC_CTX_COPY)
|
41
|
+
int ossl_HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in);
|
42
|
+
# define HMAC_CTX_copy ossl_HMAC_CTX_copy
|
38
43
|
#endif
|
39
44
|
|
40
|
-
#if !defined(
|
41
|
-
#
|
42
|
-
(d2i_of_void *)d2i_DSAPrivateKey,(char *)(dsa))
|
45
|
+
#if !defined(HAVE_X509_STORE_CTX_GET0_CURRENT_CRL)
|
46
|
+
# define X509_STORE_CTX_get0_current_crl(x) ((x)->current_crl)
|
43
47
|
#endif
|
44
48
|
|
45
|
-
#if !defined(
|
46
|
-
#
|
47
|
-
(d2i_of_void *)d2i_DSAPublicKey,(char *)(dsa))
|
49
|
+
#if !defined(HAVE_X509_STORE_SET_VERIFY_CB)
|
50
|
+
# define X509_STORE_set_verify_cb X509_STORE_set_verify_cb_func
|
48
51
|
#endif
|
49
52
|
|
50
|
-
#if !defined(
|
51
|
-
#
|
52
|
-
|
53
|
+
#if !defined(HAVE_I2D_ASN1_SET_ANY)
|
54
|
+
# define i2d_ASN1_SET_ANY(sk, x) i2d_ASN1_SET_OF_ASN1_TYPE((sk), (x), \
|
55
|
+
i2d_ASN1_TYPE, V_ASN1_SET, V_ASN1_UNIVERSAL, 0)
|
53
56
|
#endif
|
54
57
|
|
55
|
-
#if !defined(
|
56
|
-
# define
|
57
|
-
(d2i_of_void *)d2i_PKCS7_SIGNER_INFO, (char *)(si))
|
58
|
+
#if !defined(HAVE_EVP_PKEY_GET0)
|
59
|
+
# define EVP_PKEY_get0(pk) (pk->pkey.ptr)
|
58
60
|
#endif
|
59
61
|
|
60
|
-
|
61
|
-
#
|
62
|
-
|
62
|
+
/* added in 1.0.2 */
|
63
|
+
#if !defined(OPENSSL_NO_EC)
|
64
|
+
#if !defined(HAVE_EC_CURVE_NIST2NID)
|
65
|
+
int ossl_EC_curve_nist2nid(const char *);
|
66
|
+
# define EC_curve_nist2nid ossl_EC_curve_nist2nid
|
67
|
+
#endif
|
63
68
|
#endif
|
64
69
|
|
65
|
-
#if !defined(
|
66
|
-
|
70
|
+
#if !defined(HAVE_X509_REVOKED_DUP)
|
71
|
+
# define X509_REVOKED_dup(rev) (X509_REVOKED *)ASN1_dup((i2d_of_void *)i2d_X509_REVOKED, \
|
72
|
+
(d2i_of_void *)d2i_X509_REVOKED, (char *)(rev))
|
67
73
|
#endif
|
68
74
|
|
69
|
-
#if !defined(
|
70
|
-
|
75
|
+
#if !defined(HAVE_X509_STORE_CTX_GET0_STORE)
|
76
|
+
# define X509_STORE_CTX_get0_store(x) ((x)->ctx)
|
71
77
|
#endif
|
72
78
|
|
73
|
-
#if !defined(
|
74
|
-
|
79
|
+
#if !defined(HAVE_SSL_IS_SERVER)
|
80
|
+
# define SSL_is_server(s) ((s)->server)
|
75
81
|
#endif
|
76
82
|
|
77
|
-
|
78
|
-
|
83
|
+
/* added in 1.1.0 */
|
84
|
+
#if !defined(HAVE_BN_GENCB_NEW)
|
85
|
+
# define BN_GENCB_new() ((BN_GENCB *)OPENSSL_malloc(sizeof(BN_GENCB)))
|
79
86
|
#endif
|
80
87
|
|
81
|
-
#if !defined(
|
82
|
-
|
88
|
+
#if !defined(HAVE_BN_GENCB_FREE)
|
89
|
+
# define BN_GENCB_free(cb) OPENSSL_free(cb)
|
83
90
|
#endif
|
84
91
|
|
85
|
-
#if !defined(
|
86
|
-
|
92
|
+
#if !defined(HAVE_BN_GENCB_GET_ARG)
|
93
|
+
# define BN_GENCB_get_arg(cb) (cb)->arg
|
87
94
|
#endif
|
88
95
|
|
89
|
-
#if !defined(
|
90
|
-
|
96
|
+
#if !defined(HAVE_EVP_MD_CTX_NEW)
|
97
|
+
# define EVP_MD_CTX_new EVP_MD_CTX_create
|
91
98
|
#endif
|
92
99
|
|
93
|
-
#if !defined(
|
94
|
-
|
100
|
+
#if !defined(HAVE_EVP_MD_CTX_FREE)
|
101
|
+
# define EVP_MD_CTX_free EVP_MD_CTX_destroy
|
95
102
|
#endif
|
96
103
|
|
97
|
-
#if !defined(
|
98
|
-
|
104
|
+
#if !defined(HAVE_HMAC_CTX_NEW)
|
105
|
+
HMAC_CTX *ossl_HMAC_CTX_new(void);
|
106
|
+
# define HMAC_CTX_new ossl_HMAC_CTX_new
|
99
107
|
#endif
|
100
|
-
|
101
|
-
#
|
108
|
+
|
109
|
+
#if !defined(HAVE_HMAC_CTX_FREE)
|
110
|
+
void ossl_HMAC_CTX_free(HMAC_CTX *);
|
111
|
+
# define HMAC_CTX_free ossl_HMAC_CTX_free
|
102
112
|
#endif
|
103
113
|
|
104
|
-
#if !defined(
|
105
|
-
# define
|
114
|
+
#if !defined(HAVE_X509_STORE_GET_EX_DATA)
|
115
|
+
# define X509_STORE_get_ex_data(x, idx) \
|
116
|
+
CRYPTO_get_ex_data(&(x)->ex_data, (idx))
|
106
117
|
#endif
|
107
|
-
|
108
|
-
#
|
118
|
+
|
119
|
+
#if !defined(HAVE_X509_STORE_SET_EX_DATA)
|
120
|
+
# define X509_STORE_set_ex_data(x, idx, data) \
|
121
|
+
CRYPTO_set_ex_data(&(x)->ex_data, (idx), (data))
|
122
|
+
# define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef) \
|
123
|
+
CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, (l), (p), \
|
124
|
+
(newf), (dupf), (freef))
|
109
125
|
#endif
|
110
126
|
|
111
|
-
#if !defined(
|
112
|
-
|
127
|
+
#if !defined(HAVE_X509_CRL_GET0_SIGNATURE)
|
128
|
+
void ossl_X509_CRL_get0_signature(const X509_CRL *, const ASN1_BIT_STRING **, const X509_ALGOR **);
|
129
|
+
# define X509_CRL_get0_signature ossl_X509_CRL_get0_signature
|
113
130
|
#endif
|
114
131
|
|
115
|
-
#if !defined(
|
116
|
-
|
132
|
+
#if !defined(HAVE_X509_REQ_GET0_SIGNATURE)
|
133
|
+
void ossl_X509_REQ_get0_signature(const X509_REQ *, const ASN1_BIT_STRING **, const X509_ALGOR **);
|
134
|
+
# define X509_REQ_get0_signature ossl_X509_REQ_get0_signature
|
117
135
|
#endif
|
118
136
|
|
119
|
-
#if !defined(
|
120
|
-
# define
|
137
|
+
#if !defined(HAVE_X509_REVOKED_GET0_SERIALNUMBER)
|
138
|
+
# define X509_REVOKED_get0_serialNumber(x) ((x)->serialNumber)
|
121
139
|
#endif
|
122
140
|
|
123
|
-
#if !defined(
|
124
|
-
# define
|
141
|
+
#if !defined(HAVE_X509_REVOKED_GET0_REVOCATIONDATE)
|
142
|
+
# define X509_REVOKED_get0_revocationDate(x) ((x)->revocationDate)
|
125
143
|
#endif
|
126
144
|
|
127
|
-
#if !defined(
|
128
|
-
# define
|
145
|
+
#if !defined(HAVE_X509_GET0_TBS_SIGALG)
|
146
|
+
# define X509_get0_tbs_sigalg(x) ((x)->cert_info->signature)
|
129
147
|
#endif
|
130
148
|
|
131
|
-
#if !defined(
|
132
|
-
#define
|
149
|
+
#if !defined(HAVE_X509_STORE_CTX_GET0_UNTRUSTED)
|
150
|
+
# define X509_STORE_CTX_get0_untrusted(x) ((x)->untrusted)
|
133
151
|
#endif
|
134
152
|
|
135
|
-
#if !defined(
|
136
|
-
|
153
|
+
#if !defined(HAVE_X509_STORE_CTX_GET0_CERT)
|
154
|
+
# define X509_STORE_CTX_get0_cert(x) ((x)->cert)
|
137
155
|
#endif
|
138
156
|
|
139
|
-
#if !defined(
|
140
|
-
|
157
|
+
#if !defined(HAVE_X509_STORE_CTX_GET0_CHAIN)
|
158
|
+
# define X509_STORE_CTX_get0_chain(ctx) X509_STORE_CTX_get_chain(ctx)
|
141
159
|
#endif
|
142
160
|
|
143
|
-
#if !defined(
|
144
|
-
|
161
|
+
#if !defined(HAVE_OCSP_SINGLERESP_GET0_ID)
|
162
|
+
# define OCSP_SINGLERESP_get0_id(s) ((s)->certId)
|
145
163
|
#endif
|
146
164
|
|
147
|
-
#if !defined(
|
148
|
-
|
165
|
+
#if !defined(HAVE_SSL_CTX_GET_CIPHERS)
|
166
|
+
# define SSL_CTX_get_ciphers(ctx) ((ctx)->cipher_list)
|
149
167
|
#endif
|
150
168
|
|
151
|
-
#if !defined(
|
152
|
-
|
169
|
+
#if !defined(HAVE_X509_UP_REF)
|
170
|
+
# define X509_up_ref(x) \
|
171
|
+
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509)
|
153
172
|
#endif
|
154
173
|
|
155
|
-
#if !defined(
|
156
|
-
|
174
|
+
#if !defined(HAVE_X509_CRL_UP_REF)
|
175
|
+
# define X509_CRL_up_ref(x) \
|
176
|
+
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509_CRL);
|
157
177
|
#endif
|
158
178
|
|
159
|
-
#if !defined(
|
160
|
-
|
179
|
+
#if !defined(HAVE_X509_STORE_UP_REF)
|
180
|
+
# define X509_STORE_up_ref(x) \
|
181
|
+
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509_STORE);
|
161
182
|
#endif
|
162
183
|
|
163
|
-
#if !defined(
|
164
|
-
|
184
|
+
#if !defined(HAVE_SSL_SESSION_UP_REF)
|
185
|
+
# define SSL_SESSION_up_ref(x) \
|
186
|
+
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_SSL_SESSION);
|
165
187
|
#endif
|
166
188
|
|
167
|
-
#if !defined(
|
168
|
-
|
189
|
+
#if !defined(HAVE_EVP_PKEY_UP_REF)
|
190
|
+
# define EVP_PKEY_up_ref(x) \
|
191
|
+
CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
169
192
|
#endif
|
170
193
|
|
171
|
-
#if !defined(
|
172
|
-
|
194
|
+
#if !defined(HAVE_OPAQUE_OPENSSL)
|
195
|
+
#define IMPL_PKEY_GETTER(_type, _name) \
|
196
|
+
static inline _type *EVP_PKEY_get0_##_type(EVP_PKEY *pkey) { \
|
197
|
+
return pkey->pkey._name; }
|
198
|
+
#define IMPL_KEY_ACCESSOR2(_type, _group, a1, a2, _fail_cond) \
|
199
|
+
static inline void _type##_get0_##_group(const _type *obj, const BIGNUM **a1, const BIGNUM **a2) { \
|
200
|
+
if (a1) *a1 = obj->a1; \
|
201
|
+
if (a2) *a2 = obj->a2; } \
|
202
|
+
static inline int _type##_set0_##_group(_type *obj, BIGNUM *a1, BIGNUM *a2) { \
|
203
|
+
if (_fail_cond) return 0; \
|
204
|
+
BN_clear_free(obj->a1); obj->a1 = a1; \
|
205
|
+
BN_clear_free(obj->a2); obj->a2 = a2; \
|
206
|
+
return 1; }
|
207
|
+
#define IMPL_KEY_ACCESSOR3(_type, _group, a1, a2, a3, _fail_cond) \
|
208
|
+
static inline void _type##_get0_##_group(const _type *obj, const BIGNUM **a1, const BIGNUM **a2, const BIGNUM **a3) { \
|
209
|
+
if (a1) *a1 = obj->a1; \
|
210
|
+
if (a2) *a2 = obj->a2; \
|
211
|
+
if (a3) *a3 = obj->a3; } \
|
212
|
+
static inline int _type##_set0_##_group(_type *obj, BIGNUM *a1, BIGNUM *a2, BIGNUM *a3) { \
|
213
|
+
if (_fail_cond) return 0; \
|
214
|
+
BN_clear_free(obj->a1); obj->a1 = a1; \
|
215
|
+
BN_clear_free(obj->a2); obj->a2 = a2; \
|
216
|
+
BN_clear_free(obj->a3); obj->a3 = a3; \
|
217
|
+
return 1; }
|
218
|
+
|
219
|
+
#if !defined(OPENSSL_NO_RSA)
|
220
|
+
IMPL_PKEY_GETTER(RSA, rsa)
|
221
|
+
IMPL_KEY_ACCESSOR3(RSA, key, n, e, d, (n == obj->n || e == obj->e || (obj->d && d == obj->d)))
|
222
|
+
IMPL_KEY_ACCESSOR2(RSA, factors, p, q, (p == obj->p || q == obj->q))
|
223
|
+
IMPL_KEY_ACCESSOR3(RSA, crt_params, dmp1, dmq1, iqmp, (dmp1 == obj->dmp1 || dmq1 == obj->dmq1 || iqmp == obj->iqmp))
|
173
224
|
#endif
|
174
225
|
|
175
|
-
#if !defined(
|
176
|
-
|
226
|
+
#if !defined(OPENSSL_NO_DSA)
|
227
|
+
IMPL_PKEY_GETTER(DSA, dsa)
|
228
|
+
IMPL_KEY_ACCESSOR2(DSA, key, pub_key, priv_key, (pub_key == obj->pub_key || (obj->priv_key && priv_key == obj->priv_key)))
|
229
|
+
IMPL_KEY_ACCESSOR3(DSA, pqg, p, q, g, (p == obj->p || q == obj->q || g == obj->g))
|
177
230
|
#endif
|
178
231
|
|
179
|
-
#if !defined(
|
180
|
-
|
232
|
+
#if !defined(OPENSSL_NO_DH)
|
233
|
+
IMPL_PKEY_GETTER(DH, dh)
|
234
|
+
IMPL_KEY_ACCESSOR2(DH, key, pub_key, priv_key, (pub_key == obj->pub_key || (obj->priv_key && priv_key == obj->priv_key)))
|
235
|
+
IMPL_KEY_ACCESSOR3(DH, pqg, p, q, g, (p == obj->p || obj->q && q == obj->q || g == obj->g))
|
236
|
+
static inline ENGINE *DH_get0_engine(DH *dh) { return dh->engine; }
|
181
237
|
#endif
|
182
238
|
|
183
|
-
#if !defined(
|
184
|
-
|
239
|
+
#if !defined(OPENSSL_NO_EC)
|
240
|
+
IMPL_PKEY_GETTER(EC_KEY, ec)
|
185
241
|
#endif
|
186
242
|
|
187
|
-
#
|
188
|
-
|
243
|
+
#undef IMPL_PKEY_GETTER
|
244
|
+
#undef IMPL_KEY_ACCESSOR2
|
245
|
+
#undef IMPL_KEY_ACCESSOR3
|
246
|
+
#endif /* HAVE_OPAQUE_OPENSSL */
|
247
|
+
|
248
|
+
#if defined(HAVE_AUTHENTICATED_ENCRYPTION) && !defined(EVP_CTRL_AEAD_GET_TAG)
|
249
|
+
# define EVP_CTRL_AEAD_GET_TAG EVP_CTRL_GCM_GET_TAG
|
250
|
+
# define EVP_CTRL_AEAD_SET_TAG EVP_CTRL_GCM_SET_TAG
|
251
|
+
# define EVP_CTRL_AEAD_SET_IVLEN EVP_CTRL_GCM_SET_IVLEN
|
189
252
|
#endif
|
190
253
|
|
191
|
-
#if defined(
|
192
|
-
|
254
|
+
#if !defined(HAVE_X509_GET0_NOTBEFORE)
|
255
|
+
# define X509_get0_notBefore(x) X509_get_notBefore(x)
|
256
|
+
# define X509_get0_notAfter(x) X509_get_notAfter(x)
|
257
|
+
# define X509_CRL_get0_lastUpdate(x) X509_CRL_get_lastUpdate(x)
|
258
|
+
# define X509_CRL_get0_nextUpdate(x) X509_CRL_get_nextUpdate(x)
|
193
259
|
#endif
|
194
260
|
|
261
|
+
#if !defined(HAVE_SSL_SESSION_GET_PROTOCOL_VERSION)
|
262
|
+
# define SSL_SESSION_get_protocol_version(s) ((s)->ssl_version)
|
263
|
+
#endif
|
195
264
|
|
196
265
|
#endif /* _OSSL_OPENSSL_MISSING_H_ */
|
data/ext/rubysl/openssl/ossl.c
CHANGED
@@ -9,40 +9,7 @@
|
|
9
9
|
*/
|
10
10
|
#include "ossl.h"
|
11
11
|
#include <stdarg.h> /* for ossl_raise */
|
12
|
-
|
13
|
-
/*
|
14
|
-
* String to HEXString conversion
|
15
|
-
*/
|
16
|
-
int
|
17
|
-
string2hex(const unsigned char *buf, int buf_len, char **hexbuf, int *hexbuf_len)
|
18
|
-
{
|
19
|
-
static const char hex[]="0123456789abcdef";
|
20
|
-
int i, len;
|
21
|
-
|
22
|
-
if (buf_len < 0 || buf_len > INT_MAX / 2) { /* PARANOIA? */
|
23
|
-
return -1;
|
24
|
-
}
|
25
|
-
len = 2 * buf_len;
|
26
|
-
if (!hexbuf) { /* if no buf, return calculated len */
|
27
|
-
if (hexbuf_len) {
|
28
|
-
*hexbuf_len = len;
|
29
|
-
}
|
30
|
-
return len;
|
31
|
-
}
|
32
|
-
if (!(*hexbuf = OPENSSL_malloc(len + 1))) {
|
33
|
-
return -1;
|
34
|
-
}
|
35
|
-
for (i = 0; i < buf_len; i++) {
|
36
|
-
(*hexbuf)[2 * i] = hex[((unsigned char)buf[i]) >> 4];
|
37
|
-
(*hexbuf)[2 * i + 1] = hex[buf[i] & 0x0f];
|
38
|
-
}
|
39
|
-
(*hexbuf)[2 * i] = '\0';
|
40
|
-
|
41
|
-
if (hexbuf_len) {
|
42
|
-
*hexbuf_len = len;
|
43
|
-
}
|
44
|
-
return len;
|
45
|
-
}
|
12
|
+
#include <ruby/thread_native.h> /* for OpenSSL < 1.1.0 locks */
|
46
13
|
|
47
14
|
/*
|
48
15
|
* Data Conversion
|
@@ -77,7 +44,7 @@ STACK_OF(type) * \
|
|
77
44
|
ossl_protect_##name##_ary2sk(VALUE ary, int *status) \
|
78
45
|
{ \
|
79
46
|
return (STACK_OF(type)*)rb_protect( \
|
80
|
-
(VALUE(*)
|
47
|
+
(VALUE (*)(VALUE))ossl_##name##_ary2sk0, \
|
81
48
|
ary, \
|
82
49
|
status); \
|
83
50
|
} \
|
@@ -97,7 +64,7 @@ OSSL_IMPL_ARY2SK(x509, X509, cX509Cert, DupX509CertPtr)
|
|
97
64
|
|
98
65
|
#define OSSL_IMPL_SK2ARY(name, type) \
|
99
66
|
VALUE \
|
100
|
-
ossl_##name##_sk2ary(STACK_OF(type) *sk) \
|
67
|
+
ossl_##name##_sk2ary(const STACK_OF(type) *sk) \
|
101
68
|
{ \
|
102
69
|
type *t; \
|
103
70
|
int i, num; \
|
@@ -136,7 +103,7 @@ ossl_buf2str(char *buf, int len)
|
|
136
103
|
VALUE str;
|
137
104
|
int status = 0;
|
138
105
|
|
139
|
-
str = rb_protect((VALUE(*)
|
106
|
+
str = rb_protect((VALUE (*)(VALUE))ossl_str_new, len, &status);
|
140
107
|
if(!NIL_P(str)) memcpy(RSTRING_PTR(str), buf, len);
|
141
108
|
OPENSSL_free(buf);
|
142
109
|
if(status) rb_jump_tag(status);
|
@@ -144,28 +111,75 @@ ossl_buf2str(char *buf, int len)
|
|
144
111
|
return str;
|
145
112
|
}
|
146
113
|
|
114
|
+
void
|
115
|
+
ossl_bin2hex(unsigned char *in, char *out, size_t inlen)
|
116
|
+
{
|
117
|
+
const char *hex = "0123456789abcdef";
|
118
|
+
size_t i;
|
119
|
+
|
120
|
+
assert(inlen <= LONG_MAX / 2);
|
121
|
+
for (i = 0; i < inlen; i++) {
|
122
|
+
unsigned char p = in[i];
|
123
|
+
|
124
|
+
out[i * 2 + 0] = hex[p >> 4];
|
125
|
+
out[i * 2 + 1] = hex[p & 0x0f];
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
147
129
|
/*
|
148
130
|
* our default PEM callback
|
149
131
|
*/
|
150
|
-
|
151
|
-
|
132
|
+
VALUE
|
133
|
+
ossl_pem_passwd_value(VALUE pass)
|
152
134
|
{
|
153
|
-
|
135
|
+
if (NIL_P(pass))
|
136
|
+
return Qnil;
|
137
|
+
|
138
|
+
StringValue(pass);
|
154
139
|
|
155
|
-
|
156
|
-
|
140
|
+
/* PEM_BUFSIZE is currently used as the second argument of pem_password_cb,
|
141
|
+
* that is +max_len+ of ossl_pem_passwd_cb() */
|
142
|
+
if (RSTRING_LEN(pass) > PEM_BUFSIZE)
|
143
|
+
ossl_raise(eOSSLError, "password must not be longer than %d bytes", PEM_BUFSIZE);
|
157
144
|
|
158
145
|
return pass;
|
159
146
|
}
|
160
147
|
|
148
|
+
static VALUE
|
149
|
+
ossl_pem_passwd_cb0(VALUE flag)
|
150
|
+
{
|
151
|
+
VALUE pass = rb_yield(flag);
|
152
|
+
if (NIL_P(pass))
|
153
|
+
return Qnil;
|
154
|
+
StringValue(pass);
|
155
|
+
return pass;
|
156
|
+
}
|
157
|
+
|
161
158
|
int
|
162
|
-
ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *
|
159
|
+
ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
|
163
160
|
{
|
164
|
-
|
165
|
-
|
161
|
+
long len;
|
162
|
+
int status;
|
163
|
+
VALUE rflag, pass = (VALUE)pwd_;
|
164
|
+
|
165
|
+
if (RTEST(pass)) {
|
166
|
+
/* PEM_def_callback(buf, max_len, flag, StringValueCStr(pass)) does not
|
167
|
+
* work because it does not allow NUL characters and truncates to 1024
|
168
|
+
* bytes silently if the input is over 1024 bytes */
|
169
|
+
if (RB_TYPE_P(pass, T_STRING)) {
|
170
|
+
len = RSTRING_LEN(pass);
|
171
|
+
if (len <= max_len) {
|
172
|
+
memcpy(buf, RSTRING_PTR(pass), len);
|
173
|
+
return (int)len;
|
174
|
+
}
|
175
|
+
}
|
176
|
+
OSSL_Debug("passed data is not valid String???");
|
177
|
+
return -1;
|
178
|
+
}
|
166
179
|
|
167
|
-
if (
|
168
|
-
return PEM_def_callback(buf, max_len, flag,
|
180
|
+
if (!rb_block_given_p()) {
|
181
|
+
return PEM_def_callback(buf, max_len, flag, NULL);
|
182
|
+
}
|
169
183
|
|
170
184
|
while (1) {
|
171
185
|
/*
|
@@ -180,77 +194,17 @@ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd)
|
|
180
194
|
rb_set_errinfo(Qnil);
|
181
195
|
return -1;
|
182
196
|
}
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
continue;
|
187
|
-
}
|
197
|
+
if (NIL_P(pass))
|
198
|
+
return -1;
|
199
|
+
len = RSTRING_LEN(pass);
|
188
200
|
if (len > max_len) {
|
189
|
-
rb_warning("password must be
|
201
|
+
rb_warning("password must not be longer than %d bytes", max_len);
|
190
202
|
continue;
|
191
203
|
}
|
192
204
|
memcpy(buf, RSTRING_PTR(pass), len);
|
193
205
|
break;
|
194
206
|
}
|
195
|
-
return len;
|
196
|
-
}
|
197
|
-
|
198
|
-
/*
|
199
|
-
* Verify callback
|
200
|
-
*/
|
201
|
-
int ossl_verify_cb_idx;
|
202
|
-
|
203
|
-
VALUE
|
204
|
-
ossl_call_verify_cb_proc(struct ossl_verify_cb_args *args)
|
205
|
-
{
|
206
|
-
return rb_funcall(args->proc, rb_intern("call"), 2,
|
207
|
-
args->preverify_ok, args->store_ctx);
|
208
|
-
}
|
209
|
-
|
210
|
-
int
|
211
|
-
ossl_verify_cb(int ok, X509_STORE_CTX *ctx)
|
212
|
-
{
|
213
|
-
VALUE proc, rctx, ret;
|
214
|
-
struct ossl_verify_cb_args args;
|
215
|
-
int state = 0;
|
216
|
-
|
217
|
-
proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, ossl_verify_cb_idx);
|
218
|
-
if ((void*)proc == 0)
|
219
|
-
proc = (VALUE)X509_STORE_get_ex_data(ctx->ctx, ossl_verify_cb_idx);
|
220
|
-
if ((void*)proc == 0)
|
221
|
-
return ok;
|
222
|
-
if (!NIL_P(proc)) {
|
223
|
-
ret = Qfalse;
|
224
|
-
rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new,
|
225
|
-
(VALUE)ctx, &state);
|
226
|
-
if (state) {
|
227
|
-
rb_set_errinfo(Qnil);
|
228
|
-
rb_warn("StoreContext initialization failure");
|
229
|
-
}
|
230
|
-
else {
|
231
|
-
args.proc = proc;
|
232
|
-
args.preverify_ok = ok ? Qtrue : Qfalse;
|
233
|
-
args.store_ctx = rctx;
|
234
|
-
ret = rb_protect((VALUE(*)(VALUE))ossl_call_verify_cb_proc, (VALUE)&args, &state);
|
235
|
-
if (state) {
|
236
|
-
rb_set_errinfo(Qnil);
|
237
|
-
rb_warn("exception in verify_callback is ignored");
|
238
|
-
}
|
239
|
-
ossl_x509stctx_clear_ptr(rctx);
|
240
|
-
}
|
241
|
-
if (ret == Qtrue) {
|
242
|
-
X509_STORE_CTX_set_error(ctx, X509_V_OK);
|
243
|
-
ok = 1;
|
244
|
-
}
|
245
|
-
else{
|
246
|
-
if (X509_STORE_CTX_get_error(ctx) == X509_V_OK) {
|
247
|
-
X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
|
248
|
-
}
|
249
|
-
ok = 0;
|
250
|
-
}
|
251
|
-
}
|
252
|
-
|
253
|
-
return ok;
|
207
|
+
return (int)len;
|
254
208
|
}
|
255
209
|
|
256
210
|
/*
|
@@ -297,11 +251,7 @@ ossl_make_error(VALUE exc, const char *fmt, va_list args)
|
|
297
251
|
const char *msg;
|
298
252
|
long e;
|
299
253
|
|
300
|
-
#ifdef HAVE_ERR_PEEK_LAST_ERROR
|
301
254
|
e = ERR_peek_last_error();
|
302
|
-
#else
|
303
|
-
e = ERR_peek_error();
|
304
|
-
#endif
|
305
255
|
if (fmt) {
|
306
256
|
str = rb_vsprintf(fmt, args);
|
307
257
|
}
|
@@ -318,12 +268,7 @@ ossl_make_error(VALUE exc, const char *fmt, va_list args)
|
|
318
268
|
rb_str_cat2(str, msg ? msg : "(null)");
|
319
269
|
}
|
320
270
|
}
|
321
|
-
|
322
|
-
while ((e = ERR_get_error()) != 0){
|
323
|
-
rb_warn("error on stack: %s", ERR_error_string(e, NULL));
|
324
|
-
}
|
325
|
-
}
|
326
|
-
ERR_clear_error();
|
271
|
+
ossl_clear_error();
|
327
272
|
|
328
273
|
if (NIL_P(str)) str = rb_str_new(0, 0);
|
329
274
|
return rb_exc_new3(exc, str);
|
@@ -340,15 +285,32 @@ ossl_raise(VALUE exc, const char *fmt, ...)
|
|
340
285
|
rb_exc_raise(err);
|
341
286
|
}
|
342
287
|
|
343
|
-
|
344
|
-
|
288
|
+
void
|
289
|
+
ossl_clear_error(void)
|
345
290
|
{
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
291
|
+
if (dOSSL == Qtrue) {
|
292
|
+
unsigned long e;
|
293
|
+
const char *file, *data, *errstr;
|
294
|
+
int line, flags;
|
295
|
+
|
296
|
+
while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) {
|
297
|
+
errstr = ERR_error_string(e, NULL);
|
298
|
+
if (!errstr)
|
299
|
+
errstr = "(null)";
|
300
|
+
|
301
|
+
if (flags & ERR_TXT_STRING) {
|
302
|
+
if (!data)
|
303
|
+
data = "(null)";
|
304
|
+
rb_warn("error on stack: %s (%s)", errstr, data);
|
305
|
+
}
|
306
|
+
else {
|
307
|
+
rb_warn("error on stack: %s", errstr);
|
308
|
+
}
|
309
|
+
}
|
310
|
+
}
|
311
|
+
else {
|
312
|
+
ERR_clear_error();
|
313
|
+
}
|
352
314
|
}
|
353
315
|
|
354
316
|
/*
|
@@ -408,24 +370,14 @@ ossl_debug_get(VALUE self)
|
|
408
370
|
* call-seq:
|
409
371
|
* OpenSSL.debug = boolean -> boolean
|
410
372
|
*
|
411
|
-
* Turns on or off
|
412
|
-
*
|
373
|
+
* Turns on or off debug mode. With debug mode, all erros added to the OpenSSL
|
374
|
+
* error queue will be printed to stderr.
|
413
375
|
*/
|
414
376
|
static VALUE
|
415
377
|
ossl_debug_set(VALUE self, VALUE val)
|
416
378
|
{
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
if (old != dOSSL) {
|
421
|
-
if (dOSSL == Qtrue) {
|
422
|
-
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
|
423
|
-
fprintf(stderr, "OSSL_DEBUG: IS NOW ON!\n");
|
424
|
-
} else if (old == Qtrue) {
|
425
|
-
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);
|
426
|
-
fprintf(stderr, "OSSL_DEBUG: IS NOW OFF!\n");
|
427
|
-
}
|
428
|
-
}
|
379
|
+
dOSSL = RTEST(val) ? Qtrue : Qfalse;
|
380
|
+
|
429
381
|
return val;
|
430
382
|
}
|
431
383
|
|
@@ -438,15 +390,14 @@ ossl_debug_set(VALUE self, VALUE val)
|
|
438
390
|
* so otherwise will result in an error.
|
439
391
|
*
|
440
392
|
* === Examples
|
441
|
-
*
|
442
|
-
*
|
443
|
-
* OpenSSL.fips_mode = false # and off again
|
393
|
+
* OpenSSL.fips_mode = true # turn FIPS mode on
|
394
|
+
* OpenSSL.fips_mode = false # and off again
|
444
395
|
*/
|
445
396
|
static VALUE
|
446
397
|
ossl_fips_mode_set(VALUE self, VALUE enabled)
|
447
398
|
{
|
448
399
|
|
449
|
-
#ifdef
|
400
|
+
#ifdef OPENSSL_FIPS
|
450
401
|
if (RTEST(enabled)) {
|
451
402
|
int mode = FIPS_mode();
|
452
403
|
if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */
|
@@ -463,44 +414,123 @@ ossl_fips_mode_set(VALUE self, VALUE enabled)
|
|
463
414
|
#endif
|
464
415
|
}
|
465
416
|
|
417
|
+
#if defined(OSSL_DEBUG)
|
418
|
+
#if !defined(LIBRESSL_VERSION_NUMBER) && \
|
419
|
+
(OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \
|
420
|
+
defined(CRYPTO_malloc_debug_init))
|
421
|
+
/*
|
422
|
+
* call-seq:
|
423
|
+
* OpenSSL.mem_check_start -> nil
|
424
|
+
*
|
425
|
+
* Calls CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON). Starts tracking memory
|
426
|
+
* allocations. See also OpenSSL.print_mem_leaks.
|
427
|
+
*
|
428
|
+
* This is available only when built with a capable OpenSSL and --enable-debug
|
429
|
+
* configure option.
|
430
|
+
*/
|
431
|
+
static VALUE
|
432
|
+
mem_check_start(VALUE self)
|
433
|
+
{
|
434
|
+
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
|
435
|
+
return Qnil;
|
436
|
+
}
|
437
|
+
|
438
|
+
/*
|
439
|
+
* call-seq:
|
440
|
+
* OpenSSL.print_mem_leaks -> true | false
|
441
|
+
*
|
442
|
+
* For debugging the Ruby/OpenSSL library. Calls CRYPTO_mem_leaks_fp(stderr).
|
443
|
+
* Prints detected memory leaks to standard error. This cleans the global state
|
444
|
+
* up thus you cannot use any methods of the library after calling this.
|
445
|
+
*
|
446
|
+
* Returns true if leaks detected, false otherwise.
|
447
|
+
*
|
448
|
+
* This is available only when built with a capable OpenSSL and --enable-debug
|
449
|
+
* configure option.
|
450
|
+
*
|
451
|
+
* === Example
|
452
|
+
* OpenSSL.mem_check_start
|
453
|
+
* NOT_GCED = OpenSSL::PKey::RSA.new(256)
|
454
|
+
*
|
455
|
+
* END {
|
456
|
+
* GC.start
|
457
|
+
* OpenSSL.print_mem_leaks # will print the leakage
|
458
|
+
* }
|
459
|
+
*/
|
460
|
+
static VALUE
|
461
|
+
print_mem_leaks(VALUE self)
|
462
|
+
{
|
463
|
+
#if OPENSSL_VERSION_NUMBER >= 0x10100000
|
464
|
+
int ret;
|
465
|
+
#endif
|
466
|
+
|
467
|
+
BN_CTX_free(ossl_bn_ctx);
|
468
|
+
ossl_bn_ctx = NULL;
|
469
|
+
|
470
|
+
#if OPENSSL_VERSION_NUMBER >= 0x10100000
|
471
|
+
ret = CRYPTO_mem_leaks_fp(stderr);
|
472
|
+
if (ret < 0)
|
473
|
+
ossl_raise(eOSSLError, "CRYPTO_mem_leaks_fp");
|
474
|
+
return ret ? Qfalse : Qtrue;
|
475
|
+
#else
|
476
|
+
CRYPTO_mem_leaks_fp(stderr);
|
477
|
+
return Qnil;
|
478
|
+
#endif
|
479
|
+
}
|
480
|
+
#endif
|
481
|
+
#endif
|
482
|
+
|
483
|
+
#if !defined(HAVE_OPENSSL_110_THREADING_API)
|
466
484
|
/**
|
467
485
|
* Stores locks needed for OpenSSL thread safety
|
468
486
|
*/
|
469
|
-
|
470
|
-
|
487
|
+
struct CRYPTO_dynlock_value {
|
488
|
+
rb_nativethread_lock_t lock;
|
489
|
+
rb_nativethread_id_t owner;
|
490
|
+
size_t count;
|
491
|
+
};
|
471
492
|
|
472
493
|
static void
|
473
|
-
|
494
|
+
ossl_lock_init(struct CRYPTO_dynlock_value *l)
|
474
495
|
{
|
475
|
-
|
476
|
-
|
477
|
-
} else {
|
478
|
-
rb_nativethread_lock_unlock(lock);
|
479
|
-
}
|
496
|
+
rb_nativethread_lock_initialize(&l->lock);
|
497
|
+
l->count = 0;
|
480
498
|
}
|
481
499
|
|
482
500
|
static void
|
483
|
-
|
501
|
+
ossl_lock_unlock(int mode, struct CRYPTO_dynlock_value *l)
|
484
502
|
{
|
485
|
-
|
503
|
+
if (mode & CRYPTO_LOCK) {
|
504
|
+
/* TODO: rb_nativethread_id_t is not necessarily compared with ==. */
|
505
|
+
rb_nativethread_id_t tid = rb_nativethread_self();
|
506
|
+
if (l->count && l->owner == tid) {
|
507
|
+
l->count++;
|
508
|
+
return;
|
509
|
+
}
|
510
|
+
rb_nativethread_lock_lock(&l->lock);
|
511
|
+
l->owner = tid;
|
512
|
+
l->count = 1;
|
513
|
+
} else {
|
514
|
+
if (!--l->count)
|
515
|
+
rb_nativethread_lock_unlock(&l->lock);
|
516
|
+
}
|
486
517
|
}
|
487
518
|
|
488
|
-
struct CRYPTO_dynlock_value {
|
489
|
-
rb_nativethread_lock_t lock;
|
490
|
-
};
|
491
|
-
|
492
519
|
static struct CRYPTO_dynlock_value *
|
493
520
|
ossl_dyn_create_callback(const char *file, int line)
|
494
521
|
{
|
495
|
-
|
496
|
-
|
522
|
+
/* Do not use xmalloc() here, since it may raise NoMemoryError */
|
523
|
+
struct CRYPTO_dynlock_value *dynlock =
|
524
|
+
OPENSSL_malloc(sizeof(struct CRYPTO_dynlock_value));
|
525
|
+
if (dynlock)
|
526
|
+
ossl_lock_init(dynlock);
|
497
527
|
return dynlock;
|
498
528
|
}
|
499
529
|
|
500
530
|
static void
|
501
531
|
ossl_dyn_lock_callback(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)
|
502
532
|
{
|
503
|
-
ossl_lock_unlock(mode,
|
533
|
+
ossl_lock_unlock(mode, l);
|
504
534
|
}
|
505
535
|
|
506
536
|
static void
|
@@ -524,21 +554,22 @@ static unsigned long ossl_thread_id(void)
|
|
524
554
|
}
|
525
555
|
#endif
|
526
556
|
|
557
|
+
static struct CRYPTO_dynlock_value *ossl_locks;
|
558
|
+
|
559
|
+
static void
|
560
|
+
ossl_lock_callback(int mode, int type, const char *file, int line)
|
561
|
+
{
|
562
|
+
ossl_lock_unlock(mode, &ossl_locks[type]);
|
563
|
+
}
|
564
|
+
|
527
565
|
static void Init_ossl_locks(void)
|
528
566
|
{
|
529
567
|
int i;
|
530
568
|
int num_locks = CRYPTO_num_locks();
|
531
569
|
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
ossl_locks = (rb_nativethread_lock_t *) OPENSSL_malloc(num_locks * (int)sizeof(rb_nativethread_lock_t));
|
536
|
-
if (!ossl_locks) {
|
537
|
-
rb_raise(rb_eNoMemError, "CRYPTO_num_locks() is too big: %d", num_locks);
|
538
|
-
}
|
539
|
-
for (i = 0; i < num_locks; i++) {
|
540
|
-
rb_nativethread_lock_initialize(&ossl_locks[i]);
|
541
|
-
}
|
570
|
+
ossl_locks = ALLOC_N(struct CRYPTO_dynlock_value, num_locks);
|
571
|
+
for (i = 0; i < num_locks; i++)
|
572
|
+
ossl_lock_init(&ossl_locks[i]);
|
542
573
|
|
543
574
|
#ifdef HAVE_CRYPTO_THREADID_PTR
|
544
575
|
CRYPTO_THREADID_set_callback(ossl_threadid_func);
|
@@ -550,25 +581,12 @@ static void Init_ossl_locks(void)
|
|
550
581
|
CRYPTO_set_dynlock_lock_callback(ossl_dyn_lock_callback);
|
551
582
|
CRYPTO_set_dynlock_destroy_callback(ossl_dyn_destroy_callback);
|
552
583
|
}
|
584
|
+
#endif /* !HAVE_OPENSSL_110_THREADING_API */
|
553
585
|
|
554
586
|
/*
|
555
587
|
* OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
|
556
588
|
* OpenSSL[http://www.openssl.org/] library.
|
557
589
|
*
|
558
|
-
* = Install
|
559
|
-
*
|
560
|
-
* OpenSSL comes bundled with the Standard Library of Ruby.
|
561
|
-
*
|
562
|
-
* This means the OpenSSL extension is compiled with Ruby and packaged on
|
563
|
-
* build. During compile time, Ruby will need to link against the OpenSSL
|
564
|
-
* library on your system. However, you cannot use openssl provided by Apple to
|
565
|
-
* build standard library openssl.
|
566
|
-
*
|
567
|
-
* If you use OSX, you should install another openssl and run ```./configure
|
568
|
-
* --with-openssl-dir=/path/to/another-openssl```. For Homebrew user, run `brew
|
569
|
-
* install openssl` and then ```./configure --with-openssl-dir=`brew --prefix
|
570
|
-
* openssl` ```.
|
571
|
-
*
|
572
590
|
* = Examples
|
573
591
|
*
|
574
592
|
* All examples assume you have loaded OpenSSL with:
|
@@ -613,10 +631,12 @@ static void Init_ossl_locks(void)
|
|
613
631
|
*
|
614
632
|
* key2 = OpenSSL::PKey::RSA.new File.read 'private_key.pem'
|
615
633
|
* key2.public? # => true
|
634
|
+
* key2.private? # => true
|
616
635
|
*
|
617
636
|
* or
|
618
637
|
*
|
619
638
|
* key3 = OpenSSL::PKey::RSA.new File.read 'public_key.pem'
|
639
|
+
* key3.public? # => true
|
620
640
|
* key3.private? # => false
|
621
641
|
*
|
622
642
|
* === Loading an Encrypted Key
|
@@ -626,6 +646,7 @@ static void Init_ossl_locks(void)
|
|
626
646
|
* loading the key:
|
627
647
|
*
|
628
648
|
* key4_pem = File.read 'private.secure.pem'
|
649
|
+
* pass_phrase = 'my secure pass phrase goes here'
|
629
650
|
* key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
|
630
651
|
*
|
631
652
|
* == RSA Encryption
|
@@ -790,6 +811,7 @@ static void Init_ossl_locks(void)
|
|
790
811
|
* This example creates a self-signed certificate using an RSA key and a SHA1
|
791
812
|
* signature.
|
792
813
|
*
|
814
|
+
* key = OpenSSL::PKey::RSA.new 2048
|
793
815
|
* name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
|
794
816
|
*
|
795
817
|
* cert = OpenSSL::X509::Certificate.new
|
@@ -859,8 +881,9 @@ static void Init_ossl_locks(void)
|
|
859
881
|
* not readable by other users.
|
860
882
|
*
|
861
883
|
* ca_key = OpenSSL::PKey::RSA.new 2048
|
884
|
+
* pass_phrase = 'my secure pass phrase goes here'
|
862
885
|
*
|
863
|
-
* cipher = OpenSSL::Cipher
|
886
|
+
* cipher = OpenSSL::Cipher.new 'AES-128-CBC'
|
864
887
|
*
|
865
888
|
* open 'ca_key.pem', 'w', 0400 do |io|
|
866
889
|
* io.write ca_key.export(cipher, pass_phrase)
|
@@ -1013,15 +1036,21 @@ static void Init_ossl_locks(void)
|
|
1013
1036
|
* SSLSocket#connect must be called to initiate the SSL handshake and start
|
1014
1037
|
* encryption. A key and certificate are not required for the client socket.
|
1015
1038
|
*
|
1039
|
+
* Note that SSLSocket#close doesn't close the underlying socket by default. Set
|
1040
|
+
* SSLSocket#sync_close to true if you want.
|
1041
|
+
*
|
1016
1042
|
* require 'socket'
|
1017
1043
|
*
|
1018
|
-
*
|
1019
|
-
* ssl_client = OpenSSL::SSL::SSLSocket.new
|
1044
|
+
* tcp_socket = TCPSocket.new 'localhost', 5000
|
1045
|
+
* ssl_client = OpenSSL::SSL::SSLSocket.new tcp_socket, context
|
1046
|
+
* ssl_client.sync_close = true
|
1020
1047
|
* ssl_client.connect
|
1021
1048
|
*
|
1022
1049
|
* ssl_client.puts "hello server!"
|
1023
1050
|
* puts ssl_client.gets
|
1024
1051
|
*
|
1052
|
+
* ssl_client.close # shutdown the TLS connection and close tcp_socket
|
1053
|
+
*
|
1025
1054
|
* === Peer Verification
|
1026
1055
|
*
|
1027
1056
|
* An unverified SSL connection does not provide much security. For enhanced
|
@@ -1035,8 +1064,8 @@ static void Init_ossl_locks(void)
|
|
1035
1064
|
*
|
1036
1065
|
* require 'socket'
|
1037
1066
|
*
|
1038
|
-
*
|
1039
|
-
* ssl_client = OpenSSL::SSL::SSLSocket.new
|
1067
|
+
* tcp_socket = TCPSocket.new 'localhost', 5000
|
1068
|
+
* ssl_client = OpenSSL::SSL::SSLSocket.new tcp_socket, context
|
1040
1069
|
* ssl_client.connect
|
1041
1070
|
*
|
1042
1071
|
* ssl_client.puts "hello server!"
|
@@ -1049,6 +1078,7 @@ static void Init_ossl_locks(void)
|
|
1049
1078
|
void
|
1050
1079
|
Init_openssl(void)
|
1051
1080
|
{
|
1081
|
+
#undef rb_intern
|
1052
1082
|
/*
|
1053
1083
|
* Init timezone info
|
1054
1084
|
*/
|
@@ -1110,11 +1140,14 @@ Init_openssl(void)
|
|
1110
1140
|
/*
|
1111
1141
|
* Boolean indicating whether OpenSSL is FIPS-enabled or not
|
1112
1142
|
*/
|
1113
|
-
|
1114
|
-
|
1143
|
+
rb_define_const(mOSSL, "OPENSSL_FIPS",
|
1144
|
+
#ifdef OPENSSL_FIPS
|
1145
|
+
Qtrue
|
1115
1146
|
#else
|
1116
|
-
|
1147
|
+
Qfalse
|
1117
1148
|
#endif
|
1149
|
+
);
|
1150
|
+
|
1118
1151
|
rb_define_module_function(mOSSL, "fips_mode=", ossl_fips_mode_set, 1);
|
1119
1152
|
|
1120
1153
|
/*
|
@@ -1124,12 +1157,6 @@ Init_openssl(void)
|
|
1124
1157
|
eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);
|
1125
1158
|
rb_global_variable(&eOSSLError);
|
1126
1159
|
|
1127
|
-
/*
|
1128
|
-
* Verify callback Proc index for ext-data
|
1129
|
-
*/
|
1130
|
-
if ((ossl_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, (void *)"ossl_verify_cb_idx", 0, 0, 0)) < 0)
|
1131
|
-
ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index");
|
1132
|
-
|
1133
1160
|
/*
|
1134
1161
|
* Init debug core
|
1135
1162
|
*/
|
@@ -1145,7 +1172,9 @@ Init_openssl(void)
|
|
1145
1172
|
*/
|
1146
1173
|
ossl_s_to_der = rb_intern("to_der");
|
1147
1174
|
|
1175
|
+
#if !defined(HAVE_OPENSSL_110_THREADING_API)
|
1148
1176
|
Init_ossl_locks();
|
1177
|
+
#endif
|
1149
1178
|
|
1150
1179
|
/*
|
1151
1180
|
* Init components
|
@@ -1166,15 +1195,40 @@ Init_openssl(void)
|
|
1166
1195
|
Init_ossl_ocsp();
|
1167
1196
|
Init_ossl_engine();
|
1168
1197
|
Init_ossl_asn1();
|
1169
|
-
}
|
1170
1198
|
|
1171
1199
|
#if defined(OSSL_DEBUG)
|
1172
|
-
/*
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
1200
|
+
/*
|
1201
|
+
* For debugging Ruby/OpenSSL. Enable only when built with --enable-debug
|
1202
|
+
*/
|
1203
|
+
#if !defined(LIBRESSL_VERSION_NUMBER) && \
|
1204
|
+
(OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \
|
1205
|
+
defined(CRYPTO_malloc_debug_init))
|
1206
|
+
rb_define_module_function(mOSSL, "mem_check_start", mem_check_start, 0);
|
1207
|
+
rb_define_module_function(mOSSL, "print_mem_leaks", print_mem_leaks, 0);
|
1208
|
+
|
1209
|
+
#if defined(CRYPTO_malloc_debug_init) /* <= 1.0.2 */
|
1210
|
+
CRYPTO_malloc_debug_init();
|
1211
|
+
#endif
|
1212
|
+
|
1213
|
+
#if defined(V_CRYPTO_MDEBUG_ALL) /* <= 1.0.2 */
|
1214
|
+
CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
|
1215
|
+
#endif
|
1216
|
+
|
1217
|
+
#if OPENSSL_VERSION_NUMBER < 0x10100000 /* <= 1.0.2 */
|
1218
|
+
{
|
1219
|
+
int i;
|
1220
|
+
/*
|
1221
|
+
* See crypto/ex_data.c; call def_get_class() immediately to avoid
|
1222
|
+
* allocations. 15 is the maximum number that is used as the class index
|
1223
|
+
* in OpenSSL 1.0.2.
|
1224
|
+
*/
|
1225
|
+
for (i = 0; i <= 15; i++) {
|
1226
|
+
if (CRYPTO_get_ex_new_index(i, 0, (void *)"ossl-mdebug-dummy", 0, 0, 0) < 0)
|
1227
|
+
rb_raise(rb_eRuntimeError, "CRYPTO_get_ex_new_index for "
|
1228
|
+
"class index %d failed", i);
|
1229
|
+
}
|
1230
|
+
}
|
1231
|
+
#endif
|
1232
|
+
#endif
|
1233
|
+
#endif
|
1179
1234
|
}
|
1180
|
-
#endif /* OSSL_DEBUG */
|