aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2016-06-28 23:38:05 +0900
committerKazuki Yamaguchi <k@rhe.jp>2016-08-04 21:38:36 +0900
commit6dc9b914cae52c8af6e1b4d1156613bcd914eaf5 (patch)
tree1c08759e790e6daa81cda32a063d6b20b26a9b31
parentbf120798efa43c9db6c68e75037fc0a0c4735703 (diff)
downloadruby-openssl-6dc9b914cae52c8af6e1b4d1156613bcd914eaf5.tar.gz
Implement missing initialize_copytopic/fix-initialize-copy
Implement initialize_copy for: - OpenSSL::PKCS12 - OpenSSL::SSL::SSLSession - OpenSSL::X509::Attribute - OpenSSL::X509::Extension - OpenSSL::X509::Name - OpenSSL::X509::Revoked Remove initialize_copy from: - OpenSSL::SSL::SSLContext - OpenSSL::SSL::SSLSocket - OpenSSL::Engine - OpenSSL::X509::Store - OpenSSL::X509::StoreContext [Bug #12381]
-rw-r--r--ext/openssl/ossl_engine.c1
-rw-r--r--ext/openssl/ossl_pkcs12.c20
-rw-r--r--ext/openssl/ossl_ssl.c2
-rw-r--r--ext/openssl/ossl_ssl_session.c21
-rw-r--r--ext/openssl/ossl_x509attr.c20
-rw-r--r--ext/openssl/ossl_x509ext.c20
-rw-r--r--ext/openssl/ossl_x509name.c20
-rw-r--r--ext/openssl/ossl_x509revoked.c20
-rw-r--r--ext/openssl/ossl_x509store.c2
-rw-r--r--test/test_engine.rb7
-rw-r--r--test/test_pkcs12.rb5
-rw-r--r--test/test_ssl.rb15
-rw-r--r--test/test_ssl_session.rb6
-rw-r--r--test/test_x509attr.rb8
-rw-r--r--test/test_x509ext.rb6
-rw-r--r--test/test_x509name.rb5
-rw-r--r--test/test_x509req.rb5
-rw-r--r--test/test_x509store.rb7
18 files changed, 189 insertions, 1 deletions
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 9ad43c82..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]]]]]])
@@ -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_ssl.c b/ext/openssl/ossl_ssl.c
index 20a9fcfd..aab54a5a 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -2256,6 +2256,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
@@ -2580,6 +2581,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 ba34a056..10bae172 100644
--- a/ext/openssl/ossl_x509store.c
+++ b/ext/openssl/ossl_x509store.c
@@ -675,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);
@@ -691,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);
diff --git a/test/test_engine.rb b/test/test_engine.rb
index 1aa105f1..c236bd69 100644
--- a/test/test_engine.rb
+++ b/test/test_engine.rb
@@ -72,6 +72,13 @@ class OpenSSL::TestEngine < OpenSSL::TestCase
end;
end
+ def test_dup
+ with_openssl <<-'end;'
+ engine = get_engine
+ assert_raise(NoMethodError) { engine.dup }
+ end;
+ end
+
private
# this is required because OpenSSL::Engine methods change global state
diff --git a/test/test_pkcs12.rb b/test/test_pkcs12.rb
index 61fb4474..7ab501c4 100644
--- a/test/test_pkcs12.rb
+++ b/test/test_pkcs12.rb
@@ -180,6 +180,11 @@ Li8JsX5yIiuVYaBg/6ha3tOg4TCa5K/3r3tVliRZ2Es=
end
end
+ def test_dup
+ p12 = OpenSSL::PKCS12.create("pass", "name", TEST_KEY_RSA1024, @mycert)
+ assert_equal p12.to_der, p12.dup.to_der
+ end
+
private
def assert_cert expected, actual
[
diff --git a/test/test_ssl.rb b/test/test_ssl.rb
index 385eaee0..e7af8232 100644
--- a/test/test_ssl.rb
+++ b/test/test_ssl.rb
@@ -879,7 +879,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
return unless OpenSSL::SSL::SSLSocket.instance_methods.include?(:hostname)
ctx_proc = Proc.new do |ctx, ssl|
- foo_ctx = ctx.dup
+ foo_ctx = OpenSSL::SSL::SSLContext.new
ctx.servername_cb = Proc.new do |ssl2, hostname|
case hostname
@@ -1314,6 +1314,19 @@ end
pend "FIXME: SSLContext#key= currently does not raise because SSL_CTX_use_certificate() is delayed"
end
+ def test_dup
+ ctx = OpenSSL::SSL::SSLContext.new
+ sock1, sock2 = socketpair
+ ssl = OpenSSL::SSL::SSLSocket.new(sock1, ctx)
+
+ assert_raise(NoMethodError) { ctx.dup }
+ assert_raise(NoMethodError) { ssl.dup }
+ ensure
+ ssl.close if ssl
+ sock1.close
+ sock2.close
+ end
+
private
def start_server_version(version, ctx_proc=nil, server_proc=nil, &blk)
diff --git a/test/test_ssl_session.rb b/test/test_ssl_session.rb
index 84686f6b..9bcec101 100644
--- a/test/test_ssl_session.rb
+++ b/test/test_ssl_session.rb
@@ -369,6 +369,12 @@ __EOS__
assert(called[:get1])
assert(called[:get2])
end
+
+ def test_dup
+ sess_orig = OpenSSL::SSL::Session.new(DUMMY_SESSION)
+ sess_dup = sess_orig.dup
+ assert_equal(sess_orig.to_der, sess_dup.to_der)
+ end
end
end
diff --git a/test/test_x509attr.rb b/test/test_x509attr.rb
index 1ba8a875..69b8189b 100644
--- a/test/test_x509attr.rb
+++ b/test/test_x509attr.rb
@@ -51,6 +51,14 @@ class OpenSSL::TestX509Attribute < OpenSSL::TestCase
}
assert_equal(test_der, attr.to_der)
end
+
+ def test_dup
+ val = OpenSSL::ASN1::Set([
+ OpenSSL::ASN1::UTF8String("abc123")
+ ])
+ attr = OpenSSL::X509::Attribute.new("challengePassword", val)
+ assert_equal(attr.to_der, attr.dup.to_der)
+ end
end
end
diff --git a/test/test_x509ext.rb b/test/test_x509ext.rb
index 99e2eda5..33989873 100644
--- a/test/test_x509ext.rb
+++ b/test/test_x509ext.rb
@@ -62,6 +62,12 @@ class OpenSSL::TestX509Extension < OpenSSL::TestCase
%r{URI:ldap://ldap.example.com/cn=ca\?certificateRevocationList;binary},
cdp.value)
end
+
+ def test_dup
+ ext = OpenSSL::X509::Extension.new(@basic_constraints.to_der)
+ assert_equal(@basic_constraints.to_der, ext.to_der)
+ assert_equal(ext.to_der, ext.dup.to_der)
+ end
end
end
diff --git a/test/test_x509name.rb b/test/test_x509name.rb
index b87d415d..250f1d09 100644
--- a/test/test_x509name.rb
+++ b/test/test_x509name.rb
@@ -355,6 +355,11 @@ class OpenSSL::TestX509Name < OpenSSL::TestCase
expected = (d[0].ord & 0xff) | (d[1].ord & 0xff) << 8 | (d[2].ord & 0xff) << 16 | (d[3].ord & 0xff) << 24
assert_equal(expected, name_hash(name))
end
+
+ def test_dup
+ name = OpenSSL::X509::Name.parse("/CN=ruby-lang.org")
+ assert_equal(name.to_der, name.dup.to_der)
+ end
end
end
diff --git a/test/test_x509req.rb b/test/test_x509req.rb
index 287e2c18..086ccfbd 100644
--- a/test/test_x509req.rb
+++ b/test/test_x509req.rb
@@ -147,6 +147,11 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase
issue_csr(0, @dn, @dsa512, OpenSSL::Digest::MD5.new) }
end
+ def test_dup
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
+ assert_equal(req.to_der, req.dup.to_der)
+ end
+
private
def request_error_returns_false
diff --git a/test/test_x509store.rb b/test/test_x509store.rb
index 8dee1679..e0fa07ac 100644
--- a/test/test_x509store.rb
+++ b/test/test_x509store.rb
@@ -222,6 +222,13 @@ class OpenSSL::TestX509Store < OpenSSL::TestCase
}
end
end
+
+ def test_dup
+ store = OpenSSL::X509::Store.new
+ assert_raise(NoMethodError) { store.dup }
+ ctx = OpenSSL::X509::StoreContext.new(store)
+ assert_raise(NoMethodError) { ctx.dup }
+ end
end
end