openssl 2.2.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +33 -45
  3. data/History.md +260 -0
  4. data/ext/openssl/extconf.rb +85 -72
  5. data/ext/openssl/openssl_missing.c +0 -66
  6. data/ext/openssl/openssl_missing.h +26 -45
  7. data/ext/openssl/ossl.c +67 -47
  8. data/ext/openssl/ossl.h +26 -6
  9. data/ext/openssl/ossl_asn1.c +26 -13
  10. data/ext/openssl/ossl_bn.c +278 -142
  11. data/ext/openssl/ossl_bn.h +2 -1
  12. data/ext/openssl/ossl_cipher.c +12 -13
  13. data/ext/openssl/ossl_config.c +412 -41
  14. data/ext/openssl/ossl_config.h +4 -7
  15. data/ext/openssl/ossl_digest.c +15 -11
  16. data/ext/openssl/ossl_engine.c +16 -15
  17. data/ext/openssl/ossl_hmac.c +56 -135
  18. data/ext/openssl/ossl_kdf.c +11 -3
  19. data/ext/openssl/ossl_ocsp.c +5 -53
  20. data/ext/openssl/ossl_pkcs12.c +21 -3
  21. data/ext/openssl/ossl_pkcs7.c +42 -59
  22. data/ext/openssl/ossl_pkey.c +1142 -191
  23. data/ext/openssl/ossl_pkey.h +36 -73
  24. data/ext/openssl/ossl_pkey_dh.c +130 -340
  25. data/ext/openssl/ossl_pkey_dsa.c +100 -405
  26. data/ext/openssl/ossl_pkey_ec.c +163 -335
  27. data/ext/openssl/ossl_pkey_rsa.c +106 -493
  28. data/ext/openssl/ossl_ssl.c +529 -421
  29. data/ext/openssl/ossl_ssl_session.c +28 -29
  30. data/ext/openssl/ossl_ts.c +64 -39
  31. data/ext/openssl/ossl_x509.c +0 -6
  32. data/ext/openssl/ossl_x509cert.c +167 -11
  33. data/ext/openssl/ossl_x509crl.c +13 -10
  34. data/ext/openssl/ossl_x509ext.c +1 -2
  35. data/ext/openssl/ossl_x509name.c +9 -2
  36. data/ext/openssl/ossl_x509req.c +13 -10
  37. data/ext/openssl/ossl_x509revoked.c +3 -3
  38. data/ext/openssl/ossl_x509store.c +193 -90
  39. data/lib/openssl/buffering.rb +10 -1
  40. data/lib/openssl/hmac.rb +65 -0
  41. data/lib/openssl/pkey.rb +429 -0
  42. data/lib/openssl/ssl.rb +13 -8
  43. data/lib/openssl/version.rb +1 -1
  44. data/lib/openssl/x509.rb +22 -0
  45. data/lib/openssl.rb +0 -1
  46. metadata +8 -66
  47. data/ext/openssl/ruby_missing.h +0 -24
  48. data/lib/openssl/config.rb +0 -501
@@ -291,7 +291,14 @@ x509name_print(VALUE self, unsigned long iflag)
291
291
  * * OpenSSL::X509::Name::MULTILINE
292
292
  *
293
293
  * If _format_ is omitted, the largely broken and traditional OpenSSL format
294
- * is used.
294
+ * (<tt>X509_NAME_oneline()</tt> format) is chosen.
295
+ *
296
+ * <b>Use of this method is discouraged.</b> None of the formats other than
297
+ * OpenSSL::X509::Name::RFC2253 is standardized and may show an inconsistent
298
+ * behavior through \OpenSSL versions.
299
+ *
300
+ * It is recommended to use #to_utf8 instead, which is equivalent to calling
301
+ * <tt>name.to_s(OpenSSL::X509::Name::RFC2253).force_encoding("UTF-8")</tt>.
295
302
  */
296
303
  static VALUE
297
304
  ossl_x509name_to_s(int argc, VALUE *argv, VALUE self)
@@ -498,7 +505,7 @@ ossl_x509name_to_der(VALUE self)
498
505
  * You can create a Name by parsing a distinguished name String or by
499
506
  * supplying the distinguished name as an Array.
500
507
  *
501
- * name = OpenSSL::X509::Name.parse '/CN=nobody/DC=example'
508
+ * name = OpenSSL::X509::Name.parse_rfc2253 'DC=example,CN=nobody'
502
509
  *
503
510
  * name = OpenSSL::X509::Name.new [['CN', 'nobody'], ['DC', 'example']]
504
511
  */
@@ -79,23 +79,26 @@ static VALUE
79
79
  ossl_x509req_initialize(int argc, VALUE *argv, VALUE self)
80
80
  {
81
81
  BIO *in;
82
- X509_REQ *req, *x = DATA_PTR(self);
82
+ X509_REQ *req, *req_orig = RTYPEDDATA_DATA(self);
83
83
  VALUE arg;
84
84
 
85
+ rb_check_frozen(self);
85
86
  if (rb_scan_args(argc, argv, "01", &arg) == 0) {
86
87
  return self;
87
88
  }
88
89
  arg = ossl_to_der_if_possible(arg);
89
90
  in = ossl_obj2bio(&arg);
90
- req = PEM_read_bio_X509_REQ(in, &x, NULL, NULL);
91
- DATA_PTR(self) = x;
91
+ req = d2i_X509_REQ_bio(in, NULL);
92
92
  if (!req) {
93
- OSSL_BIO_reset(in);
94
- req = d2i_X509_REQ_bio(in, &x);
95
- DATA_PTR(self) = x;
93
+ OSSL_BIO_reset(in);
94
+ req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
96
95
  }
97
96
  BIO_free(in);
98
- if (!req) ossl_raise(eX509ReqError, NULL);
97
+ if (!req)
98
+ ossl_raise(eX509ReqError, "PEM_read_bio_X509_REQ");
99
+
100
+ RTYPEDDATA_DATA(self) = req;
101
+ X509_REQ_free(req_orig);
99
102
 
100
103
  return self;
101
104
  }
@@ -377,13 +380,13 @@ ossl_x509req_set_attributes(VALUE self, VALUE ary)
377
380
  OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Attr);
378
381
  }
379
382
  GetX509Req(self, req);
380
- while ((attr = X509_REQ_delete_attr(req, 0)))
381
- X509_ATTRIBUTE_free(attr);
383
+ for (i = X509_REQ_get_attr_count(req); i > 0; i--)
384
+ X509_ATTRIBUTE_free(X509_REQ_delete_attr(req, 0));
382
385
  for (i=0;i<RARRAY_LEN(ary); i++) {
383
386
  item = RARRAY_AREF(ary, i);
384
387
  attr = GetX509AttrPtr(item);
385
388
  if (!X509_REQ_add1_attr(req, attr)) {
386
- ossl_raise(eX509ReqError, NULL);
389
+ ossl_raise(eX509ReqError, "X509_REQ_add1_attr");
387
390
  }
388
391
  }
389
392
  return ary;
@@ -223,13 +223,13 @@ ossl_x509revoked_set_extensions(VALUE self, VALUE ary)
223
223
  OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext);
224
224
  }
225
225
  GetX509Rev(self, rev);
226
- while ((ext = X509_REVOKED_delete_ext(rev, 0)))
227
- X509_EXTENSION_free(ext);
226
+ for (i = X509_REVOKED_get_ext_count(rev); i > 0; i--)
227
+ X509_EXTENSION_free(X509_REVOKED_delete_ext(rev, 0));
228
228
  for (i=0; i<RARRAY_LEN(ary); i++) {
229
229
  item = RARRAY_AREF(ary, i);
230
230
  ext = GetX509ExtPtr(item);
231
231
  if(!X509_REVOKED_add_ext(rev, ext, -1)) {
232
- ossl_raise(eX509RevError, NULL);
232
+ ossl_raise(eX509RevError, "X509_REVOKED_add_ext");
233
233
  }
234
234
  }
235
235
 
@@ -52,8 +52,15 @@ struct ossl_verify_cb_args {
52
52
  };
53
53
 
54
54
  static VALUE
55
- call_verify_cb_proc(struct ossl_verify_cb_args *args)
55
+ ossl_x509stctx_new_i(VALUE arg)
56
56
  {
57
+ return ossl_x509stctx_new((X509_STORE_CTX *)arg);
58
+ }
59
+
60
+ static VALUE
61
+ call_verify_cb_proc(VALUE arg)
62
+ {
63
+ struct ossl_verify_cb_args *args = (struct ossl_verify_cb_args *)arg;
57
64
  return rb_funcall(args->proc, rb_intern("call"), 2,
58
65
  args->preverify_ok, args->store_ctx);
59
66
  }
@@ -69,7 +76,7 @@ ossl_verify_cb_call(VALUE proc, int ok, X509_STORE_CTX *ctx)
69
76
  return ok;
70
77
 
71
78
  ret = Qfalse;
72
- rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new, (VALUE)ctx, &state);
79
+ rctx = rb_protect(ossl_x509stctx_new_i, (VALUE)ctx, &state);
73
80
  if (state) {
74
81
  rb_set_errinfo(Qnil);
75
82
  rb_warn("StoreContext initialization failure");
@@ -78,7 +85,7 @@ ossl_verify_cb_call(VALUE proc, int ok, X509_STORE_CTX *ctx)
78
85
  args.proc = proc;
79
86
  args.preverify_ok = ok ? Qtrue : Qfalse;
80
87
  args.store_ctx = rctx;
81
- ret = rb_protect((VALUE(*)(VALUE))call_verify_cb_proc, (VALUE)&args, &state);
88
+ ret = rb_protect(call_verify_cb_proc, (VALUE)&args, &state);
82
89
  if (state) {
83
90
  rb_set_errinfo(Qnil);
84
91
  rb_warn("exception in verify_callback is ignored");
@@ -105,6 +112,13 @@ VALUE cX509Store;
105
112
  VALUE cX509StoreContext;
106
113
  VALUE eX509StoreError;
107
114
 
115
+ static void
116
+ ossl_x509store_mark(void *ptr)
117
+ {
118
+ X509_STORE *store = ptr;
119
+ rb_gc_mark((VALUE)X509_STORE_get_ex_data(store, store_ex_verify_cb_idx));
120
+ }
121
+
108
122
  static void
109
123
  ossl_x509store_free(void *ptr)
110
124
  {
@@ -114,7 +128,7 @@ ossl_x509store_free(void *ptr)
114
128
  static const rb_data_type_t ossl_x509store_type = {
115
129
  "OpenSSL/X509/STORE",
116
130
  {
117
- 0, ossl_x509store_free,
131
+ ossl_x509store_mark, ossl_x509store_free,
118
132
  },
119
133
  0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
120
134
  };
@@ -157,9 +171,8 @@ ossl_x509store_alloc(VALUE klass)
157
171
  VALUE obj;
158
172
 
159
173
  obj = NewX509Store(klass);
160
- if((store = X509_STORE_new()) == NULL){
161
- ossl_raise(eX509StoreError, NULL);
162
- }
174
+ if ((store = X509_STORE_new()) == NULL)
175
+ ossl_raise(eX509StoreError, "X509_STORE_new");
163
176
  SetX509Store(obj, store);
164
177
 
165
178
  return obj;
@@ -192,8 +205,9 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
192
205
  {
193
206
  X509_STORE *store;
194
207
 
195
- /* BUG: This method takes any number of arguments but appears to ignore them. */
196
208
  GetX509Store(self, store);
209
+ if (argc != 0)
210
+ rb_warn("OpenSSL::X509::Store.new does not take any arguments");
197
211
  #if !defined(HAVE_OPAQUE_OPENSSL)
198
212
  /* [Bug #405] [Bug #1678] [Bug #3000]; already fixed? */
199
213
  store->ex_data.sk = NULL;
@@ -214,8 +228,16 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
214
228
  * call-seq:
215
229
  * store.flags = flags
216
230
  *
217
- * Sets _flags_ to the Store. _flags_ consists of zero or more of the constants
218
- * defined in with name V_FLAG_* or'ed together.
231
+ * Sets the default flags used by certificate chain verification performed with
232
+ * the Store.
233
+ *
234
+ * _flags_ consists of zero or more of the constants defined in OpenSSL::X509
235
+ * with name V_FLAG_* or'ed together.
236
+ *
237
+ * OpenSSL::X509::StoreContext#flags= can be used to change the flags for a
238
+ * single verification operation.
239
+ *
240
+ * See also the man page X509_VERIFY_PARAM_set_flags(3).
219
241
  */
220
242
  static VALUE
221
243
  ossl_x509store_set_flags(VALUE self, VALUE flags)
@@ -233,9 +255,9 @@ ossl_x509store_set_flags(VALUE self, VALUE flags)
233
255
  * call-seq:
234
256
  * store.purpose = purpose
235
257
  *
236
- * Sets the store's purpose to _purpose_. If specified, the verifications on
237
- * the store will check every untrusted certificate's extensions are consistent
238
- * with the purpose. The purpose is specified by constants:
258
+ * Sets the store's default verification purpose. If specified,
259
+ * the verifications on the store will check every certificate's extensions are
260
+ * consistent with the purpose. The purpose is specified by constants:
239
261
  *
240
262
  * * X509::PURPOSE_SSL_CLIENT
241
263
  * * X509::PURPOSE_SSL_SERVER
@@ -246,6 +268,11 @@ ossl_x509store_set_flags(VALUE self, VALUE flags)
246
268
  * * X509::PURPOSE_ANY
247
269
  * * X509::PURPOSE_OCSP_HELPER
248
270
  * * X509::PURPOSE_TIMESTAMP_SIGN
271
+ *
272
+ * OpenSSL::X509::StoreContext#purpose= can be used to change the value for a
273
+ * single verification operation.
274
+ *
275
+ * See also the man page X509_VERIFY_PARAM_set_purpose(3).
249
276
  */
250
277
  static VALUE
251
278
  ossl_x509store_set_purpose(VALUE self, VALUE purpose)
@@ -262,6 +289,14 @@ ossl_x509store_set_purpose(VALUE self, VALUE purpose)
262
289
  /*
263
290
  * call-seq:
264
291
  * store.trust = trust
292
+ *
293
+ * Sets the default trust settings used by the certificate verification with
294
+ * the store.
295
+ *
296
+ * OpenSSL::X509::StoreContext#trust= can be used to change the value for a
297
+ * single verification operation.
298
+ *
299
+ * See also the man page X509_VERIFY_PARAM_set_trust(3).
265
300
  */
266
301
  static VALUE
267
302
  ossl_x509store_set_trust(VALUE self, VALUE trust)
@@ -279,7 +314,13 @@ ossl_x509store_set_trust(VALUE self, VALUE trust)
279
314
  * call-seq:
280
315
  * store.time = time
281
316
  *
282
- * Sets the time to be used in verifications.
317
+ * Sets the time to be used in the certificate verifications with the store.
318
+ * By default, if not specified, the current system time is used.
319
+ *
320
+ * OpenSSL::X509::StoreContext#time= can be used to change the value for a
321
+ * single verification operation.
322
+ *
323
+ * See also the man page X509_VERIFY_PARAM_set_time(3).
283
324
  */
284
325
  static VALUE
285
326
  ossl_x509store_set_time(VALUE self, VALUE time)
@@ -295,23 +336,23 @@ ossl_x509store_set_time(VALUE self, VALUE time)
295
336
  * Adds the certificates in _file_ to the certificate store. _file_ is the path
296
337
  * to the file, and the file contains one or more certificates in PEM format
297
338
  * concatenated together.
339
+ *
340
+ * See also the man page X509_LOOKUP_file(3).
298
341
  */
299
342
  static VALUE
300
343
  ossl_x509store_add_file(VALUE self, VALUE file)
301
344
  {
302
345
  X509_STORE *store;
303
346
  X509_LOOKUP *lookup;
304
- char *path = NULL;
347
+ const char *path;
305
348
 
306
- if(file != Qnil){
307
- path = StringValueCStr(file);
308
- }
309
349
  GetX509Store(self, store);
350
+ path = StringValueCStr(file);
310
351
  lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
311
- if(lookup == NULL) ossl_raise(eX509StoreError, NULL);
312
- if(X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM) != 1){
313
- ossl_raise(eX509StoreError, NULL);
314
- }
352
+ if (!lookup)
353
+ ossl_raise(eX509StoreError, "X509_STORE_add_lookup");
354
+ if (X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM) != 1)
355
+ ossl_raise(eX509StoreError, "X509_LOOKUP_load_file");
315
356
  #if OPENSSL_VERSION_NUMBER < 0x10101000 || defined(LIBRESSL_VERSION_NUMBER)
316
357
  /*
317
358
  * X509_load_cert_crl_file() which is called from X509_LOOKUP_load_file()
@@ -330,23 +371,23 @@ ossl_x509store_add_file(VALUE self, VALUE file)
330
371
  * store.add_path(path) -> self
331
372
  *
332
373
  * Adds _path_ as the hash dir to be looked up by the store.
374
+ *
375
+ * See also the man page X509_LOOKUP_hash_dir(3).
333
376
  */
334
377
  static VALUE
335
378
  ossl_x509store_add_path(VALUE self, VALUE dir)
336
379
  {
337
380
  X509_STORE *store;
338
381
  X509_LOOKUP *lookup;
339
- char *path = NULL;
382
+ const char *path;
340
383
 
341
- if(dir != Qnil){
342
- path = StringValueCStr(dir);
343
- }
344
384
  GetX509Store(self, store);
385
+ path = StringValueCStr(dir);
345
386
  lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
346
- if(lookup == NULL) ossl_raise(eX509StoreError, NULL);
347
- if(X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1){
348
- ossl_raise(eX509StoreError, NULL);
349
- }
387
+ if (!lookup)
388
+ ossl_raise(eX509StoreError, "X509_STORE_add_lookup");
389
+ if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1)
390
+ ossl_raise(eX509StoreError, "X509_LOOKUP_add_dir");
350
391
 
351
392
  return self;
352
393
  }
@@ -361,6 +402,8 @@ ossl_x509store_add_path(VALUE self, VALUE dir)
361
402
  *
362
403
  * * OpenSSL::X509::DEFAULT_CERT_FILE
363
404
  * * OpenSSL::X509::DEFAULT_CERT_DIR
405
+ *
406
+ * See also the man page X509_STORE_set_default_paths(3).
364
407
  */
365
408
  static VALUE
366
409
  ossl_x509store_set_default_paths(VALUE self)
@@ -368,18 +411,19 @@ ossl_x509store_set_default_paths(VALUE self)
368
411
  X509_STORE *store;
369
412
 
370
413
  GetX509Store(self, store);
371
- if (X509_STORE_set_default_paths(store) != 1){
372
- ossl_raise(eX509StoreError, NULL);
373
- }
414
+ if (X509_STORE_set_default_paths(store) != 1)
415
+ ossl_raise(eX509StoreError, "X509_STORE_set_default_paths");
374
416
 
375
417
  return Qnil;
376
418
  }
377
419
 
378
420
  /*
379
421
  * call-seq:
380
- * store.add_cert(cert)
422
+ * store.add_cert(cert) -> self
381
423
  *
382
424
  * Adds the OpenSSL::X509::Certificate _cert_ to the certificate store.
425
+ *
426
+ * See also the man page X509_STORE_add_cert(3).
383
427
  */
384
428
  static VALUE
385
429
  ossl_x509store_add_cert(VALUE self, VALUE arg)
@@ -389,9 +433,8 @@ ossl_x509store_add_cert(VALUE self, VALUE arg)
389
433
 
390
434
  cert = GetX509CertPtr(arg); /* NO NEED TO DUP */
391
435
  GetX509Store(self, store);
392
- if (X509_STORE_add_cert(store, cert) != 1){
393
- ossl_raise(eX509StoreError, NULL);
394
- }
436
+ if (X509_STORE_add_cert(store, cert) != 1)
437
+ ossl_raise(eX509StoreError, "X509_STORE_add_cert");
395
438
 
396
439
  return self;
397
440
  }
@@ -401,6 +444,8 @@ ossl_x509store_add_cert(VALUE self, VALUE arg)
401
444
  * store.add_crl(crl) -> self
402
445
  *
403
446
  * Adds the OpenSSL::X509::CRL _crl_ to the store.
447
+ *
448
+ * See also the man page X509_STORE_add_crl(3).
404
449
  */
405
450
  static VALUE
406
451
  ossl_x509store_add_crl(VALUE self, VALUE arg)
@@ -410,9 +455,8 @@ ossl_x509store_add_crl(VALUE self, VALUE arg)
410
455
 
411
456
  crl = GetX509CRLPtr(arg); /* NO NEED TO DUP */
412
457
  GetX509Store(self, store);
413
- if (X509_STORE_add_crl(store, crl) != 1){
414
- ossl_raise(eX509StoreError, NULL);
415
- }
458
+ if (X509_STORE_add_crl(store, crl) != 1)
459
+ ossl_raise(eX509StoreError, "X509_STORE_add_crl");
416
460
 
417
461
  return self;
418
462
  }
@@ -456,23 +500,16 @@ ossl_x509store_verify(int argc, VALUE *argv, VALUE self)
456
500
  return result;
457
501
  }
458
502
 
459
- /*
460
- * Public Functions
461
- */
462
- static void ossl_x509stctx_free(void*);
463
-
464
-
465
- static const rb_data_type_t ossl_x509stctx_type = {
466
- "OpenSSL/X509/STORE_CTX",
467
- {
468
- 0, ossl_x509stctx_free,
469
- },
470
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
471
- };
472
-
473
503
  /*
474
504
  * Private functions
475
505
  */
506
+ static void
507
+ ossl_x509stctx_mark(void *ptr)
508
+ {
509
+ X509_STORE_CTX *ctx = ptr;
510
+ rb_gc_mark((VALUE)X509_STORE_CTX_get_ex_data(ctx, stctx_ex_verify_cb_idx));
511
+ }
512
+
476
513
  static void
477
514
  ossl_x509stctx_free(void *ptr)
478
515
  {
@@ -484,6 +521,14 @@ ossl_x509stctx_free(void *ptr)
484
521
  X509_STORE_CTX_free(ctx);
485
522
  }
486
523
 
524
+ static const rb_data_type_t ossl_x509stctx_type = {
525
+ "OpenSSL/X509/STORE_CTX",
526
+ {
527
+ ossl_x509stctx_mark, ossl_x509stctx_free,
528
+ },
529
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
530
+ };
531
+
487
532
  static VALUE
488
533
  ossl_x509stctx_alloc(VALUE klass)
489
534
  {
@@ -491,9 +536,8 @@ ossl_x509stctx_alloc(VALUE klass)
491
536
  VALUE obj;
492
537
 
493
538
  obj = NewX509StCtx(klass);
494
- if((ctx = X509_STORE_CTX_new()) == NULL){
495
- ossl_raise(eX509StoreError, NULL);
496
- }
539
+ if ((ctx = X509_STORE_CTX_new()) == NULL)
540
+ ossl_raise(eX509StoreError, "X509_STORE_CTX_new");
497
541
  SetX509StCtx(obj, ctx);
498
542
 
499
543
  return obj;
@@ -517,7 +561,9 @@ static VALUE ossl_x509stctx_set_time(VALUE, VALUE);
517
561
 
518
562
  /*
519
563
  * call-seq:
520
- * StoreContext.new(store, cert = nil, chain = nil)
564
+ * StoreContext.new(store, cert = nil, untrusted = nil)
565
+ *
566
+ * Sets up a StoreContext for a verification of the X.509 certificate _cert_.
521
567
  */
522
568
  static VALUE
523
569
  ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
@@ -527,15 +573,24 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
527
573
  X509_STORE *x509st;
528
574
  X509 *x509 = NULL;
529
575
  STACK_OF(X509) *x509s = NULL;
576
+ int state;
530
577
 
531
578
  rb_scan_args(argc, argv, "12", &store, &cert, &chain);
532
579
  GetX509StCtx(self, ctx);
533
580
  GetX509Store(store, x509st);
534
- if(!NIL_P(cert)) x509 = DupX509CertPtr(cert); /* NEED TO DUP */
535
- if(!NIL_P(chain)) x509s = ossl_x509_ary2sk(chain);
536
- if(X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){
581
+ if (!NIL_P(cert))
582
+ x509 = DupX509CertPtr(cert); /* NEED TO DUP */
583
+ if (!NIL_P(chain)) {
584
+ x509s = ossl_protect_x509_ary2sk(chain, &state);
585
+ if (state) {
586
+ X509_free(x509);
587
+ rb_jump_tag(state);
588
+ }
589
+ }
590
+ if (X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){
591
+ X509_free(x509);
537
592
  sk_X509_pop_free(x509s, X509_free);
538
- ossl_raise(eX509StoreError, NULL);
593
+ ossl_raise(eX509StoreError, "X509_STORE_CTX_init");
539
594
  }
540
595
  if (!NIL_P(t = rb_iv_get(store, "@time")))
541
596
  ossl_x509stctx_set_time(self, t);
@@ -548,6 +603,10 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
548
603
  /*
549
604
  * call-seq:
550
605
  * stctx.verify -> true | false
606
+ *
607
+ * Performs the certificate verification using the parameters set to _stctx_.
608
+ *
609
+ * See also the man page X509_verify_cert(3).
551
610
  */
552
611
  static VALUE
553
612
  ossl_x509stctx_verify(VALUE self)
@@ -560,48 +619,45 @@ ossl_x509stctx_verify(VALUE self)
560
619
 
561
620
  switch (X509_verify_cert(ctx)) {
562
621
  case 1:
563
- return Qtrue;
622
+ return Qtrue;
564
623
  case 0:
565
- ossl_clear_error();
566
- return Qfalse;
624
+ ossl_clear_error();
625
+ return Qfalse;
567
626
  default:
568
- ossl_raise(eX509CertError, NULL);
627
+ ossl_raise(eX509CertError, "X509_verify_cert");
569
628
  }
570
629
  }
571
630
 
572
631
  /*
573
632
  * call-seq:
574
- * stctx.chain -> Array of X509::Certificate
633
+ * stctx.chain -> nil | Array of X509::Certificate
634
+ *
635
+ * Returns the verified chain.
636
+ *
637
+ * See also the man page X509_STORE_CTX_set0_verified_chain(3).
575
638
  */
576
639
  static VALUE
577
640
  ossl_x509stctx_get_chain(VALUE self)
578
641
  {
579
642
  X509_STORE_CTX *ctx;
580
- STACK_OF(X509) *chain;
581
- X509 *x509;
582
- int i, num;
583
- VALUE ary;
643
+ const STACK_OF(X509) *chain;
584
644
 
585
645
  GetX509StCtx(self, ctx);
586
- if((chain = X509_STORE_CTX_get0_chain(ctx)) == NULL){
587
- return Qnil;
588
- }
589
- if((num = sk_X509_num(chain)) < 0){
590
- OSSL_Debug("certs in chain < 0???");
591
- return rb_ary_new();
592
- }
593
- ary = rb_ary_new2(num);
594
- for(i = 0; i < num; i++) {
595
- x509 = sk_X509_value(chain, i);
596
- rb_ary_push(ary, ossl_x509_new(x509));
597
- }
598
-
599
- return ary;
646
+ chain = X509_STORE_CTX_get0_chain(ctx);
647
+ if (!chain)
648
+ return Qnil; /* Could be an empty array instead? */
649
+ return ossl_x509_sk2ary(chain);
600
650
  }
601
651
 
602
652
  /*
603
653
  * call-seq:
604
654
  * stctx.error -> Integer
655
+ *
656
+ * Returns the error code of _stctx_. This is typically called after #verify
657
+ * is done, or from the verification callback set to
658
+ * OpenSSL::X509::Store#verify_callback=.
659
+ *
660
+ * See also the man page X509_STORE_CTX_get_error(3).
605
661
  */
606
662
  static VALUE
607
663
  ossl_x509stctx_get_err(VALUE self)
@@ -616,6 +672,11 @@ ossl_x509stctx_get_err(VALUE self)
616
672
  /*
617
673
  * call-seq:
618
674
  * stctx.error = error_code
675
+ *
676
+ * Sets the error code of _stctx_. This is used by the verification callback
677
+ * set to OpenSSL::X509::Store#verify_callback=.
678
+ *
679
+ * See also the man page X509_STORE_CTX_set_error(3).
619
680
  */
620
681
  static VALUE
621
682
  ossl_x509stctx_set_error(VALUE self, VALUE err)
@@ -632,7 +693,10 @@ ossl_x509stctx_set_error(VALUE self, VALUE err)
632
693
  * call-seq:
633
694
  * stctx.error_string -> String
634
695
  *
635
- * Returns the error string corresponding to the error code retrieved by #error.
696
+ * Returns the human readable error string corresponding to the error code
697
+ * retrieved by #error.
698
+ *
699
+ * See also the man page X509_verify_cert_error_string(3).
636
700
  */
637
701
  static VALUE
638
702
  ossl_x509stctx_get_err_string(VALUE self)
@@ -649,6 +713,10 @@ ossl_x509stctx_get_err_string(VALUE self)
649
713
  /*
650
714
  * call-seq:
651
715
  * stctx.error_depth -> Integer
716
+ *
717
+ * Returns the depth of the chain. This is used in combination with #error.
718
+ *
719
+ * See also the man page X509_STORE_CTX_get_error_depth(3).
652
720
  */
653
721
  static VALUE
654
722
  ossl_x509stctx_get_err_depth(VALUE self)
@@ -663,6 +731,10 @@ ossl_x509stctx_get_err_depth(VALUE self)
663
731
  /*
664
732
  * call-seq:
665
733
  * stctx.current_cert -> X509::Certificate
734
+ *
735
+ * Returns the certificate which caused the error.
736
+ *
737
+ * See also the man page X509_STORE_CTX_get_current_cert(3).
666
738
  */
667
739
  static VALUE
668
740
  ossl_x509stctx_get_curr_cert(VALUE self)
@@ -677,6 +749,10 @@ ossl_x509stctx_get_curr_cert(VALUE self)
677
749
  /*
678
750
  * call-seq:
679
751
  * stctx.current_crl -> X509::CRL
752
+ *
753
+ * Returns the CRL which caused the error.
754
+ *
755
+ * See also the man page X509_STORE_CTX_get_current_crl(3).
680
756
  */
681
757
  static VALUE
682
758
  ossl_x509stctx_get_curr_crl(VALUE self)
@@ -696,7 +772,10 @@ ossl_x509stctx_get_curr_crl(VALUE self)
696
772
  * call-seq:
697
773
  * stctx.flags = flags
698
774
  *
699
- * Sets the verification flags to the context. See Store#flags=.
775
+ * Sets the verification flags to the context. This overrides the default value
776
+ * set by Store#flags=.
777
+ *
778
+ * See also the man page X509_VERIFY_PARAM_set_flags(3).
700
779
  */
701
780
  static VALUE
702
781
  ossl_x509stctx_set_flags(VALUE self, VALUE flags)
@@ -714,7 +793,10 @@ ossl_x509stctx_set_flags(VALUE self, VALUE flags)
714
793
  * call-seq:
715
794
  * stctx.purpose = purpose
716
795
  *
717
- * Sets the purpose of the context. See Store#purpose=.
796
+ * Sets the purpose of the context. This overrides the default value set by
797
+ * Store#purpose=.
798
+ *
799
+ * See also the man page X509_VERIFY_PARAM_set_purpose(3).
718
800
  */
719
801
  static VALUE
720
802
  ossl_x509stctx_set_purpose(VALUE self, VALUE purpose)
@@ -731,6 +813,11 @@ ossl_x509stctx_set_purpose(VALUE self, VALUE purpose)
731
813
  /*
732
814
  * call-seq:
733
815
  * stctx.trust = trust
816
+ *
817
+ * Sets the trust settings of the context. This overrides the default value set
818
+ * by Store#trust=.
819
+ *
820
+ * See also the man page X509_VERIFY_PARAM_set_trust(3).
734
821
  */
735
822
  static VALUE
736
823
  ossl_x509stctx_set_trust(VALUE self, VALUE trust)
@@ -749,6 +836,8 @@ ossl_x509stctx_set_trust(VALUE self, VALUE trust)
749
836
  * stctx.time = time
750
837
  *
751
838
  * Sets the time used in the verification. If not set, the current time is used.
839
+ *
840
+ * See also the man page X509_VERIFY_PARAM_set_time(3).
752
841
  */
753
842
  static VALUE
754
843
  ossl_x509stctx_set_time(VALUE self, VALUE time)
@@ -824,23 +913,37 @@ Init_ossl_x509store(void)
824
913
  cX509Store = rb_define_class_under(mX509, "Store", rb_cObject);
825
914
  /*
826
915
  * The callback for additional certificate verification. It is invoked for
827
- * each untrusted certificate in the chain.
916
+ * each certificate in the chain and can be used to implement custom
917
+ * certificate verification conditions.
828
918
  *
829
919
  * The callback is invoked with two values, a boolean that indicates if the
830
920
  * pre-verification by OpenSSL has succeeded or not, and the StoreContext in
831
- * use. The callback must return either true or false.
921
+ * use.
922
+ *
923
+ * The callback can use StoreContext#error= to change the error code as
924
+ * needed. The callback must return either true or false.
925
+ *
926
+ * NOTE: any exception raised within the callback will be ignored.
927
+ *
928
+ * See also the man page X509_STORE_CTX_set_verify_cb(3).
832
929
  */
833
930
  rb_attr(cX509Store, rb_intern("verify_callback"), 1, 0, Qfalse);
834
931
  /*
835
932
  * The error code set by the last call of #verify.
933
+ *
934
+ * See also StoreContext#error.
836
935
  */
837
936
  rb_attr(cX509Store, rb_intern("error"), 1, 0, Qfalse);
838
937
  /*
839
938
  * The description for the error code set by the last call of #verify.
939
+ *
940
+ * See also StoreContext#error_string.
840
941
  */
841
942
  rb_attr(cX509Store, rb_intern("error_string"), 1, 0, Qfalse);
842
943
  /*
843
944
  * The certificate chain constructed by the last call of #verify.
945
+ *
946
+ * See also StoreContext#chain.
844
947
  */
845
948
  rb_attr(cX509Store, rb_intern("chain"), 1, 0, Qfalse);
846
949
  rb_define_alloc_func(cX509Store, ossl_x509store_alloc);