From 61949eefde17da5497fe28cbbe311e459073296f Mon Sep 17 00:00:00 2001 From: gotoyuzo Date: Wed, 26 May 2004 18:14:27 +0000 Subject: * add test for OpenSSL::SSL. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6412 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/openssl/ssl_server.rb | 78 +++++++++++++++++++ test/openssl/test_ssl.rb | 184 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 262 insertions(+) create mode 100644 test/openssl/ssl_server.rb create mode 100644 test/openssl/test_ssl.rb (limited to 'test/openssl') diff --git a/test/openssl/ssl_server.rb b/test/openssl/ssl_server.rb new file mode 100644 index 0000000000..53e520379b --- /dev/null +++ b/test/openssl/ssl_server.rb @@ -0,0 +1,78 @@ +require "socket" +require "thread" +require "openssl" +require File.join(File.dirname(__FILE__), "utils.rb") + +def get_pem(io=$stdin) + buf = "" + while line = io.gets + if /^-----BEGIN / =~ line + buf << line + break + end + end + while line = io.gets + buf << line + if /^-----END / =~ line + break + end + end + return buf +end + +def make_key(pem) + begin + return OpenSSL::PKey::RSA.new(pem) + rescue + return OpenSSL::PKey::DSA.new(pem) + end +end + +ca_cert = OpenSSL::X509::Certificate.new(get_pem) +ssl_cert = OpenSSL::X509::Certificate.new(get_pem) +ssl_key = make_key(get_pem) +port = Integer(ARGV.shift) +verify_mode = Integer(ARGV.shift) +start_immediately = (/yes/ =~ ARGV.shift) + +store = OpenSSL::X509::Store.new +store.add_cert(ca_cert) +store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT +ctx = OpenSSL::SSL::SSLContext.new +ctx.cert_store = store +#ctx.extra_chain_cert = [ ca_cert ] +ctx.cert = ssl_cert +ctx.key = ssl_key +ctx.verify_mode = verify_mode + +Socket.do_not_reverse_lookup = true +tcps = TCPServer.new("0.0.0.0", port) +ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx) +ssls.start_immediately = start_immediately +ssock = nil + +Thread.start{ + while line = $stdin.gets + if /STARTTLS/ =~ line + ssock && ssock.accept + end + end + exit +} + +$stdout.sync = true +$stdout.puts Process.pid + +loop do + s = ssls.accept + ssock = s + Thread.start{ + q = Queue.new + th = Thread.start{ s.write(q.shift) while true } + while line = s.gets + q.push(line) + end + th.kill + s.close unless s.closed? + } +end diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb new file mode 100644 index 0000000000..e0517f9953 --- /dev/null +++ b/test/openssl/test_ssl.rb @@ -0,0 +1,184 @@ +begin + require "openssl" + require File.join(File.dirname(__FILE__), "utils.rb") +rescue LoadError +end +require "rbconfig" +require "socket" +require "test/unit" + +if defined?(OpenSSL) + +class OpenSSL::TestSSL < Test::Unit::TestCase + RUBY = ENV["RUBY"] || File.join( + ::Config::CONFIG["bindir"], + ::Config::CONFIG["ruby_install_name"] + ::Config::CONFIG["EXEEXT"] + ) + SSL_SERVER = File.join(File.dirname(__FILE__), "ssl_server.rb") + PORT = 20443 + ITERATIONS = ($0 == __FILE__) ? 100 : 10 + + def setup + @ca_key = OpenSSL::TestUtils::TEST_KEY_RSA2048 + @svr_key = OpenSSL::TestUtils::TEST_KEY_RSA1024 + @cli_key = OpenSSL::TestUtils::TEST_KEY_DSA256 + @ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA") + @svr = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost") + @cli = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost") + + now = Time.at(Time.now.to_i) + ca_exts = [ + ["basicConstraints","CA:TRUE",true], + ["keyUsage","cRLSign,keyCertSign",true], + ] + ee_exts = [ + ["keyUsage","keyEncipherment,digitalSignature",true], + ] + @ca_cert = issue_cert(@ca, @ca_key, 1, now, now+3600, ca_exts, + nil, nil, OpenSSL::Digest::SHA1.new) + @svr_cert = issue_cert(@svr, @svr_key, 2, now, now+1800, ee_exts, + @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new) + @cli_cert = issue_cert(@cli, @cli_key, 3, now, now+1800, ee_exts, + @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new) + @server = nil + end + + def teardown + end + + def issue_cert(*arg) + OpenSSL::TestUtils.issue_cert(*arg) + end + + def issue_crl(*arg) + OpenSSL::TestUtils.issue_crl(*arg) + end + + def start_server(port, verify_mode, start_immediately, &block) + server = nil + begin + cmd = [RUBY] + cmd << "-d" if $DEBUG + cmd << SSL_SERVER << port.to_s << verify_mode.to_s + cmd << (start_immediately ? "yes" : "no") + server = IO.popen(cmd, "w+") + server.write(@ca_cert.to_pem) + server.write(@svr_cert.to_pem) + server.write(@svr_key.to_pem) + def server.starttls; self.puts("STARTTLS") end + pid = Integer(server.gets) + $stderr.printf("%s started: pid=%d\n", SSL_SERVER, pid) if $DEBUG + block.call(server) + ensure + server.close if server + end + end + + def test_connect_and_close + start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){ + sock = TCPSocket.new("127.0.0.1", PORT) + ssl = OpenSSL::SSL::SSLSocket.new(sock) + assert(ssl.connect) + ssl.close + assert(!sock.closed?) + sock.close + + sock = TCPSocket.new("127.0.0.1", PORT) + ssl = OpenSSL::SSL::SSLSocket.new(sock) + ssl.sync_close = true # !! + assert(ssl.connect) + ssl.close + assert(sock.closed?) + } + end + + def test_read_and_write + start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){ + sock = TCPSocket.new("127.0.0.1", PORT) + ssl = OpenSSL::SSL::SSLSocket.new(sock) + ssl.sync_close = true + ssl.connect + + # syswrite and sysread + ITERATIONS.times{|i| + str = "x" * 100 + "\n" + ssl.syswrite(str) + assert_equal(str, ssl.sysread(str.size)) + + str = "x" * i * 100 + "\n" + buf = "" + ssl.syswrite(str) + assert_equal(buf.object_id, ssl.sysread(str.size, buf).object_id) + assert_equal(str, buf) + } + + # puts and gets + ITERATIONS.times{ + str = "x" * 100 + "\n" + ssl.puts(str) + assert_equal(str, ssl.gets) + } + + # read and write + ITERATIONS.times{|i| + str = "x" * 100 + "\n" + ssl.write(str) + assert_equal(str, ssl.read(str.size)) + + str = "x" * i * 100 + "\n" + buf = "" + ssl.write(str) + assert_equal(buf.object_id, ssl.read(str.size, buf).object_id) + assert_equal(str, buf) + } + + ssl.close + } + end + + def test_starttls + start_server(PORT, OpenSSL::SSL::VERIFY_NONE, false){|s| + sock = TCPSocket.new("127.0.0.1", PORT) + ssl = OpenSSL::SSL::SSLSocket.new(sock) + ssl.sync_close = true + str = "x" * 1000 + "\n" + + ITERATIONS.times{ + ssl.puts(str) + assert_equal(str, ssl.gets) + } + + s.starttls + ssl.connect + + ITERATIONS.times{ + ssl.puts(str) + assert_equal(str, ssl.gets) + } + + ssl.close + } + end + + def test_parallel + start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){ + ssls = [] + 10.times{ + sock = TCPSocket.new("127.0.0.1", PORT) + ssl = OpenSSL::SSL::SSLSocket.new(sock) + ssl.connect + ssl.sync_close = true + ssls << ssl + } + str = "x" * 1000 + "\n" + ITERATIONS.times{ + ssls.each{|ssl| + ssl.puts(str) + assert_equal(str, ssl.gets) + } + } + } + end +end + +end -- cgit v1.2.3