rubysl-openssl 0.0.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +0 -1
  3. data/.travis.yml +7 -0
  4. data/README.md +2 -2
  5. data/Rakefile +0 -1
  6. data/ext/rubysl/openssl/extconf.h +50 -0
  7. data/ext/rubysl/openssl/extconf.rb +144 -0
  8. data/ext/rubysl/openssl/openssl_missing.c +343 -0
  9. data/ext/rubysl/openssl/openssl_missing.h +191 -0
  10. data/ext/rubysl/openssl/ossl.c +552 -0
  11. data/ext/rubysl/openssl/ossl.h +233 -0
  12. data/ext/rubysl/openssl/ossl_asn1.c +1160 -0
  13. data/ext/rubysl/openssl/ossl_asn1.h +59 -0
  14. data/ext/rubysl/openssl/ossl_bio.c +86 -0
  15. data/ext/rubysl/openssl/ossl_bio.h +21 -0
  16. data/ext/rubysl/openssl/ossl_bn.c +852 -0
  17. data/ext/rubysl/openssl/ossl_bn.h +25 -0
  18. data/ext/rubysl/openssl/ossl_cipher.c +569 -0
  19. data/ext/rubysl/openssl/ossl_cipher.h +22 -0
  20. data/ext/rubysl/openssl/ossl_config.c +75 -0
  21. data/ext/rubysl/openssl/ossl_config.h +22 -0
  22. data/ext/rubysl/openssl/ossl_digest.c +259 -0
  23. data/ext/rubysl/openssl/ossl_digest.h +22 -0
  24. data/ext/rubysl/openssl/ossl_engine.c +411 -0
  25. data/ext/rubysl/openssl/ossl_engine.h +20 -0
  26. data/ext/rubysl/openssl/ossl_hmac.c +268 -0
  27. data/ext/rubysl/openssl/ossl_hmac.h +19 -0
  28. data/ext/rubysl/openssl/ossl_ns_spki.c +257 -0
  29. data/ext/rubysl/openssl/ossl_ns_spki.h +21 -0
  30. data/ext/rubysl/openssl/ossl_ocsp.c +769 -0
  31. data/ext/rubysl/openssl/ossl_ocsp.h +24 -0
  32. data/ext/rubysl/openssl/ossl_pkcs12.c +210 -0
  33. data/ext/rubysl/openssl/ossl_pkcs12.h +15 -0
  34. data/ext/rubysl/openssl/ossl_pkcs5.c +99 -0
  35. data/ext/rubysl/openssl/ossl_pkcs5.h +6 -0
  36. data/ext/rubysl/openssl/ossl_pkcs7.c +1039 -0
  37. data/ext/rubysl/openssl/ossl_pkcs7.h +22 -0
  38. data/ext/rubysl/openssl/ossl_pkey.c +240 -0
  39. data/ext/rubysl/openssl/ossl_pkey.h +141 -0
  40. data/ext/rubysl/openssl/ossl_pkey_dh.c +532 -0
  41. data/ext/rubysl/openssl/ossl_pkey_dsa.c +484 -0
  42. data/ext/rubysl/openssl/ossl_pkey_ec.c +1593 -0
  43. data/ext/rubysl/openssl/ossl_pkey_rsa.c +593 -0
  44. data/ext/rubysl/openssl/ossl_rand.c +202 -0
  45. data/ext/rubysl/openssl/ossl_rand.h +20 -0
  46. data/ext/rubysl/openssl/ossl_ssl.c +1484 -0
  47. data/ext/rubysl/openssl/ossl_ssl.h +36 -0
  48. data/ext/rubysl/openssl/ossl_ssl_session.c +307 -0
  49. data/ext/rubysl/openssl/ossl_version.h +16 -0
  50. data/ext/rubysl/openssl/ossl_x509.c +104 -0
  51. data/ext/rubysl/openssl/ossl_x509.h +114 -0
  52. data/ext/rubysl/openssl/ossl_x509attr.c +274 -0
  53. data/ext/rubysl/openssl/ossl_x509cert.c +764 -0
  54. data/ext/rubysl/openssl/ossl_x509crl.c +535 -0
  55. data/ext/rubysl/openssl/ossl_x509ext.c +458 -0
  56. data/ext/rubysl/openssl/ossl_x509name.c +399 -0
  57. data/ext/rubysl/openssl/ossl_x509req.c +466 -0
  58. data/ext/rubysl/openssl/ossl_x509revoked.c +229 -0
  59. data/ext/rubysl/openssl/ossl_x509store.c +625 -0
  60. data/ext/rubysl/openssl/ruby_missing.h +41 -0
  61. data/lib/openssl.rb +1 -0
  62. data/lib/openssl/bn.rb +35 -0
  63. data/lib/openssl/buffering.rb +241 -0
  64. data/lib/openssl/cipher.rb +65 -0
  65. data/lib/openssl/config.rb +316 -0
  66. data/lib/openssl/digest.rb +61 -0
  67. data/lib/openssl/net/ftptls.rb +53 -0
  68. data/lib/openssl/net/telnets.rb +251 -0
  69. data/lib/openssl/pkcs7.rb +25 -0
  70. data/lib/openssl/ssl-internal.rb +187 -0
  71. data/lib/openssl/ssl.rb +1 -0
  72. data/lib/openssl/x509-internal.rb +153 -0
  73. data/lib/openssl/x509.rb +1 -0
  74. data/lib/rubysl/openssl.rb +28 -0
  75. data/lib/rubysl/openssl/version.rb +5 -0
  76. data/rubysl-openssl.gemspec +19 -18
  77. data/spec/cipher_spec.rb +16 -0
  78. data/spec/config/freeze_spec.rb +17 -0
  79. data/spec/hmac/digest_spec.rb +15 -0
  80. data/spec/hmac/hexdigest_spec.rb +15 -0
  81. data/spec/random/pseudo_bytes_spec.rb +5 -0
  82. data/spec/random/random_bytes_spec.rb +5 -0
  83. data/spec/random/shared/random_bytes.rb +28 -0
  84. data/spec/shared/constants.rb +11 -0
  85. data/spec/x509/name/parse_spec.rb +47 -0
  86. metadata +153 -89
  87. data/lib/rubysl-openssl.rb +0 -7
  88. data/lib/rubysl-openssl/version.rb +0 -5
@@ -0,0 +1,191 @@
1
+ /*
2
+ * $Id$
3
+ * 'OpenSSL for Ruby' project
4
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
+ * All rights reserved.
6
+ */
7
+ /*
8
+ * This program is licenced under the same licence as Ruby.
9
+ * (See the file 'LICENCE'.)
10
+ */
11
+ #if !defined(_OSSL_OPENSSL_MISSING_H_)
12
+ #define _OSSL_OPENSSL_MISSING_H_
13
+
14
+ #if defined(__cplusplus)
15
+ extern "C" {
16
+ #endif
17
+
18
+ #ifndef TYPEDEF_D2I_OF
19
+ typedef char *d2i_of_void();
20
+ #endif
21
+ #ifndef TYPEDEF_I2D_OF
22
+ typedef int i2d_of_void();
23
+ #endif
24
+
25
+ /*
26
+ * These functions are not included in headers of OPENSSL <= 0.9.6b
27
+ */
28
+
29
+ #if !defined(PEM_read_bio_DSAPublicKey)
30
+ # define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
31
+ (void *(*)())d2i_DSAPublicKey,PEM_STRING_DSA_PUBLIC,bp,(void **)x,cb,u)
32
+ #endif
33
+
34
+ #if !defined(PEM_write_bio_DSAPublicKey)
35
+ # define PEM_write_bio_DSAPublicKey(bp,x) \
36
+ PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPublicKey,\
37
+ PEM_STRING_DSA_PUBLIC,\
38
+ bp,(char *)x, NULL, NULL, 0, NULL, NULL)
39
+ #endif
40
+
41
+ #if !defined(DSAPrivateKey_dup)
42
+ # define DSAPrivateKey_dup(dsa) (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, \
43
+ (void *(*)())d2i_DSAPrivateKey,(void *)dsa)
44
+ #endif
45
+
46
+ #if !defined(DSAPublicKey_dup)
47
+ # define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPublicKey, \
48
+ (void *(*)())d2i_DSAPublicKey,(void *)dsa)
49
+ #endif
50
+
51
+ #if !defined(X509_REVOKED_dup)
52
+ # define X509_REVOKED_dup(rev) (X509_REVOKED *)ASN1_dup((i2d_of_void *)i2d_X509_REVOKED, \
53
+ (void *(*)())d2i_X509_REVOKED, (void *)rev)
54
+ #endif
55
+
56
+ #if !defined(PKCS7_SIGNER_INFO_dup)
57
+ # define PKCS7_SIGNER_INFO_dup(si) (PKCS7_SIGNER_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_SIGNER_INFO, \
58
+ (void *(*)())d2i_PKCS7_SIGNER_INFO, (void *)si)
59
+ #endif
60
+
61
+ #if !defined(PKCS7_RECIP_INFO_dup)
62
+ # define PKCS7_RECIP_INFO_dup(ri) (PKCS7_RECIP_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO, \
63
+ (void *(*)())d2i_PKCS7_RECIP_INFO, (void *)ri)
64
+ #endif
65
+
66
+ #if !defined(HAVE_EVP_MD_CTX_INIT)
67
+ void HMAC_CTX_init(HMAC_CTX *ctx);
68
+ #endif
69
+
70
+ #if !defined(HAVE_HMAC_CTX_COPY)
71
+ void HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in);
72
+ #endif
73
+
74
+ #if !defined(HAVE_HMAC_CTX_CLEANUP)
75
+ void HMAC_CTX_cleanup(HMAC_CTX *ctx);
76
+ #endif
77
+
78
+ #if !defined(HAVE_EVP_MD_CTX_CREATE)
79
+ EVP_MD_CTX *EVP_MD_CTX_create(void);
80
+ #endif
81
+
82
+ #if !defined(HAVE_EVP_MD_CTX_INIT)
83
+ void EVP_MD_CTX_init(EVP_MD_CTX *ctx);
84
+ #endif
85
+
86
+ #if !defined(HAVE_EVP_MD_CTX_CLEANUP)
87
+ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
88
+ #endif
89
+
90
+ #if !defined(HAVE_EVP_MD_CTX_DESTROY)
91
+ void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
92
+ #endif
93
+
94
+ #if !defined(HAVE_EVP_CIPHER_CTX_COPY)
95
+ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, EVP_CIPHER_CTX *in);
96
+ #endif
97
+
98
+ #if !defined(HAVE_EVP_DIGESTINIT_EX)
99
+ # define EVP_DigestInit_ex(ctx, md, engine) EVP_DigestInit(ctx, md)
100
+ #endif
101
+ #if !defined(HAVE_EVP_DIGESTFINAL_EX)
102
+ # define EVP_DigestFinal_ex(ctx, buf, len) EVP_DigestFinal(ctx, buf, len)
103
+ #endif
104
+
105
+ #if !defined(HAVE_EVP_CIPHERINIT_EX)
106
+ # define EVP_CipherInit_ex(ctx, type, impl, key, iv, enc) EVP_CipherInit(ctx, type, key, iv, enc)
107
+ #endif
108
+ #if !defined(HAVE_EVP_CIPHERFINAL_EX)
109
+ # define EVP_CipherFinal_ex(ctx, outm, outl) EVP_CipherFinal(ctx, outm, outl)
110
+ #endif
111
+
112
+ #if !defined(EVP_CIPHER_name)
113
+ # define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e))
114
+ #endif
115
+
116
+ #if !defined(EVP_MD_name)
117
+ # define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_type(e))
118
+ #endif
119
+
120
+ #if !defined(HAVE_EVP_HMAC_INIT_EX)
121
+ # define HMAC_Init_ex(ctx, key, len, digest, engine) HMAC_Init(ctx, key, len, digest)
122
+ #endif
123
+
124
+ #if !defined(PKCS7_is_detached)
125
+ # define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))
126
+ #endif
127
+
128
+ #if !defined(PKCS7_type_is_encrypted)
129
+ # define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
130
+ #endif
131
+
132
+ #if !defined(HAVE_OPENSSL_CLEANSE)
133
+ #define OPENSSL_cleanse(p, l) memset(p, 0, l)
134
+ #endif
135
+
136
+ #if !defined(HAVE_X509_STORE_SET_EX_DATA)
137
+ void *X509_STORE_get_ex_data(X509_STORE *str, int idx);
138
+ int X509_STORE_set_ex_data(X509_STORE *str, int idx, void *data);
139
+ #endif
140
+
141
+ #if !defined(HAVE_X509_CRL_SET_VERSION)
142
+ int X509_CRL_set_version(X509_CRL *x, long version);
143
+ #endif
144
+
145
+ #if !defined(HAVE_X509_CRL_SET_ISSUER_NAME)
146
+ int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
147
+ #endif
148
+
149
+ #if !defined(HAVE_X509_CRL_SORT)
150
+ int X509_CRL_sort(X509_CRL *c);
151
+ #endif
152
+
153
+ #if !defined(HAVE_X509_CRL_ADD0_REVOKED)
154
+ int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
155
+ #endif
156
+
157
+ #if !defined(HAVE_BN_MOD_SQR)
158
+ int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
159
+ #endif
160
+
161
+ #if !defined(HAVE_BN_MOD_ADD)
162
+ int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
163
+ #endif
164
+
165
+ #if !defined(HAVE_BN_MOD_SUB)
166
+ int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
167
+ #endif
168
+
169
+ #if !defined(HAVE_BN_RAND_RANGE)
170
+ int BN_rand_range(BIGNUM *r, BIGNUM *range);
171
+ #endif
172
+
173
+ #if !defined(HAVE_BN_PSEUDO_RAND_RANGE)
174
+ int BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range);
175
+ #endif
176
+
177
+ #if !defined(HAVE_CONF_GET1_DEFAULT_CONFIG_FILE)
178
+ char *CONF_get1_default_config_file(void);
179
+ #endif
180
+
181
+ #if !defined(HAVE_PEM_DEF_CALLBACK)
182
+ int PEM_def_callback(char *buf, int num, int w, void *key);
183
+ #endif
184
+
185
+ #if defined(__cplusplus)
186
+ }
187
+ #endif
188
+
189
+
190
+ #endif /* _OSSL_OPENSSL_MISSING_H_ */
191
+
@@ -0,0 +1,552 @@
1
+ /*
2
+ * $Id: ossl.c 28367 2010-06-21 09:18:59Z shyouhei $
3
+ * 'OpenSSL for Ruby' project
4
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
+ * All rights reserved.
6
+ */
7
+ /*
8
+ * This program is licenced under the same licence as Ruby.
9
+ * (See the file 'LICENCE'.)
10
+ */
11
+ #include "ossl.h"
12
+ #include <stdarg.h> /* for ossl_raise */
13
+
14
+ /*
15
+ * String to HEXString conversion
16
+ */
17
+ int
18
+ string2hex(char *buf, int buf_len, char **hexbuf, int *hexbuf_len)
19
+ {
20
+ static const char hex[]="0123456789abcdef";
21
+ int i, len = 2 * buf_len;
22
+
23
+ if (buf_len < 0 || len < buf_len) { /* PARANOIA? */
24
+ return -1;
25
+ }
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
+ }
46
+
47
+ /*
48
+ * Data Conversion
49
+ */
50
+ STACK_OF(X509) *
51
+ ossl_x509_ary2sk0(VALUE ary)
52
+ {
53
+ STACK_OF(X509) *sk;
54
+ VALUE val;
55
+ X509 *x509;
56
+ int i;
57
+
58
+ Check_Type(ary, T_ARRAY);
59
+ sk = sk_X509_new_null();
60
+ if (!sk) ossl_raise(eOSSLError, NULL);
61
+
62
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
63
+ val = rb_ary_entry(ary, i);
64
+ if (!rb_obj_is_kind_of(val, cX509Cert)) {
65
+ sk_X509_pop_free(sk, X509_free);
66
+ ossl_raise(eOSSLError, "object not X509 cert in array");
67
+ }
68
+ x509 = DupX509CertPtr(val); /* NEED TO DUP */
69
+ sk_X509_push(sk, x509);
70
+ }
71
+ return sk;
72
+ }
73
+
74
+ STACK_OF(X509) *
75
+ ossl_protect_x509_ary2sk(VALUE ary, int *status)
76
+ {
77
+ return (STACK_OF(X509)*)rb_protect((VALUE(*)_((VALUE)))ossl_x509_ary2sk0,
78
+ ary, status);
79
+ }
80
+
81
+ STACK_OF(X509) *
82
+ ossl_x509_ary2sk(VALUE ary)
83
+ {
84
+ STACK_OF(X509) *sk;
85
+ int status = 0;
86
+
87
+ sk = ossl_protect_x509_ary2sk(ary, &status);
88
+ if(status) rb_jump_tag(status);
89
+
90
+ return sk;
91
+ }
92
+
93
+ #define OSSL_IMPL_SK2ARY(name, type) \
94
+ VALUE \
95
+ ossl_##name##_sk2ary(STACK_OF(type) *sk) \
96
+ { \
97
+ type *t; \
98
+ int i, num; \
99
+ VALUE ary; \
100
+ \
101
+ if (!sk) { \
102
+ OSSL_Debug("empty sk!"); \
103
+ return Qnil; \
104
+ } \
105
+ num = sk_##type##_num(sk); \
106
+ if (num < 0) { \
107
+ OSSL_Debug("items in sk < -1???"); \
108
+ return rb_ary_new(); \
109
+ } \
110
+ ary = rb_ary_new2(num); \
111
+ \
112
+ for (i=0; i<num; i++) { \
113
+ t = sk_##type##_value(sk, i); \
114
+ rb_ary_push(ary, ossl_##name##_new(t)); \
115
+ } \
116
+ return ary; \
117
+ }
118
+ OSSL_IMPL_SK2ARY(x509, X509)
119
+ OSSL_IMPL_SK2ARY(x509crl, X509_CRL)
120
+
121
+ static VALUE
122
+ ossl_str_new(int size)
123
+ {
124
+ return rb_str_new(0, size);
125
+ }
126
+
127
+ VALUE
128
+ ossl_buf2str(char *buf, int len)
129
+ {
130
+ VALUE str;
131
+ int status = 0;
132
+
133
+ str = rb_protect((VALUE(*)_((VALUE)))ossl_str_new, len, &status);
134
+ if(!NIL_P(str)) memcpy(RSTRING_PTR(str), buf, len);
135
+ OPENSSL_free(buf);
136
+ if(status) rb_jump_tag(status);
137
+
138
+ return str;
139
+ }
140
+
141
+ /*
142
+ * our default PEM callback
143
+ */
144
+ static VALUE
145
+ ossl_pem_passwd_cb0(VALUE flag)
146
+ {
147
+ VALUE pass;
148
+
149
+ pass = rb_yield(flag);
150
+ SafeStringValue(pass);
151
+
152
+ return pass;
153
+ }
154
+
155
+ int
156
+ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd)
157
+ {
158
+ int len, status = 0;
159
+ VALUE rflag, pass;
160
+
161
+ if (pwd || !rb_block_given_p())
162
+ return PEM_def_callback(buf, max_len, flag, pwd);
163
+
164
+ while (1) {
165
+ /*
166
+ * when the flag is nonzero, this passphrase
167
+ * will be used to perform encryption; otherwise it will
168
+ * be used to perform decryption.
169
+ */
170
+ rflag = flag ? Qtrue : Qfalse;
171
+ pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status);
172
+ if (status) return -1; /* exception was raised. */
173
+ len = RSTRING_LEN(pass);
174
+ if (len < 4) { /* 4 is OpenSSL hardcoded limit */
175
+ rb_warning("password must be longer than 4 bytes");
176
+ continue;
177
+ }
178
+ if (len > max_len) {
179
+ rb_warning("password must be shorter then %d bytes", max_len-1);
180
+ continue;
181
+ }
182
+ memcpy(buf, RSTRING_PTR(pass), len);
183
+ break;
184
+ }
185
+ return len;
186
+ }
187
+
188
+ /*
189
+ * Verify callback
190
+ */
191
+ int ossl_verify_cb_idx;
192
+
193
+ VALUE
194
+ ossl_call_verify_cb_proc(struct ossl_verify_cb_args *args)
195
+ {
196
+ return rb_funcall(args->proc, rb_intern("call"), 2,
197
+ args->preverify_ok, args->store_ctx);
198
+ }
199
+
200
+ int
201
+ ossl_verify_cb(int ok, X509_STORE_CTX *ctx)
202
+ {
203
+ VALUE proc, rctx, ret;
204
+ struct ossl_verify_cb_args args;
205
+ int state = 0;
206
+
207
+ proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, ossl_verify_cb_idx);
208
+ if ((void*)proc == 0)
209
+ proc = (VALUE)X509_STORE_get_ex_data(ctx->ctx, ossl_verify_cb_idx);
210
+ if ((void*)proc == 0)
211
+ return ok;
212
+ if (!NIL_P(proc)) {
213
+ rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new,
214
+ (VALUE)ctx, &state);
215
+ ret = Qfalse;
216
+ if (!state) {
217
+ args.proc = proc;
218
+ args.preverify_ok = ok ? Qtrue : Qfalse;
219
+ args.store_ctx = rctx;
220
+ ret = rb_ensure(ossl_call_verify_cb_proc, (VALUE)&args,
221
+ ossl_x509stctx_clear_ptr, rctx);
222
+ }
223
+ if (ret == Qtrue) {
224
+ X509_STORE_CTX_set_error(ctx, X509_V_OK);
225
+ ok = 1;
226
+ }
227
+ else{
228
+ if (X509_STORE_CTX_get_error(ctx) == X509_V_OK) {
229
+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
230
+ }
231
+ ok = 0;
232
+ }
233
+ }
234
+
235
+ return ok;
236
+ }
237
+
238
+ /*
239
+ * main module
240
+ */
241
+ VALUE mOSSL;
242
+
243
+ /*
244
+ * OpenSSLError < StandardError
245
+ */
246
+ VALUE eOSSLError;
247
+
248
+ /*
249
+ * Convert to DER string
250
+ */
251
+ ID ossl_s_to_der;
252
+
253
+ VALUE
254
+ ossl_to_der(VALUE obj)
255
+ {
256
+ VALUE tmp;
257
+
258
+ tmp = rb_funcall(obj, ossl_s_to_der, 0);
259
+ StringValue(tmp);
260
+
261
+ return tmp;
262
+ }
263
+
264
+ VALUE
265
+ ossl_to_der_if_possible(VALUE obj)
266
+ {
267
+ if(rb_respond_to(obj, ossl_s_to_der))
268
+ return ossl_to_der(obj);
269
+ return obj;
270
+ }
271
+
272
+ /*
273
+ * Errors
274
+ */
275
+ static VALUE
276
+ ossl_make_error(VALUE exc, const char *fmt, va_list args)
277
+ {
278
+ char buf[BUFSIZ];
279
+ const char *msg;
280
+ long e;
281
+ int len = 0;
282
+
283
+ #ifdef HAVE_ERR_PEEK_LAST_ERROR
284
+ e = ERR_peek_last_error();
285
+ #else
286
+ e = ERR_peek_error();
287
+ #endif
288
+ if (fmt) {
289
+ len = vsnprintf(buf, BUFSIZ, fmt, args);
290
+ }
291
+ if (len < BUFSIZ && e) {
292
+ if (dOSSL == Qtrue) /* FULL INFO */
293
+ msg = ERR_error_string(e, NULL);
294
+ else
295
+ msg = ERR_reason_error_string(e);
296
+ len += snprintf(buf+len, BUFSIZ-len, "%s%s", (len ? ": " : ""), msg);
297
+ }
298
+ if (dOSSL == Qtrue){ /* show all errors on the stack */
299
+ while ((e = ERR_get_error()) != 0){
300
+ rb_warn("error on stack: %s", ERR_error_string(e, NULL));
301
+ }
302
+ }
303
+ ERR_clear_error();
304
+
305
+ if(len > BUFSIZ) len = strlen(buf);
306
+ return rb_exc_new(exc, buf, len);
307
+ }
308
+
309
+ void
310
+ ossl_raise(VALUE exc, const char *fmt, ...)
311
+ {
312
+ va_list args;
313
+ VALUE err;
314
+ va_start(args, fmt);
315
+ err = ossl_make_error(exc, fmt, args);
316
+ va_end(args);
317
+ rb_exc_raise(err);
318
+ }
319
+
320
+ VALUE
321
+ ossl_exc_new(VALUE exc, const char *fmt, ...)
322
+ {
323
+ va_list args;
324
+ VALUE err;
325
+ va_start(args, fmt);
326
+ err = ossl_make_error(exc, fmt, args);
327
+ va_end(args);
328
+ return err;
329
+ }
330
+
331
+ /*
332
+ * call-seq:
333
+ * OpenSSL.errors -> [String...]
334
+ *
335
+ * See any remaining errors held in queue.
336
+ *
337
+ * Any errors you see here are probably due to a bug in ruby's OpenSSL implementation.
338
+ */
339
+ VALUE
340
+ ossl_get_errors()
341
+ {
342
+ VALUE ary;
343
+ long e;
344
+
345
+ ary = rb_ary_new();
346
+ while ((e = ERR_get_error()) != 0){
347
+ rb_ary_push(ary, rb_str_new2(ERR_error_string(e, NULL)));
348
+ }
349
+
350
+ return ary;
351
+ }
352
+
353
+ /*
354
+ * Debug
355
+ */
356
+ VALUE dOSSL;
357
+
358
+ #if !defined(HAVE_VA_ARGS_MACRO)
359
+ void
360
+ ossl_debug(const char *fmt, ...)
361
+ {
362
+ va_list args;
363
+
364
+ if (dOSSL == Qtrue) {
365
+ fprintf(stderr, "OSSL_DEBUG: ");
366
+ va_start(args, fmt);
367
+ vfprintf(stderr, fmt, args);
368
+ va_end(args);
369
+ fprintf(stderr, " [CONTEXT N/A]\n");
370
+ }
371
+ }
372
+ #endif
373
+
374
+ /*
375
+ * call-seq:
376
+ * OpenSSL.debug -> true | false
377
+ */
378
+ static VALUE
379
+ ossl_debug_get(VALUE self)
380
+ {
381
+ return dOSSL;
382
+ }
383
+
384
+ /*
385
+ * call-seq:
386
+ * OpenSSL.debug = boolean -> boolean
387
+ *
388
+ * Turns on or off CRYPTO_MEM_CHECK.
389
+ * Also shows some debugging message on stderr.
390
+ */
391
+ static VALUE
392
+ ossl_debug_set(VALUE self, VALUE val)
393
+ {
394
+ VALUE old = dOSSL;
395
+ dOSSL = val;
396
+
397
+ if (old != dOSSL) {
398
+ if (dOSSL == Qtrue) {
399
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
400
+ fprintf(stderr, "OSSL_DEBUG: IS NOW ON!\n");
401
+ } else if (old == Qtrue) {
402
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);
403
+ fprintf(stderr, "OSSL_DEBUG: IS NOW OFF!\n");
404
+ }
405
+ }
406
+ return val;
407
+ }
408
+
409
+ /**
410
+ * Stores locks needed for OpenSSL thread safety
411
+ */
412
+ static VALUE* ossl_locks;
413
+
414
+ static void ossl_lock_callback(int mode, int type, char *file, int line)
415
+ {
416
+ if (mode & CRYPTO_LOCK) {
417
+ rb_mutex_lock(ossl_locks[type]);
418
+ } else {
419
+ rb_mutex_unlock(ossl_locks[type]);
420
+ }
421
+ }
422
+
423
+ static unsigned long ossl_thread_id(void)
424
+ {
425
+ return NUM2ULONG(rb_obj_id(rb_thread_current()));
426
+ }
427
+
428
+ static void Init_ossl_locks(void)
429
+ {
430
+ int i;
431
+ ossl_locks = (VALUE*) OPENSSL_malloc(CRYPTO_num_locks() * sizeof(VALUE));
432
+ for (i = 0; i < CRYPTO_num_locks(); i++) {
433
+ ossl_locks[i] = rb_mutex_new();
434
+ rb_global_variable(&(ossl_locks[i]));
435
+ }
436
+
437
+ CRYPTO_set_id_callback((unsigned long (*)())ossl_thread_id);
438
+ CRYPTO_set_locking_callback((void (*)())ossl_lock_callback);
439
+ }
440
+
441
+ /*
442
+ * OSSL library init
443
+ */
444
+ void
445
+ Init_openssl()
446
+ {
447
+ /*
448
+ * Init timezone info
449
+ */
450
+ #if 0
451
+ tzset();
452
+ #endif
453
+
454
+ /*
455
+ * Init all digests, ciphers
456
+ */
457
+ /* CRYPTO_malloc_init(); */
458
+ /* ENGINE_load_builtin_engines(); */
459
+ OpenSSL_add_ssl_algorithms();
460
+ OpenSSL_add_all_algorithms();
461
+ ERR_load_crypto_strings();
462
+ SSL_load_error_strings();
463
+
464
+ /*
465
+ * FIXME:
466
+ * On unload do:
467
+ */
468
+ #if 0
469
+ CONF_modules_unload(1);
470
+ destroy_ui_method();
471
+ EVP_cleanup();
472
+ ENGINE_cleanup();
473
+ CRYPTO_cleanup_all_ex_data();
474
+ ERR_remove_state(0);
475
+ ERR_free_strings();
476
+ #endif
477
+
478
+ /*
479
+ * Init main module
480
+ */
481
+ mOSSL = rb_define_module("OpenSSL");
482
+ rb_global_variable(&mOSSL);
483
+
484
+ /*
485
+ * Constants
486
+ */
487
+ rb_define_const(mOSSL, "VERSION", rb_str_new2(OSSL_VERSION));
488
+ rb_define_const(mOSSL, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
489
+ rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));
490
+
491
+ /*
492
+ * Generic error,
493
+ * common for all classes under OpenSSL module
494
+ */
495
+ eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);
496
+ rb_global_variable(&eOSSLError);
497
+
498
+ /*
499
+ * Verify callback Proc index for ext-data
500
+ */
501
+ if ((ossl_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, "ossl_verify_cb_idx", 0, 0, 0)) < 0)
502
+ ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index");
503
+
504
+ /*
505
+ * Init debug core
506
+ */
507
+ dOSSL = Qfalse;
508
+ rb_global_variable(&dOSSL);
509
+
510
+ rb_define_module_function(mOSSL, "debug", ossl_debug_get, 0);
511
+ rb_define_module_function(mOSSL, "debug=", ossl_debug_set, 1);
512
+ rb_define_module_function(mOSSL, "errors", ossl_get_errors, 0);
513
+
514
+ /*
515
+ * Get ID of to_der
516
+ */
517
+ ossl_s_to_der = rb_intern("to_der");
518
+
519
+ Init_ossl_locks();
520
+
521
+ /*
522
+ * Init components
523
+ */
524
+ Init_ossl_bn();
525
+ Init_ossl_cipher();
526
+ Init_ossl_config();
527
+ Init_ossl_digest();
528
+ Init_ossl_hmac();
529
+ Init_ossl_ns_spki();
530
+ Init_ossl_pkcs12();
531
+ Init_ossl_pkcs7();
532
+ Init_ossl_pkcs5();
533
+ Init_ossl_pkey();
534
+ Init_ossl_rand();
535
+ Init_ossl_ssl();
536
+ Init_ossl_x509();
537
+ Init_ossl_ocsp();
538
+ Init_ossl_engine();
539
+ Init_ossl_asn1();
540
+ }
541
+
542
+ #if defined(OSSL_DEBUG)
543
+ /*
544
+ * Check if all symbols are OK with 'make LDSHARED=gcc all'
545
+ */
546
+ int
547
+ main(int argc, char *argv[], char *env[])
548
+ {
549
+ return 0;
550
+ }
551
+ #endif /* OSSL_DEBUG */
552
+