openssl 2.2.1 → 3.2.0

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +33 -45
  3. data/History.md +248 -1
  4. data/README.md +36 -19
  5. data/ext/openssl/extconf.rb +101 -68
  6. data/ext/openssl/openssl_missing.c +0 -66
  7. data/ext/openssl/openssl_missing.h +26 -45
  8. data/ext/openssl/ossl.c +128 -237
  9. data/ext/openssl/ossl.h +31 -12
  10. data/ext/openssl/ossl_asn1.c +26 -13
  11. data/ext/openssl/ossl_bn.c +213 -139
  12. data/ext/openssl/ossl_cipher.c +13 -14
  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 +10 -10
  16. data/ext/openssl/ossl_engine.c +17 -16
  17. data/ext/openssl/ossl_hmac.c +57 -136
  18. data/ext/openssl/ossl_kdf.c +12 -4
  19. data/ext/openssl/ossl_ns_spki.c +1 -1
  20. data/ext/openssl/ossl_ocsp.c +11 -59
  21. data/ext/openssl/ossl_pkcs12.c +22 -4
  22. data/ext/openssl/ossl_pkcs7.c +45 -62
  23. data/ext/openssl/ossl_pkey.c +1320 -196
  24. data/ext/openssl/ossl_pkey.h +36 -73
  25. data/ext/openssl/ossl_pkey_dh.c +152 -347
  26. data/ext/openssl/ossl_pkey_dsa.c +157 -413
  27. data/ext/openssl/ossl_pkey_ec.c +227 -343
  28. data/ext/openssl/ossl_pkey_rsa.c +159 -491
  29. data/ext/openssl/ossl_provider.c +211 -0
  30. data/ext/openssl/ossl_provider.h +5 -0
  31. data/ext/openssl/ossl_ssl.c +530 -450
  32. data/ext/openssl/ossl_ssl_session.c +29 -30
  33. data/ext/openssl/ossl_ts.c +38 -23
  34. data/ext/openssl/ossl_x509.c +0 -6
  35. data/ext/openssl/ossl_x509attr.c +1 -1
  36. data/ext/openssl/ossl_x509cert.c +168 -12
  37. data/ext/openssl/ossl_x509crl.c +14 -11
  38. data/ext/openssl/ossl_x509ext.c +14 -9
  39. data/ext/openssl/ossl_x509name.c +10 -3
  40. data/ext/openssl/ossl_x509req.c +14 -11
  41. data/ext/openssl/ossl_x509revoked.c +4 -4
  42. data/ext/openssl/ossl_x509store.c +166 -75
  43. data/lib/openssl/buffering.rb +9 -3
  44. data/lib/openssl/digest.rb +1 -5
  45. data/lib/openssl/hmac.rb +65 -0
  46. data/lib/openssl/pkey.rb +429 -0
  47. data/lib/openssl/ssl.rb +22 -17
  48. data/lib/openssl/version.rb +1 -1
  49. data/lib/openssl/x509.rb +22 -0
  50. data/lib/openssl.rb +0 -1
  51. metadata +10 -79
  52. data/ext/openssl/ruby_missing.h +0 -24
  53. data/lib/openssl/config.rb +0 -501
@@ -46,7 +46,7 @@ static const rb_data_type_t ossl_x509name_type = {
46
46
  {
47
47
  0, ossl_x509name_free,
48
48
  },
49
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
49
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
50
50
  };
51
51
 
52
52
  /*
@@ -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
  */
@@ -41,7 +41,7 @@ static const rb_data_type_t ossl_x509req_type = {
41
41
  {
42
42
  0, ossl_x509req_free,
43
43
  },
44
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
44
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
45
45
  };
46
46
 
47
47
  /*
@@ -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;
@@ -41,7 +41,7 @@ static const rb_data_type_t ossl_x509rev_type = {
41
41
  {
42
42
  0, ossl_x509rev_free,
43
43
  },
44
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
44
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
45
45
  };
46
46
 
47
47
  /*
@@ -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");
@@ -109,6 +116,9 @@ static void
109
116
  ossl_x509store_mark(void *ptr)
110
117
  {
111
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.
112
122
  rb_gc_mark((VALUE)X509_STORE_get_ex_data(store, store_ex_verify_cb_idx));
113
123
  }
114
124
 
@@ -123,7 +133,7 @@ static const rb_data_type_t ossl_x509store_type = {
123
133
  {
124
134
  ossl_x509store_mark, ossl_x509store_free,
125
135
  },
126
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
136
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
127
137
  };
128
138
 
129
139
  /*
@@ -164,9 +174,8 @@ ossl_x509store_alloc(VALUE klass)
164
174
  VALUE obj;
165
175
 
166
176
  obj = NewX509Store(klass);
167
- if((store = X509_STORE_new()) == NULL){
168
- ossl_raise(eX509StoreError, NULL);
169
- }
177
+ if ((store = X509_STORE_new()) == NULL)
178
+ ossl_raise(eX509StoreError, "X509_STORE_new");
170
179
  SetX509Store(obj, store);
171
180
 
172
181
  return obj;
@@ -181,8 +190,9 @@ ossl_x509store_set_vfy_cb(VALUE self, VALUE cb)
181
190
  X509_STORE *store;
182
191
 
183
192
  GetX509Store(self, store);
184
- X509_STORE_set_ex_data(store, store_ex_verify_cb_idx, (void *)cb);
185
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);
186
196
 
187
197
  return cb;
188
198
  }
@@ -199,8 +209,9 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
199
209
  {
200
210
  X509_STORE *store;
201
211
 
202
- /* BUG: This method takes any number of arguments but appears to ignore them. */
203
212
  GetX509Store(self, store);
213
+ if (argc != 0)
214
+ rb_warn("OpenSSL::X509::Store.new does not take any arguments");
204
215
  #if !defined(HAVE_OPAQUE_OPENSSL)
205
216
  /* [Bug #405] [Bug #1678] [Bug #3000]; already fixed? */
206
217
  store->ex_data.sk = NULL;
@@ -221,8 +232,16 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
221
232
  * call-seq:
222
233
  * store.flags = flags
223
234
  *
224
- * Sets _flags_ to the Store. _flags_ consists of zero or more of the constants
225
- * 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).
226
245
  */
227
246
  static VALUE
228
247
  ossl_x509store_set_flags(VALUE self, VALUE flags)
@@ -240,9 +259,9 @@ ossl_x509store_set_flags(VALUE self, VALUE flags)
240
259
  * call-seq:
241
260
  * store.purpose = purpose
242
261
  *
243
- * Sets the store's purpose to _purpose_. If specified, the verifications on
244
- * the store will check every untrusted certificate's extensions are consistent
245
- * 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:
246
265
  *
247
266
  * * X509::PURPOSE_SSL_CLIENT
248
267
  * * X509::PURPOSE_SSL_SERVER
@@ -253,6 +272,11 @@ ossl_x509store_set_flags(VALUE self, VALUE flags)
253
272
  * * X509::PURPOSE_ANY
254
273
  * * X509::PURPOSE_OCSP_HELPER
255
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).
256
280
  */
257
281
  static VALUE
258
282
  ossl_x509store_set_purpose(VALUE self, VALUE purpose)
@@ -269,6 +293,14 @@ ossl_x509store_set_purpose(VALUE self, VALUE purpose)
269
293
  /*
270
294
  * call-seq:
271
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).
272
304
  */
273
305
  static VALUE
274
306
  ossl_x509store_set_trust(VALUE self, VALUE trust)
@@ -286,7 +318,13 @@ ossl_x509store_set_trust(VALUE self, VALUE trust)
286
318
  * call-seq:
287
319
  * store.time = time
288
320
  *
289
- * 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).
290
328
  */
291
329
  static VALUE
292
330
  ossl_x509store_set_time(VALUE self, VALUE time)
@@ -302,23 +340,23 @@ ossl_x509store_set_time(VALUE self, VALUE time)
302
340
  * Adds the certificates in _file_ to the certificate store. _file_ is the path
303
341
  * to the file, and the file contains one or more certificates in PEM format
304
342
  * concatenated together.
343
+ *
344
+ * See also the man page X509_LOOKUP_file(3).
305
345
  */
306
346
  static VALUE
307
347
  ossl_x509store_add_file(VALUE self, VALUE file)
308
348
  {
309
349
  X509_STORE *store;
310
350
  X509_LOOKUP *lookup;
311
- char *path = NULL;
351
+ const char *path;
312
352
 
313
- if(file != Qnil){
314
- path = StringValueCStr(file);
315
- }
316
353
  GetX509Store(self, store);
354
+ path = StringValueCStr(file);
317
355
  lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
318
- if(lookup == NULL) ossl_raise(eX509StoreError, NULL);
319
- if(X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM) != 1){
320
- ossl_raise(eX509StoreError, NULL);
321
- }
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");
322
360
  #if OPENSSL_VERSION_NUMBER < 0x10101000 || defined(LIBRESSL_VERSION_NUMBER)
323
361
  /*
324
362
  * X509_load_cert_crl_file() which is called from X509_LOOKUP_load_file()
@@ -337,23 +375,23 @@ ossl_x509store_add_file(VALUE self, VALUE file)
337
375
  * store.add_path(path) -> self
338
376
  *
339
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).
340
380
  */
341
381
  static VALUE
342
382
  ossl_x509store_add_path(VALUE self, VALUE dir)
343
383
  {
344
384
  X509_STORE *store;
345
385
  X509_LOOKUP *lookup;
346
- char *path = NULL;
386
+ const char *path;
347
387
 
348
- if(dir != Qnil){
349
- path = StringValueCStr(dir);
350
- }
351
388
  GetX509Store(self, store);
389
+ path = StringValueCStr(dir);
352
390
  lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
353
- if(lookup == NULL) ossl_raise(eX509StoreError, NULL);
354
- if(X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1){
355
- ossl_raise(eX509StoreError, NULL);
356
- }
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");
357
395
 
358
396
  return self;
359
397
  }
@@ -368,6 +406,8 @@ ossl_x509store_add_path(VALUE self, VALUE dir)
368
406
  *
369
407
  * * OpenSSL::X509::DEFAULT_CERT_FILE
370
408
  * * OpenSSL::X509::DEFAULT_CERT_DIR
409
+ *
410
+ * See also the man page X509_STORE_set_default_paths(3).
371
411
  */
372
412
  static VALUE
373
413
  ossl_x509store_set_default_paths(VALUE self)
@@ -375,18 +415,19 @@ ossl_x509store_set_default_paths(VALUE self)
375
415
  X509_STORE *store;
376
416
 
377
417
  GetX509Store(self, store);
378
- if (X509_STORE_set_default_paths(store) != 1){
379
- ossl_raise(eX509StoreError, NULL);
380
- }
418
+ if (X509_STORE_set_default_paths(store) != 1)
419
+ ossl_raise(eX509StoreError, "X509_STORE_set_default_paths");
381
420
 
382
421
  return Qnil;
383
422
  }
384
423
 
385
424
  /*
386
425
  * call-seq:
387
- * store.add_cert(cert)
426
+ * store.add_cert(cert) -> self
388
427
  *
389
428
  * Adds the OpenSSL::X509::Certificate _cert_ to the certificate store.
429
+ *
430
+ * See also the man page X509_STORE_add_cert(3).
390
431
  */
391
432
  static VALUE
392
433
  ossl_x509store_add_cert(VALUE self, VALUE arg)
@@ -396,9 +437,8 @@ ossl_x509store_add_cert(VALUE self, VALUE arg)
396
437
 
397
438
  cert = GetX509CertPtr(arg); /* NO NEED TO DUP */
398
439
  GetX509Store(self, store);
399
- if (X509_STORE_add_cert(store, cert) != 1){
400
- ossl_raise(eX509StoreError, NULL);
401
- }
440
+ if (X509_STORE_add_cert(store, cert) != 1)
441
+ ossl_raise(eX509StoreError, "X509_STORE_add_cert");
402
442
 
403
443
  return self;
404
444
  }
@@ -408,6 +448,8 @@ ossl_x509store_add_cert(VALUE self, VALUE arg)
408
448
  * store.add_crl(crl) -> self
409
449
  *
410
450
  * Adds the OpenSSL::X509::CRL _crl_ to the store.
451
+ *
452
+ * See also the man page X509_STORE_add_crl(3).
411
453
  */
412
454
  static VALUE
413
455
  ossl_x509store_add_crl(VALUE self, VALUE arg)
@@ -417,9 +459,8 @@ ossl_x509store_add_crl(VALUE self, VALUE arg)
417
459
 
418
460
  crl = GetX509CRLPtr(arg); /* NO NEED TO DUP */
419
461
  GetX509Store(self, store);
420
- if (X509_STORE_add_crl(store, crl) != 1){
421
- ossl_raise(eX509StoreError, NULL);
422
- }
462
+ if (X509_STORE_add_crl(store, crl) != 1)
463
+ ossl_raise(eX509StoreError, "X509_STORE_add_crl");
423
464
 
424
465
  return self;
425
466
  }
@@ -470,6 +511,9 @@ static void
470
511
  ossl_x509stctx_mark(void *ptr)
471
512
  {
472
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.
473
517
  rb_gc_mark((VALUE)X509_STORE_CTX_get_ex_data(ctx, stctx_ex_verify_cb_idx));
474
518
  }
475
519
 
@@ -489,7 +533,7 @@ static const rb_data_type_t ossl_x509stctx_type = {
489
533
  {
490
534
  ossl_x509stctx_mark, ossl_x509stctx_free,
491
535
  },
492
- 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
536
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
493
537
  };
494
538
 
495
539
  static VALUE
@@ -499,9 +543,8 @@ ossl_x509stctx_alloc(VALUE klass)
499
543
  VALUE obj;
500
544
 
501
545
  obj = NewX509StCtx(klass);
502
- if((ctx = X509_STORE_CTX_new()) == NULL){
503
- ossl_raise(eX509StoreError, NULL);
504
- }
546
+ if ((ctx = X509_STORE_CTX_new()) == NULL)
547
+ ossl_raise(eX509StoreError, "X509_STORE_CTX_new");
505
548
  SetX509StCtx(obj, ctx);
506
549
 
507
550
  return obj;
@@ -567,6 +610,10 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
567
610
  /*
568
611
  * call-seq:
569
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).
570
617
  */
571
618
  static VALUE
572
619
  ossl_x509stctx_verify(VALUE self)
@@ -574,53 +621,50 @@ ossl_x509stctx_verify(VALUE self)
574
621
  X509_STORE_CTX *ctx;
575
622
 
576
623
  GetX509StCtx(self, ctx);
577
- X509_STORE_CTX_set_ex_data(ctx, stctx_ex_verify_cb_idx,
578
- (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);
579
626
 
580
627
  switch (X509_verify_cert(ctx)) {
581
628
  case 1:
582
- return Qtrue;
629
+ return Qtrue;
583
630
  case 0:
584
- ossl_clear_error();
585
- return Qfalse;
631
+ ossl_clear_error();
632
+ return Qfalse;
586
633
  default:
587
- ossl_raise(eX509CertError, NULL);
634
+ ossl_raise(eX509CertError, "X509_verify_cert");
588
635
  }
589
636
  }
590
637
 
591
638
  /*
592
639
  * call-seq:
593
- * 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).
594
645
  */
595
646
  static VALUE
596
647
  ossl_x509stctx_get_chain(VALUE self)
597
648
  {
598
649
  X509_STORE_CTX *ctx;
599
- STACK_OF(X509) *chain;
600
- X509 *x509;
601
- int i, num;
602
- VALUE ary;
650
+ const STACK_OF(X509) *chain;
603
651
 
604
652
  GetX509StCtx(self, ctx);
605
- if((chain = X509_STORE_CTX_get0_chain(ctx)) == NULL){
606
- return Qnil;
607
- }
608
- if((num = sk_X509_num(chain)) < 0){
609
- OSSL_Debug("certs in chain < 0???");
610
- return rb_ary_new();
611
- }
612
- ary = rb_ary_new2(num);
613
- for(i = 0; i < num; i++) {
614
- x509 = sk_X509_value(chain, i);
615
- rb_ary_push(ary, ossl_x509_new(x509));
616
- }
617
-
618
- 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);
619
657
  }
620
658
 
621
659
  /*
622
660
  * call-seq:
623
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).
624
668
  */
625
669
  static VALUE
626
670
  ossl_x509stctx_get_err(VALUE self)
@@ -635,6 +679,11 @@ ossl_x509stctx_get_err(VALUE self)
635
679
  /*
636
680
  * call-seq:
637
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).
638
687
  */
639
688
  static VALUE
640
689
  ossl_x509stctx_set_error(VALUE self, VALUE err)
@@ -651,7 +700,10 @@ ossl_x509stctx_set_error(VALUE self, VALUE err)
651
700
  * call-seq:
652
701
  * stctx.error_string -> String
653
702
  *
654
- * 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).
655
707
  */
656
708
  static VALUE
657
709
  ossl_x509stctx_get_err_string(VALUE self)
@@ -668,6 +720,10 @@ ossl_x509stctx_get_err_string(VALUE self)
668
720
  /*
669
721
  * call-seq:
670
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).
671
727
  */
672
728
  static VALUE
673
729
  ossl_x509stctx_get_err_depth(VALUE self)
@@ -682,6 +738,10 @@ ossl_x509stctx_get_err_depth(VALUE self)
682
738
  /*
683
739
  * call-seq:
684
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).
685
745
  */
686
746
  static VALUE
687
747
  ossl_x509stctx_get_curr_cert(VALUE self)
@@ -696,6 +756,10 @@ ossl_x509stctx_get_curr_cert(VALUE self)
696
756
  /*
697
757
  * call-seq:
698
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).
699
763
  */
700
764
  static VALUE
701
765
  ossl_x509stctx_get_curr_crl(VALUE self)
@@ -715,7 +779,10 @@ ossl_x509stctx_get_curr_crl(VALUE self)
715
779
  * call-seq:
716
780
  * stctx.flags = flags
717
781
  *
718
- * 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).
719
786
  */
720
787
  static VALUE
721
788
  ossl_x509stctx_set_flags(VALUE self, VALUE flags)
@@ -733,7 +800,10 @@ ossl_x509stctx_set_flags(VALUE self, VALUE flags)
733
800
  * call-seq:
734
801
  * stctx.purpose = purpose
735
802
  *
736
- * 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).
737
807
  */
738
808
  static VALUE
739
809
  ossl_x509stctx_set_purpose(VALUE self, VALUE purpose)
@@ -750,6 +820,11 @@ ossl_x509stctx_set_purpose(VALUE self, VALUE purpose)
750
820
  /*
751
821
  * call-seq:
752
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).
753
828
  */
754
829
  static VALUE
755
830
  ossl_x509stctx_set_trust(VALUE self, VALUE trust)
@@ -768,6 +843,8 @@ ossl_x509stctx_set_trust(VALUE self, VALUE trust)
768
843
  * stctx.time = time
769
844
  *
770
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).
771
848
  */
772
849
  static VALUE
773
850
  ossl_x509stctx_set_time(VALUE self, VALUE time)
@@ -843,23 +920,37 @@ Init_ossl_x509store(void)
843
920
  cX509Store = rb_define_class_under(mX509, "Store", rb_cObject);
844
921
  /*
845
922
  * The callback for additional certificate verification. It is invoked for
846
- * each untrusted certificate in the chain.
923
+ * each certificate in the chain and can be used to implement custom
924
+ * certificate verification conditions.
847
925
  *
848
926
  * The callback is invoked with two values, a boolean that indicates if the
849
927
  * pre-verification by OpenSSL has succeeded or not, and the StoreContext in
850
- * 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).
851
936
  */
852
937
  rb_attr(cX509Store, rb_intern("verify_callback"), 1, 0, Qfalse);
853
938
  /*
854
939
  * The error code set by the last call of #verify.
940
+ *
941
+ * See also StoreContext#error.
855
942
  */
856
943
  rb_attr(cX509Store, rb_intern("error"), 1, 0, Qfalse);
857
944
  /*
858
945
  * The description for the error code set by the last call of #verify.
946
+ *
947
+ * See also StoreContext#error_string.
859
948
  */
860
949
  rb_attr(cX509Store, rb_intern("error_string"), 1, 0, Qfalse);
861
950
  /*
862
951
  * The certificate chain constructed by the last call of #verify.
952
+ *
953
+ * See also StoreContext#chain.
863
954
  */
864
955
  rb_attr(cX509Store, rb_intern("chain"), 1, 0, Qfalse);
865
956
  rb_define_alloc_func(cX509Store, ossl_x509store_alloc);
@@ -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.