Ruby  2.5.0dev(2017-10-22revision60238)
ossl_x509store.c
Go to the documentation of this file.
1 /*
2  * 'OpenSSL for Ruby' project
3  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
4  * All rights reserved.
5  */
6 /*
7  * This program is licensed under the same licence as Ruby.
8  * (See the file 'LICENCE'.)
9  */
10 #include "ossl.h"
11 
12 #define NewX509Store(klass) \
13  TypedData_Wrap_Struct((klass), &ossl_x509store_type, 0)
14 #define SetX509Store(obj, st) do { \
15  if (!(st)) { \
16  ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \
17  } \
18  RTYPEDDATA_DATA(obj) = (st); \
19 } while (0)
20 #define GetX509Store(obj, st) do { \
21  TypedData_Get_Struct((obj), X509_STORE, &ossl_x509store_type, (st)); \
22  if (!(st)) { \
23  ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \
24  } \
25 } while (0)
26 
27 #define NewX509StCtx(klass) \
28  TypedData_Wrap_Struct((klass), &ossl_x509stctx_type, 0)
29 #define SetX509StCtx(obj, ctx) do { \
30  if (!(ctx)) { \
31  ossl_raise(rb_eRuntimeError, "STORE_CTX wasn't initialized!"); \
32  } \
33  RTYPEDDATA_DATA(obj) = (ctx); \
34 } while (0)
35 #define GetX509StCtx(obj, ctx) do { \
36  TypedData_Get_Struct((obj), X509_STORE_CTX, &ossl_x509stctx_type, (ctx)); \
37  if (!(ctx)) { \
38  ossl_raise(rb_eRuntimeError, "STORE_CTX is out of scope!"); \
39  } \
40 } while (0)
41 
42 /*
43  * Verify callback stuff
44  */
45 static int stctx_ex_verify_cb_idx, store_ex_verify_cb_idx;
46 static VALUE ossl_x509stctx_new(X509_STORE_CTX *);
47 
52 };
53 
54 static VALUE
55 call_verify_cb_proc(struct ossl_verify_cb_args *args)
56 {
57  return rb_funcall(args->proc, rb_intern("call"), 2,
58  args->preverify_ok, args->store_ctx);
59 }
60 
61 int
62 ossl_verify_cb_call(VALUE proc, int ok, X509_STORE_CTX *ctx)
63 {
64  VALUE rctx, ret;
65  struct ossl_verify_cb_args args;
66  int state;
67 
68  if (NIL_P(proc))
69  return ok;
70 
71  ret = Qfalse;
72  rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new, (VALUE)ctx, &state);
73  if (state) {
75  rb_warn("StoreContext initialization failure");
76  }
77  else {
78  args.proc = proc;
79  args.preverify_ok = ok ? Qtrue : Qfalse;
80  args.store_ctx = rctx;
81  ret = rb_protect((VALUE(*)(VALUE))call_verify_cb_proc, (VALUE)&args, &state);
82  if (state) {
84  rb_warn("exception in verify_callback is ignored");
85  }
86  RTYPEDDATA_DATA(rctx) = NULL;
87  }
88  if (ret == Qtrue) {
89  X509_STORE_CTX_set_error(ctx, X509_V_OK);
90  ok = 1;
91  }
92  else {
93  if (X509_STORE_CTX_get_error(ctx) == X509_V_OK)
94  X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
95  ok = 0;
96  }
97 
98  return ok;
99 }
100 
101 /*
102  * Classes
103  */
107 
108 static void
109 ossl_x509store_free(void *ptr)
110 {
111  X509_STORE_free(ptr);
112 }
113 
114 static const rb_data_type_t ossl_x509store_type = {
115  "OpenSSL/X509/STORE",
116  {
117  0, ossl_x509store_free,
118  },
120 };
121 
122 /*
123  * Public functions
124  */
125 X509_STORE *
127 {
128  X509_STORE *store;
129 
130  GetX509Store(obj, store);
131 
132  return store;
133 }
134 
135 /*
136  * Private functions
137  */
138 static int
139 x509store_verify_cb(int ok, X509_STORE_CTX *ctx)
140 {
141  VALUE proc;
142 
143  proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, stctx_ex_verify_cb_idx);
144  if (!proc)
146  store_ex_verify_cb_idx);
147  if (!proc)
148  return ok;
149 
150  return ossl_verify_cb_call(proc, ok, ctx);
151 }
152 
153 static VALUE
154 ossl_x509store_alloc(VALUE klass)
155 {
156  X509_STORE *store;
157  VALUE obj;
158 
159  obj = NewX509Store(klass);
160  if((store = X509_STORE_new()) == NULL){
162  }
163  SetX509Store(obj, store);
164 
165  return obj;
166 }
167 
168 /*
169  * General callback for OpenSSL verify
170  */
171 static VALUE
172 ossl_x509store_set_vfy_cb(VALUE self, VALUE cb)
173 {
174  X509_STORE *store;
175 
176  GetX509Store(self, store);
177  X509_STORE_set_ex_data(store, store_ex_verify_cb_idx, (void *)cb);
178  rb_iv_set(self, "@verify_callback", cb);
179 
180  return cb;
181 }
182 
183 
184 /*
185  * call-seq:
186  * X509::Store.new => store
187  *
188  * Creates a new X509::Store.
189  */
190 static VALUE
191 ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
192 {
193  X509_STORE *store;
194 
195 /* BUG: This method takes any number of arguments but appears to ignore them. */
196  GetX509Store(self, store);
197 #if !defined(HAVE_OPAQUE_OPENSSL)
198  /* [Bug #405] [Bug #1678] [Bug #3000]; already fixed? */
199  store->ex_data.sk = NULL;
200 #endif
201  X509_STORE_set_verify_cb(store, x509store_verify_cb);
202  ossl_x509store_set_vfy_cb(self, Qnil);
203 
204  /* last verification status */
205  rb_iv_set(self, "@error", Qnil);
206  rb_iv_set(self, "@error_string", Qnil);
207  rb_iv_set(self, "@chain", Qnil);
208  rb_iv_set(self, "@time", Qnil);
209 
210  return self;
211 }
212 
213 /*
214  * call-seq:
215  * store.flags = flags
216  *
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.
219  */
220 static VALUE
221 ossl_x509store_set_flags(VALUE self, VALUE flags)
222 {
223  X509_STORE *store;
224  long f = NUM2LONG(flags);
225 
226  GetX509Store(self, store);
227  X509_STORE_set_flags(store, f);
228 
229  return flags;
230 }
231 
232 /*
233  * call-seq:
234  * store.purpose = purpose
235  *
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:
239  *
240  * * X509::PURPOSE_SSL_CLIENT
241  * * X509::PURPOSE_SSL_SERVER
242  * * X509::PURPOSE_NS_SSL_SERVER
243  * * X509::PURPOSE_SMIME_SIGN
244  * * X509::PURPOSE_SMIME_ENCRYPT
245  * * X509::PURPOSE_CRL_SIGN
246  * * X509::PURPOSE_ANY
247  * * X509::PURPOSE_OCSP_HELPER
248  * * X509::PURPOSE_TIMESTAMP_SIGN
249  */
250 static VALUE
251 ossl_x509store_set_purpose(VALUE self, VALUE purpose)
252 {
253  X509_STORE *store;
254  int p = NUM2INT(purpose);
255 
256  GetX509Store(self, store);
257  X509_STORE_set_purpose(store, p);
258 
259  return purpose;
260 }
261 
262 /*
263  * call-seq:
264  * store.trust = trust
265  */
266 static VALUE
267 ossl_x509store_set_trust(VALUE self, VALUE trust)
268 {
269  X509_STORE *store;
270  int t = NUM2INT(trust);
271 
272  GetX509Store(self, store);
273  X509_STORE_set_trust(store, t);
274 
275  return trust;
276 }
277 
278 /*
279  * call-seq:
280  * store.time = time
281  *
282  * Sets the time to be used in verifications.
283  */
284 static VALUE
285 ossl_x509store_set_time(VALUE self, VALUE time)
286 {
287  rb_iv_set(self, "@time", time);
288  return time;
289 }
290 
291 /*
292  * call-seq:
293  * store.add_file(file) -> self
294  *
295  * Adds the certificates in _file_ to the certificate store. _file_ is the path
296  * to the file, and the file contains one or more certificates in PEM format
297  * concatenated together.
298  */
299 static VALUE
300 ossl_x509store_add_file(VALUE self, VALUE file)
301 {
302  X509_STORE *store;
303  X509_LOOKUP *lookup;
304  char *path = NULL;
305 
306  if(file != Qnil){
307  rb_check_safe_obj(file);
308  path = StringValueCStr(file);
309  }
310  GetX509Store(self, store);
311  lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
312  if(lookup == NULL) ossl_raise(eX509StoreError, NULL);
313  if(X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM) != 1){
315  }
316 #if OPENSSL_VERSION_NUMBER < 0x10101000 || defined(LIBRESSL_VERSION_NUMBER)
317  /*
318  * X509_load_cert_crl_file() which is called from X509_LOOKUP_load_file()
319  * did not check the return value of X509_STORE_add_{cert,crl}(), leaking
320  * "cert already in hash table" errors on the error queue, if duplicate
321  * certificates are found. This will be fixed by OpenSSL 1.1.1.
322  */
324 #endif
325 
326  return self;
327 }
328 
329 /*
330  * call-seq:
331  * store.add_path(path) -> self
332  *
333  * Adds _path_ as the hash dir to be looked up by the store.
334  */
335 static VALUE
336 ossl_x509store_add_path(VALUE self, VALUE dir)
337 {
338  X509_STORE *store;
339  X509_LOOKUP *lookup;
340  char *path = NULL;
341 
342  if(dir != Qnil){
343  rb_check_safe_obj(dir);
344  path = StringValueCStr(dir);
345  }
346  GetX509Store(self, store);
347  lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
348  if(lookup == NULL) ossl_raise(eX509StoreError, NULL);
349  if(X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1){
351  }
352 
353  return self;
354 }
355 
356 /*
357  * call-seq:
358  * store.set_default_paths
359  *
360  * Configures _store_ to look up CA certificates from the system default
361  * certificate store as needed basis. The location of the store can usually be
362  * determined by:
363  *
364  * * OpenSSL::X509::DEFAULT_CERT_FILE
365  * * OpenSSL::X509::DEFAULT_CERT_DIR
366  */
367 static VALUE
368 ossl_x509store_set_default_paths(VALUE self)
369 {
370  X509_STORE *store;
371 
372  GetX509Store(self, store);
373  if (X509_STORE_set_default_paths(store) != 1){
375  }
376 
377  return Qnil;
378 }
379 
380 /*
381  * call-seq:
382  * store.add_cert(cert)
383  *
384  * Adds the OpenSSL::X509::Certificate _cert_ to the certificate store.
385  */
386 static VALUE
387 ossl_x509store_add_cert(VALUE self, VALUE arg)
388 {
389  X509_STORE *store;
390  X509 *cert;
391 
392  cert = GetX509CertPtr(arg); /* NO NEED TO DUP */
393  GetX509Store(self, store);
394  if (X509_STORE_add_cert(store, cert) != 1){
396  }
397 
398  return self;
399 }
400 
401 /*
402  * call-seq:
403  * store.add_crl(crl) -> self
404  *
405  * Adds the OpenSSL::X509::CRL _crl_ to the store.
406  */
407 static VALUE
408 ossl_x509store_add_crl(VALUE self, VALUE arg)
409 {
410  X509_STORE *store;
411  X509_CRL *crl;
412 
413  crl = GetX509CRLPtr(arg); /* NO NEED TO DUP */
414  GetX509Store(self, store);
415  if (X509_STORE_add_crl(store, crl) != 1){
417  }
418 
419  return self;
420 }
421 
422 static VALUE ossl_x509stctx_get_err(VALUE);
423 static VALUE ossl_x509stctx_get_err_string(VALUE);
424 static VALUE ossl_x509stctx_get_chain(VALUE);
425 
426 /*
427  * call-seq:
428  * store.verify(cert, chain = nil) -> true | false
429  *
430  * Performs a certificate verification on the OpenSSL::X509::Certificate _cert_.
431  *
432  * _chain_ can be an array of OpenSSL::X509::Certificate that is used to
433  * construct the certificate chain.
434  *
435  * If a block is given, it overrides the callback set by #verify_callback=.
436  *
437  * After finishing the verification, the error information can be retrieved by
438  * #error, #error_string, and the resulting complete certificate chain can be
439  * retrieved by #chain.
440  */
441 static VALUE
442 ossl_x509store_verify(int argc, VALUE *argv, VALUE self)
443 {
444  VALUE cert, chain;
445  VALUE ctx, proc, result;
446 
447  rb_scan_args(argc, argv, "11", &cert, &chain);
448  ctx = rb_funcall(cX509StoreContext, rb_intern("new"), 3, self, cert, chain);
449  proc = rb_block_given_p() ? rb_block_proc() :
450  rb_iv_get(self, "@verify_callback");
451  rb_iv_set(ctx, "@verify_callback", proc);
452  result = rb_funcall(ctx, rb_intern("verify"), 0);
453 
454  rb_iv_set(self, "@error", ossl_x509stctx_get_err(ctx));
455  rb_iv_set(self, "@error_string", ossl_x509stctx_get_err_string(ctx));
456  rb_iv_set(self, "@chain", ossl_x509stctx_get_chain(ctx));
457 
458  return result;
459 }
460 
461 /*
462  * Public Functions
463  */
464 static void ossl_x509stctx_free(void*);
465 
466 
467 static const rb_data_type_t ossl_x509stctx_type = {
468  "OpenSSL/X509/STORE_CTX",
469  {
470  0, ossl_x509stctx_free,
471  },
473 };
474 
475 /*
476  * Private functions
477  */
478 static void
479 ossl_x509stctx_free(void *ptr)
480 {
481  X509_STORE_CTX *ctx = ptr;
483  sk_X509_pop_free(X509_STORE_CTX_get0_untrusted(ctx), X509_free);
484  if (X509_STORE_CTX_get0_cert(ctx))
485  X509_free(X509_STORE_CTX_get0_cert(ctx));
486  X509_STORE_CTX_free(ctx);
487 }
488 
489 static VALUE
490 ossl_x509stctx_alloc(VALUE klass)
491 {
492  X509_STORE_CTX *ctx;
493  VALUE obj;
494 
495  obj = NewX509StCtx(klass);
496  if((ctx = X509_STORE_CTX_new()) == NULL){
498  }
499  SetX509StCtx(obj, ctx);
500 
501  return obj;
502 }
503 
504 static VALUE
505 ossl_x509stctx_new(X509_STORE_CTX *ctx)
506 {
507  VALUE obj;
508 
510  SetX509StCtx(obj, ctx);
511 
512  return obj;
513 }
514 
515 static VALUE ossl_x509stctx_set_flags(VALUE, VALUE);
516 static VALUE ossl_x509stctx_set_purpose(VALUE, VALUE);
517 static VALUE ossl_x509stctx_set_trust(VALUE, VALUE);
518 static VALUE ossl_x509stctx_set_time(VALUE, VALUE);
519 
520 /*
521  * call-seq:
522  * StoreContext.new(store, cert = nil, chain = nil)
523  */
524 static VALUE
525 ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self)
526 {
527  VALUE store, cert, chain, t;
528  X509_STORE_CTX *ctx;
529  X509_STORE *x509st;
530  X509 *x509 = NULL;
531  STACK_OF(X509) *x509s = NULL;
532 
533  rb_scan_args(argc, argv, "12", &store, &cert, &chain);
534  GetX509StCtx(self, ctx);
535  GetX509Store(store, x509st);
536  if(!NIL_P(cert)) x509 = DupX509CertPtr(cert); /* NEED TO DUP */
537  if(!NIL_P(chain)) x509s = ossl_x509_ary2sk(chain);
538  if(X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){
539  sk_X509_pop_free(x509s, X509_free);
541  }
542  if (!NIL_P(t = rb_iv_get(store, "@time")))
543  ossl_x509stctx_set_time(self, t);
544  rb_iv_set(self, "@verify_callback", rb_iv_get(store, "@verify_callback"));
545  rb_iv_set(self, "@cert", cert);
546 
547  return self;
548 }
549 
550 /*
551  * call-seq:
552  * stctx.verify -> true | false
553  */
554 static VALUE
555 ossl_x509stctx_verify(VALUE self)
556 {
557  X509_STORE_CTX *ctx;
558 
559  GetX509StCtx(self, ctx);
560  X509_STORE_CTX_set_ex_data(ctx, stctx_ex_verify_cb_idx,
561  (void *)rb_iv_get(self, "@verify_callback"));
562 
563  switch (X509_verify_cert(ctx)) {
564  case 1:
565  return Qtrue;
566  case 0:
568  return Qfalse;
569  default:
571  }
572 }
573 
574 /*
575  * call-seq:
576  * stctx.chain -> Array of X509::Certificate
577  */
578 static VALUE
579 ossl_x509stctx_get_chain(VALUE self)
580 {
581  X509_STORE_CTX *ctx;
582  STACK_OF(X509) *chain;
583  X509 *x509;
584  int i, num;
585  VALUE ary;
586 
587  GetX509StCtx(self, ctx);
588  if((chain = X509_STORE_CTX_get0_chain(ctx)) == NULL){
589  return Qnil;
590  }
591  if((num = sk_X509_num(chain)) < 0){
592  OSSL_Debug("certs in chain < 0???");
593  return rb_ary_new();
594  }
595  ary = rb_ary_new2(num);
596  for(i = 0; i < num; i++) {
597  x509 = sk_X509_value(chain, i);
598  rb_ary_push(ary, ossl_x509_new(x509));
599  }
600 
601  return ary;
602 }
603 
604 /*
605  * call-seq:
606  * stctx.error -> Integer
607  */
608 static VALUE
609 ossl_x509stctx_get_err(VALUE self)
610 {
611  X509_STORE_CTX *ctx;
612 
613  GetX509StCtx(self, ctx);
614 
615  return INT2NUM(X509_STORE_CTX_get_error(ctx));
616 }
617 
618 /*
619  * call-seq:
620  * stctx.error = error_code
621  */
622 static VALUE
623 ossl_x509stctx_set_error(VALUE self, VALUE err)
624 {
625  X509_STORE_CTX *ctx;
626 
627  GetX509StCtx(self, ctx);
628  X509_STORE_CTX_set_error(ctx, NUM2INT(err));
629 
630  return err;
631 }
632 
633 /*
634  * call-seq:
635  * stctx.error_string -> String
636  *
637  * Returns the error string corresponding to the error code retrieved by #error.
638  */
639 static VALUE
640 ossl_x509stctx_get_err_string(VALUE self)
641 {
642  X509_STORE_CTX *ctx;
643  long err;
644 
645  GetX509StCtx(self, ctx);
646  err = X509_STORE_CTX_get_error(ctx);
647 
648  return rb_str_new2(X509_verify_cert_error_string(err));
649 }
650 
651 /*
652  * call-seq:
653  * stctx.error_depth -> Integer
654  */
655 static VALUE
656 ossl_x509stctx_get_err_depth(VALUE self)
657 {
658  X509_STORE_CTX *ctx;
659 
660  GetX509StCtx(self, ctx);
661 
662  return INT2NUM(X509_STORE_CTX_get_error_depth(ctx));
663 }
664 
665 /*
666  * call-seq:
667  * stctx.current_cert -> X509::Certificate
668  */
669 static VALUE
670 ossl_x509stctx_get_curr_cert(VALUE self)
671 {
672  X509_STORE_CTX *ctx;
673 
674  GetX509StCtx(self, ctx);
675 
676  return ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx));
677 }
678 
679 /*
680  * call-seq:
681  * stctx.current_crl -> X509::CRL
682  */
683 static VALUE
684 ossl_x509stctx_get_curr_crl(VALUE self)
685 {
686  X509_STORE_CTX *ctx;
687  X509_CRL *crl;
688 
689  GetX509StCtx(self, ctx);
690  crl = X509_STORE_CTX_get0_current_crl(ctx);
691  if (!crl)
692  return Qnil;
693 
694  return ossl_x509crl_new(crl);
695 }
696 
697 /*
698  * call-seq:
699  * stctx.flags = flags
700  *
701  * Sets the verification flags to the context. See Store#flags=.
702  */
703 static VALUE
704 ossl_x509stctx_set_flags(VALUE self, VALUE flags)
705 {
706  X509_STORE_CTX *store;
707  long f = NUM2LONG(flags);
708 
709  GetX509StCtx(self, store);
710  X509_STORE_CTX_set_flags(store, f);
711 
712  return flags;
713 }
714 
715 /*
716  * call-seq:
717  * stctx.purpose = purpose
718  *
719  * Sets the purpose of the context. See Store#purpose=.
720  */
721 static VALUE
722 ossl_x509stctx_set_purpose(VALUE self, VALUE purpose)
723 {
724  X509_STORE_CTX *store;
725  int p = NUM2INT(purpose);
726 
727  GetX509StCtx(self, store);
728  X509_STORE_CTX_set_purpose(store, p);
729 
730  return purpose;
731 }
732 
733 /*
734  * call-seq:
735  * stctx.trust = trust
736  */
737 static VALUE
738 ossl_x509stctx_set_trust(VALUE self, VALUE trust)
739 {
740  X509_STORE_CTX *store;
741  int t = NUM2INT(trust);
742 
743  GetX509StCtx(self, store);
744  X509_STORE_CTX_set_trust(store, t);
745 
746  return trust;
747 }
748 
749 /*
750  * call-seq:
751  * stctx.time = time
752  *
753  * Sets the time used in the verification. If not set, the current time is used.
754  */
755 static VALUE
756 ossl_x509stctx_set_time(VALUE self, VALUE time)
757 {
758  X509_STORE_CTX *store;
759  long t;
760 
761  t = NUM2LONG(rb_Integer(time));
762  GetX509StCtx(self, store);
763  X509_STORE_CTX_set_time(store, 0, t);
764 
765  return time;
766 }
767 
768 /*
769  * INIT
770  */
771 void
773 {
774 #if 0
775  mOSSL = rb_define_module("OpenSSL");
778 #endif
779 
780  /* Register ext_data slot for verify callback Proc */
781  stctx_ex_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, (void *)"stctx_ex_verify_cb_idx", 0, 0, 0);
782  if (stctx_ex_verify_cb_idx < 0)
783  ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index");
784  store_ex_verify_cb_idx = X509_STORE_get_ex_new_index(0, (void *)"store_ex_verify_cb_idx", 0, 0, 0);
785  if (store_ex_verify_cb_idx < 0)
786  ossl_raise(eOSSLError, "X509_STORE_get_ex_new_index");
787 
789 
790  /* Document-class: OpenSSL::X509::Store
791  *
792  * The X509 certificate store holds trusted CA certificates used to verify
793  * peer certificates.
794  *
795  * The easiest way to create a useful certificate store is:
796  *
797  * cert_store = OpenSSL::X509::Store.new
798  * cert_store.set_default_paths
799  *
800  * This will use your system's built-in certificates.
801  *
802  * If your system does not have a default set of certificates you can obtain
803  * a set extracted from Mozilla CA certificate store by cURL maintainers
804  * here: https://curl.haxx.se/docs/caextract.html (You may wish to use the
805  * firefox-db2pem.sh script to extract the certificates from a local install
806  * to avoid man-in-the-middle attacks.)
807  *
808  * After downloading or generating a cacert.pem from the above link you
809  * can create a certificate store from the pem file like this:
810  *
811  * cert_store = OpenSSL::X509::Store.new
812  * cert_store.add_file 'cacert.pem'
813  *
814  * The certificate store can be used with an SSLSocket like this:
815  *
816  * ssl_context = OpenSSL::SSL::SSLContext.new
817  * ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
818  * ssl_context.cert_store = cert_store
819  *
820  * tcp_socket = TCPSocket.open 'example.com', 443
821  *
822  * ssl_socket = OpenSSL::SSL::SSLSocket.new tcp_socket, ssl_context
823  */
824 
826  /*
827  * The callback for additional certificate verification. It is invoked for
828  * each untrusted certificate in the chain.
829  *
830  * The callback is invoked with two values, a boolean that indicates if the
831  * pre-verification by OpenSSL has succeeded or not, and the StoreContext in
832  * use. The callback must return either true or false.
833  */
834  rb_attr(cX509Store, rb_intern("verify_callback"), 1, 0, Qfalse);
835  /*
836  * The error code set by the last call of #verify.
837  */
838  rb_attr(cX509Store, rb_intern("error"), 1, 0, Qfalse);
839  /*
840  * The description for the error code set by the last call of #verify.
841  */
842  rb_attr(cX509Store, rb_intern("error_string"), 1, 0, Qfalse);
843  /*
844  * The certificate chain constructed by the last call of #verify.
845  */
846  rb_attr(cX509Store, rb_intern("chain"), 1, 0, Qfalse);
847  rb_define_alloc_func(cX509Store, ossl_x509store_alloc);
848  rb_define_method(cX509Store, "initialize", ossl_x509store_initialize, -1);
849  rb_undef_method(cX509Store, "initialize_copy");
850  rb_define_method(cX509Store, "verify_callback=", ossl_x509store_set_vfy_cb, 1);
851  rb_define_method(cX509Store, "flags=", ossl_x509store_set_flags, 1);
852  rb_define_method(cX509Store, "purpose=", ossl_x509store_set_purpose, 1);
853  rb_define_method(cX509Store, "trust=", ossl_x509store_set_trust, 1);
854  rb_define_method(cX509Store, "time=", ossl_x509store_set_time, 1);
855  rb_define_method(cX509Store, "add_path", ossl_x509store_add_path, 1);
856  rb_define_method(cX509Store, "add_file", ossl_x509store_add_file, 1);
857  rb_define_method(cX509Store, "set_default_paths", ossl_x509store_set_default_paths, 0);
858  rb_define_method(cX509Store, "add_cert", ossl_x509store_add_cert, 1);
859  rb_define_method(cX509Store, "add_crl", ossl_x509store_add_crl, 1);
860  rb_define_method(cX509Store, "verify", ossl_x509store_verify, -1);
861 
862  /*
863  * Document-class: OpenSSL::X509::StoreContext
864  *
865  * A StoreContext is used while validating a single certificate and holds
866  * the status involved.
867  */
869  rb_define_alloc_func(cX509StoreContext, ossl_x509stctx_alloc);
870  rb_define_method(cX509StoreContext, "initialize", ossl_x509stctx_initialize, -1);
871  rb_undef_method(cX509StoreContext, "initialize_copy");
872  rb_define_method(cX509StoreContext, "verify", ossl_x509stctx_verify, 0);
873  rb_define_method(cX509StoreContext, "chain", ossl_x509stctx_get_chain,0);
874  rb_define_method(cX509StoreContext, "error", ossl_x509stctx_get_err, 0);
875  rb_define_method(cX509StoreContext, "error=", ossl_x509stctx_set_error, 1);
876  rb_define_method(cX509StoreContext, "error_string", ossl_x509stctx_get_err_string,0);
877  rb_define_method(cX509StoreContext, "error_depth", ossl_x509stctx_get_err_depth, 0);
878  rb_define_method(cX509StoreContext, "current_cert", ossl_x509stctx_get_curr_cert, 0);
879  rb_define_method(cX509StoreContext, "current_crl", ossl_x509stctx_get_curr_crl, 0);
880  rb_define_method(cX509StoreContext, "flags=", ossl_x509stctx_set_flags, 1);
881  rb_define_method(cX509StoreContext, "purpose=", ossl_x509stctx_set_purpose, 1);
882  rb_define_method(cX509StoreContext, "trust=", ossl_x509stctx_set_trust, 1);
883  rb_define_method(cX509StoreContext, "time=", ossl_x509stctx_set_time, 1);
884 }
VALUE ossl_x509crl_new(X509_CRL *)
Definition: ossl_x509crl.c:61
VALUE mOSSL
Definition: ossl.c:231
#define X509_STORE_CTX_get0_untrusted(x)
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
Definition: eval.c:992
void rb_warn(const char *fmt,...)
Definition: error.c:246
#define X509_STORE_get_ex_data(x, idx)
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1138
#define INT2NUM(x)
Definition: ruby.h:1538
#define NUM2INT(x)
Definition: ruby.h:684
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:835
#define Qtrue
Definition: ruby.h:437
VALUE cX509Store
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:924
#define GetX509Store(obj, st)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:774
VALUE rb_iv_set(VALUE, const char *, VALUE)
Definition: variable.c:3095
VALUE rb_iv_get(VALUE, const char *)
Definition: variable.c:3087
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:693
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_Integer(VALUE)
Equivalent to Kernel#Integer in Ruby.
Definition: object.c:3148
VALUE cX509StoreContext
void rb_undef_method(VALUE klass, const char *name)
Definition: class.c:1533
#define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef)
#define X509_STORE_CTX_get0_chain(ctx)
#define rb_ary_new2
Definition: intern.h:90
X509 * GetX509CertPtr(VALUE)
Definition: ossl_x509cert.c:71
void ossl_clear_error(void)
Definition: ossl.c:304
#define GetX509StCtx(obj, ctx)
VALUE eX509CertError
Definition: ossl_x509cert.c:31
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1893
STACK_OF(X509) *ossl_x509_ary2sk(VALUE)
void rb_attr(VALUE, ID, int, int, int)
Definition: vm_method.c:1137
void rb_set_errinfo(VALUE err)
Sets the current exception ($!) to the given value.
Definition: eval.c:1792
VALUE rb_ary_new(void)
Definition: array.c:499
#define SetX509Store(obj, st)
#define NIL_P(v)
Definition: ruby.h:451
int ossl_verify_cb_call(VALUE proc, int ok, X509_STORE_CTX *ctx)
VALUE eOSSLError
Definition: ossl.c:236
int argc
Definition: ruby.c:187
#define Qfalse
Definition: ruby.h:436
VALUE ossl_x509_new(X509 *)
Definition: ossl_x509cert.c:51
#define rb_str_new2
Definition: intern.h:835
int err
Definition: win32.c:135
#define NewX509StCtx(klass)
#define X509_STORE_set_ex_data(x, idx, data)
X509_STORE * GetX509StorePtr(VALUE obj)
VALUE eX509StoreError
#define X509_STORE_CTX_get0_store(x)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1908
#define NewX509Store(klass)
#define Qnil
Definition: ruby.h:438
void Init_ossl_x509store(void)
VALUE rb_eStandardError
Definition: error.c:799
unsigned long VALUE
Definition: ruby.h:85
VALUE mX509
Definition: ossl_x509.c:12
#define OSSL_Debug
Definition: ossl.h:144
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:790
#define StringValueCStr(v)
Definition: ruby.h:571
#define SetX509StCtx(obj, ctx)
#define f
VALUE rb_block_proc(void)
Definition: proc.c:780
void rb_check_safe_obj(VALUE)
Definition: safe.c:117
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:293
X509 * DupX509CertPtr(VALUE)
Definition: ossl_x509cert.c:81
#define RTYPEDDATA_DATA(v)
Definition: ruby.h:1110
VALUE rb_define_module(const char *name)
Definition: class.c:768
#define X509_STORE_CTX_get0_cert(x)
X509_CRL * GetX509CRLPtr(VALUE)
Definition: ossl_x509crl.c:51
#define rb_intern(str)
#define NULL
Definition: _sdbm.c:102
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
#define NUM2LONG(x)
Definition: ruby.h:648
char ** argv
Definition: ruby.c:188