From f62cc13cfa02236460ddd740e8b07f276cc74628 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Sat, 6 Dec 2025 23:13:17 +0900 Subject: [PATCH 1/9] provider: fix potential memory leak in .load Allocate the wrapper object before attempting to load the provider. Also, expand macros NewProvider() and SetProvider(), which are only used once and are unlikely to be reused in the future. --- ext/openssl/ossl_provider.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/ext/openssl/ossl_provider.c b/ext/openssl/ossl_provider.c index ea5abb8e4..5cc4bc90f 100644 --- a/ext/openssl/ossl_provider.c +++ b/ext/openssl/ossl_provider.c @@ -5,14 +5,6 @@ #include "ossl.h" #ifdef OSSL_USE_PROVIDER -#define NewProvider(klass) \ - TypedData_Wrap_Struct((klass), &ossl_provider_type, 0) -#define SetProvider(obj, provider) do { \ - if (!(provider)) { \ - ossl_raise(rb_eRuntimeError, "Provider wasn't initialized."); \ - } \ - RTYPEDDATA_DATA(obj) = (provider); \ -} while(0) #define GetProvider(obj, provider) do { \ TypedData_Get_Struct((obj), OSSL_PROVIDER, &ossl_provider_type, (provider)); \ if (!(provider)) { \ @@ -52,17 +44,16 @@ static VALUE eProviderError; static VALUE ossl_provider_s_load(VALUE klass, VALUE name) { - OSSL_PROVIDER *provider = NULL; - VALUE obj; - + OSSL_PROVIDER *provider; + VALUE obj = TypedData_Wrap_Struct(klass, &ossl_provider_type, NULL); const char *provider_name_ptr = StringValueCStr(name); provider = OSSL_PROVIDER_load(NULL, provider_name_ptr); if (provider == NULL) { - ossl_raise(eProviderError, "Failed to load %s provider", provider_name_ptr); + ossl_raise(eProviderError, "Failed to load %"PRIsVALUE" provider", + name); } - obj = NewProvider(klass); - SetProvider(obj, provider); + RTYPEDDATA_DATA(obj) = provider; return obj; } From 02872d3c8f00c680884f869f5ae9733ff87353c1 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Thu, 25 Dec 2025 14:32:18 +0900 Subject: [PATCH 2/9] ossl.c: add helper function ossl_want_uninitialized() --- ext/openssl/ossl.c | 10 ++++++++++ ext/openssl/ossl.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index c869bc3ae..6438d96fd 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -231,6 +231,16 @@ VALUE mOSSL; */ VALUE eOSSLError; +void +ossl_want_uninitialized(VALUE self, const rb_data_type_t *type) +{ + if (rb_check_typeddata(self, type)) { + rb_raise(rb_eTypeError, "%"PRIsVALUE" already initialized", + rb_obj_class(self)); + } + rb_check_frozen(self); +} + /* * Convert to DER string */ diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h index 0a9eab4f8..452be5a2a 100644 --- a/ext/openssl/ossl.h +++ b/ext/openssl/ossl.h @@ -92,6 +92,8 @@ extern VALUE eOSSLError; }\ } while (0) +void ossl_want_uninitialized(VALUE self, const rb_data_type_t *type); + /* * Type conversions */ From 24f72a8350ed6084d1fe0a03315bec8944d1b160 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Fri, 29 May 2026 18:10:40 +0900 Subject: [PATCH 3/9] pkey, ssl, cipher, hpke: use ossl_want_uninitialized() Simplify the code and raise exceptions with a consistent error message. This unifies the exception type raised when #initialize is called twice to TypeError. This should not affect valid usage of these classes. --- ext/openssl/ossl_cipher.c | 20 +++++--------------- ext/openssl/ossl_hpke.c | 9 +++------ ext/openssl/ossl_pkey.c | 4 +--- ext/openssl/ossl_pkey_dh.c | 11 ++++------- ext/openssl/ossl_pkey_dsa.c | 10 +++------- ext/openssl/ossl_pkey_ec.c | 31 ++++++++++--------------------- ext/openssl/ossl_pkey_rsa.c | 10 +++------- ext/openssl/ossl_ssl.c | 13 +++++-------- ext/openssl/ossl_ssl_session.c | 9 +++------ test/openssl/test_cipher.rb | 2 +- test/openssl/test_hpke.rb | 4 ++-- 11 files changed, 40 insertions(+), 83 deletions(-) diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c index e9dcd943e..bed30ae3d 100644 --- a/ext/openssl/ossl_cipher.c +++ b/ext/openssl/ossl_cipher.c @@ -17,11 +17,8 @@ ossl_raise(rb_eRuntimeError, NULL); \ RTYPEDDATA_DATA(obj) = (ctx); \ } while (0) -#define GetCipherInit(obj, ctx) do { \ - TypedData_Get_Struct((obj), EVP_CIPHER_CTX, &ossl_cipher_type, (ctx)); \ -} while (0) #define GetCipher(obj, ctx) do { \ - GetCipherInit((obj), (ctx)); \ + TypedData_Get_Struct((obj), EVP_CIPHER_CTX, &ossl_cipher_type, (ctx)); \ if (!(ctx)) { \ ossl_raise(rb_eRuntimeError, "Cipher not initialized!"); \ } \ @@ -147,10 +144,7 @@ ossl_cipher_initialize(VALUE self, VALUE str) const EVP_CIPHER *cipher; VALUE cipher_holder; - GetCipherInit(self, ctx); - if (ctx) { - ossl_raise(rb_eRuntimeError, "Cipher already initialized!"); - } + ossl_want_uninitialized(self, &ossl_cipher_type); cipher = ossl_evp_cipher_fetch(str, &cipher_holder); AllocCipher(self, ctx); if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1) @@ -166,14 +160,10 @@ ossl_cipher_copy(VALUE self, VALUE other) { EVP_CIPHER_CTX *ctx1, *ctx2; - rb_check_frozen(self); - if (self == other) return self; - - GetCipherInit(self, ctx1); - if (!ctx1) { - AllocCipher(self, ctx1); - } + ossl_want_uninitialized(self, &ossl_cipher_type); GetCipher(other, ctx2); + + AllocCipher(self, ctx1); if (EVP_CIPHER_CTX_copy(ctx1, ctx2) != 1) ossl_raise(eCipherError, NULL); diff --git a/ext/openssl/ossl_hpke.c b/ext/openssl/ossl_hpke.c index 0c04fc050..b1e915ed6 100644 --- a/ext/openssl/ossl_hpke.c +++ b/ext/openssl/ossl_hpke.c @@ -121,8 +121,7 @@ ossl_hpke_ctx_new_sender(VALUE self, VALUE suite) ossl_hpke_ctx_t *data; OSSL_HPKE_SUITE *suite_st; - if (RTYPEDDATA_DATA(self)) - ossl_raise(eHPKEError, "HPKE context is already initialized"); + ossl_want_uninitialized(self, &ossl_hpke_ctx_type); if (!rb_obj_is_kind_of(suite, cSuite)) ossl_raise(eHPKEError, "invalid suite specified"); GetHpkeSuite(suite, suite_st); @@ -155,8 +154,7 @@ ossl_hpke_ctx_new_receiver(VALUE self, VALUE suite) ossl_hpke_ctx_t *data; OSSL_HPKE_SUITE *suite_st; - if (RTYPEDDATA_DATA(self)) - ossl_raise(eHPKEError, "HPKE context is already initialized"); + ossl_want_uninitialized(self, &ossl_hpke_ctx_type); if (!rb_obj_is_kind_of(suite, cSuite)) ossl_raise(eHPKEError, "invalid suite specified"); GetHpkeSuite(suite, suite_st); @@ -379,8 +377,7 @@ ossl_hpke_suite_initialize(VALUE self, VALUE kem, VALUE kdf, VALUE aead) { OSSL_HPKE_SUITE *suite, tmp; - if (RTYPEDDATA_DATA(self)) - ossl_raise(eHPKEError, "HPKE suite is already initialized"); + ossl_want_uninitialized(self, &ossl_hpke_suite_type); if (RB_INTEGER_TYPE_P(kem) && RB_INTEGER_TYPE_P(kdf) && RB_INTEGER_TYPE_P(aead)) { diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 0763cfb8b..80b207317 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -622,10 +622,8 @@ ossl_pkey_initialize_copy(VALUE self, VALUE other) { EVP_PKEY *pkey, *pkey_other; - TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + ossl_want_uninitialized(self, &ossl_evp_pkey_type); TypedData_Get_Struct(other, EVP_PKEY, &ossl_evp_pkey_type, pkey_other); - if (pkey) - rb_raise(rb_eTypeError, "pkey already initialized"); if (pkey_other) { pkey = EVP_PKEY_dup(pkey_other); if (!pkey) diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c index f33121d0f..6252ed198 100644 --- a/ext/openssl/ossl_pkey_dh.c +++ b/ext/openssl/ossl_pkey_dh.c @@ -81,12 +81,11 @@ ossl_dh_initialize(int argc, VALUE *argv, VALUE self) BIO *in = NULL; VALUE arg; - TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); - if (pkey) - rb_raise(rb_eTypeError, "pkey already initialized"); + rb_scan_args(argc, argv, "01", &arg); + ossl_want_uninitialized(self, &ossl_evp_pkey_type); /* The DH.new(size, generator) form is handled by lib/openssl/pkey.rb */ - if (rb_scan_args(argc, argv, "01", &arg) == 0) { + if (argc == 0) { #ifdef OSSL_HAVE_IMMUTABLE_PKEY rb_raise(rb_eArgError, "OpenSSL::PKey::DH.new cannot be called " \ "without arguments; pkeys are immutable with OpenSSL 3.0"); @@ -144,9 +143,7 @@ ossl_dh_initialize_copy(VALUE self, VALUE other) DH *dh, *dh_other; const BIGNUM *pub, *priv; - TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); - if (pkey) - rb_raise(rb_eTypeError, "pkey already initialized"); + ossl_want_uninitialized(self, &ossl_evp_pkey_type); GetDH(other, dh_other); dh = DHparams_dup(dh_other); diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c index 112ea7466..5eef5951d 100644 --- a/ext/openssl/ossl_pkey_dsa.c +++ b/ext/openssl/ossl_pkey_dsa.c @@ -91,12 +91,10 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self) VALUE arg, pass; int type; - TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); - if (pkey) - rb_raise(rb_eTypeError, "pkey already initialized"); + rb_scan_args(argc, argv, "02", &arg, &pass); + ossl_want_uninitialized(self, &ossl_evp_pkey_type); /* The DSA.new(size, generator) form is handled by lib/openssl/pkey.rb */ - rb_scan_args(argc, argv, "02", &arg, &pass); if (argc == 0) { #ifdef OSSL_HAVE_IMMUTABLE_PKEY rb_raise(rb_eArgError, "OpenSSL::PKey::DSA.new cannot be called " \ @@ -155,9 +153,7 @@ ossl_dsa_initialize_copy(VALUE self, VALUE other) const DSA *dsa; DSA *dsa_new; - TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); - if (pkey) - rb_raise(rb_eTypeError, "pkey already initialized"); + ossl_want_uninitialized(self, &ossl_evp_pkey_type); GetDSA(other, dsa); dsa_new = (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c index 985814e43..9e059a406 100644 --- a/ext/openssl/ossl_pkey_ec.c +++ b/ext/openssl/ossl_pkey_ec.c @@ -142,11 +142,9 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self) VALUE arg, pass; int type; - TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); - if (pkey) - rb_raise(rb_eTypeError, "pkey already initialized"); - rb_scan_args(argc, argv, "02", &arg, &pass); + ossl_want_uninitialized(self, &ossl_evp_pkey_type); + if (NIL_P(arg)) { #ifdef OSSL_HAVE_IMMUTABLE_PKEY rb_raise(rb_eArgError, "OpenSSL::PKey::EC.new cannot be called " \ @@ -202,9 +200,7 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other) const EC_KEY *ec; EC_KEY *ec_new; - TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); - if (pkey) - rb_raise(rb_eTypeError, "pkey already initialized"); + ossl_want_uninitialized(self, &ossl_evp_pkey_type); GetEC(other, ec); ec_new = EC_KEY_dup(ec); @@ -632,11 +628,10 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) VALUE arg1, arg2, arg3, arg4; EC_GROUP *group; - TypedData_Get_Struct(self, EC_GROUP, &ossl_ec_group_type, group); - if (group) - ossl_raise(rb_eRuntimeError, "EC_GROUP is already initialized"); + rb_scan_args(argc, argv, "13", &arg1, &arg2, &arg3, &arg4); + ossl_want_uninitialized(self, &ossl_ec_group_type); - switch (rb_scan_args(argc, argv, "13", &arg1, &arg2, &arg3, &arg4)) { + switch (argc) { case 1: if (rb_obj_is_kind_of(arg1, cEC_GROUP)) { const EC_GROUP *arg1_group; @@ -718,9 +713,7 @@ ossl_ec_group_initialize_copy(VALUE self, VALUE other) { EC_GROUP *group, *group_new; - TypedData_Get_Struct(self, EC_GROUP, &ossl_ec_group_type, group_new); - if (group_new) - ossl_raise(eEC_GROUP, "EC::Group already initialized"); + ossl_want_uninitialized(self, &ossl_ec_group_type); GetECGroup(other, group); group_new = EC_GROUP_dup(group); @@ -1220,11 +1213,9 @@ static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self) VALUE group_v, arg2; const EC_GROUP *group; - TypedData_Get_Struct(self, EC_POINT, &ossl_ec_point_type, point); - if (point) - rb_raise(eEC_POINT, "EC_POINT already initialized"); - rb_scan_args(argc, argv, "11", &group_v, &arg2); + ossl_want_uninitialized(self, &ossl_ec_point_type); + if (rb_obj_is_kind_of(group_v, cEC_POINT)) { if (argc != 1) rb_raise(rb_eArgError, "invalid second argument"); @@ -1271,9 +1262,7 @@ ossl_ec_point_initialize_copy(VALUE self, VALUE other) EC_GROUP *group; VALUE group_v; - TypedData_Get_Struct(self, EC_POINT, &ossl_ec_point_type, point_new); - if (point_new) - ossl_raise(eEC_POINT, "EC::Point already initialized"); + ossl_want_uninitialized(self, &ossl_ec_point_type); GetECPoint(other, point); group_v = rb_obj_dup(rb_attr_get(other, id_i_group)); diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c index 7ddc3322a..ef5c33e76 100644 --- a/ext/openssl/ossl_pkey_rsa.c +++ b/ext/openssl/ossl_pkey_rsa.c @@ -84,12 +84,10 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self) VALUE arg, pass; int type; - TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); - if (pkey) - rb_raise(rb_eTypeError, "pkey already initialized"); + rb_scan_args(argc, argv, "02", &arg, &pass); + ossl_want_uninitialized(self, &ossl_evp_pkey_type); /* The RSA.new(size, generator) form is handled by lib/openssl/pkey.rb */ - rb_scan_args(argc, argv, "02", &arg, &pass); if (argc == 0) { #ifdef OSSL_HAVE_IMMUTABLE_PKEY rb_raise(rb_eArgError, "OpenSSL::PKey::RSA.new cannot be called " \ @@ -151,9 +149,7 @@ ossl_rsa_initialize_copy(VALUE self, VALUE other) const RSA *rsa; RSA *rsa_new; - TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); - if (pkey) - rb_raise(rb_eTypeError, "pkey already initialized"); + ossl_want_uninitialized(self, &ossl_evp_pkey_type); GetRSA(other, rsa); rsa_new = (RSA *)ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey, diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index 27a811b5a..e048f5681 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -1669,18 +1669,15 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self) SSL *ssl; SSL_CTX *ctx; - TypedData_Get_Struct(self, SSL, &ossl_ssl_type, ssl); - if (ssl) - ossl_raise(eSSLError, "SSL already initialized"); - - if (rb_scan_args(argc, argv, "11:", &io, &v_ctx, &opts) == 1) - v_ctx = rb_funcall(cSSLContext, rb_intern("new"), 0); - + argc = rb_scan_args(argc, argv, "11:", &io, &v_ctx, &opts); if (!kw_ids[0]) { kw_ids[0] = rb_intern_const("sync_close"); } - rb_get_kwargs(opts, kw_ids, 0, 1, kw_args); + ossl_want_uninitialized(self, &ossl_ssl_type); + + if (argc == 1) + v_ctx = rb_funcall(cSSLContext, rb_intern("new"), 0); if (kw_args[0] != Qundef) { rb_ivar_set(self, id_i_sync_close, kw_args[0]); } diff --git a/ext/openssl/ossl_ssl_session.c b/ext/openssl/ossl_ssl_session.c index 8a2fbf410..2a33b2f20 100644 --- a/ext/openssl/ossl_ssl_session.c +++ b/ext/openssl/ossl_ssl_session.c @@ -40,8 +40,7 @@ ossl_ssl_session_initialize(VALUE self, VALUE arg1) { SSL_SESSION *ctx; - if (RTYPEDDATA_DATA(self)) - ossl_raise(eSSLSession, "SSL Session already initialized"); + ossl_want_uninitialized(self, &ossl_ssl_session_type); if (rb_obj_is_instance_of(arg1, cSSLSocket)) { SSL *ssl; @@ -73,10 +72,9 @@ ossl_ssl_session_initialize(VALUE self, VALUE arg1) static VALUE ossl_ssl_session_initialize_copy(VALUE self, VALUE other) { - SSL_SESSION *sess, *sess_other, *sess_new; + SSL_SESSION *sess_other, *sess_new; - rb_check_frozen(self); - sess = RTYPEDDATA_DATA(self); /* XXX */ + ossl_want_uninitialized(self, &ossl_ssl_session_type); GetSSLSession(other, sess_other); sess_new = ASN1_dup((i2d_of_void *)i2d_SSL_SESSION, (d2i_of_void *)d2i_SSL_SESSION, @@ -85,7 +83,6 @@ ossl_ssl_session_initialize_copy(VALUE self, VALUE other) ossl_raise(eSSLSession, "ASN1_dup"); RTYPEDDATA_DATA(self) = sess_new; - SSL_SESSION_free(sess); return self; } diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb index 6a405da0a..b7926780c 100644 --- a/test/openssl/test_cipher.rb +++ b/test/openssl/test_cipher.rb @@ -110,7 +110,7 @@ def test_random_key_iv def test_initialize cipher = OpenSSL::Cipher.new("AES-256-CBC") - assert_raise(RuntimeError) { cipher.__send__(:initialize, "AES-256-CBC") } + assert_raise(TypeError) { cipher.__send__(:initialize, "AES-256-CBC") } assert_raise(RuntimeError) { OpenSSL::Cipher.allocate.final } assert_raise(OpenSSL::Cipher::CipherError) { OpenSSL::Cipher.new("no such algorithm") diff --git a/test/openssl/test_hpke.rb b/test/openssl/test_hpke.rb index 6ac104397..593de900d 100644 --- a/test/openssl/test_hpke.rb +++ b/test/openssl/test_hpke.rb @@ -161,12 +161,12 @@ def test_export_only_suite def test_context_cannot_be_reinitialized suite = x25519_suite sender = OpenSSL::HPKE::Context::Sender.new(suite) - assert_raise(OpenSSL::HPKE::HPKEError) do + assert_raise(TypeError) do sender.send(:initialize, suite) end receiver = OpenSSL::HPKE::Context::Receiver.new(suite) - assert_raise(OpenSSL::HPKE::HPKEError) do + assert_raise(TypeError) do receiver.send(:initialize, suite) end end From 5f104287930a00f99c3e1842018f9a04e305e8e5 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Sun, 7 Dec 2025 00:14:34 +0900 Subject: [PATCH 4/9] ocsp: allocate OpenSSL objects in #initialize{,_copy} Allocate the underlying OpenSSL object in #initialize{,_copy} instead of .allocate. Allocating an empty OpenSSL object in .allocate is wasteful because #initialize{,_copy} cannot always reuse an existing object and have to allocate a new one. Some ruby/openssl classes already follow this approach, such as OpenSSL::PKey::PKey. Let's standardize on it. Also expand New*() and Set*() macros, which are only used once or twice and are not very helpful for readability in my opinion. --- ext/openssl/ossl_ocsp.c | 243 ++++++++++++++-------------------------- 1 file changed, 83 insertions(+), 160 deletions(-) diff --git a/ext/openssl/ossl_ocsp.c b/ext/openssl/ossl_ocsp.c index 9dd4b466d..150e75326 100644 --- a/ext/openssl/ossl_ocsp.c +++ b/ext/openssl/ossl_ocsp.c @@ -12,56 +12,22 @@ #if !defined(OPENSSL_NO_OCSP) -#define NewOCSPReq(klass) \ - TypedData_Wrap_Struct((klass), &ossl_ocsp_request_type, 0) -#define SetOCSPReq(obj, req) do { \ - if(!(req)) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \ - RTYPEDDATA_DATA(obj) = (req); \ -} while (0) #define GetOCSPReq(obj, req) do { \ TypedData_Get_Struct((obj), OCSP_REQUEST, &ossl_ocsp_request_type, (req)); \ if(!(req)) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \ } while (0) - -#define NewOCSPRes(klass) \ - TypedData_Wrap_Struct((klass), &ossl_ocsp_response_type, 0) -#define SetOCSPRes(obj, res) do { \ - if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \ - RTYPEDDATA_DATA(obj) = (res); \ -} while (0) #define GetOCSPRes(obj, res) do { \ TypedData_Get_Struct((obj), OCSP_RESPONSE, &ossl_ocsp_response_type, (res)); \ if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \ } while (0) - -#define NewOCSPBasicRes(klass) \ - TypedData_Wrap_Struct((klass), &ossl_ocsp_basicresp_type, 0) -#define SetOCSPBasicRes(obj, res) do { \ - if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \ - RTYPEDDATA_DATA(obj) = (res); \ -} while (0) #define GetOCSPBasicRes(obj, res) do { \ TypedData_Get_Struct((obj), OCSP_BASICRESP, &ossl_ocsp_basicresp_type, (res)); \ if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \ } while (0) - -#define NewOCSPSingleRes(klass) \ - TypedData_Wrap_Struct((klass), &ossl_ocsp_singleresp_type, 0) -#define SetOCSPSingleRes(obj, res) do { \ - if(!(res)) ossl_raise(rb_eRuntimeError, "SingleResponse wasn't initialized!"); \ - RTYPEDDATA_DATA(obj) = (res); \ -} while (0) #define GetOCSPSingleRes(obj, res) do { \ TypedData_Get_Struct((obj), OCSP_SINGLERESP, &ossl_ocsp_singleresp_type, (res)); \ if(!(res)) ossl_raise(rb_eRuntimeError, "SingleResponse wasn't initialized!"); \ } while (0) - -#define NewOCSPCertId(klass) \ - TypedData_Wrap_Struct((klass), &ossl_ocsp_certid_type, 0) -#define SetOCSPCertId(obj, cid) do { \ - if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \ - RTYPEDDATA_DATA(obj) = (cid); \ -} while (0) #define GetOCSPCertId(obj, cid) do { \ TypedData_Get_Struct((obj), OCSP_CERTID, &ossl_ocsp_certid_type, (cid)); \ if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \ @@ -148,15 +114,17 @@ static const rb_data_type_t ossl_ocsp_certid_type = { /* * Public */ +static VALUE ossl_ocspcid_alloc(VALUE klass); + static VALUE ossl_ocspcid_new(const OCSP_CERTID *cid) { - VALUE obj = NewOCSPCertId(cOCSPCertId); + VALUE obj = ossl_ocspcid_alloc(cOCSPCertId); /* OpenSSL 1.1.1 takes a non-const pointer */ OCSP_CERTID *cid_new = OCSP_CERTID_dup((OCSP_CERTID *)cid); if (!cid_new) ossl_raise(eOCSPError, "OCSP_CERTID_dup"); - SetOCSPCertId(obj, cid_new); + RTYPEDDATA_DATA(obj) = cid_new; return obj; } @@ -166,33 +134,22 @@ ossl_ocspcid_new(const OCSP_CERTID *cid) static VALUE ossl_ocspreq_alloc(VALUE klass) { - OCSP_REQUEST *req; - VALUE obj; - - obj = NewOCSPReq(klass); - if (!(req = OCSP_REQUEST_new())) - ossl_raise(eOCSPError, NULL); - SetOCSPReq(obj, req); - - return obj; + return TypedData_Wrap_Struct(klass, &ossl_ocsp_request_type, NULL); } /* :nodoc: */ static VALUE ossl_ocspreq_initialize_copy(VALUE self, VALUE other) { - OCSP_REQUEST *req, *req_old, *req_new; + OCSP_REQUEST *req, *req_new; - rb_check_frozen(self); - GetOCSPReq(self, req_old); + ossl_want_uninitialized(self, &ossl_ocsp_request_type); GetOCSPReq(other, req); req_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_REQUEST), req); if (!req_new) ossl_raise(eOCSPError, "ASN1_item_dup"); - - SetOCSPReq(self, req_new); - OCSP_REQUEST_free(req_old); + RTYPEDDATA_DATA(self) = req_new; return self; } @@ -210,21 +167,25 @@ static VALUE ossl_ocspreq_initialize(int argc, VALUE *argv, VALUE self) { VALUE arg; - OCSP_REQUEST *req, *req_new; + OCSP_REQUEST *req_new; const unsigned char *p; rb_scan_args(argc, argv, "01", &arg); - if(!NIL_P(arg)){ - GetOCSPReq(self, req); + ossl_want_uninitialized(self, &ossl_ocsp_request_type); + if (NIL_P(arg)) { + req_new = OCSP_REQUEST_new(); + if (!req_new) + ossl_raise(eOCSPError, "OCSP_REQUEST_new"); + } + else { arg = ossl_to_der_if_possible(arg); StringValue(arg); p = (unsigned char *)RSTRING_PTR(arg); req_new = d2i_OCSP_REQUEST(NULL, &p, RSTRING_LEN(arg)); if (!req_new) ossl_raise(eOCSPError, "d2i_OCSP_REQUEST"); - SetOCSPReq(self, req_new); - OCSP_REQUEST_free(req); } + RTYPEDDATA_DATA(self) = req_new; return self; } @@ -476,6 +437,12 @@ ossl_ocspreq_signed_p(VALUE self) * OCSP::Response */ +static VALUE +ossl_ocspres_alloc(VALUE klass) +{ + return TypedData_Wrap_Struct(klass, &ossl_ocsp_response_type, NULL); +} + /* call-seq: * OpenSSL::OCSP::Response.create(status, basic_response = nil) -> response * @@ -492,24 +459,10 @@ ossl_ocspres_s_create(VALUE klass, VALUE status, VALUE basic_resp) if(NIL_P(basic_resp)) bs = NULL; else GetOCSPBasicRes(basic_resp, bs); /* NO NEED TO DUP */ - obj = NewOCSPRes(klass); - if(!(res = OCSP_response_create(st, bs))) - ossl_raise(eOCSPError, NULL); - SetOCSPRes(obj, res); - - return obj; -} - -static VALUE -ossl_ocspres_alloc(VALUE klass) -{ - OCSP_RESPONSE *res; - VALUE obj; - - obj = NewOCSPRes(klass); - if(!(res = OCSP_RESPONSE_new())) - ossl_raise(eOCSPError, NULL); - SetOCSPRes(obj, res); + obj = ossl_ocspres_alloc(klass); + if (!(res = OCSP_response_create(st, bs))) + ossl_raise(eOCSPError, "OCSP_response_create"); + RTYPEDDATA_DATA(obj) = res; return obj; } @@ -518,18 +471,15 @@ ossl_ocspres_alloc(VALUE klass) static VALUE ossl_ocspres_initialize_copy(VALUE self, VALUE other) { - OCSP_RESPONSE *res, *res_old, *res_new; + OCSP_RESPONSE *res, *res_new; - rb_check_frozen(self); - GetOCSPRes(self, res_old); + ossl_want_uninitialized(self, &ossl_ocsp_response_type); GetOCSPRes(other, res); res_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_RESPONSE), res); if (!res_new) ossl_raise(eOCSPError, "ASN1_item_dup"); - - SetOCSPRes(self, res_new); - OCSP_RESPONSE_free(res_old); + RTYPEDDATA_DATA(self) = res_new; return self; } @@ -547,21 +497,25 @@ static VALUE ossl_ocspres_initialize(int argc, VALUE *argv, VALUE self) { VALUE arg; - OCSP_RESPONSE *res, *res_new; + OCSP_RESPONSE *res_new; const unsigned char *p; rb_scan_args(argc, argv, "01", &arg); - if(!NIL_P(arg)){ - GetOCSPRes(self, res); + ossl_want_uninitialized(self, &ossl_ocsp_response_type); + if (NIL_P(arg)) { + res_new = OCSP_RESPONSE_new(); + if (!res_new) + ossl_raise(eOCSPError, "OCSP_RESPONSE_new"); + } + else { arg = ossl_to_der_if_possible(arg); StringValue(arg); p = (unsigned char *)RSTRING_PTR(arg); res_new = d2i_OCSP_RESPONSE(NULL, &p, RSTRING_LEN(arg)); if (!res_new) ossl_raise(eOCSPError, "d2i_OCSP_RESPONSE"); - SetOCSPRes(self, res_new); - OCSP_RESPONSE_free(res); } + RTYPEDDATA_DATA(self) = res_new; return self; } @@ -604,6 +558,8 @@ ossl_ocspres_status_string(VALUE self) return rb_str_new2(OCSP_response_status_str(st)); } +static VALUE ossl_ocspbres_alloc(VALUE klass); + /* * call-seq: * response.basic @@ -619,10 +575,10 @@ ossl_ocspres_get_basic(VALUE self) VALUE ret; GetOCSPRes(self, res); - ret = NewOCSPBasicRes(cOCSPBasicRes); - if(!(bs = OCSP_response_get1_basic(res))) + ret = ossl_ocspbres_alloc(cOCSPBasicRes); + if (!(bs = OCSP_response_get1_basic(res))) return Qnil; - SetOCSPBasicRes(ret, bs); + RTYPEDDATA_DATA(ret) = bs; return ret; } @@ -660,33 +616,22 @@ ossl_ocspres_to_der(VALUE self) static VALUE ossl_ocspbres_alloc(VALUE klass) { - OCSP_BASICRESP *bs; - VALUE obj; - - obj = NewOCSPBasicRes(klass); - if(!(bs = OCSP_BASICRESP_new())) - ossl_raise(eOCSPError, NULL); - SetOCSPBasicRes(obj, bs); - - return obj; + return TypedData_Wrap_Struct(klass, &ossl_ocsp_basicresp_type, NULL); } /* :nodoc: */ static VALUE ossl_ocspbres_initialize_copy(VALUE self, VALUE other) { - OCSP_BASICRESP *bs, *bs_old, *bs_new; + OCSP_BASICRESP *bs, *bs_new; - rb_check_frozen(self); - GetOCSPBasicRes(self, bs_old); + ossl_want_uninitialized(self, &ossl_ocsp_basicresp_type); GetOCSPBasicRes(other, bs); bs_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_BASICRESP), bs); if (!bs_new) ossl_raise(eOCSPError, "ASN1_item_dup"); - - SetOCSPBasicRes(self, bs_new); - OCSP_BASICRESP_free(bs_old); + RTYPEDDATA_DATA(self) = bs_new; return self; } @@ -703,22 +648,24 @@ static VALUE ossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self) { VALUE arg; - OCSP_BASICRESP *res, *res_new; + OCSP_BASICRESP *bs_new; const unsigned char *p; rb_scan_args(argc, argv, "01", &arg); - if (!NIL_P(arg)) { - GetOCSPBasicRes(self, res); + if (NIL_P(arg)) { + bs_new = OCSP_BASICRESP_new(); + if (!bs_new) + ossl_raise(eOCSPError, "OCSP_BASICRESP_new"); + } + else { arg = ossl_to_der_if_possible(arg); StringValue(arg); p = (unsigned char *)RSTRING_PTR(arg); - res_new = d2i_OCSP_BASICRESP(NULL, &p, RSTRING_LEN(arg)); - if (!res_new) + bs_new = d2i_OCSP_BASICRESP(NULL, &p, RSTRING_LEN(arg)); + if (!bs_new) ossl_raise(eOCSPError, "d2i_OCSP_BASICRESP"); - SetOCSPBasicRes(self, res_new); - OCSP_BASICRESP_free(res); } - + RTYPEDDATA_DATA(self) = bs_new; return self; } @@ -1085,33 +1032,25 @@ ossl_ocspbres_to_der(VALUE self) /* * OCSP::SingleResponse */ +static VALUE +ossl_ocspsres_alloc(VALUE klass) +{ + return TypedData_Wrap_Struct(klass, &ossl_ocsp_singleresp_type, NULL); +} + static VALUE ossl_ocspsres_new(const OCSP_SINGLERESP *sres) { VALUE obj; OCSP_SINGLERESP *sres_new; - obj = NewOCSPSingleRes(cOCSPSingleRes); + obj = ossl_ocspsres_alloc(cOCSPSingleRes); /* OpenSSL 1.1.1 takes a non-const pointer */ sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), (OCSP_SINGLERESP *)sres); if (!sres_new) ossl_raise(eOCSPError, "ASN1_item_dup"); - SetOCSPSingleRes(obj, sres_new); - - return obj; -} - -static VALUE -ossl_ocspsres_alloc(VALUE klass) -{ - OCSP_SINGLERESP *sres; - VALUE obj; - - obj = NewOCSPSingleRes(klass); - if (!(sres = OCSP_SINGLERESP_new())) - ossl_raise(eOCSPError, NULL); - SetOCSPSingleRes(obj, sres); + RTYPEDDATA_DATA(obj) = sres_new; return obj; } @@ -1125,19 +1064,18 @@ ossl_ocspsres_alloc(VALUE klass) static VALUE ossl_ocspsres_initialize(VALUE self, VALUE arg) { - OCSP_SINGLERESP *res, *res_new; + OCSP_SINGLERESP *sres_new; const unsigned char *p; + ossl_want_uninitialized(self, &ossl_ocsp_singleresp_type); arg = ossl_to_der_if_possible(arg); StringValue(arg); - GetOCSPSingleRes(self, res); p = (unsigned char*)RSTRING_PTR(arg); - res_new = d2i_OCSP_SINGLERESP(NULL, &p, RSTRING_LEN(arg)); - if (!res_new) + sres_new = d2i_OCSP_SINGLERESP(NULL, &p, RSTRING_LEN(arg)); + if (!sres_new) ossl_raise(eOCSPError, "d2i_OCSP_SINGLERESP"); - SetOCSPSingleRes(self, res_new); - OCSP_SINGLERESP_free(res); + RTYPEDDATA_DATA(self) = sres_new; return self; } @@ -1146,18 +1084,15 @@ ossl_ocspsres_initialize(VALUE self, VALUE arg) static VALUE ossl_ocspsres_initialize_copy(VALUE self, VALUE other) { - OCSP_SINGLERESP *sres, *sres_old, *sres_new; + OCSP_SINGLERESP *sres, *sres_new; - rb_check_frozen(self); - GetOCSPSingleRes(self, sres_old); + ossl_want_uninitialized(self, &ossl_ocsp_singleresp_type); GetOCSPSingleRes(other, sres); sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres); if (!sres_new) ossl_raise(eOCSPError, "ASN1_item_dup"); - - SetOCSPSingleRes(self, sres_new); - OCSP_SINGLERESP_free(sres_old); + RTYPEDDATA_DATA(self) = sres_new; return self; } @@ -1389,33 +1324,22 @@ ossl_ocspsres_to_der(VALUE self) static VALUE ossl_ocspcid_alloc(VALUE klass) { - OCSP_CERTID *id; - VALUE obj; - - obj = NewOCSPCertId(klass); - if(!(id = OCSP_CERTID_new())) - ossl_raise(eOCSPError, NULL); - SetOCSPCertId(obj, id); - - return obj; + return TypedData_Wrap_Struct(klass, &ossl_ocsp_certid_type, NULL); } /* :nodoc: */ static VALUE ossl_ocspcid_initialize_copy(VALUE self, VALUE other) { - OCSP_CERTID *cid, *cid_old, *cid_new; + OCSP_CERTID *cid, *cid_new; - rb_check_frozen(self); - GetOCSPCertId(self, cid_old); + ossl_want_uninitialized(self, &ossl_ocsp_certid_type); GetOCSPCertId(other, cid); cid_new = OCSP_CERTID_dup(cid); if (!cid_new) ossl_raise(eOCSPError, "OCSP_CERTID_dup"); - - SetOCSPCertId(self, cid_new); - OCSP_CERTID_free(cid_old); + RTYPEDDATA_DATA(self) = cid_new; return self; } @@ -1437,11 +1361,12 @@ ossl_ocspcid_initialize_copy(VALUE self, VALUE other) static VALUE ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self) { - OCSP_CERTID *id, *newid; + OCSP_CERTID *newid; VALUE subject, issuer, digest; - GetOCSPCertId(self, id); - if (rb_scan_args(argc, argv, "12", &subject, &issuer, &digest) == 1) { + rb_scan_args(argc, argv, "12", &subject, &issuer, &digest); + ossl_want_uninitialized(self, &ossl_ocsp_certid_type); + if (argc == 1) { VALUE arg; const unsigned char *p; @@ -1465,9 +1390,7 @@ ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self) if (!newid) ossl_raise(eOCSPError, "OCSP_cert_to_id"); } - - SetOCSPCertId(self, newid); - OCSP_CERTID_free(id); + RTYPEDDATA_DATA(self) = newid; return self; } From 1472feb74e2773388f1b2a2fab57b907c0cf6fc3 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Sat, 6 Dec 2025 17:45:33 +0900 Subject: [PATCH 5/9] pkcs12: allocate OpenSSL objects in #initialize{,_copy} --- ext/openssl/ossl_pkcs12.c | 46 +++++++++++++++------------------------ 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/ext/openssl/ossl_pkcs12.c b/ext/openssl/ossl_pkcs12.c index a47c81354..da8fd1c3b 100644 --- a/ext/openssl/ossl_pkcs12.c +++ b/ext/openssl/ossl_pkcs12.c @@ -4,14 +4,6 @@ */ #include "ossl.h" -#define NewPKCS12(klass) \ - TypedData_Wrap_Struct((klass), &ossl_pkcs12_type, 0) - -#define SetPKCS12(obj, p12) do { \ - if(!(p12)) ossl_raise(rb_eRuntimeError, "PKCS12 wasn't initialized."); \ - RTYPEDDATA_DATA(obj) = (p12); \ -} while (0) - #define GetPKCS12(obj, p12) do { \ TypedData_Get_Struct((obj), PKCS12, &ossl_pkcs12_type, (p12)); \ if(!(p12)) ossl_raise(rb_eRuntimeError, "PKCS12 wasn't initialized."); \ @@ -50,32 +42,23 @@ static const rb_data_type_t ossl_pkcs12_type = { static VALUE ossl_pkcs12_s_allocate(VALUE klass) { - PKCS12 *p12; - VALUE obj; - - obj = NewPKCS12(klass); - if(!(p12 = PKCS12_new())) ossl_raise(ePKCS12Error, NULL); - SetPKCS12(obj, p12); - - return obj; + return TypedData_Wrap_Struct(klass, &ossl_pkcs12_type, NULL); } /* :nodoc: */ static VALUE ossl_pkcs12_initialize_copy(VALUE self, VALUE other) { - PKCS12 *p12, *p12_old, *p12_new; + PKCS12 *p12, *p12_new; - rb_check_frozen(self); - GetPKCS12(self, p12_old); + ossl_want_uninitialized(self, &ossl_pkcs12_type); GetPKCS12(other, p12); - p12_new = ASN1_dup((i2d_of_void *)i2d_PKCS12, (d2i_of_void *)d2i_PKCS12, (char *)p12); + p12_new = ASN1_dup((i2d_of_void *)i2d_PKCS12, (d2i_of_void *)d2i_PKCS12, + p12); if (!p12_new) ossl_raise(ePKCS12Error, "ASN1_dup"); - - SetPKCS12(self, p12_new); - PKCS12_free(p12_old); + RTYPEDDATA_DATA(self) = p12_new; return self; } @@ -145,13 +128,13 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self) } #endif - obj = NewPKCS12(cPKCS12); + obj = ossl_pkcs12_s_allocate(cPKCS12); x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca); p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s, nkey, ncert, kiter, miter, ktype); sk_X509_pop_free(x509s, X509_free); if(!p12) ossl_raise(ePKCS12Error, NULL); - SetPKCS12(obj, p12); + RTYPEDDATA_DATA(obj) = p12; ossl_pkcs12_set_key(obj, pkey); ossl_pkcs12_set_cert(obj, cert); @@ -191,7 +174,7 @@ ossl_x509_sk2ary_i(VALUE arg) static VALUE ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self) { - PKCS12 *p12, *p12_orig = DATA_PTR(self); + PKCS12 *p12; BIO *in; VALUE arg, pass, pkey, cert, ca; char *passphrase; @@ -200,14 +183,21 @@ ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self) STACK_OF(X509) *x509s = NULL; int st = 0; - if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) return self; + rb_scan_args(argc, argv, "02", &arg, &pass); + ossl_want_uninitialized(self, &ossl_pkcs12_type); + if (argc == 0) { + p12 = PKCS12_new(); + if (!p12) + ossl_raise(ePKCS12Error, "PKCS12_new"); + RTYPEDDATA_DATA(self) = p12; + return self; + } passphrase = NIL_P(pass) ? NULL : StringValueCStr(pass); in = ossl_obj2bio(&arg); p12 = d2i_PKCS12_bio(in, NULL); BIO_free(in); if (!p12) ossl_raise(ePKCS12Error, "d2i_PKCS12_bio"); - PKCS12_free(p12_orig); RTYPEDDATA_DATA(self) = p12; pkey = cert = ca = Qnil; From c70b060c3d1df532cd95a3dee2512ae4414f883d Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Sat, 6 Dec 2025 18:06:40 +0900 Subject: [PATCH 6/9] x509*: allocate OpenSSL objects in #initialize{,_copy} --- ext/openssl/ossl_x509attr.c | 68 ++++++++++--------------- ext/openssl/ossl_x509cert.c | 62 ++++++++--------------- ext/openssl/ossl_x509crl.c | 58 +++++++-------------- ext/openssl/ossl_x509ext.c | 66 ++++++++++-------------- ext/openssl/ossl_x509name.c | 93 +++++++++++++--------------------- ext/openssl/ossl_x509req.c | 40 +++++---------- ext/openssl/ossl_x509revoked.c | 51 +++++++------------ ext/openssl/ossl_x509store.c | 58 ++++++--------------- 8 files changed, 176 insertions(+), 320 deletions(-) diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c index 38600b9b0..c84f607e3 100644 --- a/ext/openssl/ossl_x509attr.c +++ b/ext/openssl/ossl_x509attr.c @@ -9,14 +9,6 @@ */ #include "ossl.h" -#define NewX509Attr(klass) \ - TypedData_Wrap_Struct((klass), &ossl_x509attr_type, 0) -#define SetX509Attr(obj, attr) do { \ - if (!(attr)) { \ - ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \ - } \ - RTYPEDDATA_DATA(obj) = (attr); \ -} while (0) #define GetX509Attr(obj, attr) do { \ TypedData_Get_Struct((obj), X509_ATTRIBUTE, &ossl_x509attr_type, (attr)); \ if (!(attr)) { \ @@ -44,6 +36,12 @@ static const rb_data_type_t ossl_x509attr_type = { 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; +static VALUE +ossl_x509attr_alloc(VALUE klass) +{ + return TypedData_Wrap_Struct(klass, &ossl_x509attr_type, NULL); +} + /* * Public */ @@ -53,12 +51,12 @@ ossl_x509attr_new(const X509_ATTRIBUTE *attr) X509_ATTRIBUTE *new; VALUE obj; - obj = NewX509Attr(cX509Attr); + obj = ossl_x509attr_alloc(cX509Attr); /* OpenSSL 1.1.1 takes a non-const pointer */ new = X509_ATTRIBUTE_dup((X509_ATTRIBUTE *)attr); if (!new) ossl_raise(eX509AttrError, "X509_ATTRIBUTE_dup"); - SetX509Attr(obj, new); + RTYPEDDATA_DATA(obj) = new; return obj; } @@ -73,23 +71,6 @@ GetX509AttrPtr(VALUE obj) return attr; } -/* - * Private - */ -static VALUE -ossl_x509attr_alloc(VALUE klass) -{ - X509_ATTRIBUTE *attr; - VALUE obj; - - obj = NewX509Attr(klass); - if (!(attr = X509_ATTRIBUTE_new())) - ossl_raise(eX509AttrError, NULL); - SetX509Attr(obj, attr); - - return obj; -} - /* * call-seq: * Attribute.new(oid [, value]) => attr @@ -98,21 +79,27 @@ static VALUE ossl_x509attr_initialize(int argc, VALUE *argv, VALUE self) { VALUE oid, value; - X509_ATTRIBUTE *attr, *x; + X509_ATTRIBUTE *attr; const unsigned char *p; - GetX509Attr(self, attr); - if(rb_scan_args(argc, argv, "11", &oid, &value) == 1){ + rb_scan_args(argc, argv, "11", &oid, &value); + ossl_want_uninitialized(self, &ossl_x509attr_type); + if (argc == 1) { oid = ossl_to_der_if_possible(oid); StringValue(oid); p = (unsigned char *)RSTRING_PTR(oid); - x = d2i_X509_ATTRIBUTE(&attr, &p, RSTRING_LEN(oid)); - DATA_PTR(self) = attr; - if(!x){ - ossl_raise(eX509AttrError, NULL); - } + attr = d2i_X509_ATTRIBUTE(NULL, &p, RSTRING_LEN(oid)); + if (!attr) + ossl_raise(eX509AttrError, "d2i_X509_ATTRIBUTE"); + RTYPEDDATA_DATA(self) = attr; return self; } + + attr = X509_ATTRIBUTE_new(); + if (!attr) + ossl_raise(eX509AttrError, "X509_ATTRIBUTE_new"); + RTYPEDDATA_DATA(self) = attr; + rb_funcall(self, rb_intern("oid="), 1, oid); rb_funcall(self, rb_intern("value="), 1, value); @@ -123,18 +110,15 @@ ossl_x509attr_initialize(int argc, VALUE *argv, VALUE self) static VALUE ossl_x509attr_initialize_copy(VALUE self, VALUE other) { - X509_ATTRIBUTE *attr, *attr_other, *attr_new; + X509_ATTRIBUTE *attr_other, *attr_new; - rb_check_frozen(self); - GetX509Attr(self, attr); + ossl_want_uninitialized(self, &ossl_x509attr_type); GetX509Attr(other, attr_other); attr_new = X509_ATTRIBUTE_dup(attr_other); if (!attr_new) ossl_raise(eX509AttrError, "X509_ATTRIBUTE_dup"); - - SetX509Attr(self, attr_new); - X509_ATTRIBUTE_free(attr); + RTYPEDDATA_DATA(self) = attr_new; return self; } @@ -203,7 +187,7 @@ ossl_x509attr_set_value(VALUE self, VALUE value) sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); ossl_raise(eX509AttrError, "X509_ATTRIBUTE_create_by_OBJ"); } - SetX509Attr(self, new_attr); + RTYPEDDATA_DATA(self) = new_attr; X509_ATTRIBUTE_free(attr); attr = new_attr; } diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c index 08dd184a0..b40387194 100644 --- a/ext/openssl/ossl_x509cert.c +++ b/ext/openssl/ossl_x509cert.c @@ -9,14 +9,6 @@ */ #include "ossl.h" -#define NewX509(klass) \ - TypedData_Wrap_Struct((klass), &ossl_x509_type, 0) -#define SetX509(obj, x509) do { \ - if (!(x509)) { \ - ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \ - } \ - RTYPEDDATA_DATA(obj) = (x509); \ -} while (0) #define GetX509(obj, x509) do { \ TypedData_Get_Struct((obj), X509, &ossl_x509_type, (x509)); \ if (!(x509)) { \ @@ -44,6 +36,12 @@ static const rb_data_type_t ossl_x509_type = { 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; +static VALUE +ossl_x509_alloc(VALUE klass) +{ + return TypedData_Wrap_Struct(klass, &ossl_x509_type, NULL); +} + /* * Public */ @@ -53,12 +51,12 @@ ossl_x509_new(const X509 *x509) X509 *new; VALUE obj; - obj = NewX509(cX509Cert); + obj = ossl_x509_alloc(cX509Cert); /* OpenSSL 1.1.1 takes a non-const pointer */ new = X509_dup((X509 *)x509); if (!new) ossl_raise(eX509CertError, "X509_dup"); - SetX509(obj, new); + RTYPEDDATA_DATA(obj) = new; return obj; } @@ -85,23 +83,6 @@ DupX509CertPtr(VALUE obj) return x509; } -/* - * Private - */ -static VALUE -ossl_x509_alloc(VALUE klass) -{ - X509 *x509; - VALUE obj; - - obj = NewX509(klass); - x509 = X509_new(); - if (!x509) ossl_raise(eX509CertError, NULL); - SetX509(obj, x509); - - return obj; -} - /* * call-seq: * Certificate.new => cert @@ -111,12 +92,16 @@ static VALUE ossl_x509_initialize(int argc, VALUE *argv, VALUE self) { BIO *in; - X509 *x509, *x509_orig = RTYPEDDATA_DATA(self); + X509 *x509; VALUE arg; - rb_check_frozen(self); - if (rb_scan_args(argc, argv, "01", &arg) == 0) { - /* create just empty X509Cert */ + rb_scan_args(argc, argv, "01", &arg); + ossl_want_uninitialized(self, &ossl_x509_type); + if (argc == 0) { + x509 = X509_new(); + if (!x509) + ossl_raise(eX509CertError, "X509_new"); + RTYPEDDATA_DATA(self) = x509; return self; } arg = ossl_to_der_if_possible(arg); @@ -131,7 +116,6 @@ ossl_x509_initialize(int argc, VALUE *argv, VALUE self) ossl_raise(eX509CertError, "PEM_read_bio_X509"); RTYPEDDATA_DATA(self) = x509; - X509_free(x509_orig); return self; } @@ -140,19 +124,15 @@ ossl_x509_initialize(int argc, VALUE *argv, VALUE self) static VALUE ossl_x509_copy(VALUE self, VALUE other) { - X509 *a, *b, *x509; - - rb_check_frozen(self); - if (self == other) return self; + X509 *b, *x509; - GetX509(self, a); + ossl_want_uninitialized(self, &ossl_x509_type); GetX509(other, b); x509 = X509_dup(b); - if (!x509) ossl_raise(eX509CertError, NULL); - - DATA_PTR(self) = x509; - X509_free(a); + if (!x509) + ossl_raise(eX509CertError, "X509_dup"); + RTYPEDDATA_DATA(self) = x509; return self; } diff --git a/ext/openssl/ossl_x509crl.c b/ext/openssl/ossl_x509crl.c index a0fabe522..4e6c359cb 100644 --- a/ext/openssl/ossl_x509crl.c +++ b/ext/openssl/ossl_x509crl.c @@ -9,14 +9,6 @@ */ #include "ossl.h" -#define NewX509CRL(klass) \ - TypedData_Wrap_Struct((klass), &ossl_x509crl_type, 0) -#define SetX509CRL(obj, crl) do { \ - if (!(crl)) { \ - ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \ - } \ - RTYPEDDATA_DATA(obj) = (crl); \ -} while (0) #define GetX509CRL(obj, crl) do { \ TypedData_Get_Struct((obj), X509_CRL, &ossl_x509crl_type, (crl)); \ if (!(crl)) { \ @@ -44,6 +36,12 @@ static const rb_data_type_t ossl_x509crl_type = { 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; +static VALUE +ossl_x509crl_alloc(VALUE klass) +{ + return TypedData_Wrap_Struct(klass, &ossl_x509crl_type, NULL); +} + /* * PUBLIC */ @@ -63,30 +61,12 @@ ossl_x509crl_new(const X509_CRL *crl) X509_CRL *tmp; VALUE obj; - obj = NewX509CRL(cX509CRL); + obj = ossl_x509crl_alloc(cX509CRL); /* OpenSSL 1.1.1 takes a non-const pointer */ tmp = X509_CRL_dup((X509_CRL *)crl); if (!tmp) ossl_raise(eX509CRLError, "X509_CRL_dup"); - SetX509CRL(obj, tmp); - - return obj; -} - -/* - * PRIVATE - */ -static VALUE -ossl_x509crl_alloc(VALUE klass) -{ - X509_CRL *crl; - VALUE obj; - - obj = NewX509CRL(klass); - if (!(crl = X509_CRL_new())) { - ossl_raise(eX509CRLError, NULL); - } - SetX509CRL(obj, crl); + RTYPEDDATA_DATA(obj) = tmp; return obj; } @@ -95,11 +75,16 @@ static VALUE ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self) { BIO *in; - X509_CRL *crl, *crl_orig = RTYPEDDATA_DATA(self); + X509_CRL *crl; VALUE arg; - rb_check_frozen(self); - if (rb_scan_args(argc, argv, "01", &arg) == 0) { + rb_scan_args(argc, argv, "01", &arg); + ossl_want_uninitialized(self, &ossl_x509crl_type); + if (argc == 0) { + crl = X509_CRL_new(); + if (!crl) + ossl_raise(eX509CRLError, "X509_CRL_new"); + RTYPEDDATA_DATA(self) = crl; return self; } arg = ossl_to_der_if_possible(arg); @@ -112,9 +97,7 @@ ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self) BIO_free(in); if (!crl) ossl_raise(eX509CRLError, "PEM_read_bio_X509_CRL"); - RTYPEDDATA_DATA(self) = crl; - X509_CRL_free(crl_orig); return self; } @@ -123,17 +106,14 @@ ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self) static VALUE ossl_x509crl_copy(VALUE self, VALUE other) { - X509_CRL *a, *b, *crl; + X509_CRL *b, *crl; - rb_check_frozen(self); - if (self == other) return self; - GetX509CRL(self, a); + ossl_want_uninitialized(self, &ossl_x509crl_type); GetX509CRL(other, b); if (!(crl = X509_CRL_dup(b))) { ossl_raise(eX509CRLError, NULL); } - X509_CRL_free(a); - DATA_PTR(self) = crl; + RTYPEDDATA_DATA(self) = crl; return self; } diff --git a/ext/openssl/ossl_x509ext.c b/ext/openssl/ossl_x509ext.c index 1fe727d3f..effc6b829 100644 --- a/ext/openssl/ossl_x509ext.c +++ b/ext/openssl/ossl_x509ext.c @@ -9,14 +9,6 @@ */ #include "ossl.h" -#define NewX509Ext(klass) \ - TypedData_Wrap_Struct((klass), &ossl_x509ext_type, 0) -#define SetX509Ext(obj, ext) do { \ - if (!(ext)) { \ - ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \ - } \ - RTYPEDDATA_DATA(obj) = (ext); \ -} while (0) #define GetX509Ext(obj, ext) do { \ TypedData_Get_Struct((obj), X509_EXTENSION, &ossl_x509ext_type, (ext)); \ if (!(ext)) { \ @@ -58,6 +50,12 @@ static const rb_data_type_t ossl_x509ext_type = { 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; +static VALUE +ossl_x509ext_alloc(VALUE klass) +{ + return TypedData_Wrap_Struct(klass, &ossl_x509ext_type, NULL); +} + /* * Public */ @@ -67,12 +65,12 @@ ossl_x509ext_new(const X509_EXTENSION *ext) X509_EXTENSION *new; VALUE obj; - obj = NewX509Ext(cX509Ext); + obj = ossl_x509ext_alloc(cX509Ext); /* OpenSSL 1.1.1 takes a non-const pointer */ new = X509_EXTENSION_dup((X509_EXTENSION *)ext); if (!new) ossl_raise(eX509ExtError, "X509_EXTENSION_dup"); - SetX509Ext(obj, new); + RTYPEDDATA_DATA(obj) = new; return obj; } @@ -221,7 +219,7 @@ ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self) StringValueCStr(valstr); GetX509ExtFactory(self, ctx); - obj = NewX509Ext(cX509Ext); + obj = ossl_x509ext_alloc(cX509Ext); rconf = rb_iv_get(self, "@config"); conf = NIL_P(rconf) ? NULL : GetConfig(rconf); X509V3_set_nconf(ctx, conf); @@ -231,7 +229,7 @@ ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self) if (!ext){ ossl_raise(eX509ExtError, "%"PRIsVALUE" = %"PRIsVALUE, oid, valstr); } - SetX509Ext(obj, ext); + RTYPEDDATA_DATA(obj) = ext; return obj; } @@ -239,20 +237,6 @@ ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self) /* * Ext */ -static VALUE -ossl_x509ext_alloc(VALUE klass) -{ - X509_EXTENSION *ext; - VALUE obj; - - obj = NewX509Ext(klass); - if(!(ext = X509_EXTENSION_new())){ - ossl_raise(eX509ExtError, NULL); - } - SetX509Ext(obj, ext); - - return obj; -} /* * call-seq: @@ -271,19 +255,26 @@ ossl_x509ext_initialize(int argc, VALUE *argv, VALUE self) { VALUE oid, value, critical; const unsigned char *p; - X509_EXTENSION *ext, *x; + X509_EXTENSION *ext; - GetX509Ext(self, ext); - if(rb_scan_args(argc, argv, "12", &oid, &value, &critical) == 1){ + rb_scan_args(argc, argv, "12", &oid, &value, &critical); + ossl_want_uninitialized(self, &ossl_x509ext_type); + if (argc == 1) { oid = ossl_to_der_if_possible(oid); StringValue(oid); p = (unsigned char *)RSTRING_PTR(oid); - x = d2i_X509_EXTENSION(&ext, &p, RSTRING_LEN(oid)); - DATA_PTR(self) = ext; - if(!x) - ossl_raise(eX509ExtError, NULL); + ext = d2i_X509_EXTENSION(NULL, &p, RSTRING_LEN(oid)); + if (!ext) + ossl_raise(eX509ExtError, "d2i_X509_EXTENSION"); + RTYPEDDATA_DATA(self) = ext; return self; } + + ext = X509_EXTENSION_new(); + if (!ext) + ossl_raise(eX509ExtError, "X509_EXTENSION_new"); + RTYPEDDATA_DATA(self) = ext; + rb_funcall(self, rb_intern("oid="), 1, oid); rb_funcall(self, rb_intern("value="), 1, value); if(argc > 2) rb_funcall(self, rb_intern("critical="), 1, critical); @@ -295,18 +286,15 @@ ossl_x509ext_initialize(int argc, VALUE *argv, VALUE self) static VALUE ossl_x509ext_initialize_copy(VALUE self, VALUE other) { - X509_EXTENSION *ext, *ext_other, *ext_new; + X509_EXTENSION *ext_other, *ext_new; - rb_check_frozen(self); - GetX509Ext(self, ext); + ossl_want_uninitialized(self, &ossl_x509ext_type); GetX509Ext(other, ext_other); ext_new = X509_EXTENSION_dup(ext_other); if (!ext_new) ossl_raise(eX509ExtError, "X509_EXTENSION_dup"); - - SetX509Ext(self, ext_new); - X509_EXTENSION_free(ext); + RTYPEDDATA_DATA(self) = ext_new; return self; } diff --git a/ext/openssl/ossl_x509name.c b/ext/openssl/ossl_x509name.c index eb97b23c0..23363b695 100644 --- a/ext/openssl/ossl_x509name.c +++ b/ext/openssl/ossl_x509name.c @@ -9,14 +9,6 @@ */ #include "ossl.h" -#define NewX509Name(klass) \ - TypedData_Wrap_Struct((klass), &ossl_x509name_type, 0) -#define SetX509Name(obj, name) do { \ - if (!(name)) { \ - ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \ - } \ - RTYPEDDATA_DATA(obj) = (name); \ -} while (0) #define GetX509Name(obj, name) do { \ TypedData_Get_Struct((obj), X509_NAME, &ossl_x509name_type, (name)); \ if (!(name)) { \ @@ -49,6 +41,12 @@ static const rb_data_type_t ossl_x509name_type = { 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; +static VALUE +ossl_x509name_alloc(VALUE klass) +{ + return TypedData_Wrap_Struct(klass, &ossl_x509name_type, NULL); +} + /* * Public */ @@ -58,12 +56,12 @@ ossl_x509name_new(const X509_NAME *name) X509_NAME *new; VALUE obj; - obj = NewX509Name(cX509Name); + obj = ossl_x509name_alloc(cX509Name); /* OpenSSL 1.1.1 takes a non-const pointer */ new = X509_NAME_dup((X509_NAME *)name); if (!new) ossl_raise(eX509NameError, "X509_NAME_dup"); - SetX509Name(obj, new); + RTYPEDDATA_DATA(obj) = new; return obj; } @@ -81,21 +79,6 @@ GetX509NamePtr(VALUE obj) /* * Private */ -static VALUE -ossl_x509name_alloc(VALUE klass) -{ - X509_NAME *name; - VALUE obj; - - obj = NewX509Name(klass); - if (!(name = X509_NAME_new())) { - ossl_raise(eX509NameError, NULL); - } - SetX509Name(obj, name); - - return obj; -} - static ID id_aref; static VALUE ossl_x509name_add_entry(int, VALUE*, VALUE); #define rb_aref(obj, key) rb_funcall((obj), id_aref, 1, (key)) @@ -141,35 +124,34 @@ ossl_x509name_init_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, args)) static VALUE ossl_x509name_initialize(int argc, VALUE *argv, VALUE self) { - X509_NAME *name; - VALUE arg, template; - - GetX509Name(self, name); - if (rb_scan_args(argc, argv, "02", &arg, &template) == 0) { - return self; - } - else { - VALUE tmp = rb_check_array_type(arg); - if (!NIL_P(tmp)) { - VALUE args; - if(NIL_P(template)) template = OBJECT_TYPE_TEMPLATE; - args = rb_ary_new3(2, self, template); - rb_block_call(tmp, rb_intern("each"), 0, 0, ossl_x509name_init_i, args); - } - else{ - const unsigned char *p; - VALUE str = ossl_to_der_if_possible(arg); - X509_NAME *x; - StringValue(str); - p = (unsigned char *)RSTRING_PTR(str); - x = d2i_X509_NAME(&name, &p, RSTRING_LEN(str)); - DATA_PTR(self) = name; - if(!x){ - ossl_raise(eX509NameError, NULL); - } + VALUE arg, template, tmp = Qnil; + + rb_scan_args(argc, argv, "02", &arg, &template); + ossl_want_uninitialized(self, &ossl_x509name_type); + + if (argc == 0 || !NIL_P((tmp = rb_check_array_type(arg)))) { + X509_NAME *name = X509_NAME_new(); + if (!name) + ossl_raise(eX509NameError, "X509_NAME_new"); + RTYPEDDATA_DATA(self) = name; + + if (argc > 0) { + if (NIL_P(template)) + template = OBJECT_TYPE_TEMPLATE; + rb_block_call(tmp, rb_intern("each"), 0, 0, ossl_x509name_init_i, + rb_ary_new_from_args(2, self, template)); } + return self; } + VALUE str = ossl_to_der_if_possible(arg); + StringValue(str); + const unsigned char *p = (unsigned char *)RSTRING_PTR(str); + X509_NAME *name = d2i_X509_NAME(NULL, &p, RSTRING_LEN(str)); + if (!name) + ossl_raise(eX509NameError, "d2i_X509_NAME"); + RTYPEDDATA_DATA(self) = name; + return self; } @@ -177,18 +159,15 @@ ossl_x509name_initialize(int argc, VALUE *argv, VALUE self) static VALUE ossl_x509name_initialize_copy(VALUE self, VALUE other) { - X509_NAME *name, *name_other, *name_new; + X509_NAME *name_other, *name_new; - rb_check_frozen(self); - GetX509Name(self, name); + ossl_want_uninitialized(self, &ossl_x509name_type); GetX509Name(other, name_other); name_new = X509_NAME_dup(name_other); if (!name_new) ossl_raise(eX509NameError, "X509_NAME_dup"); - - SetX509Name(self, name_new); - X509_NAME_free(name); + RTYPEDDATA_DATA(self) = name_new; return self; } diff --git a/ext/openssl/ossl_x509req.c b/ext/openssl/ossl_x509req.c index ad5dd0803..fd4f58888 100644 --- a/ext/openssl/ossl_x509req.c +++ b/ext/openssl/ossl_x509req.c @@ -9,14 +9,6 @@ */ #include "ossl.h" -#define NewX509Req(klass) \ - TypedData_Wrap_Struct((klass), &ossl_x509req_type, 0) -#define SetX509Req(obj, req) do { \ - if (!(req)) { \ - ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \ - } \ - RTYPEDDATA_DATA(obj) = (req); \ -} while (0) #define GetX509Req(obj, req) do { \ TypedData_Get_Struct((obj), X509_REQ, &ossl_x509req_type, (req)); \ if (!(req)) { \ @@ -63,27 +55,23 @@ GetX509ReqPtr(VALUE obj) static VALUE ossl_x509req_alloc(VALUE klass) { - X509_REQ *req; - VALUE obj; - - obj = NewX509Req(klass); - if (!(req = X509_REQ_new())) { - ossl_raise(eX509ReqError, NULL); - } - SetX509Req(obj, req); - - return obj; + return TypedData_Wrap_Struct(klass, &ossl_x509req_type, NULL); } static VALUE ossl_x509req_initialize(int argc, VALUE *argv, VALUE self) { BIO *in; - X509_REQ *req, *req_orig = RTYPEDDATA_DATA(self); + X509_REQ *req; VALUE arg; - rb_check_frozen(self); - if (rb_scan_args(argc, argv, "01", &arg) == 0) { + rb_scan_args(argc, argv, "01", &arg); + ossl_want_uninitialized(self, &ossl_x509req_type); + if (argc == 0) { + req = X509_REQ_new(); + if (!req) + ossl_raise(eX509ReqError, "X509_REQ_new"); + RTYPEDDATA_DATA(self) = req; return self; } arg = ossl_to_der_if_possible(arg); @@ -98,7 +86,6 @@ ossl_x509req_initialize(int argc, VALUE *argv, VALUE self) ossl_raise(eX509ReqError, "PEM_read_bio_X509_REQ"); RTYPEDDATA_DATA(self) = req; - X509_REQ_free(req_orig); return self; } @@ -107,17 +94,14 @@ ossl_x509req_initialize(int argc, VALUE *argv, VALUE self) static VALUE ossl_x509req_copy(VALUE self, VALUE other) { - X509_REQ *a, *b, *req; + X509_REQ *b, *req; - rb_check_frozen(self); - if (self == other) return self; - GetX509Req(self, a); + ossl_want_uninitialized(self, &ossl_x509req_type); GetX509Req(other, b); if (!(req = X509_REQ_dup(b))) { ossl_raise(eX509ReqError, NULL); } - X509_REQ_free(a); - DATA_PTR(self) = req; + RTYPEDDATA_DATA(self) = req; return self; } diff --git a/ext/openssl/ossl_x509revoked.c b/ext/openssl/ossl_x509revoked.c index 0151961e9..5eff36957 100644 --- a/ext/openssl/ossl_x509revoked.c +++ b/ext/openssl/ossl_x509revoked.c @@ -9,14 +9,6 @@ */ #include "ossl.h" -#define NewX509Rev(klass) \ - TypedData_Wrap_Struct((klass), &ossl_x509rev_type, 0) -#define SetX509Rev(obj, rev) do { \ - if (!(rev)) { \ - ossl_raise(rb_eRuntimeError, "REV wasn't initialized!"); \ - } \ - RTYPEDDATA_DATA(obj) = (rev); \ -} while (0) #define GetX509Rev(obj, rev) do { \ TypedData_Get_Struct((obj), X509_REVOKED, &ossl_x509rev_type, (rev)); \ if (!(rev)) { \ @@ -44,6 +36,12 @@ static const rb_data_type_t ossl_x509rev_type = { 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; +static VALUE +ossl_x509revoked_alloc(VALUE klass) +{ + return TypedData_Wrap_Struct(klass, &ossl_x509rev_type, NULL); +} + /* * PUBLIC */ @@ -53,12 +51,12 @@ ossl_x509revoked_new(const X509_REVOKED *rev) X509_REVOKED *new; VALUE obj; - obj = NewX509Rev(cX509Rev); + obj = ossl_x509revoked_alloc(cX509Rev); /* OpenSSL 1.1.1 takes a non-const pointer */ new = X509_REVOKED_dup((X509_REVOKED *)rev); if (!new) ossl_raise(eX509RevError, "X509_REVOKED_dup"); - SetX509Rev(obj, new); + RTYPEDDATA_DATA(obj) = new; return obj; } @@ -76,28 +74,20 @@ DupX509RevokedPtr(VALUE obj) return new; } -/* - * PRIVATE - */ static VALUE -ossl_x509revoked_alloc(VALUE klass) +ossl_x509revoked_initialize(int argc, VALUE *argv, VALUE self) { X509_REVOKED *rev; - VALUE obj; - obj = NewX509Rev(klass); - if (!(rev = X509_REVOKED_new())) { - ossl_raise(eX509RevError, NULL); - } - SetX509Rev(obj, rev); + if (argc != 0) + rb_warn("OpenSSL::X509::Revoked.new does not take any arguments"); + ossl_want_uninitialized(self, &ossl_x509rev_type); - return obj; -} + rev = X509_REVOKED_new(); + if (!rev) + ossl_raise(eX509RevError, "X509_REVOKED_new"); + RTYPEDDATA_DATA(self) = rev; -static VALUE -ossl_x509revoked_initialize(int argc, VALUE *argv, VALUE self) -{ - /* EMPTY */ return self; } @@ -105,18 +95,15 @@ ossl_x509revoked_initialize(int argc, VALUE *argv, VALUE self) static VALUE ossl_x509revoked_initialize_copy(VALUE self, VALUE other) { - X509_REVOKED *rev, *rev_other, *rev_new; + X509_REVOKED *rev_other, *rev_new; - rb_check_frozen(self); - GetX509Rev(self, rev); + ossl_want_uninitialized(self, &ossl_x509rev_type); GetX509Rev(other, rev_other); rev_new = X509_REVOKED_dup(rev_other); if (!rev_new) ossl_raise(eX509RevError, "X509_REVOKED_dup"); - - SetX509Rev(self, rev_new); - X509_REVOKED_free(rev); + RTYPEDDATA_DATA(self) = rev_new; return self; } diff --git a/ext/openssl/ossl_x509store.c b/ext/openssl/ossl_x509store.c index ee9f3d0e3..ac07ddf78 100644 --- a/ext/openssl/ossl_x509store.c +++ b/ext/openssl/ossl_x509store.c @@ -9,14 +9,6 @@ */ #include "ossl.h" -#define NewX509Store(klass) \ - TypedData_Wrap_Struct((klass), &ossl_x509store_type, 0) -#define SetX509Store(obj, st) do { \ - if (!(st)) { \ - ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \ - } \ - RTYPEDDATA_DATA(obj) = (st); \ -} while (0) #define GetX509Store(obj, st) do { \ TypedData_Get_Struct((obj), X509_STORE, &ossl_x509store_type, (st)); \ if (!(st)) { \ @@ -24,14 +16,6 @@ } \ } while (0) -#define NewX509StCtx(klass) \ - TypedData_Wrap_Struct((klass), &ossl_x509stctx_type, 0) -#define SetX509StCtx(obj, ctx) do { \ - if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "STORE_CTX wasn't initialized!"); \ - } \ - RTYPEDDATA_DATA(obj) = (ctx); \ -} while (0) #define GetX509StCtx(obj, ctx) do { \ TypedData_Get_Struct((obj), X509_STORE_CTX, &ossl_x509stctx_type, (ctx)); \ if (!(ctx)) { \ @@ -183,15 +167,7 @@ x509store_verify_cb(int ok, X509_STORE_CTX *ctx) static VALUE ossl_x509store_alloc(VALUE klass) { - X509_STORE *store; - VALUE obj; - - obj = NewX509Store(klass); - if ((store = X509_STORE_new()) == NULL) - ossl_raise(eX509StoreError, "X509_STORE_new"); - SetX509Store(obj, store); - - return obj; + return TypedData_Wrap_Struct(klass, &ossl_x509store_type, NULL); } /* @@ -223,9 +199,14 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self) { X509_STORE *store; - GetX509Store(self, store); if (argc != 0) rb_warn("OpenSSL::X509::Store.new does not take any arguments"); + ossl_want_uninitialized(self, &ossl_x509store_type); + + store = X509_STORE_new(); + if (!store) + ossl_raise(eX509StoreError, "X509_STORE_new"); + RTYPEDDATA_DATA(self) = store; X509_STORE_set_verify_cb(store, x509store_verify_cb); ossl_x509store_set_vfy_cb(self, Qnil); @@ -622,26 +603,13 @@ static const rb_data_type_t ossl_x509stctx_type = { static VALUE ossl_x509stctx_alloc(VALUE klass) { - X509_STORE_CTX *ctx; - VALUE obj; - - obj = NewX509StCtx(klass); - if ((ctx = X509_STORE_CTX_new()) == NULL) - ossl_raise(eX509StoreError, "X509_STORE_CTX_new"); - SetX509StCtx(obj, ctx); - - return obj; + return TypedData_Wrap_Struct(klass, &ossl_x509stctx_type, NULL); } static VALUE ossl_x509stctx_new(X509_STORE_CTX *ctx) { - VALUE obj; - - obj = NewX509StCtx(cX509StoreContext); - SetX509StCtx(obj, ctx); - - return obj; + return TypedData_Wrap_Struct(cX509StoreContext, &ossl_x509stctx_type, ctx); } static VALUE ossl_x509stctx_set_flags(VALUE, VALUE); @@ -665,7 +633,13 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self) int state; rb_scan_args(argc, argv, "12", &store, &cert, &chain); - GetX509StCtx(self, ctx); + ossl_want_uninitialized(self, &ossl_x509stctx_type); + + ctx = X509_STORE_CTX_new(); + if (!ctx) + ossl_raise(eX509StoreError, "X509_STORE_CTX_new"); + RTYPEDDATA_DATA(self) = ctx; + GetX509Store(store, x509st); if (!NIL_P(cert)) x509 = DupX509CertPtr(cert); /* NEED TO DUP */ From 4cbe86fd1e0b93aad8254580539e8612927298a5 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Sat, 6 Dec 2025 23:02:30 +0900 Subject: [PATCH 7/9] ts: allocate OpenSSL objects in #initialize{,_copy} --- ext/openssl/ossl_ts.c | 98 +++++++++++++------------------------------ 1 file changed, 29 insertions(+), 69 deletions(-) diff --git a/ext/openssl/ossl_ts.c b/ext/openssl/ossl_ts.c index 317f7786a..bddece098 100644 --- a/ext/openssl/ossl_ts.c +++ b/ext/openssl/ossl_ts.c @@ -11,14 +11,6 @@ #ifndef OPENSSL_NO_TS -#define NewTSRequest(klass) \ - TypedData_Wrap_Struct((klass), &ossl_ts_req_type, 0) -#define SetTSRequest(obj, req) do { \ - if (!(req)) { \ - ossl_raise(rb_eRuntimeError, "TS_REQ wasn't initialized."); \ - } \ - RTYPEDDATA_DATA(obj) = (req); \ -} while (0) #define GetTSRequest(obj, req) do { \ TypedData_Get_Struct((obj), TS_REQ, &ossl_ts_req_type, (req)); \ if (!(req)) { \ @@ -26,14 +18,6 @@ } \ } while (0) -#define NewTSResponse(klass) \ - TypedData_Wrap_Struct((klass), &ossl_ts_resp_type, 0) -#define SetTSResponse(obj, resp) do { \ - if (!(resp)) { \ - ossl_raise(rb_eRuntimeError, "TS_RESP wasn't initialized."); \ - } \ - RTYPEDDATA_DATA(obj) = (resp); \ -} while (0) #define GetTSResponse(obj, resp) do { \ TypedData_Get_Struct((obj), TS_RESP, &ossl_ts_resp_type, (resp)); \ if (!(resp)) { \ @@ -41,14 +25,6 @@ } \ } while (0) -#define NewTSTokenInfo(klass) \ - TypedData_Wrap_Struct((klass), &ossl_ts_token_info_type, 0) -#define SetTSTokenInfo(obj, info) do { \ - if (!(info)) { \ - ossl_raise(rb_eRuntimeError, "TS_TST_INFO wasn't initialized."); \ - } \ - RTYPEDDATA_DATA(obj) = (info); \ -} while (0) #define GetTSTokenInfo(obj, info) do { \ TypedData_Get_Struct((obj), TS_TST_INFO, &ossl_ts_token_info_type, (info)); \ if (!(info)) { \ @@ -141,19 +117,7 @@ obj_to_asn1obj_i(VALUE obj) static VALUE ossl_ts_req_alloc(VALUE klass) { - TS_REQ *req; - VALUE obj; - - obj = NewTSRequest(klass); - if (!(req = TS_REQ_new())) - ossl_raise(eTimestampError, NULL); - SetTSRequest(obj, req); - - /* Defaults */ - TS_REQ_set_version(req, 1); - TS_REQ_set_cert_req(req, 1); - - return obj; + return TypedData_Wrap_Struct(klass, &ossl_ts_req_type, NULL); } /* @@ -168,11 +132,24 @@ ossl_ts_req_alloc(VALUE klass) static VALUE ossl_ts_req_initialize(int argc, VALUE *argv, VALUE self) { - TS_REQ *req, *req_orig = DATA_PTR(self); + TS_REQ *req; BIO *in; VALUE arg; - if(rb_scan_args(argc, argv, "01", &arg) == 0) { + rb_scan_args(argc, argv, "01", &arg); + ossl_want_uninitialized(self, &ossl_ts_req_type); + if (argc == 0) { + req = TS_REQ_new(); + if (!req) + ossl_raise(eTimestampError, "TS_REQ_new"); + RTYPEDDATA_DATA(self) = req; + + /* Defaults */ + if (!TS_REQ_set_version(req, 1)) + ossl_raise(eTimestampError, "TS_REQ_set_version"); + if (!TS_REQ_set_cert_req(req, 1)) + ossl_raise(eTimestampError, "TS_REQ_set_cert_req"); + return self; } @@ -184,7 +161,6 @@ ossl_ts_req_initialize(int argc, VALUE *argv, VALUE self) ossl_raise(eTimestampError, "Error when decoding the timestamp request"); } - TS_REQ_free(req_orig); RTYPEDDATA_DATA(self) = req; return self; @@ -499,15 +475,7 @@ ossl_ts_req_to_text(VALUE self) static VALUE ossl_ts_resp_alloc(VALUE klass) { - TS_RESP *resp; - VALUE obj; - - obj = NewTSResponse(klass); - if (!(resp = TS_RESP_new())) - ossl_raise(eTimestampError, NULL); - SetTSResponse(obj, resp); - - return obj; + return TypedData_Wrap_Struct(klass, &ossl_ts_resp_type, NULL); } /* @@ -523,9 +491,10 @@ ossl_ts_resp_alloc(VALUE klass) static VALUE ossl_ts_resp_initialize(VALUE self, VALUE der) { - TS_RESP *resp, *resp_orig = DATA_PTR(self); + TS_RESP *resp; BIO *in; + ossl_want_uninitialized(self, &ossl_ts_resp_type); der = ossl_to_der_if_possible(der); in = ossl_obj2bio(&der); resp = d2i_TS_RESP_bio(in, NULL); @@ -534,7 +503,6 @@ ossl_ts_resp_initialize(VALUE self, VALUE der) ossl_raise(eTimestampError, "Error when decoding the timestamp response"); } - TS_RESP_free(resp_orig); RTYPEDDATA_DATA(self) = resp; return self; @@ -667,6 +635,8 @@ ossl_ts_resp_get_token(VALUE self) return ossl_pkcs7_new(p7); } +static VALUE ossl_ts_token_info_alloc(VALUE klass); + /* * Get the response's token info if present. * @@ -684,12 +654,10 @@ ossl_ts_resp_get_token_info(VALUE self) if (!(info = TS_RESP_get_tst_info(resp))) return Qnil; - obj = NewTSTokenInfo(cTimestampTokenInfo); - + obj = ossl_ts_token_info_alloc(cTimestampTokenInfo); if (!(copy = TS_TST_INFO_dup(info))) - ossl_raise(eTimestampError, NULL); - - SetTSTokenInfo(obj, copy); + ossl_raise(eTimestampError, "TS_TST_INFO_dup"); + RTYPEDDATA_DATA(obj) = copy; return obj; } @@ -854,15 +822,7 @@ ossl_ts_resp_verify(int argc, VALUE *argv, VALUE self) static VALUE ossl_ts_token_info_alloc(VALUE klass) { - TS_TST_INFO *info; - VALUE obj; - - obj = NewTSTokenInfo(klass); - if (!(info = TS_TST_INFO_new())) - ossl_raise(eTimestampError, NULL); - SetTSTokenInfo(obj, info); - - return obj; + return TypedData_Wrap_Struct(klass, &ossl_ts_token_info_type, NULL); } /* @@ -878,9 +838,10 @@ ossl_ts_token_info_alloc(VALUE klass) static VALUE ossl_ts_token_info_initialize(VALUE self, VALUE der) { - TS_TST_INFO *info, *info_orig = DATA_PTR(self); + TS_TST_INFO *info; BIO *in; + ossl_want_uninitialized(self, &ossl_ts_token_info_type); der = ossl_to_der_if_possible(der); in = ossl_obj2bio(&der); info = d2i_TS_TST_INFO_bio(in, NULL); @@ -889,7 +850,6 @@ ossl_ts_token_info_initialize(VALUE self, VALUE der) ossl_raise(eTimestampError, "Error when decoding the timestamp token info"); } - TS_TST_INFO_free(info_orig); RTYPEDDATA_DATA(self) = info; return self; @@ -1184,7 +1144,7 @@ ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request) const char * err_msg = NULL; int status = 0; - tsresp = NewTSResponse(cTimestampResponse); + tsresp = ossl_ts_resp_alloc(cTimestampResponse); tsa_cert = GetX509CertPtr(certificate); sign_key = GetPrivPKeyPtr(key); GetTSRequest(request, req); @@ -1281,7 +1241,7 @@ ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request) * information. */ ossl_clear_error(); - SetTSResponse(tsresp, response); + RTYPEDDATA_DATA(tsresp) = response; ret = tsresp; end: From 6bb2810f594d74b0adb510f57aa1cc9ff9edab21 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Sun, 7 Dec 2025 00:01:08 +0900 Subject: [PATCH 8/9] pkcs7: allocate OpenSSL objects in #initialize{,_copy} --- ext/openssl/ossl_pkcs7.c | 148 +++++++++++++++------------------------ 1 file changed, 57 insertions(+), 91 deletions(-) diff --git a/ext/openssl/ossl_pkcs7.c b/ext/openssl/ossl_pkcs7.c index 44e8cb305..aed950a5c 100644 --- a/ext/openssl/ossl_pkcs7.c +++ b/ext/openssl/ossl_pkcs7.c @@ -9,44 +9,18 @@ */ #include "ossl.h" -#define NewPKCS7(klass) \ - TypedData_Wrap_Struct((klass), &ossl_pkcs7_type, 0) -#define SetPKCS7(obj, pkcs7) do { \ - if (!(pkcs7)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \ - } \ - RTYPEDDATA_DATA(obj) = (pkcs7); \ -} while (0) #define GetPKCS7(obj, pkcs7) do { \ TypedData_Get_Struct((obj), PKCS7, &ossl_pkcs7_type, (pkcs7)); \ if (!(pkcs7)) { \ ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \ } \ } while (0) - -#define NewPKCS7si(klass) \ - TypedData_Wrap_Struct((klass), &ossl_pkcs7_signer_info_type, 0) -#define SetPKCS7si(obj, p7si) do { \ - if (!(p7si)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \ - } \ - RTYPEDDATA_DATA(obj) = (p7si); \ -} while (0) #define GetPKCS7si(obj, p7si) do { \ TypedData_Get_Struct((obj), PKCS7_SIGNER_INFO, &ossl_pkcs7_signer_info_type, (p7si)); \ if (!(p7si)) { \ ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \ } \ } while (0) - -#define NewPKCS7ri(klass) \ - TypedData_Wrap_Struct((klass), &ossl_pkcs7_recip_info_type, 0) -#define SetPKCS7ri(obj, p7ri) do { \ - if (!(p7ri)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \ - } \ - RTYPEDDATA_DATA(obj) = (p7ri); \ -} while (0) #define GetPKCS7ri(obj, p7ri) do { \ TypedData_Get_Struct((obj), PKCS7_RECIP_INFO, &ossl_pkcs7_recip_info_type, (p7ri)); \ if (!(p7ri)) { \ @@ -84,16 +58,22 @@ static const rb_data_type_t ossl_pkcs7_type = { 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; +static VALUE +ossl_pkcs7_alloc(VALUE klass) +{ + return TypedData_Wrap_Struct(klass, &ossl_pkcs7_type, NULL); +} + VALUE ossl_pkcs7_new(PKCS7 *p7) { PKCS7 *new; - VALUE obj = NewPKCS7(cPKCS7); + VALUE obj = ossl_pkcs7_alloc(cPKCS7); new = PKCS7_dup(p7); if (!new) ossl_raise(ePKCS7Error, "PKCS7_dup"); - SetPKCS7(obj, new); + RTYPEDDATA_DATA(obj) = new; return obj; } @@ -159,32 +139,36 @@ ossl_PKCS7_RECIP_INFO_dup(PKCS7_RECIP_INFO *ri) return ri_new; } +static VALUE ossl_pkcs7si_alloc(VALUE klass); + static VALUE ossl_pkcs7si_new(PKCS7_SIGNER_INFO *p7si) { PKCS7_SIGNER_INFO *p7si_new; VALUE obj; - obj = NewPKCS7si(cPKCS7Signer); + obj = ossl_pkcs7si_alloc(cPKCS7Signer); p7si_new = ossl_PKCS7_SIGNER_INFO_dup(p7si); if (!p7si_new) ossl_raise(ePKCS7Error, "ASN1_dup"); - SetPKCS7si(obj, p7si_new); + RTYPEDDATA_DATA(obj) = p7si_new; return obj; } +static VALUE ossl_pkcs7ri_alloc(VALUE klass); + static VALUE ossl_pkcs7ri_new(PKCS7_RECIP_INFO *p7ri) { PKCS7_RECIP_INFO *p7ri_new; VALUE obj; - obj = NewPKCS7ri(cPKCS7Recipient); + obj = ossl_pkcs7ri_alloc(cPKCS7Recipient); p7ri_new = ossl_PKCS7_RECIP_INFO_dup(p7ri); if (!p7ri_new) ossl_raise(ePKCS7Error,"ASN1_dup"); - SetPKCS7ri(obj, p7ri_new); + RTYPEDDATA_DATA(obj) = p7ri_new; return obj; } @@ -200,7 +184,7 @@ ossl_pkcs7_s_read_smime(VALUE klass, VALUE arg) PKCS7 *pkcs7; VALUE ret, data; - ret = NewPKCS7(cPKCS7); + ret = ossl_pkcs7_alloc(klass); in = ossl_obj2bio(&arg); out = NULL; pkcs7 = SMIME_read_PKCS7(in, &out); @@ -211,9 +195,9 @@ ossl_pkcs7_s_read_smime(VALUE klass, VALUE arg) PKCS7_free(pkcs7); ossl_raise(ePKCS7Error, "No content in PKCS7"); } + RTYPEDDATA_DATA(ret) = pkcs7; data = out ? ossl_membio2str(out) : Qnil; - SetPKCS7(ret, pkcs7); ossl_pkcs7_set_data(ret, data); ossl_pkcs7_set_err_string(ret, Qnil); @@ -275,7 +259,7 @@ ossl_pkcs7_s_sign(int argc, VALUE *argv, VALUE klass) x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ flg = NIL_P(flags) ? 0 : NUM2INT(flags); - ret = NewPKCS7(cPKCS7); + ret = ossl_pkcs7_alloc(klass); in = ossl_obj2bio(&data); if(NIL_P(certs)) x509s = NULL; else{ @@ -290,11 +274,12 @@ ossl_pkcs7_s_sign(int argc, VALUE *argv, VALUE klass) sk_X509_pop_free(x509s, X509_free); ossl_raise(ePKCS7Error, NULL); } - SetPKCS7(ret, pkcs7); - ossl_pkcs7_set_data(ret, data); - ossl_pkcs7_set_err_string(ret, Qnil); BIO_free(in); sk_X509_pop_free(x509s, X509_free); + RTYPEDDATA_DATA(ret) = pkcs7; + + ossl_pkcs7_set_data(ret, data); + ossl_pkcs7_set_err_string(ret, Qnil); return ret; } @@ -329,7 +314,7 @@ ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass) } ciph = ossl_evp_cipher_fetch(cipher, &cipher_holder); flg = NIL_P(flags) ? 0 : NUM2INT(flags); - ret = NewPKCS7(cPKCS7); + ret = ossl_pkcs7_alloc(klass); in = ossl_obj2bio(&data); x509s = ossl_protect_x509_ary2sk(certs, &status); if(status){ @@ -342,29 +327,15 @@ ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass) ossl_raise(ePKCS7Error, NULL); } BIO_free(in); - SetPKCS7(ret, p7); + sk_X509_pop_free(x509s, X509_free); + RTYPEDDATA_DATA(ret) = p7; + ossl_pkcs7_set_data(ret, data); rb_ivar_set(ret, id_cipher_holder, cipher_holder); - sk_X509_pop_free(x509s, X509_free); return ret; } -static VALUE -ossl_pkcs7_alloc(VALUE klass) -{ - PKCS7 *pkcs7; - VALUE obj; - - obj = NewPKCS7(klass); - if (!(pkcs7 = PKCS7_new())) { - ossl_raise(ePKCS7Error, NULL); - } - SetPKCS7(obj, pkcs7); - - return obj; -} - /* * call-seq: * PKCS7.new => pkcs7 @@ -375,12 +346,19 @@ ossl_pkcs7_alloc(VALUE klass) static VALUE ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self) { - PKCS7 *p7, *p7_orig = RTYPEDDATA_DATA(self); + PKCS7 *p7; BIO *in; VALUE arg; - if(rb_scan_args(argc, argv, "01", &arg) == 0) + rb_scan_args(argc, argv, "01", &arg); + ossl_want_uninitialized(self, &ossl_pkcs7_type); + if (argc == 0) { + p7 = PKCS7_new(); + if (!p7) + ossl_raise(ePKCS7Error, "PKCS7_new"); + RTYPEDDATA_DATA(self) = p7; return self; + } arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(&arg); p7 = d2i_PKCS7_bio(in, NULL); @@ -397,7 +375,6 @@ ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self) } RTYPEDDATA_DATA(self) = p7; - PKCS7_free(p7_orig); ossl_pkcs7_set_data(self, Qnil); ossl_pkcs7_set_err_string(self, Qnil); @@ -408,20 +385,15 @@ ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self) static VALUE ossl_pkcs7_copy(VALUE self, VALUE other) { - PKCS7 *a, *b, *pkcs7; + PKCS7 *b, *pkcs7; - rb_check_frozen(self); - if (self == other) return self; - - GetPKCS7(self, a); + ossl_want_uninitialized(self, &ossl_pkcs7_type); GetPKCS7(other, b); pkcs7 = PKCS7_dup(b); - if (!pkcs7) { - ossl_raise(ePKCS7Error, NULL); - } - DATA_PTR(self) = pkcs7; - PKCS7_free(a); + if (!pkcs7) + ossl_raise(ePKCS7Error, "PKCS7_dup"); + RTYPEDDATA_DATA(self) = pkcs7; return self; } @@ -954,16 +926,7 @@ ossl_pkcs7_to_pem(VALUE self) static VALUE ossl_pkcs7si_alloc(VALUE klass) { - PKCS7_SIGNER_INFO *p7si; - VALUE obj; - - obj = NewPKCS7si(klass); - if (!(p7si = PKCS7_SIGNER_INFO_new())) { - ossl_raise(ePKCS7Error, NULL); - } - SetPKCS7si(obj, p7si); - - return obj; + return TypedData_Wrap_Struct(klass, &ossl_pkcs7_signer_info_type, NULL); } static VALUE @@ -975,10 +938,16 @@ ossl_pkcs7si_initialize(VALUE self, VALUE cert, VALUE key, VALUE digest) const EVP_MD *md; VALUE md_holder; + ossl_want_uninitialized(self, &ossl_pkcs7_signer_info_type); pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ md = ossl_evp_md_fetch(digest, &md_holder); - GetPKCS7si(self, p7si); + + p7si = PKCS7_SIGNER_INFO_new(); + if (!p7si) + ossl_raise(ePKCS7Error, "PKCS7_SIGNER_INFO_new"); + RTYPEDDATA_DATA(self) = p7si; + if (PKCS7_SIGNER_INFO_set(p7si, x509, pkey, md) <= 0) ossl_raise(ePKCS7Error, "PKCS7_SIGNER_INFO_set"); rb_ivar_set(self, id_md_holder, md_holder); @@ -1035,16 +1004,7 @@ ossl_pkcs7si_get_signed_time(VALUE self) static VALUE ossl_pkcs7ri_alloc(VALUE klass) { - PKCS7_RECIP_INFO *p7ri; - VALUE obj; - - obj = NewPKCS7ri(klass); - if (!(p7ri = PKCS7_RECIP_INFO_new())) { - ossl_raise(ePKCS7Error, NULL); - } - SetPKCS7ri(obj, p7ri); - - return obj; + return TypedData_Wrap_Struct(klass, &ossl_pkcs7_recip_info_type, NULL); } static VALUE @@ -1053,8 +1013,14 @@ ossl_pkcs7ri_initialize(VALUE self, VALUE cert) PKCS7_RECIP_INFO *p7ri; X509 *x509; + ossl_want_uninitialized(self, &ossl_pkcs7_recip_info_type); x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ - GetPKCS7ri(self, p7ri); + + p7ri = PKCS7_RECIP_INFO_new(); + if (!p7ri) + ossl_raise(ePKCS7Error, "PKCS7_RECIP_INFO_new"); + RTYPEDDATA_DATA(self) = p7ri; + if (PKCS7_RECIP_INFO_set(p7ri, x509) <= 0) { ossl_raise(ePKCS7Error, NULL); } From f9026106a30f40662dbb25e3e69c60a410d5d3a3 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Sun, 7 Dec 2025 00:16:03 +0900 Subject: [PATCH 9/9] ns_spki: allocate OpenSSL objects in #initialize{,_copy} --- ext/openssl/ossl_ns_spki.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/ext/openssl/ossl_ns_spki.c b/ext/openssl/ossl_ns_spki.c index 8440c2ee8..eb9933948 100644 --- a/ext/openssl/ossl_ns_spki.c +++ b/ext/openssl/ossl_ns_spki.c @@ -9,14 +9,6 @@ */ #include "ossl.h" -#define NewSPKI(klass) \ - TypedData_Wrap_Struct((klass), &ossl_netscape_spki_type, 0) -#define SetSPKI(obj, spki) do { \ - if (!(spki)) { \ - ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \ - } \ - RTYPEDDATA_DATA(obj) = (spki); \ -} while (0) #define GetSPKI(obj, spki) do { \ TypedData_Get_Struct((obj), NETSCAPE_SPKI, &ossl_netscape_spki_type, (spki)); \ if (!(spki)) { \ @@ -56,16 +48,7 @@ static const rb_data_type_t ossl_netscape_spki_type = { static VALUE ossl_spki_alloc(VALUE klass) { - NETSCAPE_SPKI *spki; - VALUE obj; - - obj = NewSPKI(klass); - if (!(spki = NETSCAPE_SPKI_new())) { - ossl_raise(eSPKIError, NULL); - } - SetSPKI(obj, spki); - - return obj; + return TypedData_Wrap_Struct(klass, &ossl_netscape_spki_type, NULL); } /* @@ -82,7 +65,13 @@ ossl_spki_initialize(int argc, VALUE *argv, VALUE self) VALUE buffer; const unsigned char *p; - if (rb_scan_args(argc, argv, "01", &buffer) == 0) { + rb_scan_args(argc, argv, "01", &buffer); + ossl_want_uninitialized(self, &ossl_netscape_spki_type); + if (argc == 0) { + spki = NETSCAPE_SPKI_new(); + if (!spki) + ossl_raise(eSPKIError, "NETSCAPE_SPKI_new"); + RTYPEDDATA_DATA(self) = spki; return self; } StringValue(buffer); @@ -93,8 +82,7 @@ ossl_spki_initialize(int argc, VALUE *argv, VALUE self) ossl_raise(eSPKIError, NULL); } } - NETSCAPE_SPKI_free(DATA_PTR(self)); - SetSPKI(self, spki); + RTYPEDDATA_DATA(self) = spki; return self; }