diff options
Diffstat (limited to 'ext/openssl/ossl_x509store.c')
-rw-r--r-- | ext/openssl/ossl_x509store.c | 85 |
1 files changed, 56 insertions, 29 deletions
diff --git a/ext/openssl/ossl_x509store.c b/ext/openssl/ossl_x509store.c index 5e0ab8d850..670519febc 100644 --- a/ext/openssl/ossl_x509store.c +++ b/ext/openssl/ossl_x509store.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -52,8 +52,15 @@ struct ossl_verify_cb_args { }; static VALUE -call_verify_cb_proc(struct ossl_verify_cb_args *args) +ossl_x509stctx_new_i(VALUE arg) { + return ossl_x509stctx_new((X509_STORE_CTX *)arg); +} + +static VALUE +call_verify_cb_proc(VALUE arg) +{ + struct ossl_verify_cb_args *args = (struct ossl_verify_cb_args *)arg; return rb_funcall(args->proc, rb_intern("call"), 2, args->preverify_ok, args->store_ctx); } @@ -69,7 +76,7 @@ ossl_verify_cb_call(VALUE proc, int ok, X509_STORE_CTX *ctx) return ok; ret = Qfalse; - rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new, (VALUE)ctx, &state); + rctx = rb_protect(ossl_x509stctx_new_i, (VALUE)ctx, &state); if (state) { rb_set_errinfo(Qnil); rb_warn("StoreContext initialization failure"); @@ -78,7 +85,7 @@ ossl_verify_cb_call(VALUE proc, int ok, X509_STORE_CTX *ctx) args.proc = proc; args.preverify_ok = ok ? Qtrue : Qfalse; args.store_ctx = rctx; - ret = rb_protect((VALUE(*)(VALUE))call_verify_cb_proc, (VALUE)&args, &state); + ret = rb_protect(call_verify_cb_proc, (VALUE)&args, &state); if (state) { rb_set_errinfo(Qnil); rb_warn("exception in verify_callback is ignored"); @@ -106,6 +113,16 @@ VALUE cX509StoreContext; VALUE eX509StoreError; static void +ossl_x509store_mark(void *ptr) +{ + X509_STORE *store = ptr; + // Note: this reference is stored as @verify_callback so we don't need to mark it. + // However we do need to ensure GC compaction won't move it, hence why + // we call rb_gc_mark here. + rb_gc_mark((VALUE)X509_STORE_get_ex_data(store, store_ex_verify_cb_idx)); +} + +static void ossl_x509store_free(void *ptr) { X509_STORE_free(ptr); @@ -114,9 +131,9 @@ ossl_x509store_free(void *ptr) static const rb_data_type_t ossl_x509store_type = { "OpenSSL/X509/STORE", { - 0, ossl_x509store_free, + ossl_x509store_mark, ossl_x509store_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -173,8 +190,9 @@ ossl_x509store_set_vfy_cb(VALUE self, VALUE cb) X509_STORE *store; GetX509Store(self, store); - X509_STORE_set_ex_data(store, store_ex_verify_cb_idx, (void *)cb); rb_iv_set(self, "@verify_callback", cb); + // We don't need to trigger a write barrier because `rb_iv_set` did it. + X509_STORE_set_ex_data(store, store_ex_verify_cb_idx, (void *)cb); return cb; } @@ -205,7 +223,6 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self) rb_iv_set(self, "@error", Qnil); rb_iv_set(self, "@error_string", Qnil); rb_iv_set(self, "@chain", Qnil); - rb_iv_set(self, "@time", Qnil); return self; } @@ -311,7 +328,16 @@ ossl_x509store_set_trust(VALUE self, VALUE trust) static VALUE ossl_x509store_set_time(VALUE self, VALUE time) { - rb_iv_set(self, "@time", time); + X509_STORE *store; + X509_VERIFY_PARAM *param; + + GetX509Store(self, store); +#ifdef HAVE_X509_STORE_GET0_PARAM + param = X509_STORE_get0_param(store); +#else + param = store->param; +#endif + X509_VERIFY_PARAM_set_time(param, NUM2LONG(rb_Integer(time))); return time; } @@ -487,23 +513,19 @@ ossl_x509store_verify(int argc, VALUE *argv, VALUE self) } /* - * Public Functions - */ -static void ossl_x509stctx_free(void*); - - -static const rb_data_type_t ossl_x509stctx_type = { - "OpenSSL/X509/STORE_CTX", - { - 0, ossl_x509stctx_free, - }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, -}; - -/* * Private functions */ static void +ossl_x509stctx_mark(void *ptr) +{ + X509_STORE_CTX *ctx = ptr; + // Note: this reference is stored as @verify_callback so we don't need to mark it. + // However we do need to ensure GC compaction won't move it, hence why + // we call rb_gc_mark here. + rb_gc_mark((VALUE)X509_STORE_CTX_get_ex_data(ctx, stctx_ex_verify_cb_idx)); +} + +static void ossl_x509stctx_free(void *ptr) { X509_STORE_CTX *ctx = ptr; @@ -514,6 +536,14 @@ ossl_x509stctx_free(void *ptr) X509_STORE_CTX_free(ctx); } +static const rb_data_type_t ossl_x509stctx_type = { + "OpenSSL/X509/STORE_CTX", + { + ossl_x509stctx_mark, ossl_x509stctx_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + static VALUE ossl_x509stctx_alloc(VALUE klass) { @@ -542,7 +572,6 @@ ossl_x509stctx_new(X509_STORE_CTX *ctx) static VALUE ossl_x509stctx_set_flags(VALUE, VALUE); static VALUE ossl_x509stctx_set_purpose(VALUE, VALUE); static VALUE ossl_x509stctx_set_trust(VALUE, VALUE); -static VALUE ossl_x509stctx_set_time(VALUE, VALUE); /* * call-seq: @@ -553,7 +582,7 @@ static VALUE ossl_x509stctx_set_time(VALUE, VALUE); static VALUE ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self) { - VALUE store, cert, chain, t; + VALUE store, cert, chain; X509_STORE_CTX *ctx; X509_STORE *x509st; X509 *x509 = NULL; @@ -577,8 +606,6 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self) sk_X509_pop_free(x509s, X509_free); ossl_raise(eX509StoreError, "X509_STORE_CTX_init"); } - if (!NIL_P(t = rb_iv_get(store, "@time"))) - ossl_x509stctx_set_time(self, t); rb_iv_set(self, "@verify_callback", rb_iv_get(store, "@verify_callback")); rb_iv_set(self, "@cert", cert); @@ -599,8 +626,8 @@ ossl_x509stctx_verify(VALUE self) X509_STORE_CTX *ctx; GetX509StCtx(self, ctx); - X509_STORE_CTX_set_ex_data(ctx, stctx_ex_verify_cb_idx, - (void *)rb_iv_get(self, "@verify_callback")); + VALUE cb = rb_iv_get(self, "@verify_callback"); + X509_STORE_CTX_set_ex_data(ctx, stctx_ex_verify_cb_idx, (void *)cb); switch (X509_verify_cert(ctx)) { case 1: |