diff options
-rw-r--r-- | ext/openssl/ossl.h | 3 | ||||
-rw-r--r-- | ext/openssl/ossl_bn.c | 2 | ||||
-rw-r--r-- | ext/openssl/ossl_cipher.c | 46 | ||||
-rw-r--r-- | ext/openssl/ossl_digest.c | 18 | ||||
-rw-r--r-- | ext/openssl/ossl_engine.c | 18 | ||||
-rw-r--r-- | ext/openssl/ossl_hmac.c | 14 | ||||
-rw-r--r-- | ext/openssl/ossl_ns_spki.c | 19 | ||||
-rw-r--r-- | ext/openssl/ossl_ocsp.c | 72 | ||||
-rw-r--r-- | ext/openssl/ossl_pkcs12.c | 18 | ||||
-rw-r--r-- | ext/openssl/ossl_pkcs7.c | 54 | ||||
-rw-r--r-- | ext/openssl/ossl_pkey.c | 14 | ||||
-rw-r--r-- | ext/openssl/ossl_pkey.h | 5 | ||||
-rw-r--r-- | ext/openssl/ossl_pkey_ec.c | 40 | ||||
-rw-r--r-- | ext/openssl/ossl_ssl.c | 75 | ||||
-rw-r--r-- | ext/openssl/ossl_ssl.h | 8 | ||||
-rw-r--r-- | ext/openssl/ossl_ssl_session.c | 37 | ||||
-rw-r--r-- | ext/openssl/ossl_x509attr.c | 18 | ||||
-rw-r--r-- | ext/openssl/ossl_x509cert.c | 18 | ||||
-rw-r--r-- | ext/openssl/ossl_x509crl.c | 18 | ||||
-rw-r--r-- | ext/openssl/ossl_x509ext.c | 32 | ||||
-rw-r--r-- | ext/openssl/ossl_x509name.c | 18 | ||||
-rw-r--r-- | ext/openssl/ossl_x509req.c | 18 | ||||
-rw-r--r-- | ext/openssl/ossl_x509revoked.c | 18 | ||||
-rw-r--r-- | ext/openssl/ossl_x509store.c | 37 |
24 files changed, 507 insertions, 113 deletions
diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h index c843c06f..a53f0f41 100644 --- a/ext/openssl/ossl.h +++ b/ext/openssl/ossl.h @@ -64,6 +64,9 @@ extern "C" { #include <openssl/rand.h> #include <openssl/conf.h> #include <openssl/conf_api.h> +#if !defined(_WIN32) +# include <openssl/crypto.h> +#endif #undef X509_NAME #undef PKCS7_SIGNER_INFO #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_EVP_CIPHER_CTX_ENGINE) diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c index 0af7d639..58796fe2 100644 --- a/ext/openssl/ossl_bn.c +++ b/ext/openssl/ossl_bn.c @@ -45,7 +45,7 @@ ossl_bn_size(const void *ptr) static const rb_data_type_t ossl_bn_type = { "OpenSSL/BN", {0, ossl_bn_free, ossl_bn_size,}, - NULL, NULL, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, }; diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c index 0efadd19..08fdacfb 100644 --- a/ext/openssl/ossl_cipher.c +++ b/ext/openssl/ossl_cipher.c @@ -43,7 +43,7 @@ static size_t ossl_cipher_memsize(const void *ptr); static const rb_data_type_t ossl_cipher_type = { "OpenSSL/Cipher", {0, ossl_cipher_free, ossl_cipher_memsize,}, - NULL, NULL, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, }; @@ -346,6 +346,33 @@ ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self) return Qnil; } +static int +ossl_cipher_update_long(EVP_CIPHER_CTX *ctx, unsigned char *out, long *out_len_ptr, + const unsigned char *in, long in_len) +{ + int out_part_len; + long out_len = 0; +#define UPDATE_LENGTH_LIMIT INT_MAX + +#if SIZEOF_LONG > UPDATE_LENGTH_LIMIT + if (in_len > UPDATE_LENGTH_LIMIT) { + const int in_part_len = (UPDATE_LENGTH_LIMIT / 2 + 1) & ~1; + do { + if (!EVP_CipherUpdate(ctx, out ? (out + out_len) : 0, + &out_part_len, in, in_part_len)) + return 0; + out_len += out_part_len; + in += in_part_len; + } while ((in_len -= in_part_len) > UPDATE_LENGTH_LIMIT); + } +#endif + if (!EVP_CipherUpdate(ctx, out ? (out + out_len) : 0, + &out_part_len, in, (int)in_len)) + return 0; + if (out_len_ptr) *out_len_ptr = out_len += out_part_len; + return 1; +} + /* * call-seq: * cipher.update(data [, buffer]) -> string or buffer @@ -364,17 +391,21 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self) { EVP_CIPHER_CTX *ctx; unsigned char *in; - int in_len, out_len; + long in_len, out_len; VALUE data, str; rb_scan_args(argc, argv, "11", &data, &str); StringValue(data); in = (unsigned char *)RSTRING_PTR(data); - if ((in_len = RSTRING_LENINT(data)) == 0) + if ((in_len = RSTRING_LEN(data)) == 0) ossl_raise(rb_eArgError, "data must not be empty"); GetCipher(self, ctx); out_len = in_len+EVP_CIPHER_CTX_block_size(ctx); + if (out_len <= 0) { + ossl_raise(rb_eRangeError, + "data too big to make output buffer: %ld bytes", in_len); + } if (NIL_P(str)) { str = rb_str_new(0, out_len); @@ -383,7 +414,7 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self) rb_str_resize(str, out_len); } - if (!EVP_CipherUpdate(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len)) + if (!ossl_cipher_update_long(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len)) ossl_raise(eCipherError, NULL); assert(out_len < RSTRING_LEN(str)); rb_str_set_len(str, out_len); @@ -523,17 +554,16 @@ ossl_cipher_set_auth_data(VALUE self, VALUE data) { EVP_CIPHER_CTX *ctx; unsigned char *in; - int in_len; - int out_len; + long in_len, out_len; StringValue(data); in = (unsigned char *) RSTRING_PTR(data); - in_len = RSTRING_LENINT(data); + in_len = RSTRING_LEN(data); GetCipher(self, ctx); - if (!EVP_CipherUpdate(ctx, NULL, &out_len, in, in_len)) + if (!ossl_cipher_update_long(ctx, NULL, &out_len, in, in_len)) ossl_raise(eCipherError, "couldn't set additional authenticated data"); return data; diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c index bf618c83..6ce5316f 100644 --- a/ext/openssl/ossl_digest.c +++ b/ext/openssl/ossl_digest.c @@ -11,7 +11,7 @@ #include "ossl.h" #define GetDigest(obj, ctx) do { \ - Data_Get_Struct((obj), EVP_MD_CTX, (ctx)); \ + TypedData_Get_Struct((obj), EVP_MD_CTX, &ossl_digest_type, (ctx)); \ if (!(ctx)) { \ ossl_raise(rb_eRuntimeError, "Digest CTX wasn't initialized!"); \ } \ @@ -29,6 +29,20 @@ VALUE eDigestError; static VALUE ossl_digest_alloc(VALUE klass); +static void +ossl_digest_free(void *ctx) +{ + EVP_MD_CTX_destroy(ctx); +} + +static const rb_data_type_t ossl_digest_type = { + "OpenSSL/Digest", + { + 0, ossl_digest_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + /* * Public */ @@ -87,7 +101,7 @@ ossl_digest_alloc(VALUE klass) ctx = EVP_MD_CTX_create(); if (ctx == NULL) ossl_raise(rb_eRuntimeError, "EVP_MD_CTX_create() failed"); - obj = Data_Wrap_Struct(klass, 0, EVP_MD_CTX_destroy, ctx); + obj = TypedData_Wrap_Struct(klass, &ossl_digest_type, ctx); return obj; } diff --git a/ext/openssl/ossl_engine.c b/ext/openssl/ossl_engine.c index 96bce5e2..04b5879b 100644 --- a/ext/openssl/ossl_engine.c +++ b/ext/openssl/ossl_engine.c @@ -16,10 +16,10 @@ if (!(engine)) { \ ossl_raise(rb_eRuntimeError, "ENGINE wasn't initialized."); \ } \ - (obj) = Data_Wrap_Struct((klass), 0, ENGINE_free, (engine)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_engine_type, (engine)); \ } while(0) #define GetEngine(obj, engine) do { \ - Data_Get_Struct((obj), ENGINE, (engine)); \ + TypedData_Get_Struct((obj), ENGINE, &ossl_engine_type, (engine)); \ if (!(engine)) { \ ossl_raise(rb_eRuntimeError, "ENGINE wasn't initialized."); \ } \ @@ -57,6 +57,20 @@ do{\ }\ }while(0) +static void +ossl_engine_free(void *engine) +{ + ENGINE_free(engine); +} + +static const rb_data_type_t ossl_engine_type = { + "OpenSSL/Engine", + { + 0, ossl_engine_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + /* Document-method: OpenSSL::Engine.load * * call-seq: diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c index 516e3ed8..74fc962b 100644 --- a/ext/openssl/ossl_hmac.c +++ b/ext/openssl/ossl_hmac.c @@ -13,9 +13,9 @@ #include "ossl.h" #define MakeHMAC(obj, klass, ctx) \ - (obj) = Data_Make_Struct((klass), HMAC_CTX, 0, ossl_hmac_free, (ctx)) + (obj) = TypedData_Make_Struct((klass), HMAC_CTX, &ossl_hmac_type, (ctx)) #define GetHMAC(obj, ctx) do { \ - Data_Get_Struct((obj), HMAC_CTX, (ctx)); \ + TypedData_Get_Struct((obj), HMAC_CTX, &ossl_hmac_type, (ctx)); \ if (!(ctx)) { \ ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \ } \ @@ -39,12 +39,20 @@ VALUE eHMACError; * Private */ static void -ossl_hmac_free(HMAC_CTX *ctx) +ossl_hmac_free(void *ctx) { HMAC_CTX_cleanup(ctx); ruby_xfree(ctx); } +static const rb_data_type_t ossl_hmac_type = { + "OpenSSL/HMAC", + { + 0, ossl_hmac_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + static VALUE ossl_hmac_alloc(VALUE klass) { diff --git a/ext/openssl/ossl_ns_spki.c b/ext/openssl/ossl_ns_spki.c index 965bbe87..d2a52e6f 100644 --- a/ext/openssl/ossl_ns_spki.c +++ b/ext/openssl/ossl_ns_spki.c @@ -14,10 +14,10 @@ if (!(spki)) { \ ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \ } \ - (obj) = Data_Wrap_Struct((klass), 0, NETSCAPE_SPKI_free, (spki)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_netscape_spki_type, (spki)); \ } while (0) #define GetSPKI(obj, spki) do { \ - Data_Get_Struct((obj), NETSCAPE_SPKI, (spki)); \ + TypedData_Get_Struct((obj), NETSCAPE_SPKI, &ossl_netscape_spki_type, (spki)); \ if (!(spki)) { \ ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \ } \ @@ -37,6 +37,21 @@ VALUE eSPKIError; /* * Private functions */ + +static void +ossl_netscape_spki_free(void *spki) +{ + NETSCAPE_SPKI_free(spki); +} + +static const rb_data_type_t ossl_netscape_spki_type = { + "OpenSSL/NETSCAPE_SPKI", + { + 0, ossl_netscape_spki_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + static VALUE ossl_spki_alloc(VALUE klass) { diff --git a/ext/openssl/ossl_ocsp.c b/ext/openssl/ossl_ocsp.c index 9848ba27..dc31d79c 100644 --- a/ext/openssl/ossl_ocsp.c +++ b/ext/openssl/ossl_ocsp.c @@ -15,10 +15,10 @@ #define WrapOCSPReq(klass, obj, req) do { \ if(!(req)) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \ - (obj) = Data_Wrap_Struct((klass), 0, OCSP_REQUEST_free, (req)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_ocsp_request_type, (req)); \ } while (0) #define GetOCSPReq(obj, req) do { \ - Data_Get_Struct((obj), OCSP_REQUEST, (req)); \ + TypedData_Get_Struct((obj), OCSP_REQUEST, &ossl_ocsp_request_type, (req)); \ if(!(req)) ossl_raise(rb_eRuntimeError, "Request wasn't initialized!"); \ } while (0) #define SafeGetOCSPReq(obj, req) do { \ @@ -28,10 +28,10 @@ #define WrapOCSPRes(klass, obj, res) do { \ if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \ - (obj) = Data_Wrap_Struct((klass), 0, OCSP_RESPONSE_free, (res)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_ocsp_response_type, (res)); \ } while (0) #define GetOCSPRes(obj, res) do { \ - Data_Get_Struct((obj), OCSP_RESPONSE, (res)); \ + TypedData_Get_Struct((obj), OCSP_RESPONSE, &ossl_ocsp_response_type, (res)); \ if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \ } while (0) #define SafeGetOCSPRes(obj, res) do { \ @@ -41,10 +41,10 @@ #define WrapOCSPBasicRes(klass, obj, res) do { \ if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \ - (obj) = Data_Wrap_Struct((klass), 0, OCSP_BASICRESP_free, (res)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_ocsp_basicresp_type, (res)); \ } while (0) #define GetOCSPBasicRes(obj, res) do { \ - Data_Get_Struct((obj), OCSP_BASICRESP, (res)); \ + TypedData_Get_Struct((obj), OCSP_BASICRESP, &ossl_ocsp_basicresp_type, (res)); \ if(!(res)) ossl_raise(rb_eRuntimeError, "Response wasn't initialized!"); \ } while (0) #define SafeGetOCSPBasicRes(obj, res) do { \ @@ -54,10 +54,10 @@ #define WrapOCSPCertId(klass, obj, cid) do { \ if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \ - (obj) = Data_Wrap_Struct((klass), 0, OCSP_CERTID_free, (cid)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_ocsp_certid_type, (cid)); \ } while (0) #define GetOCSPCertId(obj, cid) do { \ - Data_Get_Struct((obj), OCSP_CERTID, (cid)); \ + TypedData_Get_Struct((obj), OCSP_CERTID, &ossl_ocsp_certid_type, (cid)); \ if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \ } while (0) #define SafeGetOCSPCertId(obj, cid) do { \ @@ -72,6 +72,62 @@ VALUE cOCSPRes; VALUE cOCSPBasicRes; VALUE cOCSPCertId; +static void +ossl_ocsp_request_free(void *ptr) +{ + OCSP_REQUEST_free(ptr); +} + +static const rb_data_type_t ossl_ocsp_request_type = { + "OpenSSL/OCSP/REQUEST", + { + 0, ossl_ocsp_request_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + +static void +ossl_ocsp_response_free(void *ptr) +{ + OCSP_RESPONSE_free(ptr); +} + +static const rb_data_type_t ossl_ocsp_response_type = { + "OpenSSL/OCSP/RESPONSE", + { + 0, ossl_ocsp_response_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + +static void +ossl_ocsp_basicresp_free(void *ptr) +{ + OCSP_BASICRESP_free(ptr); +} + +static const rb_data_type_t ossl_ocsp_basicresp_type = { + "OpenSSL/OCSP/BASICRESP", + { + 0, ossl_ocsp_basicresp_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + +static void +ossl_ocsp_certid_free(void *ptr) +{ + OCSP_CERTID_free(ptr); +} + +static const rb_data_type_t ossl_ocsp_certid_type = { + "OpenSSL/OCSP/CERTID", + { + 0, ossl_ocsp_certid_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + /* * Public */ diff --git a/ext/openssl/ossl_pkcs12.c b/ext/openssl/ossl_pkcs12.c index b3974cb7..53e0e619 100644 --- a/ext/openssl/ossl_pkcs12.c +++ b/ext/openssl/ossl_pkcs12.c @@ -7,11 +7,11 @@ #define WrapPKCS12(klass, obj, p12) do { \ if(!(p12)) ossl_raise(rb_eRuntimeError, "PKCS12 wasn't initialized."); \ - (obj) = Data_Wrap_Struct((klass), 0, PKCS12_free, (p12)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_pkcs12_type, (p12)); \ } while (0) #define GetPKCS12(obj, p12) do { \ - Data_Get_Struct((obj), PKCS12, (p12)); \ + TypedData_Get_Struct((obj), PKCS12, &ossl_pkcs12_type, (p12)); \ if(!(p12)) ossl_raise(rb_eRuntimeError, "PKCS12 wasn't initialized."); \ } while (0) @@ -36,6 +36,20 @@ VALUE ePKCS12Error; /* * Private */ +static void +ossl_pkcs12_free(void *ptr) +{ + PKCS12_free(ptr); +} + +static const rb_data_type_t ossl_pkcs12_type = { + "OpenSSL/PKCS12", + { + 0, ossl_pkcs12_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + static VALUE ossl_pkcs12_s_allocate(VALUE klass) { diff --git a/ext/openssl/ossl_pkcs7.c b/ext/openssl/ossl_pkcs7.c index f476807f..f4a5088e 100644 --- a/ext/openssl/ossl_pkcs7.c +++ b/ext/openssl/ossl_pkcs7.c @@ -14,10 +14,10 @@ if (!(pkcs7)) { \ ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \ } \ - (obj) = Data_Wrap_Struct((klass), 0, PKCS7_free, (pkcs7)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_pkcs7_type, (pkcs7)); \ } while (0) #define GetPKCS7(obj, pkcs7) do { \ - Data_Get_Struct((obj), PKCS7, (pkcs7)); \ + TypedData_Get_Struct((obj), PKCS7, &ossl_pkcs7_type, (pkcs7)); \ if (!(pkcs7)) { \ ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \ } \ @@ -31,10 +31,10 @@ if (!(p7si)) { \ ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \ } \ - (obj) = Data_Wrap_Struct((klass), 0, PKCS7_SIGNER_INFO_free, (p7si)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_pkcs7_signer_info_type, (p7si)); \ } while (0) #define GetPKCS7si(obj, p7si) do { \ - Data_Get_Struct((obj), PKCS7_SIGNER_INFO, (p7si)); \ + TypedData_Get_Struct((obj), PKCS7_SIGNER_INFO, &ossl_pkcs7_signer_info_type, (p7si)); \ if (!(p7si)) { \ ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \ } \ @@ -48,10 +48,10 @@ if (!(p7ri)) { \ ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \ } \ - (obj) = Data_Wrap_Struct((klass), 0, PKCS7_RECIP_INFO_free, (p7ri)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_pkcs7_recip_info_type, (p7ri)); \ } while (0) #define GetPKCS7ri(obj, p7ri) do { \ - Data_Get_Struct((obj), PKCS7_RECIP_INFO, (p7ri)); \ + TypedData_Get_Struct((obj), PKCS7_RECIP_INFO, &ossl_pkcs7_recip_info_type, (p7ri)); \ if (!(p7ri)) { \ ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \ } \ @@ -76,6 +76,48 @@ VALUE cPKCS7Signer; VALUE cPKCS7Recipient; VALUE ePKCS7Error; +static void +ossl_pkcs7_free(void *ptr) +{ + PKCS7_free(ptr); +} + +static const rb_data_type_t ossl_pkcs7_type = { + "OpenSSL/PKCS7", + { + 0, ossl_pkcs7_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + +static void +ossl_pkcs7_signer_info_free(void *ptr) +{ + PKCS7_SIGNER_INFO_free(ptr); +} + +static const rb_data_type_t ossl_pkcs7_signer_info_type = { + "OpenSSL/PKCS7/SIGNER_INFO", + { + 0, ossl_pkcs7_signer_info_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + +static void +ossl_pkcs7_recip_info_free(void *ptr) +{ + PKCS7_RECIP_INFO_free(ptr); +} + +static const rb_data_type_t ossl_pkcs7_recip_info_type = { + "OpenSSL/PKCS7/RECIP_INFO", + { + 0, ossl_pkcs7_recip_info_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + /* * Public * (MADE PRIVATE UNTIL SOMEBODY WILL NEED THEM) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 43942274..aa9b046d 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -69,9 +69,23 @@ ossl_generate_cb_stop(void *ptr) } #endif +static void +ossl_evp_pkey_free(void *ptr) +{ + EVP_PKEY_free(ptr); +} + /* * Public */ +const rb_data_type_t ossl_evp_pkey_type = { + "OpenSSL/EVP_PKEY", + { + 0, ossl_evp_pkey_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + VALUE ossl_pkey_new(EVP_PKEY *pkey) { diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h index 686e956e..6c0b7fd6 100644 --- a/ext/openssl/ossl_pkey.h +++ b/ext/openssl/ossl_pkey.h @@ -15,6 +15,7 @@ extern VALUE mPKey; extern VALUE cPKey; extern VALUE ePKeyError; extern ID id_private_q; +extern const rb_data_type_t ossl_evp_pkey_type; #define OSSL_PKEY_SET_PRIVATE(obj) rb_iv_set((obj), "private", Qtrue) #define OSSL_PKEY_SET_PUBLIC(obj) rb_iv_set((obj), "private", Qfalse) @@ -24,11 +25,11 @@ extern ID id_private_q; if (!(pkey)) { \ rb_raise(rb_eRuntimeError, "PKEY wasn't initialized!"); \ } \ - (obj) = Data_Wrap_Struct((klass), 0, EVP_PKEY_free, (pkey)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_evp_pkey_type, (pkey)); \ OSSL_PKEY_SET_PUBLIC(obj); \ } while (0) #define GetPKey(obj, pkey) do {\ - Data_Get_Struct((obj), EVP_PKEY, (pkey));\ + TypedData_Get_Struct((obj), EVP_PKEY, &ossl_evp_pkey_type, (pkey)); \ if (!(pkey)) { \ rb_raise(rb_eRuntimeError, "PKEY wasn't initialized!");\ } \ diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c index cec00597..d63f7573 100644 --- a/ext/openssl/ossl_pkey_ec.c +++ b/ext/openssl/ossl_pkey_ec.c @@ -20,6 +20,8 @@ typedef struct { #define EXPORT_PEM 0 #define EXPORT_DER 1 +static const rb_data_type_t ossl_ec_group_type; +static const rb_data_type_t ossl_ec_point_type; #define GetPKeyEC(obj, pkey) do { \ GetPKey((obj), (pkey)); \ @@ -30,7 +32,7 @@ typedef struct { #define SafeGet_ec_group(obj, group) do { \ OSSL_Check_Kind((obj), cEC_GROUP); \ - Data_Get_Struct((obj), ossl_ec_group, (group)); \ + TypedData_Get_Struct((obj), ossl_ec_group, &ossl_ec_group_type, (group)); \ } while(0) #define Get_EC_KEY(obj, key) do { \ @@ -52,7 +54,7 @@ typedef struct { #define Get_EC_GROUP(obj, g) do { \ ossl_ec_group *ec_group; \ - Data_Get_Struct((obj), ossl_ec_group, ec_group); \ + TypedData_Get_Struct((obj), ossl_ec_group, &ossl_ec_group_type, ec_group); \ if (ec_group == NULL) \ ossl_raise(eEC_GROUP, "missing ossl_ec_group structure"); \ (g) = ec_group->group; \ @@ -71,7 +73,7 @@ typedef struct { #define Get_EC_POINT(obj, p) do { \ ossl_ec_point *ec_point; \ - Data_Get_Struct((obj), ossl_ec_point, ec_point); \ + TypedData_Get_Struct((obj), ossl_ec_point, &ossl_ec_point_type, ec_point); \ if (ec_point == NULL) \ ossl_raise(eEC_POINT, "missing ossl_ec_point structure"); \ (p) = ec_point->point; \ @@ -369,7 +371,7 @@ static VALUE ossl_ec_point_dup(const EC_POINT *point, VALUE group_v) ossl_ec_point *new_point; obj = rb_obj_alloc(cEC_POINT); - Data_Get_Struct(obj, ossl_ec_point, new_point); + TypedData_Get_Struct(obj, ossl_ec_point, &ossl_ec_point_type, new_point); SafeRequire_EC_GROUP(group_v, group); @@ -707,19 +709,28 @@ static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig) UNREACHABLE; } -static void ossl_ec_group_free(ossl_ec_group *ec_group) +static void ossl_ec_group_free(void *ptr) { + ossl_ec_group *ec_group = ptr; if (!ec_group->dont_free && ec_group->group) EC_GROUP_clear_free(ec_group->group); ruby_xfree(ec_group); } +static const rb_data_type_t ossl_ec_group_type = { + "OpenSSL/ec_group", + { + 0, ossl_ec_group_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + static VALUE ossl_ec_group_alloc(VALUE klass) { ossl_ec_group *ec_group; VALUE obj; - obj = Data_Make_Struct(klass, ossl_ec_group, 0, ossl_ec_group_free, ec_group); + obj = TypedData_Make_Struct(klass, ossl_ec_group, &ossl_ec_group_type, ec_group); return obj; } @@ -746,7 +757,7 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) ossl_ec_group *ec_group; EC_GROUP *group = NULL; - Data_Get_Struct(self, ossl_ec_group, ec_group); + TypedData_Get_Struct(self, ossl_ec_group, &ossl_ec_group_type, ec_group); if (ec_group->group != NULL) ossl_raise(rb_eRuntimeError, "EC_GROUP is already initialized"); @@ -1219,19 +1230,28 @@ static VALUE ossl_ec_group_to_text(VALUE self) } -static void ossl_ec_point_free(ossl_ec_point *ec_point) +static void ossl_ec_point_free(void *ptr) { + ossl_ec_point *ec_point = ptr; if (!ec_point->dont_free && ec_point->point) EC_POINT_clear_free(ec_point->point); ruby_xfree(ec_point); } +static const rb_data_type_t ossl_ec_point_type = { + "OpenSSL/ec_point", + { + 0, ossl_ec_point_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + static VALUE ossl_ec_point_alloc(VALUE klass) { ossl_ec_point *ec_point; VALUE obj; - obj = Data_Make_Struct(klass, ossl_ec_point, 0, ossl_ec_point_free, ec_point); + obj = TypedData_Make_Struct(klass, ossl_ec_point, &ossl_ec_point_type, ec_point); return obj; } @@ -1252,7 +1272,7 @@ static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self) VALUE group_v = Qnil; const EC_GROUP *group = NULL; - Data_Get_Struct(self, ossl_ec_point, ec_point); + TypedData_Get_Struct(self, ossl_ec_point, &ossl_ec_point_type, ec_point); if (ec_point->point) ossl_raise(eEC_POINT, "EC_POINT already initialized"); diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index ccfd72dd..af93252e 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -24,6 +24,10 @@ # define TO_SOCKET(s) (s) #endif +#define GetSSLCTX(obj, ctx) do { \ + TypedData_Get_Struct((obj), SSL_CTX, &ossl_sslctx_type, (ctx)); \ +} while (0) + VALUE mSSL; VALUE eSSLError; VALUE cSSLContext; @@ -150,13 +154,22 @@ int ossl_ssl_ex_client_cert_cb_idx; int ossl_ssl_ex_tmp_dh_callback_idx; static void -ossl_sslctx_free(SSL_CTX *ctx) +ossl_sslctx_free(void *ptr) { + SSL_CTX *ctx = ptr; if(ctx && SSL_CTX_get_ex_data(ctx, ossl_ssl_ex_store_p)== (void*)1) ctx->cert_store = NULL; SSL_CTX_free(ctx); } +static const rb_data_type_t ossl_sslctx_type = { + "OpenSSL/SSL/CTX", + { + 0, ossl_sslctx_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + static VALUE ossl_sslctx_s_alloc(VALUE klass) { @@ -172,7 +185,7 @@ ossl_sslctx_s_alloc(VALUE klass) ossl_raise(eSSLError, "SSL_CTX_new"); } SSL_CTX_set_mode(ctx, mode); - return Data_Wrap_Struct(klass, 0, ossl_sslctx_free, ctx); + return TypedData_Wrap_Struct(klass, &ossl_sslctx_type, ctx); } /* @@ -203,7 +216,7 @@ ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method) if (!method) { ossl_raise(rb_eArgError, "unknown SSL method `%s'.", s); } - Data_Get_Struct(self, SSL_CTX, ctx); + GetSSLCTX(self, ctx); if (SSL_CTX_set_ssl_version(ctx, method) != 1) { ossl_raise(eSSLError, "SSL_CTX_set_ssl_version"); } @@ -244,7 +257,7 @@ ossl_call_client_cert_cb(VALUE obj) VALUE cb, ary, cert, key; SSL *ssl; - Data_Get_Struct(obj, SSL, ssl); + GetSSL(obj, ssl); cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_client_cert_cb_idx); if (NIL_P(cb)) return Qfalse; ary = rb_funcall(cb, rb_intern("call"), 1, obj); @@ -280,7 +293,7 @@ ossl_call_tmp_dh_callback(VALUE *args) VALUE cb, dh; EVP_PKEY *pkey; - Data_Get_Struct(args[0], SSL, ssl); + GetSSL(args[0], ssl); cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_tmp_dh_callback_idx); if (NIL_P(cb)) return Qfalse; dh = rb_funcall(cb, rb_intern("call"), 3, args[0], args[1], args[2]); @@ -482,7 +495,7 @@ ossl_sslctx_add_extra_chain_cert_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg)) X509 *x509; SSL_CTX *ctx; - Data_Get_Struct(arg, SSL_CTX, ctx); + GetSSLCTX(arg, ctx); x509 = DupX509CertPtr(i); if(!SSL_CTX_add_extra_chain_cert(ctx, x509)){ ossl_raise(eSSLError, NULL); @@ -513,8 +526,8 @@ ossl_call_servername_cb(VALUE ary) SSL_CTX *ctx2; ossl_sslctx_setup(ret_obj); - Data_Get_Struct(ssl_obj, SSL, ssl); - Data_Get_Struct(ret_obj, SSL_CTX, ctx2); + GetSSL(ssl_obj, ssl); + GetSSLCTX(ret_obj, ctx2); SSL_set_SSL_CTX(ssl, ctx2); } else if (!NIL_P(ret_obj)) { ossl_raise(rb_eArgError, "servername_cb must return an OpenSSL::SSL::SSLContext object or nil"); @@ -665,7 +678,7 @@ ossl_sslctx_setup(VALUE self) VALUE val; if(OBJ_FROZEN(self)) return Qnil; - Data_Get_Struct(self, SSL_CTX, ctx); + GetSSLCTX(self, ctx); #if !defined(OPENSSL_NO_DH) if (RTEST(ossl_sslctx_get_tmp_dh_cb(self))){ @@ -841,7 +854,7 @@ ossl_sslctx_get_ciphers(VALUE self) VALUE ary; int i, num; - Data_Get_Struct(self, SSL_CTX, ctx); + GetSSLCTX(self, ctx); if(!ctx){ rb_warning("SSL_CTX is not initialized."); return Qnil; @@ -896,7 +909,7 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v) StringValue(str); } - Data_Get_Struct(self, SSL_CTX, ctx); + GetSSLCTX(self, ctx); if(!ctx){ ossl_raise(eSSLError, "SSL_CTX is not initialized."); return Qnil; @@ -920,7 +933,7 @@ ossl_sslctx_session_add(VALUE self, VALUE arg) SSL_CTX *ctx; SSL_SESSION *sess; - Data_Get_Struct(self, SSL_CTX, ctx); + GetSSLCTX(self, ctx); SafeGetSSLSession(arg, sess); return SSL_CTX_add_session(ctx, sess) == 1 ? Qtrue : Qfalse; @@ -938,7 +951,7 @@ ossl_sslctx_session_remove(VALUE self, VALUE arg) SSL_CTX *ctx; SSL_SESSION *sess; - Data_Get_Struct(self, SSL_CTX, ctx); + GetSSLCTX(self, ctx); SafeGetSSLSession(arg, sess); return SSL_CTX_remove_session(ctx, sess) == 1 ? Qtrue : Qfalse; @@ -955,7 +968,7 @@ ossl_sslctx_get_session_cache_mode(VALUE self) { SSL_CTX *ctx; - Data_Get_Struct(self, SSL_CTX, ctx); + GetSSLCTX(self, ctx); return LONG2NUM(SSL_CTX_get_session_cache_mode(ctx)); } @@ -973,7 +986,7 @@ ossl_sslctx_set_session_cache_mode(VALUE self, VALUE arg) { SSL_CTX *ctx; - Data_Get_Struct(self, SSL_CTX, ctx); + GetSSLCTX(self, ctx); SSL_CTX_set_session_cache_mode(ctx, NUM2LONG(arg)); @@ -992,7 +1005,7 @@ ossl_sslctx_get_session_cache_size(VALUE self) { SSL_CTX *ctx; - Data_Get_Struct(self, SSL_CTX, ctx); + GetSSLCTX(self, ctx); return LONG2NUM(SSL_CTX_sess_get_cache_size(ctx)); } @@ -1009,7 +1022,7 @@ ossl_sslctx_set_session_cache_size(VALUE self, VALUE arg) { SSL_CTX *ctx; - Data_Get_Struct(self, SSL_CTX, ctx); + GetSSLCTX(self, ctx); SSL_CTX_sess_set_cache_size(ctx, NUM2LONG(arg)); @@ -1044,7 +1057,7 @@ ossl_sslctx_get_session_cache_stats(VALUE self) SSL_CTX *ctx; VALUE hash; - Data_Get_Struct(self, SSL_CTX, ctx); + GetSSLCTX(self, ctx); hash = rb_hash_new(); rb_hash_aset(hash, ID2SYM(rb_intern("cache_num")), LONG2NUM(SSL_CTX_sess_number(ctx))); @@ -1079,7 +1092,7 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "01", &arg1); - Data_Get_Struct(self, SSL_CTX, ctx); + GetSSLCTX(self, ctx); if (NIL_P(arg1)) { tm = time(0); @@ -1120,15 +1133,23 @@ ossl_ssl_shutdown(SSL *ssl) } static void -ossl_ssl_free(SSL *ssl) +ossl_ssl_free(void *ssl) { SSL_free(ssl); } +const rb_data_type_t ossl_ssl_type = { + "OpenSSL/SSL", + { + 0, ossl_ssl_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + static VALUE ossl_ssl_s_alloc(VALUE klass) { - return Data_Wrap_Struct(klass, 0, ossl_ssl_free, NULL); + return TypedData_Wrap_Struct(klass, &ossl_ssl_type, NULL); } /* @@ -1177,14 +1198,14 @@ ossl_ssl_setup(VALUE self) SSL *ssl; rb_io_t *fptr; - Data_Get_Struct(self, SSL, ssl); + GetSSL(self, ssl); if(!ssl){ #ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME VALUE hostname = rb_iv_get(self, "@hostname"); #endif v_ctx = ossl_ssl_get_ctx(self); - Data_Get_Struct(v_ctx, SSL_CTX, ctx); + GetSSLCTX(v_ctx, ctx); ssl = SSL_new(ctx); if (!ssl) { @@ -1224,7 +1245,7 @@ ossl_ssl_setup(VALUE self) #define ossl_ssl_data_get_struct(v, ssl) \ do { \ - Data_Get_Struct((v), SSL, (ssl)); \ + GetSSL((v), (ssl)); \ if (!(ssl)) { \ rb_warning("SSL session is not started yet."); \ return Qnil; \ @@ -1394,7 +1415,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock) } if(ilen == 0) return str; - Data_Get_Struct(self, SSL, ssl); + GetSSL(self, ssl); GetOpenFile(ossl_ssl_get_io(self), fptr); if (ssl) { if(!nonblock && SSL_pending(ssl) <= 0) @@ -1486,7 +1507,7 @@ ossl_ssl_write_internal(VALUE self, VALUE str, int nonblock, int no_exception) rb_io_t *fptr; StringValue(str); - Data_Get_Struct(self, SSL, ssl); + GetSSL(self, ssl); GetOpenFile(ossl_ssl_get_io(self), fptr); if (ssl) { @@ -1571,7 +1592,7 @@ ossl_ssl_close(VALUE self) /* ossl_ssl_data_get_struct() is not usable here because it may return * from this function; */ - Data_Get_Struct(self, SSL, ssl); + GetSSL(self, ssl); io = ossl_ssl_get_io(self); if (!RTEST(rb_funcall(io, rb_intern("closed?"), 0))) { diff --git a/ext/openssl/ossl_ssl.h b/ext/openssl/ossl_ssl.h index 034762fc..0c20b107 100644 --- a/ext/openssl/ossl_ssl.h +++ b/ext/openssl/ossl_ssl.h @@ -11,8 +11,12 @@ #if !defined(_OSSL_SSL_H_) #define _OSSL_SSL_H_ +#define GetSSL(obj, ssl) do { \ + TypedData_Get_Struct((obj), SSL, &ossl_ssl_type, (ssl)); \ +} while (0) + #define GetSSLSession(obj, sess) do { \ - Data_Get_Struct((obj), SSL_SESSION, (sess)); \ + TypedData_Get_Struct((obj), SSL_SESSION, &ossl_ssl_session_type, (sess)); \ if (!(sess)) { \ ossl_raise(rb_eRuntimeError, "SSL Session wasn't initialized."); \ } \ @@ -23,6 +27,8 @@ GetSSLSession((obj), (sess)); \ } while (0) +extern const rb_data_type_t ossl_ssl_type; +extern const rb_data_type_t ossl_ssl_session_type; extern VALUE mSSL; extern VALUE eSSLError; extern VALUE cSSLSocket; diff --git a/ext/openssl/ossl_ssl_session.c b/ext/openssl/ossl_ssl_session.c index a7437caf..e1bbc6fb 100644 --- a/ext/openssl/ossl_ssl_session.c +++ b/ext/openssl/ossl_ssl_session.c @@ -4,25 +4,26 @@ #include "ossl.h" -#define GetSSLSession(obj, sess) do { \ - Data_Get_Struct((obj), SSL_SESSION, (sess)); \ - if (!(sess)) { \ - ossl_raise(rb_eRuntimeError, "SSL Session wasn't initialized."); \ - } \ -} while (0) - -#define SafeGetSSLSession(obj, sess) do { \ - OSSL_Check_Kind((obj), cSSLSession); \ - GetSSLSession((obj), (sess)); \ -} while (0) - - VALUE cSSLSession; static VALUE eSSLSession; +static void +ossl_ssl_session_free(void *ptr) +{ + SSL_SESSION_free(ptr); +} + +const rb_data_type_t ossl_ssl_session_type = { + "OpenSSL/SSL/Session", + { + 0, ossl_ssl_session_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + static VALUE ossl_ssl_session_alloc(VALUE klass) { - return Data_Wrap_Struct(klass, 0, SSL_SESSION_free, NULL); + return TypedData_Wrap_Struct(klass, &ossl_ssl_session_type, NULL); } /* @@ -43,7 +44,7 @@ static VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1) if (rb_obj_is_instance_of(arg1, cSSLSocket)) { SSL *ssl; - Data_Get_Struct(arg1, SSL, ssl); + GetSSL(arg1, ssl); if (!ssl || (ctx = SSL_get1_session(ssl)) == NULL) ossl_raise(eSSLSession, "no session available"); @@ -78,7 +79,11 @@ int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b) if (a->ssl_version != b->ssl_version || a->session_id_length != b->session_id_length) return 1; - return memcmp(a->session_id,b-> session_id, a->session_id_length); +#if defined(_WIN32) + return memcmp(a->session_id, b->session_id, a->session_id_length); +#else + return CRYPTO_memcmp(a->session_id, b->session_id, a->session_id_length); +#endif } #endif diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c index fdf0481c..c9036cad 100644 --- a/ext/openssl/ossl_x509attr.c +++ b/ext/openssl/ossl_x509attr.c @@ -14,10 +14,10 @@ if (!(attr)) { \ ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \ } \ - (obj) = Data_Wrap_Struct((klass), 0, X509_ATTRIBUTE_free, (attr)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_x509attr_type, (attr)); \ } while (0) #define GetX509Attr(obj, attr) do { \ - Data_Get_Struct((obj), X509_ATTRIBUTE, (attr)); \ + TypedData_Get_Struct((obj), X509_ATTRIBUTE, &ossl_x509attr_type, (attr)); \ if (!(attr)) { \ ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \ } \ @@ -33,6 +33,20 @@ VALUE cX509Attr; VALUE eX509AttrError; +static void +ossl_x509attr_free(void *ptr) +{ + X509_ATTRIBUTE_free(ptr); +} + +static const rb_data_type_t ossl_x509attr_type = { + "OpenSSL/X509/ATTRIBUTE", + { + 0, ossl_x509attr_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + /* * Public */ diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c index 0c8f0751..b76ea793 100644 --- a/ext/openssl/ossl_x509cert.c +++ b/ext/openssl/ossl_x509cert.c @@ -14,10 +14,10 @@ if (!(x509)) { \ ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \ } \ - (obj) = Data_Wrap_Struct((klass), 0, X509_free, (x509)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_x509_type, (x509)); \ } while (0) #define GetX509(obj, x509) do { \ - Data_Get_Struct((obj), X509, (x509)); \ + TypedData_Get_Struct((obj), X509, &ossl_x509_type, (x509)); \ if (!(x509)) { \ ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \ } \ @@ -33,6 +33,20 @@ VALUE cX509Cert; VALUE eX509CertError; +static void +ossl_x509_free(void *ptr) +{ + X509_free(ptr); +} + +static const rb_data_type_t ossl_x509_type = { + "OpenSSL/X509", + { + 0, ossl_x509_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + /* * Public */ diff --git a/ext/openssl/ossl_x509crl.c b/ext/openssl/ossl_x509crl.c index beacc260..461c226f 100644 --- a/ext/openssl/ossl_x509crl.c +++ b/ext/openssl/ossl_x509crl.c @@ -14,10 +14,10 @@ if (!(crl)) { \ ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \ } \ - (obj) = Data_Wrap_Struct((klass), 0, X509_CRL_free, (crl)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_x509crl_type, (crl)); \ } while (0) #define GetX509CRL(obj, crl) do { \ - Data_Get_Struct((obj), X509_CRL, (crl)); \ + TypedData_Get_Struct((obj), X509_CRL, &ossl_x509crl_type, (crl)); \ if (!(crl)) { \ ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \ } \ @@ -33,6 +33,20 @@ VALUE cX509CRL; VALUE eX509CRLError; +static void +ossl_x509crl_free(void *ptr) +{ + X509_CRL_free(ptr); +} + +static const rb_data_type_t ossl_x509crl_type = { + "OpenSSL/X509/CRL", + { + 0, ossl_x509crl_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + /* * PUBLIC */ diff --git a/ext/openssl/ossl_x509ext.c b/ext/openssl/ossl_x509ext.c index 48625f85..faffe06a 100644 --- a/ext/openssl/ossl_x509ext.c +++ b/ext/openssl/ossl_x509ext.c @@ -14,10 +14,10 @@ if (!(ext)) { \ ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \ } \ - (obj) = Data_Wrap_Struct((klass), 0, X509_EXTENSION_free, (ext)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_x509ext_type, (ext)); \ } while (0) #define GetX509Ext(obj, ext) do { \ - Data_Get_Struct((obj), X509_EXTENSION, (ext)); \ + TypedData_Get_Struct((obj), X509_EXTENSION, &ossl_x509ext_type, (ext)); \ if (!(ext)) { \ ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \ } \ @@ -30,10 +30,10 @@ if (!((ctx) = OPENSSL_malloc(sizeof(X509V3_CTX)))) \ ossl_raise(rb_eRuntimeError, "CTX wasn't allocated!"); \ X509V3_set_ctx((ctx), NULL, NULL, NULL, NULL, 0); \ - (obj) = Data_Wrap_Struct((klass), 0, ossl_x509extfactory_free, (ctx)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_x509extfactory_type, (ctx)); \ } while (0) #define GetX509ExtFactory(obj, ctx) do { \ - Data_Get_Struct((obj), X509V3_CTX, (ctx)); \ + TypedData_Get_Struct((obj), X509V3_CTX, &ossl_x509extfactory_type, (ctx)); \ if (!(ctx)) { \ ossl_raise(rb_eRuntimeError, "CTX wasn't initialized!"); \ } \ @@ -46,6 +46,20 @@ VALUE cX509Ext; VALUE cX509ExtFactory; VALUE eX509ExtError; +static void +ossl_x509ext_free(void *ptr) +{ + X509_EXTENSION_free(ptr); +} + +static const rb_data_type_t ossl_x509ext_type = { + "OpenSSL/X509/EXTENSION", + { + 0, ossl_x509ext_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + /* * Public */ @@ -98,11 +112,19 @@ DupX509ExtPtr(VALUE obj) * Ext factory */ static void -ossl_x509extfactory_free(X509V3_CTX *ctx) +ossl_x509extfactory_free(void *ctx) { OPENSSL_free(ctx); } +static const rb_data_type_t ossl_x509extfactory_type = { + "OpenSSL/X509/EXTENSION/Factory", + { + 0, ossl_x509extfactory_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + static VALUE ossl_x509extfactory_alloc(VALUE klass) { diff --git a/ext/openssl/ossl_x509name.c b/ext/openssl/ossl_x509name.c index cf541e56..546cf3bf 100644 --- a/ext/openssl/ossl_x509name.c +++ b/ext/openssl/ossl_x509name.c @@ -14,10 +14,10 @@ if (!(name)) { \ ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \ } \ - (obj) = Data_Wrap_Struct((klass), 0, X509_NAME_free, (name)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_x509name_type, (name)); \ } while (0) #define GetX509Name(obj, name) do { \ - Data_Get_Struct((obj), X509_NAME, (name)); \ + TypedData_Get_Struct((obj), X509_NAME, &ossl_x509name_type, (name)); \ if (!(name)) { \ ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \ } \ @@ -38,6 +38,20 @@ VALUE cX509Name; VALUE eX509NameError; +static void +ossl_x509name_free(void *ptr) +{ + X509_NAME_free(ptr); +} + +static const rb_data_type_t ossl_x509name_type = { + "OpenSSL/X509/NAME", + { + 0, ossl_x509name_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + /* * Public */ diff --git a/ext/openssl/ossl_x509req.c b/ext/openssl/ossl_x509req.c index a7f5dd20..529b6850 100644 --- a/ext/openssl/ossl_x509req.c +++ b/ext/openssl/ossl_x509req.c @@ -14,10 +14,10 @@ if (!(req)) { \ ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \ } \ - (obj) = Data_Wrap_Struct((klass), 0, X509_REQ_free, (req)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_x509req_type, (req)); \ } while (0) #define GetX509Req(obj, req) do { \ - Data_Get_Struct((obj), X509_REQ, (req)); \ + TypedData_Get_Struct((obj), X509_REQ, &ossl_x509req_type, (req)); \ if (!(req)) { \ ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \ } \ @@ -33,6 +33,20 @@ VALUE cX509Req; VALUE eX509ReqError; +static void +ossl_x509req_free(void *ptr) +{ + X509_REQ_free(ptr); +} + +static const rb_data_type_t ossl_x509req_type = { + "OpenSSL/X509/REQ", + { + 0, ossl_x509req_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + /* * Public functions */ diff --git a/ext/openssl/ossl_x509revoked.c b/ext/openssl/ossl_x509revoked.c index c98a95ea..30c362c3 100644 --- a/ext/openssl/ossl_x509revoked.c +++ b/ext/openssl/ossl_x509revoked.c @@ -14,10 +14,10 @@ if (!(rev)) { \ ossl_raise(rb_eRuntimeError, "REV wasn't initialized!"); \ } \ - (obj) = Data_Wrap_Struct((klass), 0, X509_REVOKED_free, (rev)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_x509rev_type, (rev)); \ } while (0) #define GetX509Rev(obj, rev) do { \ - Data_Get_Struct((obj), X509_REVOKED, (rev)); \ + TypedData_Get_Struct((obj), X509_REVOKED, &ossl_x509rev_type, (rev)); \ if (!(rev)) { \ ossl_raise(rb_eRuntimeError, "REV wasn't initialized!"); \ } \ @@ -33,6 +33,20 @@ VALUE cX509Rev; VALUE eX509RevError; +static void +ossl_x509rev_free(void *ptr) +{ + X509_REVOKED_free(ptr); +} + +static const rb_data_type_t ossl_x509rev_type = { + "OpenSSL/X509/REV", + { + 0, ossl_x509rev_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + /* * PUBLIC */ diff --git a/ext/openssl/ossl_x509store.c b/ext/openssl/ossl_x509store.c index dd924bf9..3093e28a 100644 --- a/ext/openssl/ossl_x509store.c +++ b/ext/openssl/ossl_x509store.c @@ -14,10 +14,10 @@ if (!(st)) { \ ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \ } \ - (obj) = Data_Wrap_Struct((klass), 0, X509_STORE_free, (st)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_x509store_type, (st)); \ } while (0) #define GetX509Store(obj, st) do { \ - Data_Get_Struct((obj), X509_STORE, (st)); \ + TypedData_Get_Struct((obj), X509_STORE, &ossl_x509store_type, (st)); \ if (!(st)) { \ ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \ } \ @@ -31,10 +31,10 @@ if (!(ctx)) { \ ossl_raise(rb_eRuntimeError, "STORE_CTX wasn't initialized!"); \ } \ - (obj) = Data_Wrap_Struct((klass), 0, ossl_x509stctx_free, (ctx)); \ + (obj) = TypedData_Wrap_Struct((klass), &ossl_x509stctx_type, (ctx)); \ } while (0) #define GetX509StCtx(obj, ctx) do { \ - Data_Get_Struct((obj), X509_STORE_CTX, (ctx)); \ + TypedData_Get_Struct((obj), X509_STORE_CTX, &ossl_x509stctx_type, (ctx)); \ if (!(ctx)) { \ ossl_raise(rb_eRuntimeError, "STORE_CTX is out of scope!"); \ } \ @@ -51,6 +51,20 @@ VALUE cX509Store; VALUE cX509StoreContext; VALUE eX509StoreError; +static void +ossl_x509store_free(void *ptr) +{ + X509_STORE_free(ptr); +} + +static const rb_data_type_t ossl_x509store_type = { + "OpenSSL/X509/STORE", + { + 0, ossl_x509store_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + /* * Public functions */ @@ -342,7 +356,17 @@ ossl_x509store_verify(int argc, VALUE *argv, VALUE self) /* * Public Functions */ -static void ossl_x509stctx_free(X509_STORE_CTX*); +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, +}; + VALUE ossl_x509stctx_new(X509_STORE_CTX *ctx) @@ -367,8 +391,9 @@ ossl_x509stctx_clear_ptr(VALUE obj) * Private functions */ static void -ossl_x509stctx_free(X509_STORE_CTX *ctx) +ossl_x509stctx_free(void *ptr) { + X509_STORE_CTX *ctx = ptr; if(ctx->untrusted) sk_X509_pop_free(ctx->untrusted, X509_free); if(ctx->cert) |