openssl 2.2.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +33 -45
  3. data/History.md +300 -0
  4. data/README.md +36 -19
  5. data/ext/openssl/extconf.rb +119 -79
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +26 -45
  8. data/ext/openssl/ossl.c +131 -233
  9. data/ext/openssl/ossl.h +31 -12
  10. data/ext/openssl/ossl_asn1.c +26 -13
  11. data/ext/openssl/ossl_bn.c +279 -143
  12. data/ext/openssl/ossl_bn.h +2 -1
  13. data/ext/openssl/ossl_cipher.c +13 -14
  14. data/ext/openssl/ossl_config.c +412 -41
  15. data/ext/openssl/ossl_config.h +4 -7
  16. data/ext/openssl/ossl_digest.c +16 -12
  17. data/ext/openssl/ossl_engine.c +17 -16
  18. data/ext/openssl/ossl_hmac.c +57 -136
  19. data/ext/openssl/ossl_kdf.c +12 -4
  20. data/ext/openssl/ossl_ns_spki.c +1 -1
  21. data/ext/openssl/ossl_ocsp.c +11 -59
  22. data/ext/openssl/ossl_pkcs12.c +22 -4
  23. data/ext/openssl/ossl_pkcs7.c +45 -62
  24. data/ext/openssl/ossl_pkey.c +1320 -196
  25. data/ext/openssl/ossl_pkey.h +36 -73
  26. data/ext/openssl/ossl_pkey_dh.c +152 -347
  27. data/ext/openssl/ossl_pkey_dsa.c +157 -413
  28. data/ext/openssl/ossl_pkey_ec.c +227 -343
  29. data/ext/openssl/ossl_pkey_rsa.c +159 -491
  30. data/ext/openssl/ossl_provider.c +211 -0
  31. data/ext/openssl/ossl_provider.h +5 -0
  32. data/ext/openssl/ossl_ssl.c +593 -467
  33. data/ext/openssl/ossl_ssl_session.c +29 -30
  34. data/ext/openssl/ossl_ts.c +67 -42
  35. data/ext/openssl/ossl_x509.c +0 -6
  36. data/ext/openssl/ossl_x509attr.c +1 -1
  37. data/ext/openssl/ossl_x509cert.c +168 -12
  38. data/ext/openssl/ossl_x509crl.c +14 -11
  39. data/ext/openssl/ossl_x509ext.c +14 -9
  40. data/ext/openssl/ossl_x509name.c +10 -3
  41. data/ext/openssl/ossl_x509req.c +14 -11
  42. data/ext/openssl/ossl_x509revoked.c +4 -4
  43. data/ext/openssl/ossl_x509store.c +204 -94
  44. data/lib/openssl/buffering.rb +10 -4
  45. data/lib/openssl/digest.rb +1 -5
  46. data/lib/openssl/hmac.rb +65 -0
  47. data/lib/openssl/pkey.rb +429 -0
  48. data/lib/openssl/ssl.rb +23 -18
  49. data/lib/openssl/version.rb +1 -1
  50. data/lib/openssl/x509.rb +22 -0
  51. data/lib/openssl.rb +0 -1
  52. metadata +13 -68
  53. data/ext/openssl/ruby_missing.h +0 -24
  54. data/lib/openssl/config.rb +0 -501
@@ -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,16 @@ 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
+ // Note: this reference is stored as @verify_callback so we don't need to mark it.
120
+ // However we do need to ensure GC compaction won't move it, hence why
121
+ // we call rb_gc_mark here.
122
+ rb_gc_mark((VALUE)X509_STORE_get_ex_data(store, store_ex_verify_cb_idx));
123
+ }
124
+
108
125
  static void
109
126
  ossl_x509store_free(void *ptr)
110
127
  {
@@ -114,9 +131,9 @@ ossl_x509store_free(void *ptr)
114
131
  static const rb_data_type_t ossl_x509store_type = {
115
132
  "OpenSSL/X509/STORE",
116
133
  {
117
- 0, ossl_x509store_free,
134
+ ossl_x509store_mark, ossl_x509store_free,
118
135
  },
119
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
136
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
120
137
  };
121
138
 
122
139
  /*
@@ -157,9 +174,8 @@ ossl_x509store_alloc(VALUE klass)
157
174
  VALUE obj;
158
175
 
159
176
  obj = NewX509Store(klass);
160
- if((store = X509_STORE_new()) == NULL){
161
- ossl_raise(eX509StoreError, NULL);
162
- }
177
+ if ((store = X509_STORE_new()) == NULL)
178
+ ossl_raise(eX509StoreError, "X509_STORE_new");
163
179
  SetX509Store(obj, store);
164
180
 
165
181
  return obj;
@@ -174,8 +190,9 @@ ossl_x509store_set_vfy_cb(VALUE self, VALUE cb)
174
190
  X509_STORE *store;
175
191
 
176
192
  GetX509Store(self, store);
177
- X509_STORE_set_ex_data(store, store_ex_verify_cb_idx, (void *)cb);
178
193
  rb_iv_set(self, "@verify_callback", cb);
194
+ // We don't need to trigger a write barrier because `rb_iv_set` did it.
195
+ X509_STORE_set_ex_data(store, store_ex_verify_cb_idx, (void *)cb);
179
196
 
180
197
  return cb;
181
198
  }
@@ -192,8 +209,9 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
192
209
  {
193
210
  X509_STORE *store;
194
211
 
195
- /* BUG: This method takes any number of arguments but appears to ignore them. */
196
212
  GetX509Store(self, store);
213
+ if (argc != 0)
214
+ rb_warn("OpenSSL::X509::Store.new does not take any arguments");
197
215
  #if !defined(HAVE_OPAQUE_OPENSSL)
198
216
  /* [Bug #405] [Bug #1678] [Bug #3000]; already fixed? */
199
217
  store->ex_data.sk = NULL;
@@ -214,8 +232,16 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
214
232
  * call-seq:
215
233
  * store.flags = flags
216
234
  *
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.
235
+ * Sets the default flags used by certificate chain verification performed with
236
+ * the Store.
237
+ *
238
+ * _flags_ consists of zero or more of the constants defined in OpenSSL::X509
239
+ * with name V_FLAG_* or'ed together.
240
+ *
241
+ * OpenSSL::X509::StoreContext#flags= can be used to change the flags for a
242
+ * single verification operation.
243
+ *
244
+ * See also the man page X509_VERIFY_PARAM_set_flags(3).
219
245
  */
220
246
  static VALUE
221
247
  ossl_x509store_set_flags(VALUE self, VALUE flags)
@@ -233,9 +259,9 @@ ossl_x509store_set_flags(VALUE self, VALUE flags)
233
259
  * call-seq:
234
260
  * store.purpose = purpose
235
261
  *
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:
262
+ * Sets the store's default verification purpose. If specified,
263
+ * the verifications on the store will check every certificate's extensions are
264
+ * consistent with the purpose. The purpose is specified by constants:
239
265
  *
240
266
  * * X509::PURPOSE_SSL_CLIENT
241
267
  * * X509::PURPOSE_SSL_SERVER
@@ -246,6 +272,11 @@ ossl_x509store_set_flags(VALUE self, VALUE flags)
246
272
  * * X509::PURPOSE_ANY
247
273
  * * X509::PURPOSE_OCSP_HELPER
248
274
  * * X509::PURPOSE_TIMESTAMP_SIGN
275
+ *
276
+ * OpenSSL::X509::StoreContext#purpose= can be used to change the value for a
277
+ * single verification operation.
278
+ *
279
+ * See also the man page X509_VERIFY_PARAM_set_purpose(3).
249
280
  */
250
281
  static VALUE
251
282
  ossl_x509store_set_purpose(VALUE self, VALUE purpose)
@@ -262,6 +293,14 @@ ossl_x509store_set_purpose(VALUE self, VALUE purpose)
262
293
  /*
263
294
  * call-seq:
264
295
  * store.trust = trust
296
+ *
297
+ * Sets the default trust settings used by the certificate verification with
298
+ * the store.
299
+ *
300
+ * OpenSSL::X509::StoreContext#trust= can be used to change the value for a
301
+ * single verification operation.
302
+ *
303
+ * See also the man page X509_VERIFY_PARAM_set_trust(3).
265
304
  */
266
305
  static VALUE
267
306
  ossl_x509store_set_trust(VALUE self, VALUE trust)
@@ -279,7 +318,13 @@ ossl_x509store_set_trust(VALUE self, VALUE trust)
279
318
  * call-seq:
280
319
  * store.time = time
281
320
  *
282
- * Sets the time to be used in verifications.
321
+ * Sets the time to be used in the certificate verifications with the store.
322
+ * By default, if not specified, the current system time is used.
323
+ *
324
+ * OpenSSL::X509::StoreContext#time= can be used to change the value for a
325
+ * single verification operation.
326
+ *
327
+ * See also the man page X509_VERIFY_PARAM_set_time(3).
283
328
  */
284
329
  static VALUE
285
330
  ossl_x509store_set_time(VALUE self, VALUE time)
@@ -295,23 +340,23 @@ ossl_x509store_set_time(VALUE self, VALUE time)
295
340
  * Adds the certificates in _file_ to the certificate store. _file_ is the path
296
341
  * to the file, and the file contains one or more certificates in PEM format
297
342
  * concatenated together.
343
+ *
344
+ * See also the man page X509_LOOKUP_file(3).
298
345
  */
299
346
  static VALUE
300
347
  ossl_x509store_add_file(VALUE self, VALUE file)
301
348
  {
302
349
  X509_STORE *store;
303
350
  X509_LOOKUP *lookup;
304
- char *path = NULL;
351
+ const char *path;
305
352
 
306
- if(file != Qnil){
307
- path = StringValueCStr(file);
308
- }
309
353
  GetX509Store(self, store);
354
+ path = StringValueCStr(file);
310
355
  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
- }
356
+ if (!lookup)
357
+ ossl_raise(eX509StoreError, "X509_STORE_add_lookup");
358
+ if (X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM) != 1)
359
+ ossl_raise(eX509StoreError, "X509_LOOKUP_load_file");
315
360
  #if OPENSSL_VERSION_NUMBER < 0x10101000 || defined(LIBRESSL_VERSION_NUMBER)
316
361
  /*
317
362
  * X509_load_cert_crl_file() which is called from X509_LOOKUP_load_file()
@@ -330,23 +375,23 @@ ossl_x509store_add_file(VALUE self, VALUE file)
330
375
  * store.add_path(path) -> self
331
376
  *
332
377
  * Adds _path_ as the hash dir to be looked up by the store.
378
+ *
379
+ * See also the man page X509_LOOKUP_hash_dir(3).
333
380
  */
334
381
  static VALUE
335
382
  ossl_x509store_add_path(VALUE self, VALUE dir)
336
383
  {
337
384
  X509_STORE *store;
338
385
  X509_LOOKUP *lookup;
339
- char *path = NULL;
386
+ const char *path;
340
387
 
341
- if(dir != Qnil){
342
- path = StringValueCStr(dir);
343
- }
344
388
  GetX509Store(self, store);
389
+ path = StringValueCStr(dir);
345
390
  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
- }
391
+ if (!lookup)
392
+ ossl_raise(eX509StoreError, "X509_STORE_add_lookup");
393
+ if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1)
394
+ ossl_raise(eX509StoreError, "X509_LOOKUP_add_dir");
350
395
 
351
396
  return self;
352
397
  }
@@ -361,6 +406,8 @@ ossl_x509store_add_path(VALUE self, VALUE dir)
361
406
  *
362
407
  * * OpenSSL::X509::DEFAULT_CERT_FILE
363
408
  * * OpenSSL::X509::DEFAULT_CERT_DIR
409
+ *
410
+ * See also the man page X509_STORE_set_default_paths(3).
364
411
  */
365
412
  static VALUE
366
413
  ossl_x509store_set_default_paths(VALUE self)
@@ -368,18 +415,19 @@ ossl_x509store_set_default_paths(VALUE self)
368
415
  X509_STORE *store;
369
416
 
370
417
  GetX509Store(self, store);
371
- if (X509_STORE_set_default_paths(store) != 1){
372
- ossl_raise(eX509StoreError, NULL);
373
- }
418
+ if (X509_STORE_set_default_paths(store) != 1)
419
+ ossl_raise(eX509StoreError, "X509_STORE_set_default_paths");
374
420
 
375
421
  return Qnil;
376
422
  }
377
423
 
378
424
  /*
379
425
  * call-seq:
380
- * store.add_cert(cert)
426
+ * store.add_cert(cert) -> self
381
427
  *
382
428
  * Adds the OpenSSL::X509::Certificate _cert_ to the certificate store.
429
+ *
430
+ * See also the man page X509_STORE_add_cert(3).
383
431
  */
384
432
  static VALUE
385
433
  ossl_x509store_add_cert(VALUE self, VALUE arg)
@@ -389,9 +437,8 @@ ossl_x509store_add_cert(VALUE self, VALUE arg)
389
437
 
390
438
  cert = GetX509CertPtr(arg); /* NO NEED TO DUP */
391
439
  GetX509Store(self, store);
392
- if (X509_STORE_add_cert(store, cert) != 1){
393
- ossl_raise(eX509StoreError, NULL);
394
- }
440
+ if (X509_STORE_add_cert(store, cert) != 1)
441
+ ossl_raise(eX509StoreError, "X509_STORE_add_cert");
395
442
 
396
443
  return self;
397
444
  }
@@ -401,6 +448,8 @@ ossl_x509store_add_cert(VALUE self, VALUE arg)
401
448
  * store.add_crl(crl) -> self
402
449
  *
403
450
  * Adds the OpenSSL::X509::CRL _crl_ to the store.
451
+ *
452
+ * See also the man page X509_STORE_add_crl(3).
404
453
  */
405
454
  static VALUE
406
455
  ossl_x509store_add_crl(VALUE self, VALUE arg)
@@ -410,9 +459,8 @@ ossl_x509store_add_crl(VALUE self, VALUE arg)
410
459
 
411
460
  crl = GetX509CRLPtr(arg); /* NO NEED TO DUP */
412
461
  GetX509Store(self, store);
413
- if (X509_STORE_add_crl(store, crl) != 1){
414
- ossl_raise(eX509StoreError, NULL);
415
- }
462
+ if (X509_STORE_add_crl(store, crl) != 1)
463
+ ossl_raise(eX509StoreError, "X509_STORE_add_crl");
416
464
 
417
465
  return self;
418
466
  }
@@ -456,23 +504,19 @@ ossl_x509store_verify(int argc, VALUE *argv, VALUE self)
456
504
  return result;
457
505
  }
458
506
 
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
507
  /*
474
508
  * Private functions
475
509
  */
510
+ static void
511
+ ossl_x509stctx_mark(void *ptr)
512
+ {
513
+ X509_STORE_CTX *ctx = ptr;
514
+ // Note: this reference is stored as @verify_callback so we don't need to mark it.
515
+ // However we do need to ensure GC compaction won't move it, hence why
516
+ // we call rb_gc_mark here.
517
+ rb_gc_mark((VALUE)X509_STORE_CTX_get_ex_data(ctx, stctx_ex_verify_cb_idx));
518
+ }
519
+
476
520
  static void
477
521
  ossl_x509stctx_free(void *ptr)
478
522
  {
@@ -484,6 +528,14 @@ ossl_x509stctx_free(void *ptr)
484
528
  X509_STORE_CTX_free(ctx);
485
529
  }
486
530
 
531
+ static const rb_data_type_t ossl_x509stctx_type = {
532
+ "OpenSSL/X509/STORE_CTX",
533
+ {
534
+ ossl_x509stctx_mark, ossl_x509stctx_free,
535
+ },
536
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
537
+ };
538
+
487
539
  static VALUE
488
540
  ossl_x509stctx_alloc(VALUE klass)
489
541
  {
@@ -491,9 +543,8 @@ ossl_x509stctx_alloc(VALUE klass)
491
543
  VALUE obj;
492
544
 
493
545
  obj = NewX509StCtx(klass);
494
- if((ctx = X509_STORE_CTX_new()) == NULL){
495
- ossl_raise(eX509StoreError, NULL);
496
- }
546
+ if ((ctx = X509_STORE_CTX_new()) == NULL)
547
+ ossl_raise(eX509StoreError, "X509_STORE_CTX_new");
497
548
  SetX509StCtx(obj, ctx);
498
549
 
499
550
  return obj;
@@ -517,7 +568,9 @@ static VALUE ossl_x509stctx_set_time(VALUE, VALUE);
517
568
 
518
569
  /*
519
570
  * call-seq:
520
- * StoreContext.new(store, cert = nil, chain = nil)
571
+ * StoreContext.new(store, cert = nil, untrusted = nil)
572
+ *
573
+ * Sets up a StoreContext for a verification of the X.509 certificate _cert_.
521
574
  */
522
575
  static VALUE
523
576
  ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
@@ -527,15 +580,24 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
527
580
  X509_STORE *x509st;
528
581
  X509 *x509 = NULL;
529
582
  STACK_OF(X509) *x509s = NULL;
583
+ int state;
530
584
 
531
585
  rb_scan_args(argc, argv, "12", &store, &cert, &chain);
532
586
  GetX509StCtx(self, ctx);
533
587
  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){
588
+ if (!NIL_P(cert))
589
+ x509 = DupX509CertPtr(cert); /* NEED TO DUP */
590
+ if (!NIL_P(chain)) {
591
+ x509s = ossl_protect_x509_ary2sk(chain, &state);
592
+ if (state) {
593
+ X509_free(x509);
594
+ rb_jump_tag(state);
595
+ }
596
+ }
597
+ if (X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){
598
+ X509_free(x509);
537
599
  sk_X509_pop_free(x509s, X509_free);
538
- ossl_raise(eX509StoreError, NULL);
600
+ ossl_raise(eX509StoreError, "X509_STORE_CTX_init");
539
601
  }
540
602
  if (!NIL_P(t = rb_iv_get(store, "@time")))
541
603
  ossl_x509stctx_set_time(self, t);
@@ -548,6 +610,10 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
548
610
  /*
549
611
  * call-seq:
550
612
  * stctx.verify -> true | false
613
+ *
614
+ * Performs the certificate verification using the parameters set to _stctx_.
615
+ *
616
+ * See also the man page X509_verify_cert(3).
551
617
  */
552
618
  static VALUE
553
619
  ossl_x509stctx_verify(VALUE self)
@@ -555,53 +621,50 @@ ossl_x509stctx_verify(VALUE self)
555
621
  X509_STORE_CTX *ctx;
556
622
 
557
623
  GetX509StCtx(self, ctx);
558
- X509_STORE_CTX_set_ex_data(ctx, stctx_ex_verify_cb_idx,
559
- (void *)rb_iv_get(self, "@verify_callback"));
624
+ VALUE cb = rb_iv_get(self, "@verify_callback");
625
+ X509_STORE_CTX_set_ex_data(ctx, stctx_ex_verify_cb_idx, (void *)cb);
560
626
 
561
627
  switch (X509_verify_cert(ctx)) {
562
628
  case 1:
563
- return Qtrue;
629
+ return Qtrue;
564
630
  case 0:
565
- ossl_clear_error();
566
- return Qfalse;
631
+ ossl_clear_error();
632
+ return Qfalse;
567
633
  default:
568
- ossl_raise(eX509CertError, NULL);
634
+ ossl_raise(eX509CertError, "X509_verify_cert");
569
635
  }
570
636
  }
571
637
 
572
638
  /*
573
639
  * call-seq:
574
- * stctx.chain -> Array of X509::Certificate
640
+ * stctx.chain -> nil | Array of X509::Certificate
641
+ *
642
+ * Returns the verified chain.
643
+ *
644
+ * See also the man page X509_STORE_CTX_set0_verified_chain(3).
575
645
  */
576
646
  static VALUE
577
647
  ossl_x509stctx_get_chain(VALUE self)
578
648
  {
579
649
  X509_STORE_CTX *ctx;
580
- STACK_OF(X509) *chain;
581
- X509 *x509;
582
- int i, num;
583
- VALUE ary;
650
+ const STACK_OF(X509) *chain;
584
651
 
585
652
  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;
653
+ chain = X509_STORE_CTX_get0_chain(ctx);
654
+ if (!chain)
655
+ return Qnil; /* Could be an empty array instead? */
656
+ return ossl_x509_sk2ary(chain);
600
657
  }
601
658
 
602
659
  /*
603
660
  * call-seq:
604
661
  * stctx.error -> Integer
662
+ *
663
+ * Returns the error code of _stctx_. This is typically called after #verify
664
+ * is done, or from the verification callback set to
665
+ * OpenSSL::X509::Store#verify_callback=.
666
+ *
667
+ * See also the man page X509_STORE_CTX_get_error(3).
605
668
  */
606
669
  static VALUE
607
670
  ossl_x509stctx_get_err(VALUE self)
@@ -616,6 +679,11 @@ ossl_x509stctx_get_err(VALUE self)
616
679
  /*
617
680
  * call-seq:
618
681
  * stctx.error = error_code
682
+ *
683
+ * Sets the error code of _stctx_. This is used by the verification callback
684
+ * set to OpenSSL::X509::Store#verify_callback=.
685
+ *
686
+ * See also the man page X509_STORE_CTX_set_error(3).
619
687
  */
620
688
  static VALUE
621
689
  ossl_x509stctx_set_error(VALUE self, VALUE err)
@@ -632,7 +700,10 @@ ossl_x509stctx_set_error(VALUE self, VALUE err)
632
700
  * call-seq:
633
701
  * stctx.error_string -> String
634
702
  *
635
- * Returns the error string corresponding to the error code retrieved by #error.
703
+ * Returns the human readable error string corresponding to the error code
704
+ * retrieved by #error.
705
+ *
706
+ * See also the man page X509_verify_cert_error_string(3).
636
707
  */
637
708
  static VALUE
638
709
  ossl_x509stctx_get_err_string(VALUE self)
@@ -649,6 +720,10 @@ ossl_x509stctx_get_err_string(VALUE self)
649
720
  /*
650
721
  * call-seq:
651
722
  * stctx.error_depth -> Integer
723
+ *
724
+ * Returns the depth of the chain. This is used in combination with #error.
725
+ *
726
+ * See also the man page X509_STORE_CTX_get_error_depth(3).
652
727
  */
653
728
  static VALUE
654
729
  ossl_x509stctx_get_err_depth(VALUE self)
@@ -663,6 +738,10 @@ ossl_x509stctx_get_err_depth(VALUE self)
663
738
  /*
664
739
  * call-seq:
665
740
  * stctx.current_cert -> X509::Certificate
741
+ *
742
+ * Returns the certificate which caused the error.
743
+ *
744
+ * See also the man page X509_STORE_CTX_get_current_cert(3).
666
745
  */
667
746
  static VALUE
668
747
  ossl_x509stctx_get_curr_cert(VALUE self)
@@ -677,6 +756,10 @@ ossl_x509stctx_get_curr_cert(VALUE self)
677
756
  /*
678
757
  * call-seq:
679
758
  * stctx.current_crl -> X509::CRL
759
+ *
760
+ * Returns the CRL which caused the error.
761
+ *
762
+ * See also the man page X509_STORE_CTX_get_current_crl(3).
680
763
  */
681
764
  static VALUE
682
765
  ossl_x509stctx_get_curr_crl(VALUE self)
@@ -696,7 +779,10 @@ ossl_x509stctx_get_curr_crl(VALUE self)
696
779
  * call-seq:
697
780
  * stctx.flags = flags
698
781
  *
699
- * Sets the verification flags to the context. See Store#flags=.
782
+ * Sets the verification flags to the context. This overrides the default value
783
+ * set by Store#flags=.
784
+ *
785
+ * See also the man page X509_VERIFY_PARAM_set_flags(3).
700
786
  */
701
787
  static VALUE
702
788
  ossl_x509stctx_set_flags(VALUE self, VALUE flags)
@@ -714,7 +800,10 @@ ossl_x509stctx_set_flags(VALUE self, VALUE flags)
714
800
  * call-seq:
715
801
  * stctx.purpose = purpose
716
802
  *
717
- * Sets the purpose of the context. See Store#purpose=.
803
+ * Sets the purpose of the context. This overrides the default value set by
804
+ * Store#purpose=.
805
+ *
806
+ * See also the man page X509_VERIFY_PARAM_set_purpose(3).
718
807
  */
719
808
  static VALUE
720
809
  ossl_x509stctx_set_purpose(VALUE self, VALUE purpose)
@@ -731,6 +820,11 @@ ossl_x509stctx_set_purpose(VALUE self, VALUE purpose)
731
820
  /*
732
821
  * call-seq:
733
822
  * stctx.trust = trust
823
+ *
824
+ * Sets the trust settings of the context. This overrides the default value set
825
+ * by Store#trust=.
826
+ *
827
+ * See also the man page X509_VERIFY_PARAM_set_trust(3).
734
828
  */
735
829
  static VALUE
736
830
  ossl_x509stctx_set_trust(VALUE self, VALUE trust)
@@ -749,6 +843,8 @@ ossl_x509stctx_set_trust(VALUE self, VALUE trust)
749
843
  * stctx.time = time
750
844
  *
751
845
  * Sets the time used in the verification. If not set, the current time is used.
846
+ *
847
+ * See also the man page X509_VERIFY_PARAM_set_time(3).
752
848
  */
753
849
  static VALUE
754
850
  ossl_x509stctx_set_time(VALUE self, VALUE time)
@@ -824,23 +920,37 @@ Init_ossl_x509store(void)
824
920
  cX509Store = rb_define_class_under(mX509, "Store", rb_cObject);
825
921
  /*
826
922
  * The callback for additional certificate verification. It is invoked for
827
- * each untrusted certificate in the chain.
923
+ * each certificate in the chain and can be used to implement custom
924
+ * certificate verification conditions.
828
925
  *
829
926
  * The callback is invoked with two values, a boolean that indicates if the
830
927
  * pre-verification by OpenSSL has succeeded or not, and the StoreContext in
831
- * use. The callback must return either true or false.
928
+ * use.
929
+ *
930
+ * The callback can use StoreContext#error= to change the error code as
931
+ * needed. The callback must return either true or false.
932
+ *
933
+ * NOTE: any exception raised within the callback will be ignored.
934
+ *
935
+ * See also the man page X509_STORE_CTX_set_verify_cb(3).
832
936
  */
833
937
  rb_attr(cX509Store, rb_intern("verify_callback"), 1, 0, Qfalse);
834
938
  /*
835
939
  * The error code set by the last call of #verify.
940
+ *
941
+ * See also StoreContext#error.
836
942
  */
837
943
  rb_attr(cX509Store, rb_intern("error"), 1, 0, Qfalse);
838
944
  /*
839
945
  * The description for the error code set by the last call of #verify.
946
+ *
947
+ * See also StoreContext#error_string.
840
948
  */
841
949
  rb_attr(cX509Store, rb_intern("error_string"), 1, 0, Qfalse);
842
950
  /*
843
951
  * The certificate chain constructed by the last call of #verify.
952
+ *
953
+ * See also StoreContext#chain.
844
954
  */
845
955
  rb_attr(cX509Store, rb_intern("chain"), 1, 0, Qfalse);
846
956
  rb_define_alloc_func(cX509Store, ossl_x509store_alloc);
@@ -31,7 +31,7 @@ module OpenSSL::Buffering
31
31
 
32
32
  force_encoding(BINARY)
33
33
  end
34
-
34
+
35
35
  def << string
36
36
  if string.encoding == BINARY
37
37
  super(string)
@@ -93,14 +93,20 @@ module OpenSSL::Buffering
93
93
  nil
94
94
  else
95
95
  size = @rbuffer.size unless size
96
- ret = @rbuffer[0, size]
97
- @rbuffer[0, size] = ""
98
- ret
96
+ @rbuffer.slice!(0, size)
99
97
  end
100
98
  end
101
99
 
102
100
  public
103
101
 
102
+ # call-seq:
103
+ # ssl.getbyte => 81
104
+ #
105
+ # Get the next 8bit byte from `ssl`. Returns `nil` on EOF
106
+ def getbyte
107
+ read(1)&.ord
108
+ end
109
+
104
110
  ##
105
111
  # Reads _size_ bytes from the stream. If _buf_ is provided it must
106
112
  # reference a string which will receive the data.
@@ -18,13 +18,9 @@ module OpenSSL
18
18
  # Return the hash value computed with _name_ Digest. _name_ is either the
19
19
  # long name or short name of a supported digest algorithm.
20
20
  #
21
- # === Examples
21
+ # === Example
22
22
  #
23
23
  # OpenSSL::Digest.digest("SHA256", "abc")
24
- #
25
- # which is equivalent to:
26
- #
27
- # OpenSSL::Digest.digest('SHA256', "abc")
28
24
 
29
25
  def self.digest(name, data)
30
26
  super(data, name)