rubysl-openssl 2.10 → 2.11

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.
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 */