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
@@ -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->serialNumber);
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
- rev->serialNumber = num_to_asn1integer(num, rev->serialNumber);
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->revocationDate);
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
- time_t sec;
172
+ ASN1_TIME *asn1time;
148
173
 
149
- sec = time_to_time_t(time);
150
174
  GetX509Rev(self, rev);
151
- if (!X509_time_adj(rev->revocationDate, 0, &sec)) {
152
- ossl_raise(eX509RevError, NULL);
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
- sk_X509_EXTENSION_pop_free(rev->extensions, X509_EXTENSION_free);
200
- rev->extensions = NULL;
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
- CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
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, ossl_verify_cb_idx, (void*)cb);
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) -> store
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
- SafeStringValue(file);
244
- path = RSTRING_PTR(file);
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
- SafeStringValue(dir);
265
- path = RSTRING_PTR(dir);
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
- * Adds the default certificates to the certificate store. These certificates
282
- * are loaded from the default configuration directory which can usually be
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
- * File.dirname OpenSSL::Config::DEFAULT_CONFIG_FILE
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->untrusted)
404
- sk_X509_pop_free(ctx->untrusted, X509_free);
405
- if(ctx->cert)
406
- X509_free(ctx->cert);
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, ossl_verify_cb_idx,
471
- (void*)rb_iv_get(self, "@verify_callback"));
472
- result = X509_verify_cert(ctx);
473
-
474
- return result ? Qtrue : Qfalse;
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 = X509_STORE_CTX_get_chain(ctx)) == NULL){
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 INT2FIX(X509_STORE_CTX_get_error(ctx));
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 INT2FIX(X509_STORE_CTX_get_error_depth(ctx));
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
- if(!ctx->current_crl) return Qnil;
719
+ crl = X509_STORE_CTX_get0_current_crl(ctx);
720
+ if (!crl)
721
+ return Qnil;
564
722
 
565
- return ossl_x509crl_new(ctx->current_crl);
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
- * storectx.time = time => time
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
- VALUE x509stctx;
631
-
803
+ #undef rb_intern
632
804
  #if 0
633
- mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
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
- * obtain a set from Mozilla here: http://curl.haxx.se/docs/caextract.html
653
- * (Note that this set does not have an HTTPS download option so you may
654
- * wish to use the firefox-db2pem.sh script to extract the certificates
655
- * from a local install to avoid man-in-the-middle attacks.)
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
- cX509StoreContext = rb_define_class_under(mX509,"StoreContext",rb_cObject);
693
- x509stctx = cX509StoreContext;
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(x509stctx,"initialize", ossl_x509stctx_initialize, -1);
696
- rb_define_method(x509stctx,"verify", ossl_x509stctx_verify, 0);
697
- rb_define_method(x509stctx,"chain", ossl_x509stctx_get_chain,0);
698
- rb_define_method(x509stctx,"error", ossl_x509stctx_get_err, 0);
699
- rb_define_method(x509stctx,"error=", ossl_x509stctx_set_error, 1);
700
- rb_define_method(x509stctx,"error_string",ossl_x509stctx_get_err_string,0);
701
- rb_define_method(x509stctx,"error_depth", ossl_x509stctx_get_err_depth, 0);
702
- rb_define_method(x509stctx,"current_cert",ossl_x509stctx_get_curr_cert, 0);
703
- rb_define_method(x509stctx,"current_crl", ossl_x509stctx_get_curr_crl, 0);
704
- rb_define_method(x509stctx,"flags=", ossl_x509stctx_set_flags, 1);
705
- rb_define_method(x509stctx,"purpose=", ossl_x509stctx_set_purpose, 1);
706
- rb_define_method(x509stctx,"trust=", ossl_x509stctx_set_trust, 1);
707
- rb_define_method(x509stctx,"time=", ossl_x509stctx_set_time, 1);
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
  }