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.
- checksums.yaml +5 -5
- data/ext/rubysl/openssl/deprecation.rb +7 -3
- data/ext/rubysl/openssl/extconf.rb +148 -103
- data/ext/rubysl/openssl/openssl_missing.c +94 -275
- data/ext/rubysl/openssl/openssl_missing.h +167 -98
- data/ext/rubysl/openssl/ossl.c +266 -212
- data/ext/rubysl/openssl/ossl.h +27 -89
- data/ext/rubysl/openssl/ossl_asn1.c +157 -221
- data/ext/rubysl/openssl/ossl_asn1.h +11 -3
- data/ext/rubysl/openssl/ossl_bio.c +10 -40
- data/ext/rubysl/openssl/ossl_bio.h +1 -2
- data/ext/rubysl/openssl/ossl_bn.c +144 -100
- data/ext/rubysl/openssl/ossl_bn.h +3 -1
- data/ext/rubysl/openssl/ossl_cipher.c +270 -195
- data/ext/rubysl/openssl/ossl_config.c +7 -1
- data/ext/rubysl/openssl/ossl_config.h +0 -1
- data/ext/rubysl/openssl/ossl_digest.c +40 -29
- data/ext/rubysl/openssl/ossl_engine.c +23 -62
- data/ext/rubysl/openssl/ossl_hmac.c +82 -55
- data/ext/rubysl/openssl/ossl_ns_spki.c +22 -22
- data/ext/rubysl/openssl/ossl_ocsp.c +894 -144
- data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
- data/ext/rubysl/openssl/ossl_pkcs12.c +47 -19
- data/ext/rubysl/openssl/ossl_pkcs5.c +7 -15
- data/ext/rubysl/openssl/ossl_pkcs7.c +38 -15
- data/ext/rubysl/openssl/ossl_pkey.c +151 -99
- data/ext/rubysl/openssl/ossl_pkey.h +123 -29
- data/ext/rubysl/openssl/ossl_pkey_dh.c +143 -92
- data/ext/rubysl/openssl/ossl_pkey_dsa.c +149 -104
- data/ext/rubysl/openssl/ossl_pkey_ec.c +646 -524
- data/ext/rubysl/openssl/ossl_pkey_rsa.c +180 -121
- data/ext/rubysl/openssl/ossl_rand.c +25 -21
- data/ext/rubysl/openssl/ossl_ssl.c +795 -413
- data/ext/rubysl/openssl/ossl_ssl.h +3 -0
- data/ext/rubysl/openssl/ossl_ssl_session.c +83 -77
- data/ext/rubysl/openssl/ossl_version.h +1 -1
- data/ext/rubysl/openssl/ossl_x509.c +92 -8
- data/ext/rubysl/openssl/ossl_x509.h +14 -5
- data/ext/rubysl/openssl/ossl_x509attr.c +77 -41
- data/ext/rubysl/openssl/ossl_x509cert.c +45 -46
- data/ext/rubysl/openssl/ossl_x509crl.c +51 -57
- data/ext/rubysl/openssl/ossl_x509ext.c +39 -33
- data/ext/rubysl/openssl/ossl_x509name.c +68 -45
- data/ext/rubysl/openssl/ossl_x509req.c +32 -38
- data/ext/rubysl/openssl/ossl_x509revoked.c +43 -9
- data/ext/rubysl/openssl/ossl_x509store.c +309 -104
- data/ext/rubysl/openssl/ruby_missing.h +8 -6
- data/lib/openssl/buffering.rb +11 -5
- data/lib/openssl/cipher.rb +23 -15
- data/lib/openssl/digest.rb +7 -10
- data/lib/openssl/pkey.rb +15 -8
- data/lib/openssl/ssl.rb +81 -105
- data/lib/rubysl/openssl.rb +1 -4
- data/lib/rubysl/openssl/version.rb +1 -1
- metadata +3 -4
@@ -109,6 +109,25 @@ ossl_x509revoked_initialize(int argc, VALUE *argv, VALUE self)
|
|
109
109
|
return self;
|
110
110
|
}
|
111
111
|
|
112
|
+
static VALUE
|
113
|
+
ossl_x509revoked_initialize_copy(VALUE self, VALUE other)
|
114
|
+
{
|
115
|
+
X509_REVOKED *rev, *rev_other, *rev_new;
|
116
|
+
|
117
|
+
rb_check_frozen(self);
|
118
|
+
GetX509Rev(self, rev);
|
119
|
+
SafeGetX509Rev(other, rev_other);
|
120
|
+
|
121
|
+
rev_new = X509_REVOKED_dup(rev_other);
|
122
|
+
if (!rev_new)
|
123
|
+
ossl_raise(eX509RevError, "X509_REVOKED_dup");
|
124
|
+
|
125
|
+
SetX509Rev(self, rev_new);
|
126
|
+
X509_REVOKED_free(rev);
|
127
|
+
|
128
|
+
return self;
|
129
|
+
}
|
130
|
+
|
112
131
|
static VALUE
|
113
132
|
ossl_x509revoked_get_serial(VALUE self)
|
114
133
|
{
|
@@ -116,16 +135,22 @@ ossl_x509revoked_get_serial(VALUE self)
|
|
116
135
|
|
117
136
|
GetX509Rev(self, rev);
|
118
137
|
|
119
|
-
return asn1integer_to_num(rev
|
138
|
+
return asn1integer_to_num(X509_REVOKED_get0_serialNumber(rev));
|
120
139
|
}
|
121
140
|
|
122
141
|
static VALUE
|
123
142
|
ossl_x509revoked_set_serial(VALUE self, VALUE num)
|
124
143
|
{
|
125
144
|
X509_REVOKED *rev;
|
145
|
+
ASN1_INTEGER *asn1int;
|
126
146
|
|
127
147
|
GetX509Rev(self, rev);
|
128
|
-
|
148
|
+
asn1int = num_to_asn1integer(num, NULL);
|
149
|
+
if (!X509_REVOKED_set_serialNumber(rev, asn1int)) {
|
150
|
+
ASN1_INTEGER_free(asn1int);
|
151
|
+
ossl_raise(eX509RevError, "X509_REVOKED_set_serialNumber");
|
152
|
+
}
|
153
|
+
ASN1_INTEGER_free(asn1int);
|
129
154
|
|
130
155
|
return num;
|
131
156
|
}
|
@@ -137,20 +162,22 @@ ossl_x509revoked_get_time(VALUE self)
|
|
137
162
|
|
138
163
|
GetX509Rev(self, rev);
|
139
164
|
|
140
|
-
return asn1time_to_time(rev
|
165
|
+
return asn1time_to_time(X509_REVOKED_get0_revocationDate(rev));
|
141
166
|
}
|
142
167
|
|
143
168
|
static VALUE
|
144
169
|
ossl_x509revoked_set_time(VALUE self, VALUE time)
|
145
170
|
{
|
146
171
|
X509_REVOKED *rev;
|
147
|
-
|
172
|
+
ASN1_TIME *asn1time;
|
148
173
|
|
149
|
-
sec = time_to_time_t(time);
|
150
174
|
GetX509Rev(self, rev);
|
151
|
-
|
152
|
-
|
175
|
+
asn1time = ossl_x509_time_adjust(NULL, time);
|
176
|
+
if (!X509_REVOKED_set_revocationDate(rev, asn1time)) {
|
177
|
+
ASN1_TIME_free(asn1time);
|
178
|
+
ossl_raise(eX509RevError, "X509_REVOKED_set_revocationDate");
|
153
179
|
}
|
180
|
+
ASN1_TIME_free(asn1time);
|
154
181
|
|
155
182
|
return time;
|
156
183
|
}
|
@@ -196,8 +223,8 @@ ossl_x509revoked_set_extensions(VALUE self, VALUE ary)
|
|
196
223
|
OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
|
197
224
|
}
|
198
225
|
GetX509Rev(self, rev);
|
199
|
-
|
200
|
-
|
226
|
+
while ((ext = X509_REVOKED_delete_ext(rev, 0)))
|
227
|
+
X509_EXTENSION_free(ext);
|
201
228
|
for (i=0; i<RARRAY_LEN(ary); i++) {
|
202
229
|
item = RARRAY_AREF(ary, i);
|
203
230
|
ext = GetX509ExtPtr(item);
|
@@ -228,12 +255,19 @@ ossl_x509revoked_add_extension(VALUE self, VALUE ext)
|
|
228
255
|
void
|
229
256
|
Init_ossl_x509revoked(void)
|
230
257
|
{
|
258
|
+
#if 0
|
259
|
+
mOSSL = rb_define_module("OpenSSL");
|
260
|
+
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
261
|
+
mX509 = rb_define_module_under(mOSSL, "X509");
|
262
|
+
#endif
|
263
|
+
|
231
264
|
eX509RevError = rb_define_class_under(mX509, "RevokedError", eOSSLError);
|
232
265
|
|
233
266
|
cX509Rev = rb_define_class_under(mX509, "Revoked", rb_cObject);
|
234
267
|
|
235
268
|
rb_define_alloc_func(cX509Rev, ossl_x509revoked_alloc);
|
236
269
|
rb_define_method(cX509Rev, "initialize", ossl_x509revoked_initialize, -1);
|
270
|
+
rb_define_copy_func(cX509Rev, ossl_x509revoked_initialize_copy);
|
237
271
|
|
238
272
|
rb_define_method(cX509Rev, "serial", ossl_x509revoked_get_serial, 0);
|
239
273
|
rb_define_method(cX509Rev, "serial=", ossl_x509revoked_set_serial, 1);
|
@@ -47,6 +47,65 @@
|
|
47
47
|
GetX509Store((obj), (ctx)); \
|
48
48
|
} while (0)
|
49
49
|
|
50
|
+
/*
|
51
|
+
* Verify callback stuff
|
52
|
+
*/
|
53
|
+
static int stctx_ex_verify_cb_idx, store_ex_verify_cb_idx;
|
54
|
+
static VALUE ossl_x509stctx_new(X509_STORE_CTX *);
|
55
|
+
|
56
|
+
struct ossl_verify_cb_args {
|
57
|
+
VALUE proc;
|
58
|
+
VALUE preverify_ok;
|
59
|
+
VALUE store_ctx;
|
60
|
+
};
|
61
|
+
|
62
|
+
static VALUE
|
63
|
+
call_verify_cb_proc(struct ossl_verify_cb_args *args)
|
64
|
+
{
|
65
|
+
return rb_funcall(args->proc, rb_intern("call"), 2,
|
66
|
+
args->preverify_ok, args->store_ctx);
|
67
|
+
}
|
68
|
+
|
69
|
+
int
|
70
|
+
ossl_verify_cb_call(VALUE proc, int ok, X509_STORE_CTX *ctx)
|
71
|
+
{
|
72
|
+
VALUE rctx, ret;
|
73
|
+
struct ossl_verify_cb_args args;
|
74
|
+
int state;
|
75
|
+
|
76
|
+
if (NIL_P(proc))
|
77
|
+
return ok;
|
78
|
+
|
79
|
+
ret = Qfalse;
|
80
|
+
rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new, (VALUE)ctx, &state);
|
81
|
+
if (state) {
|
82
|
+
rb_set_errinfo(Qnil);
|
83
|
+
rb_warn("StoreContext initialization failure");
|
84
|
+
}
|
85
|
+
else {
|
86
|
+
args.proc = proc;
|
87
|
+
args.preverify_ok = ok ? Qtrue : Qfalse;
|
88
|
+
args.store_ctx = rctx;
|
89
|
+
ret = rb_protect((VALUE(*)(VALUE))call_verify_cb_proc, (VALUE)&args, &state);
|
90
|
+
if (state) {
|
91
|
+
rb_set_errinfo(Qnil);
|
92
|
+
rb_warn("exception in verify_callback is ignored");
|
93
|
+
}
|
94
|
+
RTYPEDDATA_DATA(rctx) = NULL;
|
95
|
+
}
|
96
|
+
if (ret == Qtrue) {
|
97
|
+
X509_STORE_CTX_set_error(ctx, X509_V_OK);
|
98
|
+
ok = 1;
|
99
|
+
}
|
100
|
+
else {
|
101
|
+
if (X509_STORE_CTX_get_error(ctx) == X509_V_OK)
|
102
|
+
X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
|
103
|
+
ok = 0;
|
104
|
+
}
|
105
|
+
|
106
|
+
return ok;
|
107
|
+
}
|
108
|
+
|
50
109
|
/*
|
51
110
|
* Classes
|
52
111
|
*/
|
@@ -98,7 +157,7 @@ DupX509StorePtr(VALUE obj)
|
|
98
157
|
X509_STORE *store;
|
99
158
|
|
100
159
|
SafeGetX509Store(obj, store);
|
101
|
-
|
160
|
+
X509_STORE_up_ref(store);
|
102
161
|
|
103
162
|
return store;
|
104
163
|
}
|
@@ -106,6 +165,21 @@ DupX509StorePtr(VALUE obj)
|
|
106
165
|
/*
|
107
166
|
* Private functions
|
108
167
|
*/
|
168
|
+
static int
|
169
|
+
x509store_verify_cb(int ok, X509_STORE_CTX *ctx)
|
170
|
+
{
|
171
|
+
VALUE proc;
|
172
|
+
|
173
|
+
proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, stctx_ex_verify_cb_idx);
|
174
|
+
if (!proc)
|
175
|
+
proc = (VALUE)X509_STORE_get_ex_data(X509_STORE_CTX_get0_store(ctx),
|
176
|
+
store_ex_verify_cb_idx);
|
177
|
+
if (!proc)
|
178
|
+
return ok;
|
179
|
+
|
180
|
+
return ossl_verify_cb_call(proc, ok, ctx);
|
181
|
+
}
|
182
|
+
|
109
183
|
static VALUE
|
110
184
|
ossl_x509store_alloc(VALUE klass)
|
111
185
|
{
|
@@ -130,7 +204,7 @@ ossl_x509store_set_vfy_cb(VALUE self, VALUE cb)
|
|
130
204
|
X509_STORE *store;
|
131
205
|
|
132
206
|
GetX509Store(self, store);
|
133
|
-
X509_STORE_set_ex_data(store,
|
207
|
+
X509_STORE_set_ex_data(store, store_ex_verify_cb_idx, (void *)cb);
|
134
208
|
rb_iv_set(self, "@verify_callback", cb);
|
135
209
|
|
136
210
|
return cb;
|
@@ -141,6 +215,7 @@ ossl_x509store_set_vfy_cb(VALUE self, VALUE cb)
|
|
141
215
|
* call-seq:
|
142
216
|
* X509::Store.new => store
|
143
217
|
*
|
218
|
+
* Creates a new X509::Store.
|
144
219
|
*/
|
145
220
|
static VALUE
|
146
221
|
ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
|
@@ -149,15 +224,12 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
|
|
149
224
|
|
150
225
|
/* BUG: This method takes any number of arguments but appears to ignore them. */
|
151
226
|
GetX509Store(self, store);
|
227
|
+
#if !defined(HAVE_OPAQUE_OPENSSL)
|
228
|
+
/* [Bug #405] [Bug #1678] [Bug #3000]; already fixed? */
|
152
229
|
store->ex_data.sk = NULL;
|
153
|
-
X509_STORE_set_verify_cb_func(store, ossl_verify_cb);
|
154
|
-
ossl_x509store_set_vfy_cb(self, Qnil);
|
155
|
-
|
156
|
-
#if (OPENSSL_VERSION_NUMBER < 0x00907000L)
|
157
|
-
rb_iv_set(self, "@flags", INT2FIX(0));
|
158
|
-
rb_iv_set(self, "@purpose", INT2FIX(0));
|
159
|
-
rb_iv_set(self, "@trust", INT2FIX(0));
|
160
230
|
#endif
|
231
|
+
X509_STORE_set_verify_cb(store, x509store_verify_cb);
|
232
|
+
ossl_x509store_set_vfy_cb(self, Qnil);
|
161
233
|
|
162
234
|
/* last verification status */
|
163
235
|
rb_iv_set(self, "@error", Qnil);
|
@@ -168,54 +240,77 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
|
|
168
240
|
return self;
|
169
241
|
}
|
170
242
|
|
243
|
+
/*
|
244
|
+
* call-seq:
|
245
|
+
* store.flags = flag
|
246
|
+
*
|
247
|
+
* Sets +flag+ to the Store. +flag+ consists of zero or more of the constants
|
248
|
+
* defined in with name V_FLAG_* or'ed together.
|
249
|
+
*/
|
171
250
|
static VALUE
|
172
251
|
ossl_x509store_set_flags(VALUE self, VALUE flags)
|
173
252
|
{
|
174
|
-
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
|
175
253
|
X509_STORE *store;
|
176
254
|
long f = NUM2LONG(flags);
|
177
255
|
|
178
256
|
GetX509Store(self, store);
|
179
257
|
X509_STORE_set_flags(store, f);
|
180
|
-
#else
|
181
|
-
rb_iv_set(self, "@flags", flags);
|
182
|
-
#endif
|
183
258
|
|
184
259
|
return flags;
|
185
260
|
}
|
186
261
|
|
262
|
+
/*
|
263
|
+
* call-seq:
|
264
|
+
* store.purpose = purpose
|
265
|
+
*
|
266
|
+
* Sets the store's purpose to +purpose+. If specified, the verifications on
|
267
|
+
* the store will check every untrusted certificate's extensions are consistent
|
268
|
+
* with the purpose. The purpose is specified by constants:
|
269
|
+
*
|
270
|
+
* * X509::PURPOSE_SSL_CLIENT
|
271
|
+
* * X509::PURPOSE_SSL_SERVER
|
272
|
+
* * X509::PURPOSE_NS_SSL_SERVER
|
273
|
+
* * X509::PURPOSE_SMIME_SIGN
|
274
|
+
* * X509::PURPOSE_SMIME_ENCRYPT
|
275
|
+
* * X509::PURPOSE_CRL_SIGN
|
276
|
+
* * X509::PURPOSE_ANY
|
277
|
+
* * X509::PURPOSE_OCSP_HELPER
|
278
|
+
* * X509::PURPOSE_TIMESTAMP_SIGN
|
279
|
+
*/
|
187
280
|
static VALUE
|
188
281
|
ossl_x509store_set_purpose(VALUE self, VALUE purpose)
|
189
282
|
{
|
190
|
-
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
|
191
283
|
X509_STORE *store;
|
192
284
|
int p = NUM2INT(purpose);
|
193
285
|
|
194
286
|
GetX509Store(self, store);
|
195
287
|
X509_STORE_set_purpose(store, p);
|
196
|
-
#else
|
197
|
-
rb_iv_set(self, "@purpose", purpose);
|
198
|
-
#endif
|
199
288
|
|
200
289
|
return purpose;
|
201
290
|
}
|
202
291
|
|
292
|
+
/*
|
293
|
+
* call-seq:
|
294
|
+
* store.trust = trust
|
295
|
+
*/
|
203
296
|
static VALUE
|
204
297
|
ossl_x509store_set_trust(VALUE self, VALUE trust)
|
205
298
|
{
|
206
|
-
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
|
207
299
|
X509_STORE *store;
|
208
300
|
int t = NUM2INT(trust);
|
209
301
|
|
210
302
|
GetX509Store(self, store);
|
211
303
|
X509_STORE_set_trust(store, t);
|
212
|
-
#else
|
213
|
-
rb_iv_set(self, "@trust", trust);
|
214
|
-
#endif
|
215
304
|
|
216
305
|
return trust;
|
217
306
|
}
|
218
307
|
|
308
|
+
/*
|
309
|
+
* call-seq:
|
310
|
+
* store.time = time
|
311
|
+
*
|
312
|
+
* Sets the time to be used in verifications.
|
313
|
+
*/
|
219
314
|
static VALUE
|
220
315
|
ossl_x509store_set_time(VALUE self, VALUE time)
|
221
316
|
{
|
@@ -225,13 +320,11 @@ ossl_x509store_set_time(VALUE self, VALUE time)
|
|
225
320
|
|
226
321
|
/*
|
227
322
|
* call-seq:
|
228
|
-
* store.add_file(file) ->
|
229
|
-
*
|
323
|
+
* store.add_file(file) -> self
|
230
324
|
*
|
231
325
|
* Adds the certificates in +file+ to the certificate store. The +file+ can
|
232
326
|
* contain multiple PEM-encoded certificates.
|
233
327
|
*/
|
234
|
-
|
235
328
|
static VALUE
|
236
329
|
ossl_x509store_add_file(VALUE self, VALUE file)
|
237
330
|
{
|
@@ -240,8 +333,8 @@ ossl_x509store_add_file(VALUE self, VALUE file)
|
|
240
333
|
char *path = NULL;
|
241
334
|
|
242
335
|
if(file != Qnil){
|
243
|
-
|
244
|
-
path =
|
336
|
+
rb_check_safe_obj(file);
|
337
|
+
path = StringValueCStr(file);
|
245
338
|
}
|
246
339
|
GetX509Store(self, store);
|
247
340
|
lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
|
@@ -249,10 +342,25 @@ ossl_x509store_add_file(VALUE self, VALUE file)
|
|
249
342
|
if(X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM) != 1){
|
250
343
|
ossl_raise(eX509StoreError, NULL);
|
251
344
|
}
|
345
|
+
#if OPENSSL_VERSION_NUMBER < 0x10101000 || defined(LIBRESSL_VERSION_NUMBER)
|
346
|
+
/*
|
347
|
+
* X509_load_cert_crl_file() which is called from X509_LOOKUP_load_file()
|
348
|
+
* did not check the return value of X509_STORE_add_{cert,crl}(), leaking
|
349
|
+
* "cert already in hash table" errors on the error queue, if duplicate
|
350
|
+
* certificates are found. This will be fixed by OpenSSL 1.1.1.
|
351
|
+
*/
|
352
|
+
ossl_clear_error();
|
353
|
+
#endif
|
252
354
|
|
253
355
|
return self;
|
254
356
|
}
|
255
357
|
|
358
|
+
/*
|
359
|
+
* call-seq:
|
360
|
+
* store.add_path(path) -> self
|
361
|
+
*
|
362
|
+
* Adds +path+ as the hash dir to be looked up by the store.
|
363
|
+
*/
|
256
364
|
static VALUE
|
257
365
|
ossl_x509store_add_path(VALUE self, VALUE dir)
|
258
366
|
{
|
@@ -261,8 +369,8 @@ ossl_x509store_add_path(VALUE self, VALUE dir)
|
|
261
369
|
char *path = NULL;
|
262
370
|
|
263
371
|
if(dir != Qnil){
|
264
|
-
|
265
|
-
path =
|
372
|
+
rb_check_safe_obj(dir);
|
373
|
+
path = StringValueCStr(dir);
|
266
374
|
}
|
267
375
|
GetX509Store(self, store);
|
268
376
|
lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
|
@@ -278,11 +386,12 @@ ossl_x509store_add_path(VALUE self, VALUE dir)
|
|
278
386
|
* call-seq:
|
279
387
|
* store.set_default_paths
|
280
388
|
*
|
281
|
-
*
|
282
|
-
*
|
389
|
+
* Configures +store+ to look up CA certificates from the system default
|
390
|
+
* certificate store as needed basis. The location of the store can usually be
|
283
391
|
* determined by:
|
284
392
|
*
|
285
|
-
*
|
393
|
+
* * OpenSSL::X509::DEFAULT_CERT_FILE
|
394
|
+
* * OpenSSL::X509::DEFAULT_CERT_DIR
|
286
395
|
*/
|
287
396
|
static VALUE
|
288
397
|
ossl_x509store_set_default_paths(VALUE self)
|
@@ -303,7 +412,6 @@ ossl_x509store_set_default_paths(VALUE self)
|
|
303
412
|
*
|
304
413
|
* Adds the OpenSSL::X509::Certificate +cert+ to the certificate store.
|
305
414
|
*/
|
306
|
-
|
307
415
|
static VALUE
|
308
416
|
ossl_x509store_add_cert(VALUE self, VALUE arg)
|
309
417
|
{
|
@@ -319,6 +427,12 @@ ossl_x509store_add_cert(VALUE self, VALUE arg)
|
|
319
427
|
return self;
|
320
428
|
}
|
321
429
|
|
430
|
+
/*
|
431
|
+
* call-seq:
|
432
|
+
* store.add_crl(crl) -> self
|
433
|
+
*
|
434
|
+
* Adds the OpenSSL::X509::CRL +crl+ to the store.
|
435
|
+
*/
|
322
436
|
static VALUE
|
323
437
|
ossl_x509store_add_crl(VALUE self, VALUE arg)
|
324
438
|
{
|
@@ -338,6 +452,21 @@ static VALUE ossl_x509stctx_get_err(VALUE);
|
|
338
452
|
static VALUE ossl_x509stctx_get_err_string(VALUE);
|
339
453
|
static VALUE ossl_x509stctx_get_chain(VALUE);
|
340
454
|
|
455
|
+
/*
|
456
|
+
* call-seq:
|
457
|
+
* store.verify(cert, chain = nil) -> true | false
|
458
|
+
*
|
459
|
+
* Performs a certificate verification on the OpenSSL::X509::Certificate +cert+.
|
460
|
+
*
|
461
|
+
* +chain+ can be an array of OpenSSL::X509::Certificate that is used to
|
462
|
+
* construct the certificate chain.
|
463
|
+
*
|
464
|
+
* If a block is given, it overrides the callback set by #verify_callback=.
|
465
|
+
*
|
466
|
+
* After finishing the verification, the error information can be retrieved by
|
467
|
+
* #error, #error_string, and the resuting complete certificate chain can be
|
468
|
+
* retrieved by #chain.
|
469
|
+
*/
|
341
470
|
static VALUE
|
342
471
|
ossl_x509store_verify(int argc, VALUE *argv, VALUE self)
|
343
472
|
{
|
@@ -372,27 +501,6 @@ static const rb_data_type_t ossl_x509stctx_type = {
|
|
372
501
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
373
502
|
};
|
374
503
|
|
375
|
-
|
376
|
-
VALUE
|
377
|
-
ossl_x509stctx_new(X509_STORE_CTX *ctx)
|
378
|
-
{
|
379
|
-
VALUE obj;
|
380
|
-
|
381
|
-
obj = NewX509StCtx(cX509StoreContext);
|
382
|
-
SetX509StCtx(obj, ctx);
|
383
|
-
|
384
|
-
return obj;
|
385
|
-
}
|
386
|
-
|
387
|
-
VALUE
|
388
|
-
ossl_x509stctx_clear_ptr(VALUE obj)
|
389
|
-
{
|
390
|
-
OSSL_Check_Kind(obj, cX509StoreContext);
|
391
|
-
RDATA(obj)->data = NULL;
|
392
|
-
|
393
|
-
return obj;
|
394
|
-
}
|
395
|
-
|
396
504
|
/*
|
397
505
|
* Private functions
|
398
506
|
*/
|
@@ -400,10 +508,10 @@ static void
|
|
400
508
|
ossl_x509stctx_free(void *ptr)
|
401
509
|
{
|
402
510
|
X509_STORE_CTX *ctx = ptr;
|
403
|
-
if(ctx
|
404
|
-
sk_X509_pop_free(ctx
|
405
|
-
if(ctx
|
406
|
-
X509_free(ctx
|
511
|
+
if (X509_STORE_CTX_get0_untrusted(ctx))
|
512
|
+
sk_X509_pop_free(X509_STORE_CTX_get0_untrusted(ctx), X509_free);
|
513
|
+
if (X509_STORE_CTX_get0_cert(ctx))
|
514
|
+
X509_free(X509_STORE_CTX_get0_cert(ctx));
|
407
515
|
X509_STORE_CTX_free(ctx);
|
408
516
|
}
|
409
517
|
|
@@ -422,11 +530,26 @@ ossl_x509stctx_alloc(VALUE klass)
|
|
422
530
|
return obj;
|
423
531
|
}
|
424
532
|
|
533
|
+
static VALUE
|
534
|
+
ossl_x509stctx_new(X509_STORE_CTX *ctx)
|
535
|
+
{
|
536
|
+
VALUE obj;
|
537
|
+
|
538
|
+
obj = NewX509StCtx(cX509StoreContext);
|
539
|
+
SetX509StCtx(obj, ctx);
|
540
|
+
|
541
|
+
return obj;
|
542
|
+
}
|
543
|
+
|
425
544
|
static VALUE ossl_x509stctx_set_flags(VALUE, VALUE);
|
426
545
|
static VALUE ossl_x509stctx_set_purpose(VALUE, VALUE);
|
427
546
|
static VALUE ossl_x509stctx_set_trust(VALUE, VALUE);
|
428
547
|
static VALUE ossl_x509stctx_set_time(VALUE, VALUE);
|
429
548
|
|
549
|
+
/*
|
550
|
+
* call-seq:
|
551
|
+
* StoreContext.new(store, cert = nil, chain = nil)
|
552
|
+
*/
|
430
553
|
static VALUE
|
431
554
|
ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
|
432
555
|
{
|
@@ -441,17 +564,10 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
|
|
441
564
|
SafeGetX509Store(store, x509st);
|
442
565
|
if(!NIL_P(cert)) x509 = DupX509CertPtr(cert); /* NEED TO DUP */
|
443
566
|
if(!NIL_P(chain)) x509s = ossl_x509_ary2sk(chain);
|
444
|
-
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
|
445
567
|
if(X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){
|
446
568
|
sk_X509_pop_free(x509s, X509_free);
|
447
569
|
ossl_raise(eX509StoreError, NULL);
|
448
570
|
}
|
449
|
-
#else
|
450
|
-
X509_STORE_CTX_init(ctx, x509st, x509, x509s);
|
451
|
-
ossl_x509stctx_set_flags(self, rb_iv_get(store, "@flags"));
|
452
|
-
ossl_x509stctx_set_purpose(self, rb_iv_get(store, "@purpose"));
|
453
|
-
ossl_x509stctx_set_trust(self, rb_iv_get(store, "@trust"));
|
454
|
-
#endif
|
455
571
|
if (!NIL_P(t = rb_iv_get(store, "@time")))
|
456
572
|
ossl_x509stctx_set_time(self, t);
|
457
573
|
rb_iv_set(self, "@verify_callback", rb_iv_get(store, "@verify_callback"));
|
@@ -460,20 +576,34 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
|
|
460
576
|
return self;
|
461
577
|
}
|
462
578
|
|
579
|
+
/*
|
580
|
+
* call-seq:
|
581
|
+
* stctx.verify -> true | false
|
582
|
+
*/
|
463
583
|
static VALUE
|
464
584
|
ossl_x509stctx_verify(VALUE self)
|
465
585
|
{
|
466
586
|
X509_STORE_CTX *ctx;
|
467
|
-
int result;
|
468
587
|
|
469
588
|
GetX509StCtx(self, ctx);
|
470
|
-
X509_STORE_CTX_set_ex_data(ctx,
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
589
|
+
X509_STORE_CTX_set_ex_data(ctx, stctx_ex_verify_cb_idx,
|
590
|
+
(void *)rb_iv_get(self, "@verify_callback"));
|
591
|
+
|
592
|
+
switch (X509_verify_cert(ctx)) {
|
593
|
+
case 1:
|
594
|
+
return Qtrue;
|
595
|
+
case 0:
|
596
|
+
ossl_clear_error();
|
597
|
+
return Qfalse;
|
598
|
+
default:
|
599
|
+
ossl_raise(eX509CertError, NULL);
|
600
|
+
}
|
475
601
|
}
|
476
602
|
|
603
|
+
/*
|
604
|
+
* call-seq:
|
605
|
+
* stctx.chain -> Array of X509::Certificate
|
606
|
+
*/
|
477
607
|
static VALUE
|
478
608
|
ossl_x509stctx_get_chain(VALUE self)
|
479
609
|
{
|
@@ -484,7 +614,7 @@ ossl_x509stctx_get_chain(VALUE self)
|
|
484
614
|
VALUE ary;
|
485
615
|
|
486
616
|
GetX509StCtx(self, ctx);
|
487
|
-
if((chain =
|
617
|
+
if((chain = X509_STORE_CTX_get0_chain(ctx)) == NULL){
|
488
618
|
return Qnil;
|
489
619
|
}
|
490
620
|
if((num = sk_X509_num(chain)) < 0){
|
@@ -500,6 +630,10 @@ ossl_x509stctx_get_chain(VALUE self)
|
|
500
630
|
return ary;
|
501
631
|
}
|
502
632
|
|
633
|
+
/*
|
634
|
+
* call-seq:
|
635
|
+
* stctx.error -> Integer
|
636
|
+
*/
|
503
637
|
static VALUE
|
504
638
|
ossl_x509stctx_get_err(VALUE self)
|
505
639
|
{
|
@@ -507,9 +641,13 @@ ossl_x509stctx_get_err(VALUE self)
|
|
507
641
|
|
508
642
|
GetX509StCtx(self, ctx);
|
509
643
|
|
510
|
-
return
|
644
|
+
return INT2NUM(X509_STORE_CTX_get_error(ctx));
|
511
645
|
}
|
512
646
|
|
647
|
+
/*
|
648
|
+
* call-seq:
|
649
|
+
* stctx.error = error_code
|
650
|
+
*/
|
513
651
|
static VALUE
|
514
652
|
ossl_x509stctx_set_error(VALUE self, VALUE err)
|
515
653
|
{
|
@@ -521,6 +659,12 @@ ossl_x509stctx_set_error(VALUE self, VALUE err)
|
|
521
659
|
return err;
|
522
660
|
}
|
523
661
|
|
662
|
+
/*
|
663
|
+
* call-seq:
|
664
|
+
* stctx.error_string -> String
|
665
|
+
*
|
666
|
+
* Returns the error string corresponding to the error code retrieved by #error.
|
667
|
+
*/
|
524
668
|
static VALUE
|
525
669
|
ossl_x509stctx_get_err_string(VALUE self)
|
526
670
|
{
|
@@ -533,6 +677,10 @@ ossl_x509stctx_get_err_string(VALUE self)
|
|
533
677
|
return rb_str_new2(X509_verify_cert_error_string(err));
|
534
678
|
}
|
535
679
|
|
680
|
+
/*
|
681
|
+
* call-seq:
|
682
|
+
* stctx.error_depth -> Integer
|
683
|
+
*/
|
536
684
|
static VALUE
|
537
685
|
ossl_x509stctx_get_err_depth(VALUE self)
|
538
686
|
{
|
@@ -540,9 +688,13 @@ ossl_x509stctx_get_err_depth(VALUE self)
|
|
540
688
|
|
541
689
|
GetX509StCtx(self, ctx);
|
542
690
|
|
543
|
-
return
|
691
|
+
return INT2NUM(X509_STORE_CTX_get_error_depth(ctx));
|
544
692
|
}
|
545
693
|
|
694
|
+
/*
|
695
|
+
* call-seq:
|
696
|
+
* stctx.current_cert -> X509::Certificate
|
697
|
+
*/
|
546
698
|
static VALUE
|
547
699
|
ossl_x509stctx_get_curr_cert(VALUE self)
|
548
700
|
{
|
@@ -553,21 +705,30 @@ ossl_x509stctx_get_curr_cert(VALUE self)
|
|
553
705
|
return ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx));
|
554
706
|
}
|
555
707
|
|
708
|
+
/*
|
709
|
+
* call-seq:
|
710
|
+
* stctx.current_crl -> X509::CRL
|
711
|
+
*/
|
556
712
|
static VALUE
|
557
713
|
ossl_x509stctx_get_curr_crl(VALUE self)
|
558
714
|
{
|
559
|
-
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
|
560
715
|
X509_STORE_CTX *ctx;
|
716
|
+
X509_CRL *crl;
|
561
717
|
|
562
718
|
GetX509StCtx(self, ctx);
|
563
|
-
|
719
|
+
crl = X509_STORE_CTX_get0_current_crl(ctx);
|
720
|
+
if (!crl)
|
721
|
+
return Qnil;
|
564
722
|
|
565
|
-
return ossl_x509crl_new(
|
566
|
-
#else
|
567
|
-
return Qnil;
|
568
|
-
#endif
|
723
|
+
return ossl_x509crl_new(crl);
|
569
724
|
}
|
570
725
|
|
726
|
+
/*
|
727
|
+
* call-seq:
|
728
|
+
* stctx.flags = flags
|
729
|
+
*
|
730
|
+
* Sets the verification flags to the context. See Store#flags=.
|
731
|
+
*/
|
571
732
|
static VALUE
|
572
733
|
ossl_x509stctx_set_flags(VALUE self, VALUE flags)
|
573
734
|
{
|
@@ -580,6 +741,12 @@ ossl_x509stctx_set_flags(VALUE self, VALUE flags)
|
|
580
741
|
return flags;
|
581
742
|
}
|
582
743
|
|
744
|
+
/*
|
745
|
+
* call-seq:
|
746
|
+
* stctx.purpose = purpose
|
747
|
+
*
|
748
|
+
* Sets the purpose of the context. See Store#purpose=.
|
749
|
+
*/
|
583
750
|
static VALUE
|
584
751
|
ossl_x509stctx_set_purpose(VALUE self, VALUE purpose)
|
585
752
|
{
|
@@ -592,6 +759,10 @@ ossl_x509stctx_set_purpose(VALUE self, VALUE purpose)
|
|
592
759
|
return purpose;
|
593
760
|
}
|
594
761
|
|
762
|
+
/*
|
763
|
+
* call-seq:
|
764
|
+
* stctx.trust = trust
|
765
|
+
*/
|
595
766
|
static VALUE
|
596
767
|
ossl_x509stctx_set_trust(VALUE self, VALUE trust)
|
597
768
|
{
|
@@ -606,7 +777,9 @@ ossl_x509stctx_set_trust(VALUE self, VALUE trust)
|
|
606
777
|
|
607
778
|
/*
|
608
779
|
* call-seq:
|
609
|
-
*
|
780
|
+
* stctx.time = time
|
781
|
+
*
|
782
|
+
* Sets the time used in the verification. If not set, the current time is used.
|
610
783
|
*/
|
611
784
|
static VALUE
|
612
785
|
ossl_x509stctx_set_time(VALUE self, VALUE time)
|
@@ -627,13 +800,21 @@ ossl_x509stctx_set_time(VALUE self, VALUE time)
|
|
627
800
|
void
|
628
801
|
Init_ossl_x509store(void)
|
629
802
|
{
|
630
|
-
|
631
|
-
|
803
|
+
#undef rb_intern
|
632
804
|
#if 0
|
633
|
-
mOSSL = rb_define_module("OpenSSL");
|
805
|
+
mOSSL = rb_define_module("OpenSSL");
|
806
|
+
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
634
807
|
mX509 = rb_define_module_under(mOSSL, "X509");
|
635
808
|
#endif
|
636
809
|
|
810
|
+
/* Register ext_data slot for verify callback Proc */
|
811
|
+
stctx_ex_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, (void *)"stctx_ex_verify_cb_idx", 0, 0, 0);
|
812
|
+
if (stctx_ex_verify_cb_idx < 0)
|
813
|
+
ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index");
|
814
|
+
store_ex_verify_cb_idx = X509_STORE_get_ex_new_index(0, (void *)"store_ex_verify_cb_idx", 0, 0, 0);
|
815
|
+
if (store_ex_verify_cb_idx < 0)
|
816
|
+
ossl_raise(eOSSLError, "X509_STORE_get_ex_new_index");
|
817
|
+
|
637
818
|
eX509StoreError = rb_define_class_under(mX509, "StoreError", eOSSLError);
|
638
819
|
|
639
820
|
/* Document-class: OpenSSL::X509::Store
|
@@ -648,11 +829,11 @@ Init_ossl_x509store(void)
|
|
648
829
|
*
|
649
830
|
* This will use your system's built-in certificates.
|
650
831
|
*
|
651
|
-
* If your system does not have a default set of certificates you can
|
652
|
-
*
|
653
|
-
*
|
654
|
-
*
|
655
|
-
*
|
832
|
+
* If your system does not have a default set of certificates you can obtain
|
833
|
+
* a set extracted from Mozilla CA certificate store by cURL maintainers
|
834
|
+
* here: https://curl.haxx.se/docs/caextract.html (You may wish to use the
|
835
|
+
* firefox-db2pem.sh script to extract the certificates from a local install
|
836
|
+
* to avoid man-in-the-middle attacks.)
|
656
837
|
*
|
657
838
|
* After downloading or generating a cacert.pem from the above link you
|
658
839
|
* can create a certificate store from the pem file like this:
|
@@ -663,6 +844,7 @@ Init_ossl_x509store(void)
|
|
663
844
|
* The certificate store can be used with an SSLSocket like this:
|
664
845
|
*
|
665
846
|
* ssl_context = OpenSSL::SSL::SSLContext.new
|
847
|
+
* ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
666
848
|
* ssl_context.cert_store = cert_store
|
667
849
|
*
|
668
850
|
* tcp_socket = TCPSocket.open 'example.com', 443
|
@@ -671,12 +853,30 @@ Init_ossl_x509store(void)
|
|
671
853
|
*/
|
672
854
|
|
673
855
|
cX509Store = rb_define_class_under(mX509, "Store", rb_cObject);
|
856
|
+
/*
|
857
|
+
* The callback for additional certificate verification. It is invoked for
|
858
|
+
* each untrusted certificate in the chain.
|
859
|
+
*
|
860
|
+
* The callback is invoked with two values, a boolean that indicates if the
|
861
|
+
* pre-verification by OpenSSL has succeeded or not, and the StoreContext in
|
862
|
+
* use. The callback must return either true or false.
|
863
|
+
*/
|
674
864
|
rb_attr(cX509Store, rb_intern("verify_callback"), 1, 0, Qfalse);
|
865
|
+
/*
|
866
|
+
* The error code set by the last call of #verify.
|
867
|
+
*/
|
675
868
|
rb_attr(cX509Store, rb_intern("error"), 1, 0, Qfalse);
|
869
|
+
/*
|
870
|
+
* The description for the error code set by the last call of #verify.
|
871
|
+
*/
|
676
872
|
rb_attr(cX509Store, rb_intern("error_string"), 1, 0, Qfalse);
|
873
|
+
/*
|
874
|
+
* The certificate chain constructed by the last call of #verify.
|
875
|
+
*/
|
677
876
|
rb_attr(cX509Store, rb_intern("chain"), 1, 0, Qfalse);
|
678
877
|
rb_define_alloc_func(cX509Store, ossl_x509store_alloc);
|
679
878
|
rb_define_method(cX509Store, "initialize", ossl_x509store_initialize, -1);
|
879
|
+
rb_undef_method(cX509Store, "initialize_copy");
|
680
880
|
rb_define_method(cX509Store, "verify_callback=", ossl_x509store_set_vfy_cb, 1);
|
681
881
|
rb_define_method(cX509Store, "flags=", ossl_x509store_set_flags, 1);
|
682
882
|
rb_define_method(cX509Store, "purpose=", ossl_x509store_set_purpose, 1);
|
@@ -689,21 +889,26 @@ Init_ossl_x509store(void)
|
|
689
889
|
rb_define_method(cX509Store, "add_crl", ossl_x509store_add_crl, 1);
|
690
890
|
rb_define_method(cX509Store, "verify", ossl_x509store_verify, -1);
|
691
891
|
|
692
|
-
|
693
|
-
|
892
|
+
/*
|
893
|
+
* Document-class: OpenSSL::X509::StoreContext
|
894
|
+
*
|
895
|
+
* A StoreContext is used while validating a single certificate and holds
|
896
|
+
* the status involved.
|
897
|
+
*/
|
898
|
+
cX509StoreContext = rb_define_class_under(mX509,"StoreContext", rb_cObject);
|
694
899
|
rb_define_alloc_func(cX509StoreContext, ossl_x509stctx_alloc);
|
695
|
-
rb_define_method(
|
696
|
-
|
697
|
-
rb_define_method(
|
698
|
-
rb_define_method(
|
699
|
-
rb_define_method(
|
700
|
-
rb_define_method(
|
701
|
-
rb_define_method(
|
702
|
-
rb_define_method(
|
703
|
-
rb_define_method(
|
704
|
-
rb_define_method(
|
705
|
-
rb_define_method(
|
706
|
-
rb_define_method(
|
707
|
-
rb_define_method(
|
708
|
-
|
900
|
+
rb_define_method(cX509StoreContext, "initialize", ossl_x509stctx_initialize, -1);
|
901
|
+
rb_undef_method(cX509StoreContext, "initialize_copy");
|
902
|
+
rb_define_method(cX509StoreContext, "verify", ossl_x509stctx_verify, 0);
|
903
|
+
rb_define_method(cX509StoreContext, "chain", ossl_x509stctx_get_chain,0);
|
904
|
+
rb_define_method(cX509StoreContext, "error", ossl_x509stctx_get_err, 0);
|
905
|
+
rb_define_method(cX509StoreContext, "error=", ossl_x509stctx_set_error, 1);
|
906
|
+
rb_define_method(cX509StoreContext, "error_string", ossl_x509stctx_get_err_string,0);
|
907
|
+
rb_define_method(cX509StoreContext, "error_depth", ossl_x509stctx_get_err_depth, 0);
|
908
|
+
rb_define_method(cX509StoreContext, "current_cert", ossl_x509stctx_get_curr_cert, 0);
|
909
|
+
rb_define_method(cX509StoreContext, "current_crl", ossl_x509stctx_get_curr_crl, 0);
|
910
|
+
rb_define_method(cX509StoreContext, "flags=", ossl_x509stctx_set_flags, 1);
|
911
|
+
rb_define_method(cX509StoreContext, "purpose=", ossl_x509stctx_set_purpose, 1);
|
912
|
+
rb_define_method(cX509StoreContext, "trust=", ossl_x509stctx_set_trust, 1);
|
913
|
+
rb_define_method(cX509StoreContext, "time=", ossl_x509stctx_set_time, 1);
|
709
914
|
}
|