Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

store and storecontext: shareable when frozen #807

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion ext/openssl/ossl.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#else
#define RUBY_TYPED_FROZEN_SHAREABLE 0
#endif

#include <openssl/opensslv.h>

#include <openssl/err.h>
Expand Down
35 changes: 34 additions & 1 deletion ext/openssl/ossl_x509store.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ static const rb_data_type_t ossl_x509store_type = {
{
ossl_x509store_mark, ossl_x509store_free,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE,
};

/*
Expand Down Expand Up @@ -224,6 +224,10 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self)
rb_iv_set(self, "@error_string", Qnil);
rb_iv_set(self, "@chain", Qnil);

/* added certificate/CRL references */
rb_iv_set(self, "@certificates", rb_ary_new());
rb_iv_set(self, "@crls", rb_ary_new());

return self;
}

Expand All @@ -246,6 +250,7 @@ static VALUE
ossl_x509store_set_flags(VALUE self, VALUE flags)
{
X509_STORE *store;
rb_check_frozen(self);
long f = NUM2LONG(flags);

GetX509Store(self, store);
Expand Down Expand Up @@ -281,6 +286,7 @@ static VALUE
ossl_x509store_set_purpose(VALUE self, VALUE purpose)
{
X509_STORE *store;
rb_check_frozen(self);
int p = NUM2INT(purpose);

GetX509Store(self, store);
Expand All @@ -305,6 +311,7 @@ static VALUE
ossl_x509store_set_trust(VALUE self, VALUE trust)
{
X509_STORE *store;
rb_check_frozen(self);
int t = NUM2INT(trust);

GetX509Store(self, store);
Expand All @@ -331,6 +338,7 @@ ossl_x509store_set_time(VALUE self, VALUE time)
X509_STORE *store;
X509_VERIFY_PARAM *param;

rb_check_frozen(self);
GetX509Store(self, store);
#ifdef HAVE_X509_STORE_GET0_PARAM
param = X509_STORE_get0_param(store);
Expand Down Expand Up @@ -358,6 +366,7 @@ ossl_x509store_add_file(VALUE self, VALUE file)
X509_LOOKUP *lookup;
const char *path;

rb_check_frozen(self);
GetX509Store(self, store);
path = StringValueCStr(file);
lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
Expand Down Expand Up @@ -393,6 +402,7 @@ ossl_x509store_add_path(VALUE self, VALUE dir)
X509_LOOKUP *lookup;
const char *path;

rb_check_frozen(self);
GetX509Store(self, store);
path = StringValueCStr(dir);
lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
Expand Down Expand Up @@ -422,6 +432,7 @@ ossl_x509store_set_default_paths(VALUE self)
{
X509_STORE *store;

rb_check_frozen(self);
GetX509Store(self, store);
if (X509_STORE_set_default_paths(store) != 1)
ossl_raise(eX509StoreError, "X509_STORE_set_default_paths");
Expand All @@ -442,12 +453,20 @@ ossl_x509store_add_cert(VALUE self, VALUE arg)
{
X509_STORE *store;
X509 *cert;
VALUE certificates;

rb_check_frozen(self);

cert = GetX509CertPtr(arg); /* NO NEED TO DUP */
GetX509Store(self, store);
if (X509_STORE_add_cert(store, cert) != 1)
ossl_raise(eX509StoreError, "X509_STORE_add_cert");

certificates = rb_iv_get(self, "@certificates");

if(!RTEST(rb_funcall(certificates, rb_intern("include?"), 1, arg)))
rb_ary_push(certificates, arg);

return self;
}

Expand All @@ -464,12 +483,20 @@ ossl_x509store_add_crl(VALUE self, VALUE arg)
{
X509_STORE *store;
X509_CRL *crl;
VALUE crls;

rb_check_frozen(self);

crl = GetX509CRLPtr(arg); /* NO NEED TO DUP */
GetX509Store(self, store);
if (X509_STORE_add_crl(store, crl) != 1)
ossl_raise(eX509StoreError, "X509_STORE_add_crl");

crls = rb_iv_get(self, "@crls");

if(!RTEST(rb_funcall(crls, rb_intern("include?"), 1, arg)))
rb_ary_push(crls, arg);

return self;
}

Expand Down Expand Up @@ -498,6 +525,7 @@ ossl_x509store_verify(int argc, VALUE *argv, VALUE self)
VALUE cert, chain;
VALUE ctx, proc, result;

rb_check_frozen(self);
rb_scan_args(argc, argv, "11", &cert, &chain);
ctx = rb_funcall(cX509StoreContext, rb_intern("new"), 3, self, cert, chain);
proc = rb_block_given_p() ? rb_block_proc() :
Expand Down Expand Up @@ -695,6 +723,7 @@ ossl_x509stctx_set_error(VALUE self, VALUE err)
{
X509_STORE_CTX *ctx;

rb_check_frozen(self);
GetX509StCtx(self, ctx);
X509_STORE_CTX_set_error(ctx, NUM2INT(err));

Expand Down Expand Up @@ -793,6 +822,7 @@ static VALUE
ossl_x509stctx_set_flags(VALUE self, VALUE flags)
{
X509_STORE_CTX *store;
rb_check_frozen(self);
long f = NUM2LONG(flags);

GetX509StCtx(self, store);
Expand All @@ -814,6 +844,7 @@ static VALUE
ossl_x509stctx_set_purpose(VALUE self, VALUE purpose)
{
X509_STORE_CTX *store;
rb_check_frozen(self);
int p = NUM2INT(purpose);

GetX509StCtx(self, store);
Expand All @@ -835,6 +866,7 @@ static VALUE
ossl_x509stctx_set_trust(VALUE self, VALUE trust)
{
X509_STORE_CTX *store;
rb_check_frozen(self);
int t = NUM2INT(trust);

GetX509StCtx(self, store);
Expand All @@ -857,6 +889,7 @@ ossl_x509stctx_set_time(VALUE self, VALUE time)
X509_STORE_CTX *store;
long t;

rb_check_frozen(self);
t = NUM2LONG(rb_Integer(time));
GetX509StCtx(self, store);
X509_STORE_CTX_set_time(store, 0, t);
Expand Down
8 changes: 5 additions & 3 deletions lib/openssl/ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,11 @@ class SSLContext
)
end

DEFAULT_CERT_STORE = OpenSSL::X509::Store.new # :nodoc:
DEFAULT_CERT_STORE.set_default_paths
DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
DEFAULT_CERT_STORE = OpenSSL::X509::Store.new.tap do |store| # :nodoc:
store.set_default_paths
store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
store.freeze
end

# A callback invoked when DH parameters are required for ephemeral DH key
# exchange.
Expand Down
8 changes: 8 additions & 0 deletions lib/openssl/x509.rb
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,14 @@ def ==(other)
end
end

class Store
def freeze
super
@certificates.each(&:freeze)
@crls.each(&:freeze)
end
end

class StoreContext
def cleanup
warn "(#{caller.first}) OpenSSL::X509::StoreContext#cleanup is deprecated with no replacement" if $VERBOSE
Expand Down
7 changes: 7 additions & 0 deletions test/openssl/test_x509store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ def test_verify_simple
assert_match(/ok/i, store.error_string)
assert_equal(OpenSSL::X509::V_OK, store.error)
assert_equal([ee1_cert, ca2_cert, ca1_cert], store.chain)

# frozen, operation invalid
store = OpenSSL::X509::Store.new
store.freeze
assert_raise(FrozenError) do
store.verify(ee1_cert, [ca2_cert, ca1_cert])
end
end

def test_verify_callback
Expand Down