diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index 5716e6f10..40ef68cb9 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 0b479a720..d23e828f3 100644 --- a/ext/openssl/ossl.h +++ b/ext/openssl/ossl.h @@ -98,6 +98,8 @@ extern VALUE eOSSLError; }\ } while (0) +void ossl_want_uninitialized(VALUE self, const rb_data_type_t *type); + /* * Type conversions */ 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_ns_spki.c b/ext/openssl/ossl_ns_spki.c index 8440c2ee8..e308aaef7 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, 0); } /* @@ -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; } 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; } diff --git a/ext/openssl/ossl_pkcs12.c b/ext/openssl/ossl_pkcs12.c index a47c81354..60796bcae 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, 0); } /* :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, + (char *)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; diff --git a/ext/openssl/ossl_pkcs7.c b/ext/openssl/ossl_pkcs7.c index 44e8cb305..608388806 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, 0); +} + 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); } diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index a53332b17..f49b3e652 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 3f2975c5a..3faa0771b 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 041646a05..a6d86be43 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 " \ @@ -154,9 +152,7 @@ ossl_dsa_initialize_copy(VALUE self, VALUE other) EVP_PKEY *pkey; 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 35f031819..225bb2c9f 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 " \ @@ -201,9 +199,7 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other) EVP_PKEY *pkey; EC_KEY *ec, *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); @@ -631,11 +627,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; @@ -717,9 +712,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); @@ -1219,11 +1212,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"); @@ -1270,9 +1261,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 039b2c6a3..a8a2710c5 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 " \ @@ -150,9 +148,7 @@ ossl_rsa_initialize_copy(VALUE self, VALUE other) EVP_PKEY *pkey; 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_provider.c b/ext/openssl/ossl_provider.c index ea5abb8e4..fd788bb4d 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, 0); 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; } diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index 3d913a396..b0c3612dc 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -1643,18 +1643,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/ext/openssl/ossl_ts.c b/ext/openssl/ossl_ts.c index 317f7786a..831a6409f 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, 0); } /* @@ -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, 0); } /* @@ -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, 0); } /* @@ -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: diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c index 38600b9b0..9acaa6ad5 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, 0); +} + /* * 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..72e295adf 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, 0); +} + /* * 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 9b59bda9e..fdfa5030f 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, 0); +} + /* * 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..3c2834575 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, 0); +} + /* * 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..381774c2d 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, 0); +} + /* * 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..a940dfd34 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, 0); } 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..77064c4c3 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, 0); +} + /* * 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 9e43336c4..c99f623ae 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)) { \ @@ -170,15 +154,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, 0); } /* @@ -210,9 +186,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); @@ -529,26 +510,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, 0); } 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); @@ -572,7 +540,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 */ 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")