summaryrefslogtreecommitdiff
path: root/ext/openssl/ossl_x509store.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/openssl/ossl_x509store.c')
-rw-r--r--ext/openssl/ossl_x509store.c66
1 files changed, 44 insertions, 22 deletions
diff --git a/ext/openssl/ossl_x509store.c b/ext/openssl/ossl_x509store.c
index 5e0ab8d850..f27381ca90 100644
--- a/ext/openssl/ossl_x509store.c
+++ b/ext/openssl/ossl_x509store.c
@@ -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;
}
@@ -487,23 +505,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 +528,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)
{
@@ -599,8 +621,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: