rubysl-openssl 2.10 → 2.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +5 -5
  2. data/ext/rubysl/openssl/deprecation.rb +7 -3
  3. data/ext/rubysl/openssl/extconf.rb +148 -103
  4. data/ext/rubysl/openssl/openssl_missing.c +94 -275
  5. data/ext/rubysl/openssl/openssl_missing.h +167 -98
  6. data/ext/rubysl/openssl/ossl.c +266 -212
  7. data/ext/rubysl/openssl/ossl.h +27 -89
  8. data/ext/rubysl/openssl/ossl_asn1.c +157 -221
  9. data/ext/rubysl/openssl/ossl_asn1.h +11 -3
  10. data/ext/rubysl/openssl/ossl_bio.c +10 -40
  11. data/ext/rubysl/openssl/ossl_bio.h +1 -2
  12. data/ext/rubysl/openssl/ossl_bn.c +144 -100
  13. data/ext/rubysl/openssl/ossl_bn.h +3 -1
  14. data/ext/rubysl/openssl/ossl_cipher.c +270 -195
  15. data/ext/rubysl/openssl/ossl_config.c +7 -1
  16. data/ext/rubysl/openssl/ossl_config.h +0 -1
  17. data/ext/rubysl/openssl/ossl_digest.c +40 -29
  18. data/ext/rubysl/openssl/ossl_engine.c +23 -62
  19. data/ext/rubysl/openssl/ossl_hmac.c +82 -55
  20. data/ext/rubysl/openssl/ossl_ns_spki.c +22 -22
  21. data/ext/rubysl/openssl/ossl_ocsp.c +894 -144
  22. data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
  23. data/ext/rubysl/openssl/ossl_pkcs12.c +47 -19
  24. data/ext/rubysl/openssl/ossl_pkcs5.c +7 -15
  25. data/ext/rubysl/openssl/ossl_pkcs7.c +38 -15
  26. data/ext/rubysl/openssl/ossl_pkey.c +151 -99
  27. data/ext/rubysl/openssl/ossl_pkey.h +123 -29
  28. data/ext/rubysl/openssl/ossl_pkey_dh.c +143 -92
  29. data/ext/rubysl/openssl/ossl_pkey_dsa.c +149 -104
  30. data/ext/rubysl/openssl/ossl_pkey_ec.c +646 -524
  31. data/ext/rubysl/openssl/ossl_pkey_rsa.c +180 -121
  32. data/ext/rubysl/openssl/ossl_rand.c +25 -21
  33. data/ext/rubysl/openssl/ossl_ssl.c +795 -413
  34. data/ext/rubysl/openssl/ossl_ssl.h +3 -0
  35. data/ext/rubysl/openssl/ossl_ssl_session.c +83 -77
  36. data/ext/rubysl/openssl/ossl_version.h +1 -1
  37. data/ext/rubysl/openssl/ossl_x509.c +92 -8
  38. data/ext/rubysl/openssl/ossl_x509.h +14 -5
  39. data/ext/rubysl/openssl/ossl_x509attr.c +77 -41
  40. data/ext/rubysl/openssl/ossl_x509cert.c +45 -46
  41. data/ext/rubysl/openssl/ossl_x509crl.c +51 -57
  42. data/ext/rubysl/openssl/ossl_x509ext.c +39 -33
  43. data/ext/rubysl/openssl/ossl_x509name.c +68 -45
  44. data/ext/rubysl/openssl/ossl_x509req.c +32 -38
  45. data/ext/rubysl/openssl/ossl_x509revoked.c +43 -9
  46. data/ext/rubysl/openssl/ossl_x509store.c +309 -104
  47. data/ext/rubysl/openssl/ruby_missing.h +8 -6
  48. data/lib/openssl/buffering.rb +11 -5
  49. data/lib/openssl/cipher.rb +23 -15
  50. data/lib/openssl/digest.rb +7 -10
  51. data/lib/openssl/pkey.rb +15 -8
  52. data/lib/openssl/ssl.rb +81 -105
  53. data/lib/rubysl/openssl.rb +1 -4
  54. data/lib/rubysl/openssl/version.rb +1 -1
  55. 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
- #if defined(__cplusplus)
14
- extern "C" {
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
- #ifndef TYPEDEF_D2I_OF
18
- typedef char *d2i_of_void();
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
- #ifndef TYPEDEF_I2D_OF
21
- typedef int i2d_of_void();
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
- * These functions are not included in headers of OPENSSL <= 0.9.6b
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(PEM_read_bio_DSAPublicKey)
29
- # define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
30
- (d2i_of_void *)d2i_DSAPublicKey,PEM_STRING_DSA_PUBLIC,(bp),(void **)(x),(cb),(u))
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(PEM_write_bio_DSAPublicKey)
34
- # define PEM_write_bio_DSAPublicKey(bp,x) \
35
- PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPublicKey,\
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(DSAPrivateKey_dup)
41
- # define DSAPrivateKey_dup(dsa) (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, \
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(DSAPublicKey_dup)
46
- # define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPublicKey, \
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(X509_REVOKED_dup)
51
- # define X509_REVOKED_dup(rev) (X509_REVOKED *)ASN1_dup((i2d_of_void *)i2d_X509_REVOKED, \
52
- (d2i_of_void *)d2i_X509_REVOKED, (char *)(rev))
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(PKCS7_SIGNER_INFO_dup)
56
- # define PKCS7_SIGNER_INFO_dup(si) (PKCS7_SIGNER_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_SIGNER_INFO, \
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
- #if !defined(PKCS7_RECIP_INFO_dup)
61
- # define PKCS7_RECIP_INFO_dup(ri) (PKCS7_RECIP_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO, \
62
- (d2i_of_void *)d2i_PKCS7_RECIP_INFO, (char *)(ri))
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(HAVE_HMAC_CTX_INIT)
66
- void HMAC_CTX_init(HMAC_CTX *ctx);
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(HAVE_HMAC_CTX_COPY)
70
- void HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in);
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(HAVE_HMAC_CTX_CLEANUP)
74
- void HMAC_CTX_cleanup(HMAC_CTX *ctx);
79
+ #if !defined(HAVE_SSL_IS_SERVER)
80
+ # define SSL_is_server(s) ((s)->server)
75
81
  #endif
76
82
 
77
- #if !defined(HAVE_EVP_MD_CTX_CREATE)
78
- EVP_MD_CTX *EVP_MD_CTX_create(void);
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(HAVE_EVP_MD_CTX_INIT)
82
- void EVP_MD_CTX_init(EVP_MD_CTX *ctx);
88
+ #if !defined(HAVE_BN_GENCB_FREE)
89
+ # define BN_GENCB_free(cb) OPENSSL_free(cb)
83
90
  #endif
84
91
 
85
- #if !defined(HAVE_EVP_MD_CTX_CLEANUP)
86
- int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
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(HAVE_EVP_MD_CTX_DESTROY)
90
- void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
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(HAVE_EVP_CIPHER_CTX_COPY)
94
- int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, EVP_CIPHER_CTX *in);
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(HAVE_EVP_DIGESTINIT_EX)
98
- # define EVP_DigestInit_ex(ctx, md, engine) EVP_DigestInit((ctx), (md))
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
- #if !defined(HAVE_EVP_DIGESTFINAL_EX)
101
- # define EVP_DigestFinal_ex(ctx, buf, len) EVP_DigestFinal((ctx), (buf), (len))
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(HAVE_EVP_CIPHERINIT_EX)
105
- # define EVP_CipherInit_ex(ctx, type, impl, key, iv, enc) EVP_CipherInit((ctx), (type), (key), (iv), (enc))
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
- #if !defined(HAVE_EVP_CIPHERFINAL_EX)
108
- # define EVP_CipherFinal_ex(ctx, outm, outl) EVP_CipherFinal((ctx), (outm), (outl))
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(EVP_CIPHER_name)
112
- # define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e))
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(EVP_MD_name)
116
- # define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_type(e))
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(HAVE_EVP_HMAC_INIT_EX)
120
- # define HMAC_Init_ex(ctx, key, len, digest, engine) HMAC_Init((ctx), (key), (len), (digest))
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(PKCS7_is_detached)
124
- # define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))
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(PKCS7_type_is_encrypted)
128
- # define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
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(HAVE_OPENSSL_CLEANSE)
132
- #define OPENSSL_cleanse(p, l) memset((p), 0, (l))
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(HAVE_X509_STORE_GET_EX_DATA)
136
- void *X509_STORE_get_ex_data(X509_STORE *str, int idx);
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(HAVE_X509_STORE_SET_EX_DATA)
140
- int X509_STORE_set_ex_data(X509_STORE *str, int idx, void *data);
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(HAVE_X509_CRL_SET_VERSION)
144
- int X509_CRL_set_version(X509_CRL *x, long version);
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(HAVE_X509_CRL_SET_ISSUER_NAME)
148
- int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
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(HAVE_X509_CRL_SORT)
152
- int X509_CRL_sort(X509_CRL *c);
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(HAVE_X509_CRL_ADD0_REVOKED)
156
- int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
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(HAVE_BN_MOD_SQR)
160
- int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
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(HAVE_BN_MOD_ADD)
164
- int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
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(HAVE_BN_MOD_SUB)
168
- int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
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(HAVE_BN_RAND_RANGE)
172
- int BN_rand_range(BIGNUM *r, BIGNUM *range);
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(HAVE_BN_PSEUDO_RAND_RANGE)
176
- int BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range);
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(HAVE_CONF_GET1_DEFAULT_CONFIG_FILE)
180
- char *CONF_get1_default_config_file(void);
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(HAVE_PEM_DEF_CALLBACK)
184
- int PEM_def_callback(char *buf, int num, int w, void *key);
239
+ #if !defined(OPENSSL_NO_EC)
240
+ IMPL_PKEY_GETTER(EC_KEY, ec)
185
241
  #endif
186
242
 
187
- #if !defined(HAVE_ASN1_PUT_EOC)
188
- int ASN1_put_eoc(unsigned char **pp);
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(__cplusplus)
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_ */
@@ -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(*)_((VALUE)))ossl_##name##_ary2sk0, \
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(*)_((VALUE)))ossl_str_new, len, &status);
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
- static VALUE
151
- ossl_pem_passwd_cb0(VALUE flag)
132
+ VALUE
133
+ ossl_pem_passwd_value(VALUE pass)
152
134
  {
153
- VALUE pass;
135
+ if (NIL_P(pass))
136
+ return Qnil;
137
+
138
+ StringValue(pass);
154
139
 
155
- pass = rb_yield(flag);
156
- SafeStringValue(pass);
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 *pwd)
159
+ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
163
160
  {
164
- int len, status = 0;
165
- VALUE rflag, pass;
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 (pwd || !rb_block_given_p())
168
- return PEM_def_callback(buf, max_len, flag, pwd);
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
- len = RSTRING_LENINT(pass);
184
- if (len < 4) { /* 4 is OpenSSL hardcoded limit */
185
- rb_warning("password must be longer than 4 bytes");
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 shorter then %d bytes", max_len-1);
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
- if (dOSSL == Qtrue){ /* show all errors on the stack */
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
- VALUE
344
- ossl_exc_new(VALUE exc, const char *fmt, ...)
288
+ void
289
+ ossl_clear_error(void)
345
290
  {
346
- va_list args;
347
- VALUE err;
348
- va_start(args, fmt);
349
- err = ossl_make_error(exc, fmt, args);
350
- va_end(args);
351
- return err;
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 CRYPTO_MEM_CHECK.
412
- * Also shows some debugging message on stderr.
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
- VALUE old = dOSSL;
418
- dOSSL = val;
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
- * OpenSSL.fips_mode = true # turn FIPS mode on
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 HAVE_OPENSSL_FIPS
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
- #include "ruby/thread_native.h"
470
- static rb_nativethread_lock_t *ossl_locks;
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
- ossl_lock_unlock(int mode, rb_nativethread_lock_t *lock)
494
+ ossl_lock_init(struct CRYPTO_dynlock_value *l)
474
495
  {
475
- if (mode & CRYPTO_LOCK) {
476
- rb_nativethread_lock_lock(lock);
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
- ossl_lock_callback(int mode, int type, const char *file, int line)
501
+ ossl_lock_unlock(int mode, struct CRYPTO_dynlock_value *l)
484
502
  {
485
- ossl_lock_unlock(mode, &ossl_locks[type]);
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
- struct CRYPTO_dynlock_value *dynlock = (struct CRYPTO_dynlock_value *)OPENSSL_malloc((int)sizeof(struct CRYPTO_dynlock_value));
496
- rb_nativethread_lock_initialize(&dynlock->lock);
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, &l->lock);
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
- if ((unsigned)num_locks >= INT_MAX / (int)sizeof(VALUE)) {
533
- rb_raise(rb_eRuntimeError, "CRYPTO_num_locks() is too big: %d", num_locks);
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::Cipher.new 'AES-128-CBC'
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
- * tcp_client = TCPSocket.new 'localhost', 5000
1019
- * ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
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
- * tcp_client = TCPSocket.new 'localhost', 5000
1039
- * ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
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
- #ifdef HAVE_OPENSSL_FIPS
1114
- rb_define_const(mOSSL, "OPENSSL_FIPS", Qtrue);
1143
+ rb_define_const(mOSSL, "OPENSSL_FIPS",
1144
+ #ifdef OPENSSL_FIPS
1145
+ Qtrue
1115
1146
  #else
1116
- rb_define_const(mOSSL, "OPENSSL_FIPS", Qfalse);
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
- * Check if all symbols are OK with 'make LDSHARED=gcc all'
1174
- */
1175
- int
1176
- main(int argc, char *argv[])
1177
- {
1178
- return 0;
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 */