diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2016-08-09 16:50:08 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2016-08-09 16:50:30 +0900 |
commit | 580c6d4a51d7a8713e46b06474341e1297d4de13 (patch) | |
tree | 2f12292b98ccafd30ec5df61f77376494471188c /ext/openssl | |
parent | 714f0d8f2d2b35075158d870e7e8298e31d8c409 (diff) | |
parent | 3292933e67790dddfc28dcaba3ed08c066216d40 (diff) | |
download | ruby-openssl-580c6d4a51d7a8713e46b06474341e1297d4de13.tar.gz |
Merge branch 'master' into topic/doc-work
Diffstat (limited to 'ext/openssl')
-rw-r--r-- | ext/openssl/openssl_missing.h | 1 | ||||
-rw-r--r-- | ext/openssl/ossl.c | 76 | ||||
-rw-r--r-- | ext/openssl/ossl.h | 9 | ||||
-rw-r--r-- | ext/openssl/ossl_asn1.c | 6 | ||||
-rw-r--r-- | ext/openssl/ossl_bio.c | 4 | ||||
-rw-r--r-- | ext/openssl/ossl_cipher.c | 94 | ||||
-rw-r--r-- | ext/openssl/ossl_digest.c | 16 | ||||
-rw-r--r-- | ext/openssl/ossl_engine.c | 1 | ||||
-rw-r--r-- | ext/openssl/ossl_pkcs12.c | 26 | ||||
-rw-r--r-- | ext/openssl/ossl_pkey.c | 20 | ||||
-rw-r--r-- | ext/openssl/ossl_pkey.h | 2 | ||||
-rw-r--r-- | ext/openssl/ossl_pkey_dsa.c | 17 | ||||
-rw-r--r-- | ext/openssl/ossl_pkey_rsa.c | 4 | ||||
-rw-r--r-- | ext/openssl/ossl_ssl.c | 103 | ||||
-rw-r--r-- | ext/openssl/ossl_ssl_session.c | 21 | ||||
-rw-r--r-- | ext/openssl/ossl_x509attr.c | 20 | ||||
-rw-r--r-- | ext/openssl/ossl_x509ext.c | 20 | ||||
-rw-r--r-- | ext/openssl/ossl_x509name.c | 20 | ||||
-rw-r--r-- | ext/openssl/ossl_x509revoked.c | 20 | ||||
-rw-r--r-- | ext/openssl/ossl_x509store.c | 18 |
20 files changed, 355 insertions, 143 deletions
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h index 769c7c2d..d2fdce16 100644 --- a/ext/openssl/openssl_missing.h +++ b/ext/openssl/openssl_missing.h @@ -231,6 +231,7 @@ IMPL_PKEY_GETTER(EC_KEY, ec) #if defined(HAVE_AUTHENTICATED_ENCRYPTION) && !defined(EVP_CTRL_AEAD_GET_TAG) # define EVP_CTRL_AEAD_GET_TAG EVP_CTRL_GCM_GET_TAG # define EVP_CTRL_AEAD_SET_TAG EVP_CTRL_GCM_SET_TAG +# define EVP_CTRL_AEAD_SET_IVLEN EVP_CTRL_GCM_SET_IVLEN #endif #endif /* _OSSL_OPENSSL_MISSING_H_ */ diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index 88e0e79a..bbd9af3b 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -9,6 +9,7 @@ */ #include "ossl.h" #include <stdarg.h> /* for ossl_raise */ +#include <ruby/thread_native.h> /* for OpenSSL < 1.1.0 locks */ /* * String to HEXString conversion @@ -77,7 +78,7 @@ STACK_OF(type) * \ ossl_protect_##name##_ary2sk(VALUE ary, int *status) \ { \ return (STACK_OF(type)*)rb_protect( \ - (VALUE(*)_((VALUE)))ossl_##name##_ary2sk0, \ + (VALUE (*)(VALUE))ossl_##name##_ary2sk0, \ ary, \ status); \ } \ @@ -136,7 +137,7 @@ ossl_buf2str(char *buf, int len) VALUE str; int status = 0; - str = rb_protect((VALUE(*)_((VALUE)))ossl_str_new, len, &status); + str = rb_protect((VALUE (*)(VALUE))ossl_str_new, len, &status); if(!NIL_P(str)) memcpy(RSTRING_PTR(str), buf, len); OPENSSL_free(buf); if(status) rb_jump_tag(status); @@ -242,54 +243,54 @@ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_) int ossl_store_ctx_ex_verify_cb_idx; int ossl_store_ex_verify_cb_idx; -VALUE +struct ossl_verify_cb_args { + VALUE proc; + VALUE preverify_ok; + VALUE store_ctx; +}; + +static VALUE ossl_call_verify_cb_proc(struct ossl_verify_cb_args *args) { return rb_funcall(args->proc, rb_intern("call"), 2, - args->preverify_ok, args->store_ctx); + args->preverify_ok, args->store_ctx); } int -ossl_verify_cb(int ok, X509_STORE_CTX *ctx) +ossl_verify_cb_call(VALUE proc, int ok, X509_STORE_CTX *ctx) { - VALUE proc, rctx, ret; + VALUE rctx, ret; struct ossl_verify_cb_args args; - int state = 0; + int state; - proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, ossl_store_ctx_ex_verify_cb_idx); - if (!proc) - proc = (VALUE)X509_STORE_get_ex_data(X509_STORE_CTX_get0_store(ctx), ossl_store_ex_verify_cb_idx); - if (!proc) + if (NIL_P(proc)) return ok; - if (!NIL_P(proc)) { - ret = Qfalse; - rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new, - (VALUE)ctx, &state); + + ret = Qfalse; + rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new, (VALUE)ctx, &state); + if (state) { + rb_set_errinfo(Qnil); + rb_warn("StoreContext initialization failure"); + } + else { + args.proc = proc; + args.preverify_ok = ok ? Qtrue : Qfalse; + args.store_ctx = rctx; + ret = rb_protect((VALUE(*)(VALUE))ossl_call_verify_cb_proc, (VALUE)&args, &state); if (state) { rb_set_errinfo(Qnil); - rb_warn("StoreContext initialization failure"); - } - else { - args.proc = proc; - args.preverify_ok = ok ? Qtrue : Qfalse; - args.store_ctx = rctx; - ret = rb_protect((VALUE(*)(VALUE))ossl_call_verify_cb_proc, (VALUE)&args, &state); - if (state) { - rb_set_errinfo(Qnil); - rb_warn("exception in verify_callback is ignored"); - } - ossl_x509stctx_clear_ptr(rctx); - } - if (ret == Qtrue) { - X509_STORE_CTX_set_error(ctx, X509_V_OK); - ok = 1; - } - else{ - if (X509_STORE_CTX_get_error(ctx) == X509_V_OK) { - X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED); - } - ok = 0; + rb_warn("exception in verify_callback is ignored"); } + ossl_x509stctx_clear_ptr(rctx); + } + if (ret == Qtrue) { + X509_STORE_CTX_set_error(ctx, X509_V_OK); + ok = 1; + } + else { + if (X509_STORE_CTX_get_error(ctx) == X509_V_OK) + X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED); + ok = 0; } return ok; @@ -511,7 +512,6 @@ ossl_fips_mode_set(VALUE self, VALUE enabled) /** * Stores locks needed for OpenSSL thread safety */ -#include "ruby/thread_native.h" static rb_nativethread_lock_t *ossl_locks; static void diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h index 2317fa8b..c15a25bc 100644 --- a/ext/openssl/ossl.h +++ b/ext/openssl/ossl.h @@ -154,14 +154,7 @@ void ossl_clear_error(void); extern int ossl_store_ctx_ex_verify_cb_idx; extern int ossl_store_ex_verify_cb_idx; -struct ossl_verify_cb_args { - VALUE proc; - VALUE preverify_ok; - VALUE store_ctx; -}; - -VALUE ossl_call_verify_cb_proc(struct ossl_verify_cb_args *); -int ossl_verify_cb(int, X509_STORE_CTX *); +int ossl_verify_cb_call(VALUE, int, X509_STORE_CTX *); /* * String to DER String diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c index eb48aa5b..5fea9a2f 100644 --- a/ext/openssl/ossl_asn1.c +++ b/ext/openssl/ossl_asn1.c @@ -383,7 +383,7 @@ decode_int(unsigned char* der, long length) p = der; if(!(ai = d2i_ASN1_INTEGER(NULL, &p, length))) ossl_raise(eASN1Error, NULL); - ret = rb_protect((VALUE(*)_((VALUE)))asn1integer_to_num, + ret = rb_protect((VALUE (*)(VALUE))asn1integer_to_num, (VALUE)ai, &status); ASN1_INTEGER_free(ai); if(status) rb_jump_tag(status); @@ -423,7 +423,7 @@ decode_enum(unsigned char* der, long length) p = der; if(!(ai = d2i_ASN1_ENUMERATED(NULL, &p, length))) ossl_raise(eASN1Error, NULL); - ret = rb_protect((VALUE(*)_((VALUE)))asn1integer_to_num, + ret = rb_protect((VALUE (*)(VALUE))asn1integer_to_num, (VALUE)ai, &status); ASN1_ENUMERATED_free(ai); if(status) rb_jump_tag(status); @@ -485,7 +485,7 @@ decode_time(unsigned char* der, long length) p = der; if(!(time = d2i_ASN1_TIME(NULL, &p, length))) ossl_raise(eASN1Error, NULL); - ret = rb_protect((VALUE(*)_((VALUE)))asn1time_to_time, + ret = rb_protect((VALUE (*)(VALUE))asn1time_to_time, (VALUE)time, &status); ASN1_TIME_free(time); if(status) rb_jump_tag(status); diff --git a/ext/openssl/ossl_bio.c b/ext/openssl/ossl_bio.c index cd258264..feaf2296 100644 --- a/ext/openssl/ossl_bio.c +++ b/ext/openssl/ossl_bio.c @@ -51,7 +51,7 @@ BIO * ossl_protect_obj2bio(VALUE obj, int *status) { BIO *ret = NULL; - ret = (BIO*)rb_protect((VALUE(*)_((VALUE)))ossl_obj2bio, obj, status); + ret = (BIO*)rb_protect((VALUE (*)(VALUE))ossl_obj2bio, obj, status); return ret; } @@ -70,7 +70,7 @@ ossl_membio2str0(BIO *bio) VALUE ossl_protect_membio2str(BIO *bio, int *status) { - return rb_protect((VALUE(*)_((VALUE)))ossl_membio2str0, (VALUE)bio, status); + return rb_protect((VALUE (*)(VALUE))ossl_membio2str0, (VALUE)bio, status); } VALUE diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c index 76b0aae9..83c43904 100644 --- a/ext/openssl/ossl_cipher.c +++ b/ext/openssl/ossl_cipher.c @@ -331,25 +331,23 @@ ossl_cipher_update_long(EVP_CIPHER_CTX *ctx, unsigned char *out, long *out_len_p const unsigned char *in, long in_len) { int out_part_len; + int limit = INT_MAX / 2 + 1; 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; + + do { + int in_part_len = in_len > limit ? limit : (int)in_len; + + 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 -= limit) > 0); + + if (out_len_ptr) + *out_len_ptr = out_len; + return 1; } @@ -499,12 +497,17 @@ static VALUE ossl_cipher_set_iv(VALUE self, VALUE iv) { EVP_CIPHER_CTX *ctx; - int iv_len; + int iv_len = 0; StringValue(iv); GetCipher(self, ctx); - iv_len = EVP_CIPHER_CTX_iv_length(ctx); +#if defined(HAVE_AUTHENTICATED_ENCRYPTION) + if (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER) + iv_len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx); +#endif + if (!iv_len) + iv_len = EVP_CIPHER_CTX_iv_length(ctx); if (RSTRING_LEN(iv) != iv_len) ossl_raise(rb_eArgError, "iv must be %d bytes", iv_len); @@ -638,11 +641,42 @@ ossl_cipher_is_authenticated(VALUE self) return (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER) ? Qtrue : Qfalse; } + +/* + * call-seq: + * cipher.iv_len = integer -> integer + * + * Sets the IV/nonce length of the Cipher. Normally block ciphers don't allow + * changing the IV length, but some make use of IV for 'nonce'. You may need + * this for interoperability with other applications. + */ +static VALUE +ossl_cipher_set_iv_length(VALUE self, VALUE iv_length) +{ + int len = NUM2INT(iv_length); + EVP_CIPHER_CTX *ctx; + + GetCipher(self, ctx); + if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER)) + ossl_raise(eCipherError, "cipher does not support AEAD"); + + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, len, NULL)) + ossl_raise(eCipherError, "unable to set IV length"); + + /* + * EVP_CIPHER_CTX_iv_length() returns the default length. So we need to save + * the length somewhere. Luckily currently we aren't using app_data. + */ + EVP_CIPHER_CTX_set_app_data(ctx, (void *)(VALUE)len); + + return iv_length; +} #else #define ossl_cipher_set_auth_data rb_f_notimplement #define ossl_cipher_get_auth_tag rb_f_notimplement #define ossl_cipher_set_auth_tag rb_f_notimplement #define ossl_cipher_is_authenticated rb_f_notimplement +#define ossl_cipher_set_iv_length rb_f_notimplement #endif /* @@ -708,13 +742,30 @@ ossl_cipher_set_padding(VALUE self, VALUE padding) * Returns the key length in bytes of the Cipher. */ CIPHER_0ARG_INT(key_length) + /* * call-seq: * cipher.iv_len -> integer * * Returns the expected length in bytes for an IV for this Cipher. */ -CIPHER_0ARG_INT(iv_length) +static VALUE +ossl_cipher_iv_length(VALUE self) +{ + EVP_CIPHER_CTX *ctx; + int len = 0; + + GetCipher(self, ctx); +#if defined(HAVE_AUTHENTICATED_ENCRYPTION) + if (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER) + len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx); +#endif + if (!len) + len = EVP_CIPHER_CTX_iv_length(ctx); + + return INT2NUM(len); +} + /* * call-seq: * cipher.block_size -> integer @@ -953,6 +1004,7 @@ Init_ossl_cipher(void) rb_define_method(cCipher, "key_len=", ossl_cipher_set_key_length, 1); rb_define_method(cCipher, "key_len", ossl_cipher_key_length, 0); rb_define_method(cCipher, "iv=", ossl_cipher_set_iv, 1); + rb_define_method(cCipher, "iv_len=", ossl_cipher_set_iv_length, 1); rb_define_method(cCipher, "iv_len", ossl_cipher_iv_length, 0); rb_define_method(cCipher, "block_size", ossl_cipher_block_size, 0); rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1); diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c index 317083fe..f9451220 100644 --- a/ext/openssl/ossl_digest.c +++ b/ext/openssl/ossl_digest.c @@ -203,7 +203,9 @@ ossl_digest_update(VALUE self, VALUE data) StringValue(data); GetDigest(self, ctx); - EVP_DigestUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)); + + if (!EVP_DigestUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) + ossl_raise(eDigestError, "EVP_DigestUpdate"); return self; } @@ -218,19 +220,21 @@ ossl_digest_finish(int argc, VALUE *argv, VALUE self) { EVP_MD_CTX *ctx; VALUE str; - - rb_scan_args(argc, argv, "01", &str); + int out_len; GetDigest(self, ctx); + rb_scan_args(argc, argv, "01", &str); + out_len = EVP_MD_CTX_size(ctx); if (NIL_P(str)) { - str = rb_str_new(NULL, EVP_MD_CTX_size(ctx)); + str = rb_str_new(NULL, out_len); } else { StringValue(str); - rb_str_resize(str, EVP_MD_CTX_size(ctx)); + rb_str_resize(str, out_len); } - EVP_DigestFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), NULL); + if (!EVP_DigestFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), NULL)) + ossl_raise(eDigestError, "EVP_DigestFinal_ex"); return str; } diff --git a/ext/openssl/ossl_engine.c b/ext/openssl/ossl_engine.c index 1da8430f..f4863b36 100644 --- a/ext/openssl/ossl_engine.c +++ b/ext/openssl/ossl_engine.c @@ -543,6 +543,7 @@ Init_ossl_engine(void) rb_define_singleton_method(cEngine, "engines", ossl_engine_s_engines, 0); rb_define_singleton_method(cEngine, "by_id", ossl_engine_s_by_id, 1); rb_undef_method(CLASS_OF(cEngine), "new"); + rb_undef_method(cEngine, "initialize_copy"); rb_define_method(cEngine, "id", ossl_engine_get_id, 0); rb_define_method(cEngine, "name", ossl_engine_get_name, 0); diff --git a/ext/openssl/ossl_pkcs12.c b/ext/openssl/ossl_pkcs12.c index 43fc5e51..33ad08a7 100644 --- a/ext/openssl/ossl_pkcs12.c +++ b/ext/openssl/ossl_pkcs12.c @@ -65,6 +65,25 @@ ossl_pkcs12_s_allocate(VALUE klass) return obj; } +static VALUE +ossl_pkcs12_initialize_copy(VALUE self, VALUE other) +{ + PKCS12 *p12, *p12_old, *p12_new; + + rb_check_frozen(self); + GetPKCS12(self, p12_old); + SafeGetPKCS12(other, 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); + + return self; +} + /* * call-seq: * PKCS12.create(pass, name, key, cert [, ca, [, key_pbe [, cert_pbe [, key_iter [, mac_iter [, keytype]]]]]]) @@ -171,14 +190,14 @@ ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self) if(!PKCS12_parse(pkcs, passphrase, &key, &x509, &x509s)) ossl_raise(ePKCS12Error, "PKCS12_parse"); ERR_pop_to_mark(); - pkey = rb_protect((VALUE(*)_((VALUE)))ossl_pkey_new, (VALUE)key, + pkey = rb_protect((VALUE (*)(VALUE))ossl_pkey_new, (VALUE)key, &st); /* NO DUP */ if(st) goto err; - cert = rb_protect((VALUE(*)_((VALUE)))ossl_x509_new, (VALUE)x509, &st); + cert = rb_protect((VALUE (*)(VALUE))ossl_x509_new, (VALUE)x509, &st); if(st) goto err; if(x509s){ ca = - rb_protect((VALUE(*)_((VALUE)))ossl_x509_sk2ary, (VALUE)x509s, &st); + rb_protect((VALUE (*)(VALUE))ossl_x509_sk2ary, (VALUE)x509s, &st); if(st) goto err; } @@ -231,6 +250,7 @@ Init_ossl_pkcs12(void) rb_define_singleton_method(cPKCS12, "create", ossl_pkcs12_s_create, -1); rb_define_alloc_func(cPKCS12, ossl_pkcs12_s_allocate); + rb_define_copy_func(cPKCS12, ossl_pkcs12_initialize_copy); rb_attr(cPKCS12, rb_intern("key"), 1, 0, Qfalse); rb_attr(cPKCS12, rb_intern("certificate"), 1, 0, Qfalse); rb_attr(cPKCS12, rb_intern("ca_certs"), 1, 0, Qfalse); diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 2058af74..7b237337 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -15,7 +15,7 @@ VALUE mPKey; VALUE cPKey; VALUE ePKeyError; -ID id_private_q; +static ID id_private_q; /* * callback for generating keys @@ -197,20 +197,6 @@ DupPKeyPtr(VALUE obj) return pkey; } -EVP_PKEY * -DupPrivPKeyPtr(VALUE obj) -{ - EVP_PKEY *pkey; - - if (rb_funcallv(obj, id_private_q, 0, NULL) != Qtrue) { - ossl_raise(rb_eArgError, "Private key is needed."); - } - SafeGetPKey(obj, pkey); - EVP_PKEY_up_ref(pkey); - - return pkey; -} - /* * Private */ @@ -272,9 +258,7 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) VALUE str; int result; - if (rb_funcallv(self, id_private_q, 0, NULL) != Qtrue) - ossl_raise(rb_eArgError, "Private key is needed."); - GetPKey(self, pkey); + pkey = GetPrivPKeyPtr(self); md = GetDigestPtr(digest); StringValue(data); str = rb_str_new(0, EVP_PKEY_size(pkey)+16); diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h index 1f68352c..218f2ebb 100644 --- a/ext/openssl/ossl_pkey.h +++ b/ext/openssl/ossl_pkey.h @@ -13,7 +13,6 @@ 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) @@ -53,7 +52,6 @@ VALUE ossl_pkey_new_from_file(VALUE); EVP_PKEY *GetPKeyPtr(VALUE); EVP_PKEY *DupPKeyPtr(VALUE); EVP_PKEY *GetPrivPKeyPtr(VALUE); -EVP_PKEY *DupPrivPKeyPtr(VALUE); void Init_ossl_pkey(void); /* diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c index 7c08620c..db103cb6 100644 --- a/ext/openssl/ossl_pkey_dsa.c +++ b/ext/openssl/ossl_pkey_dsa.c @@ -95,8 +95,6 @@ ossl_dsa_new(EVP_PKEY *pkey) struct dsa_blocking_gen_arg { DSA *dsa; int size; - unsigned char* seed; - int seed_len; int *counter; unsigned long *h; BN_GENCB *cb; @@ -107,7 +105,8 @@ static void * dsa_blocking_gen(void *arg) { struct dsa_blocking_gen_arg *gen = (struct dsa_blocking_gen_arg *)arg; - gen->result = DSA_generate_parameters_ex(gen->dsa, gen->size, gen->seed, gen->seed_len, gen->counter, gen->h, gen->cb); + gen->result = DSA_generate_parameters_ex(gen->dsa, gen->size, NULL, 0, + gen->counter, gen->h, gen->cb); return 0; } @@ -118,13 +117,9 @@ dsa_generate(int size) struct dsa_blocking_gen_arg gen_arg; DSA *dsa = DSA_new(); BN_GENCB *cb = BN_GENCB_new(); - unsigned char seed[20]; - int seed_len = 20, counter; + int counter; unsigned long h; - if (RAND_bytes(seed, seed_len) <= 0) - return NULL; - if (!dsa || !cb) { DSA_free(dsa); BN_GENCB_free(cb); @@ -136,8 +131,6 @@ dsa_generate(int size) BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg); gen_arg.dsa = dsa; gen_arg.size = size; - gen_arg.seed = seed; - gen_arg.seed_len = seed_len; gen_arg.counter = &counter; gen_arg.h = &h; gen_arg.cb = cb; @@ -387,14 +380,14 @@ static VALUE ossl_dsa_to_der(VALUE self) { DSA *dsa; - int (*i2d_func)_((DSA*, unsigned char**)); + int (*i2d_func)(DSA *, unsigned char **); unsigned char *p; long len; VALUE str; GetDSA(self, dsa); if(DSA_HAS_PRIVATE(dsa)) - i2d_func = (int(*)_((DSA*,unsigned char**)))i2d_DSAPrivateKey; + i2d_func = (int (*)(DSA *,unsigned char **))i2d_DSAPrivateKey; else i2d_func = i2d_DSA_PUBKEY; if((len = i2d_func(dsa, NULL)) <= 0) diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c index 18507ebb..e003d9ff 100644 --- a/ext/openssl/ossl_pkey_rsa.c +++ b/ext/openssl/ossl_pkey_rsa.c @@ -383,7 +383,7 @@ static VALUE ossl_rsa_to_der(VALUE self) { RSA *rsa; - int (*i2d_func)_((const RSA*, unsigned char**)); + int (*i2d_func)(const RSA *, unsigned char **); unsigned char *p; long len; VALUE str; @@ -392,7 +392,7 @@ ossl_rsa_to_der(VALUE self) if (RSA_HAS_PRIVATE(rsa)) i2d_func = i2d_RSAPrivateKey; else - i2d_func = (int (*)(const RSA*, unsigned char**))i2d_RSA_PUBKEY; + i2d_func = (int (*)(const RSA *, unsigned char **))i2d_RSA_PUBKEY; if((len = i2d_func(rsa, NULL)) <= 0) ossl_raise(eRSAError, NULL); str = rb_str_new(0, len); diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index 5044c6d1..a443c055 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -64,18 +64,15 @@ static VALUE eSSLErrorWaitWritable; #define ossl_sslctx_get_client_cert_cb(o) rb_iv_get((o),"@client_cert_cb") #define ossl_sslctx_get_tmp_ecdh_cb(o) rb_iv_get((o),"@tmp_ecdh_callback") #define ossl_sslctx_get_sess_id_ctx(o) rb_iv_get((o),"@session_id_context") +#define ossl_sslctx_get_verify_hostname(o) rb_iv_get((o),"@verify_hostname") #define ossl_ssl_get_io(o) rb_iv_get((o),"@io") #define ossl_ssl_get_ctx(o) rb_iv_get((o),"@context") -#define ossl_ssl_get_x509(o) rb_iv_get((o),"@x509") -#define ossl_ssl_get_key(o) rb_iv_get((o),"@key") #define ossl_ssl_set_io(o,v) rb_iv_set((o),"@io",(v)) #define ossl_ssl_set_ctx(o,v) rb_iv_set((o),"@context",(v)) #define ossl_ssl_set_sync_close(o,v) rb_iv_set((o),"@sync_close",(v)) #define ossl_ssl_set_hostname_v(o,v) rb_iv_set((o),"@hostname",(v)) -#define ossl_ssl_set_x509(o,v) rb_iv_set((o),"@x509",(v)) -#define ossl_ssl_set_key(o,v) rb_iv_set((o),"@key",(v)) #define ossl_ssl_set_tmp_dh(o,v) rb_iv_set((o),"@tmp_dh",(v)) #define ossl_ssl_set_tmp_ecdh(o,v) rb_iv_set((o),"@tmp_ecdh",(v)) @@ -225,28 +222,30 @@ ossl_call_client_cert_cb(VALUE obj) { VALUE cb, ary, cert, key; - cb = rb_funcall(obj, rb_intern("client_cert_cb"), 0); - if (NIL_P(cb)) return Qfalse; + cb = ossl_sslctx_get_client_cert_cb(ossl_ssl_get_ctx(obj)); + if (NIL_P(cb)) + return Qnil; + ary = rb_funcall(cb, rb_intern("call"), 1, obj); Check_Type(ary, T_ARRAY); GetX509CertPtr(cert = rb_ary_entry(ary, 0)); - GetPKeyPtr(key = rb_ary_entry(ary, 1)); - ossl_ssl_set_x509(obj, cert); - ossl_ssl_set_key(obj, key); + GetPrivPKeyPtr(key = rb_ary_entry(ary, 1)); - return Qtrue; + return rb_ary_new3(2, cert, key); } static int ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey) { - VALUE obj, success; + VALUE obj, ret; obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); - success = rb_protect(ossl_call_client_cert_cb, obj, NULL); - if (!RTEST(success)) return 0; - *x509 = DupX509CertPtr(ossl_ssl_get_x509(obj)); - *pkey = DupPKeyPtr(ossl_ssl_get_key(obj)); + ret = rb_protect(ossl_call_client_cert_cb, obj, NULL); + if (NIL_P(ret)) + return 0; + + *x509 = DupX509CertPtr(RARRAY_AREF(ret, 0)); + *pkey = DupPKeyPtr(RARRAY_AREF(ret, 1)); return 1; } @@ -319,16 +318,50 @@ ossl_tmp_ecdh_callback(SSL *ssl, int is_export, int keylength) } #endif +static VALUE +call_verify_certificate_identity(VALUE ctx_v) +{ + X509_STORE_CTX *ctx = (X509_STORE_CTX *)ctx_v; + SSL *ssl; + VALUE ssl_obj, hostname, cert_obj; + + ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); + ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); + hostname = rb_attr_get(ssl_obj, rb_intern("@hostname")); + + if (!RTEST(hostname)) { + rb_warning("verify_hostname requires hostname to be set"); + return Qtrue; + } + + cert_obj = ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx)); + return rb_funcall(mSSL, rb_intern("verify_certificate_identity"), 2, + cert_obj, hostname); +} + static int ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { - VALUE cb; + VALUE cb, ssl_obj, verify_hostname, ret; SSL *ssl; + int status; ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx); - X509_STORE_CTX_set_ex_data(ctx, ossl_store_ctx_ex_verify_cb_idx, (void *)cb); - return ossl_verify_cb(preverify_ok, ctx); + ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); + verify_hostname = ossl_sslctx_get_verify_hostname(ossl_ssl_get_ctx(ssl_obj)); + + if (preverify_ok && RTEST(verify_hostname) && !SSL_is_server(ssl) && + !X509_STORE_CTX_get_error_depth(ctx)) { + ret = rb_protect(call_verify_certificate_identity, (VALUE)ctx, &status); + if (status) { + rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status)); + return 0; + } + preverify_ok = ret == Qtrue; + } + + return ossl_verify_cb_call(cb, preverify_ok, ctx); } static VALUE @@ -464,7 +497,7 @@ ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess) rb_ary_push(ary, sslctx_obj); rb_ary_push(ary, sess_obj); - rb_protect((VALUE(*)_((VALUE)))ossl_call_session_remove_cb, ary, &state); + rb_protect(ossl_call_session_remove_cb, ary, &state); if (state) { /* the SSL_CTX is frozen, nowhere to save state. @@ -540,7 +573,7 @@ ssl_servername_cb(SSL *ssl, int *ad, void *arg) rb_ary_push(ary, ssl_obj); rb_ary_push(ary, rb_str_new2(servername)); - rb_protect((VALUE(*)_((VALUE)))ossl_call_servername_cb, ary, &state); + rb_protect(ossl_call_servername_cb, ary, &state); if (state) { rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state)); return SSL_TLSEXT_ERR_ALERT_FATAL; @@ -624,8 +657,7 @@ ssl_npn_select_cb_common(VALUE cb, const unsigned char **out, unsigned char *out static int ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg) { - VALUE sslctx_obj = (VALUE) arg; - VALUE protocols = rb_iv_get(sslctx_obj, "@_protocols"); + VALUE protocols = (VALUE)arg; *out = (const unsigned char *) RSTRING_PTR(protocols); *outlen = RSTRING_LENINT(protocols); @@ -776,7 +808,7 @@ ossl_sslctx_setup(VALUE self) val = ossl_sslctx_get_cert(self); cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */ val = ossl_sslctx_get_key(self); - key = NIL_P(val) ? NULL : GetPKeyPtr(val); /* NO DUP NEEDED */ + key = NIL_P(val) ? NULL : GetPrivPKeyPtr(val); /* NO DUP NEEDED */ if (cert && key) { if (!SSL_CTX_use_certificate(ctx, cert)) { /* Adds a ref => Safe to FREE */ @@ -835,8 +867,8 @@ ossl_sslctx_setup(VALUE self) #ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB val = rb_iv_get(self, "@npn_protocols"); if (!NIL_P(val)) { - rb_iv_set(self, "@_protocols", ssl_encode_npn_protocols(val)); - SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *) self); + VALUE encoded = ssl_encode_npn_protocols(val); + SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)encoded); OSSL_Debug("SSL NPN advertise callback added"); } if (RTEST(rb_iv_get(self, "@npn_select_cb"))) { @@ -1744,7 +1776,13 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts) if (ssl_started(ssl)) { for (;;){ - nwrite = SSL_write(ssl, RSTRING_PTR(str), RSTRING_LENINT(str)); + int num = RSTRING_LENINT(str); + + /* SSL_write(3ssl) manpage states num == 0 is undefined */ + if (num == 0) + goto end; + + nwrite = SSL_write(ssl, RSTRING_PTR(str), num); switch(ssl_get_error(ssl, nwrite)){ case SSL_ERROR_NONE: goto end; @@ -2223,6 +2261,7 @@ Init_ossl_ssl(void) */ cSSLContext = rb_define_class_under(mSSL, "SSLContext", rb_cObject); rb_define_alloc_func(cSSLContext, ossl_sslctx_s_alloc); + rb_undef_method(cSSLContext, "initialize_copy"); /* * Context certificate @@ -2278,11 +2317,20 @@ Init_ossl_ssl(void) * +store_context+ is an OpenSSL::X509::StoreContext containing the * context used for certificate verification. * - * If the callback returns false verification is stopped. + * If the callback returns false, the chain verification is immediately + * stopped and a bad_certificate alert is then sent. */ rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse); /* + * Whether to check the server certificate is valid for the hostname. + * + * In order to make this work, verify_mode must be set to VERIFY_PEER and + * the server hostname must be given by OpenSSL::SSL::SSLSocket#hostname=. + */ + rb_attr(cSSLContext, rb_intern("verify_hostname"), 1, 1, Qfalse); + + /* * An OpenSSL::X509::Store used for certificate verification */ rb_attr(cSSLContext, rb_intern("cert_store"), 1, 1, Qfalse); @@ -2538,6 +2586,7 @@ Init_ossl_ssl(void) rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qfalse); rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc); rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1); + rb_undef_method(cSSLSocket, "initialize_copy"); rb_define_method(cSSLSocket, "connect", ossl_ssl_connect, 0); rb_define_method(cSSLSocket, "connect_nonblock", ossl_ssl_connect_nonblock, -1); rb_define_method(cSSLSocket, "accept", ossl_ssl_accept, 0); diff --git a/ext/openssl/ossl_ssl_session.c b/ext/openssl/ossl_ssl_session.c index 81d5c4e4..6ff670d5 100644 --- a/ext/openssl/ossl_ssl_session.c +++ b/ext/openssl/ossl_ssl_session.c @@ -73,6 +73,26 @@ static VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1) return self; } +static VALUE +ossl_ssl_session_initialize_copy(VALUE self, VALUE other) +{ + SSL_SESSION *sess, *sess_other, *sess_new; + + rb_check_frozen(self); + sess = RTYPEDDATA_DATA(self); /* XXX */ + SafeGetSSLSession(other, sess_other); + + sess_new = ASN1_dup((i2d_of_void *)i2d_SSL_SESSION, (d2i_of_void *)d2i_SSL_SESSION, + (char *)sess_other); + if (!sess_new) + ossl_raise(eSSLSession, "ASN1_dup"); + + RTYPEDDATA_DATA(self) = sess_new; + SSL_SESSION_free(sess); + + return self; +} + #if HAVE_SSL_SESSION_CMP == 0 int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b) { @@ -317,6 +337,7 @@ void Init_ossl_ssl_session(void) rb_define_alloc_func(cSSLSession, ossl_ssl_session_alloc); rb_define_method(cSSLSession, "initialize", ossl_ssl_session_initialize, 1); + rb_define_copy_func(cSSLSession, ossl_ssl_session_initialize_copy); rb_define_method(cSSLSession, "==", ossl_ssl_session_eq, 1); diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c index fc1690ce..6b7f9da4 100644 --- a/ext/openssl/ossl_x509attr.c +++ b/ext/openssl/ossl_x509attr.c @@ -130,6 +130,25 @@ ossl_x509attr_initialize(int argc, VALUE *argv, VALUE self) return self; } +static VALUE +ossl_x509attr_initialize_copy(VALUE self, VALUE other) +{ + X509_ATTRIBUTE *attr, *attr_other, *attr_new; + + rb_check_frozen(self); + GetX509Attr(self, attr); + SafeGetX509Attr(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); + + return self; +} + /* * call-seq: * attr.oid = string => string @@ -300,6 +319,7 @@ Init_ossl_x509attr(void) cX509Attr = rb_define_class_under(mX509, "Attribute", rb_cObject); rb_define_alloc_func(cX509Attr, ossl_x509attr_alloc); rb_define_method(cX509Attr, "initialize", ossl_x509attr_initialize, -1); + rb_define_copy_func(cX509Attr, ossl_x509attr_initialize_copy); rb_define_method(cX509Attr, "oid=", ossl_x509attr_set_oid, 1); rb_define_method(cX509Attr, "oid", ossl_x509attr_get_oid, 0); rb_define_method(cX509Attr, "value=", ossl_x509attr_set_value, 1); diff --git a/ext/openssl/ossl_x509ext.c b/ext/openssl/ossl_x509ext.c index 48daa6bb..021cc8ab 100644 --- a/ext/openssl/ossl_x509ext.c +++ b/ext/openssl/ossl_x509ext.c @@ -323,6 +323,25 @@ 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; + + rb_check_frozen(self); + GetX509Ext(self, ext); + SafeGetX509Ext(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); + + return self; +} + +static VALUE ossl_x509ext_set_oid(VALUE self, VALUE oid) { X509_EXTENSION *ext; @@ -475,6 +494,7 @@ Init_ossl_x509ext(void) cX509Ext = rb_define_class_under(mX509, "Extension", rb_cObject); rb_define_alloc_func(cX509Ext, ossl_x509ext_alloc); rb_define_method(cX509Ext, "initialize", ossl_x509ext_initialize, -1); + rb_define_copy_func(cX509Ext, ossl_x509ext_initialize_copy); rb_define_method(cX509Ext, "oid=", ossl_x509ext_set_oid, 1); rb_define_method(cX509Ext, "value=", ossl_x509ext_set_value, 1); rb_define_method(cX509Ext, "critical=", ossl_x509ext_set_critical, 1); diff --git a/ext/openssl/ossl_x509name.c b/ext/openssl/ossl_x509name.c index a99be7ee..f8cbbdb9 100644 --- a/ext/openssl/ossl_x509name.c +++ b/ext/openssl/ossl_x509name.c @@ -181,6 +181,25 @@ ossl_x509name_initialize(int argc, VALUE *argv, VALUE self) return self; } +static VALUE +ossl_x509name_initialize_copy(VALUE self, VALUE other) +{ + X509_NAME *name, *name_other, *name_new; + + rb_check_frozen(self); + GetX509Name(self, name); + SafeGetX509Name(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); + + return self; +} + /* * call-seq: * name.add_entry(oid, value [, type]) => self @@ -464,6 +483,7 @@ Init_ossl_x509name(void) rb_define_alloc_func(cX509Name, ossl_x509name_alloc); rb_define_method(cX509Name, "initialize", ossl_x509name_initialize, -1); + rb_define_copy_func(cX509Name, ossl_x509name_initialize_copy); rb_define_method(cX509Name, "add_entry", ossl_x509name_add_entry, -1); rb_define_method(cX509Name, "to_s", ossl_x509name_to_s, -1); rb_define_method(cX509Name, "to_a", ossl_x509name_to_a, 0); diff --git a/ext/openssl/ossl_x509revoked.c b/ext/openssl/ossl_x509revoked.c index 87a9b323..6f170077 100644 --- a/ext/openssl/ossl_x509revoked.c +++ b/ext/openssl/ossl_x509revoked.c @@ -110,6 +110,25 @@ 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; + + rb_check_frozen(self); + GetX509Rev(self, rev); + SafeGetX509Rev(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); + + return self; +} + +static VALUE ossl_x509revoked_get_serial(VALUE self) { X509_REVOKED *rev; @@ -239,6 +258,7 @@ Init_ossl_x509revoked(void) rb_define_alloc_func(cX509Rev, ossl_x509revoked_alloc); rb_define_method(cX509Rev, "initialize", ossl_x509revoked_initialize, -1); + rb_define_copy_func(cX509Rev, ossl_x509revoked_initialize_copy); rb_define_method(cX509Rev, "serial", ossl_x509revoked_get_serial, 0); rb_define_method(cX509Rev, "serial=", ossl_x509revoked_set_serial, 1); diff --git a/ext/openssl/ossl_x509store.c b/ext/openssl/ossl_x509store.c index f3d6bf3b..10bae172 100644 --- a/ext/openssl/ossl_x509store.c +++ b/ext/openssl/ossl_x509store.c @@ -106,6 +106,20 @@ DupX509StorePtr(VALUE obj) /* * Private functions */ +static int +x509store_verify_cb(int ok, X509_STORE_CTX *ctx) +{ + VALUE proc; + + proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, ossl_store_ctx_ex_verify_cb_idx); + if (!proc) + proc = (VALUE)X509_STORE_get_ex_data(X509_STORE_CTX_get0_store(ctx), ossl_store_ex_verify_cb_idx); + if (!proc) + return ok; + + return ossl_verify_cb_call(proc, ok, ctx); +} + static VALUE ossl_x509store_alloc(VALUE klass) { @@ -153,7 +167,7 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self) /* [Bug #405] [Bug #1678] [Bug #3000]; already fixed? */ store->ex_data.sk = NULL; #endif - X509_STORE_set_verify_cb(store, ossl_verify_cb); + X509_STORE_set_verify_cb(store, x509store_verify_cb); ossl_x509store_set_vfy_cb(self, Qnil); /* last verification status */ @@ -661,6 +675,7 @@ Init_ossl_x509store(void) rb_attr(cX509Store, rb_intern("chain"), 1, 0, Qfalse); rb_define_alloc_func(cX509Store, ossl_x509store_alloc); rb_define_method(cX509Store, "initialize", ossl_x509store_initialize, -1); + rb_undef_method(cX509Store, "initialize_copy"); rb_define_method(cX509Store, "verify_callback=", ossl_x509store_set_vfy_cb, 1); rb_define_method(cX509Store, "flags=", ossl_x509store_set_flags, 1); rb_define_method(cX509Store, "purpose=", ossl_x509store_set_purpose, 1); @@ -677,6 +692,7 @@ Init_ossl_x509store(void) x509stctx = cX509StoreContext; rb_define_alloc_func(cX509StoreContext, ossl_x509stctx_alloc); rb_define_method(x509stctx,"initialize", ossl_x509stctx_initialize, -1); + rb_undef_method(x509stctx, "initialize_copy"); rb_define_method(x509stctx,"verify", ossl_x509stctx_verify, 0); rb_define_method(x509stctx,"chain", ossl_x509stctx_get_chain,0); rb_define_method(x509stctx,"error", ossl_x509stctx_get_err, 0); |