diff --git a/ChangeLog b/ChangeLog index a14ce74421..23df84c71f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Sun Dec 13 23:07:05 2009 NAKAMURA, Hiroshi + + * test/openssl/*: added some tests from jruby-openssl. + Mon Dec 7 07:05:05 2009 Marc-Andre Lafortune * lib/bigdecimal.rb: fix comparison operators [ruby-core:26646] diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb index d671908165..173e757d8c 100644 --- a/test/openssl/test_cipher.rb +++ b/test/openssl/test_cipher.rb @@ -1,3 +1,10 @@ +if defined?(JRUBY_VERSION) + require "java" + base = File.join(File.dirname(__FILE__), '..', '..') + $CLASSPATH << File.join(base, 'pkg', 'classes') + $CLASSPATH << File.join(base, 'lib', 'bcprov-jdk15-144.jar') +end + begin require "openssl" rescue LoadError @@ -12,6 +19,7 @@ class OpenSSL::TestCipher < Test::Unit::TestCase @c2 = OpenSSL::Cipher::DES.new(:EDE3, "CBC") @key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" @iv = "\0\0\0\0\0\0\0\0" + @iv1 = "\1\1\1\1\1\1\1\1" @hexkey = "0000000000000000000000000000000000000000000000" @hexiv = "0000000000000000" @data = "DATA" @@ -63,9 +71,80 @@ class OpenSSL::TestCipher < Test::Unit::TestCase assert_equal(s1, s2, "encrypt reset") end + def test_set_iv + @c1.encrypt + @c1.key = @key + @c1.iv = @iv + s1 = @c1.update(@data) + @c1.final + @c1.iv = @iv1 + s1 += @c1.update(@data) + @c1.final + @c1.reset + @c1.iv = @iv + s2 = @c1.update(@data) + @c1.final + @c1.iv = @iv1 + s2 += @c1.update(@data) + @c1.final + assert_equal(s1, s2, "encrypt reset") + end + def test_empty_data @c1.encrypt - assert_raises(ArgumentError){ @c1.update("") } + assert_raise(ArgumentError){ @c1.update("") } + end + + def test_disable_padding(padding=0) + # assume a padding size of 8 + # encrypt the data with padding + @c1.encrypt + @c1.key = @key + @c1.iv = @iv + encrypted_data = @c1.update(@data) + @c1.final + assert_equal(8, encrypted_data.size) + # decrypt with padding disabled + @c1.decrypt + @c1.padding = padding + decrypted_data = @c1.update(encrypted_data) + @c1.final + # check that the result contains the padding + assert_equal(8, decrypted_data.size) + assert_equal(@data, decrypted_data[0...@data.size]) + end + + if PLATFORM =~ /java/ + # JRuby extension - using Java padding types + + def test_disable_padding_javastyle + test_disable_padding('NoPadding') + end + + def test_iso10126_padding + @c1.encrypt + @c1.key = @key + @c1.iv = @iv + @c1.padding = 'ISO10126Padding' + encrypted_data = @c1.update(@data) + @c1.final + # decrypt with padding disabled to see the padding + @c1.decrypt + @c1.padding = 0 + decrypted_data = @c1.update(encrypted_data) + @c1.final + assert_equal(@data, decrypted_data[0...@data.size]) + # last byte should be the amount of padding + assert_equal(4, decrypted_data[-1]) + end + + def test_iso10126_padding_boundry + @data = 'HELODATA' # 8 bytes, same as padding size + @c1.encrypt + @c1.key = @key + @c1.iv = @iv + @c1.padding = 'ISO10126Padding' + encrypted_data = @c1.update(@data) + @c1.final + # decrypt with padding disabled to see the padding + @c1.decrypt + @c1.padding = 0 + decrypted_data = @c1.update(encrypted_data) + @c1.final + assert_equal(@data, decrypted_data[0...@data.size]) + # padding should be one whole block + assert_equal(8, decrypted_data[-1]) + end end if OpenSSL::OPENSSL_VERSION_NUMBER > 0x00907000 @@ -90,6 +169,30 @@ class OpenSSL::TestCipher < Test::Unit::TestCase } end end + + # JRUBY-4028 + def test_jruby_4028 + key = "0599E113A7EE32A9" + data = "1234567890~5J96LC303C1D22DD~20090930005944~http%3A%2F%2Flocalhost%3A8080%2Flogin%3B0%3B1~http%3A%2F%2Fmix-stage.oracle.com%2F~00" + c1 = OpenSSL::Cipher::Cipher.new("DES-CBC") + c1.padding = 0 + c1.iv = "0" * 8 + c1.encrypt + c1.key = key + e = c1.update data + e << c1.final + + c2 = OpenSSL::Cipher::Cipher.new("DES-CBC") + c2.padding = 0 + c2.iv = "0" * 8 + c2.decrypt + c2.key = key + d = c2.update e + d << c2.final + + assert_equal "\342\320B.\300&X\310\344\253\025\215\017*\22015\344\024D\342\213\361\336\311\271\326\016\243\214\026\2545\002\237,\017s\202\316&Ew\323\221H\376\200\304\201\365\332Im\240\361\037\246\3536\001A2\341\324o0\350\364%=\325\330\240\324u\225\304h\277\272\361f\024\324\352\336\353N\002/]C\370!\003)\212oa\225\207\333\340\245\207\024\351\037\327[\212\001{\216\f\315\345\372\v\226\r\233?\002\vJK", e + assert_equal data, d + end end end diff --git a/test/openssl/test_ec.rb b/test/openssl/test_ec.rb index 671901ca36..66dbf54b4d 100644 --- a/test/openssl/test_ec.rb +++ b/test/openssl/test_ec.rb @@ -89,7 +89,7 @@ class OpenSSL::TestEC < Test::Unit::TestCase sig = key.dsa_sign_asn1(@data1) assert_equal(key.dsa_verify_asn1(@data1, sig), true) - assert_raises(OpenSSL::PKey::ECError) { key.dsa_sign_asn1(@data2) } + assert_raise(OpenSSL::PKey::ECError) { key.dsa_sign_asn1(@data2) } end end diff --git a/test/openssl/test_hmac.rb b/test/openssl/test_hmac.rb index 2f8d6bba20..adcb6f719c 100644 --- a/test/openssl/test_hmac.rb +++ b/test/openssl/test_hmac.rb @@ -29,6 +29,16 @@ class OpenSSL::TestHMAC < Test::Unit::TestCase h = @h1.dup assert_equal(@h1.digest, h.digest, "dup digest") end + + def test_sha256 + digest256 = OpenSSL::Digest::Digest.new("sha256") + assert_equal( + "\210\236-\3270\331Yq\265\177sE\266\231hXa\332\250\026\235O&c*\307\001\227~\260n\362", + OpenSSL::HMAC.digest(digest256, 'blah', "blah")) + assert_equal( + "889e2dd730d95971b57f7345b699685861daa8169d4f26632ac701977eb06ef2", + OpenSSL::HMAC.hexdigest(digest256, 'blah', "blah")) + end end end diff --git a/test/openssl/test_ns_spki.rb b/test/openssl/test_ns_spki.rb index 3937132aa0..7b3806b830 100644 --- a/test/openssl/test_ns_spki.rb +++ b/test/openssl/test_ns_spki.rb @@ -22,6 +22,16 @@ class OpenSSL::TestNSSPI < Test::Unit::TestCase def teardown end +def pr(obj, ind=0) + if obj.respond_to?(:value) + puts((" "*ind) + obj.class.to_s + ":") + pr(obj.value,(ind+1)) + elsif obj.respond_to?(:each) && !(String===obj) + obj.each {|v| pr(v,ind+1) } + else + puts((" "*ind) + obj.inspect) + end +end def test_build_data key1 = OpenSSL::TestUtils::TEST_KEY_RSA1024 diff --git a/test/openssl/test_pkcs7.rb b/test/openssl/test_pkcs7.rb index 9b472c1795..cb57ddce71 100644 --- a/test/openssl/test_pkcs7.rb +++ b/test/openssl/test_pkcs7.rb @@ -28,6 +28,7 @@ class OpenSSL::TestPKCS7 < Test::Unit::TestCase ["keyUsage","Non Repudiation, Digital Signature, Key Encipherment",true], ["authorityKeyIdentifier","keyid:always",false], ["extendedKeyUsage","clientAuth, emailProtection, codeSigning",false], + ["nsCertType","client,email",false], ] @ee1_cert = issue_cert(ee1, @rsa1024, 2, Time.now, Time.now+1800, ee_exts, @ca_cert, @rsa2048, OpenSSL::Digest::SHA1.new) diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb index d1cee84f4a..9c21d428bb 100644 --- a/test/openssl/test_ssl.rb +++ b/test/openssl/test_ssl.rb @@ -6,6 +6,8 @@ end require "rbconfig" require "socket" require "test/unit" +require 'tempfile' + begin loadpath = $:.dup $:.replace($: | [File.expand_path("../ruby", File.dirname(__FILE__))]) @@ -58,6 +60,20 @@ class OpenSSL::TestSSL < Test::Unit::TestCase OpenSSL::TestUtils.issue_crl(*arg) end + def choose_port(port) + tcps = nil + 100.times{ |i| + begin + tcps = TCPServer.new("127.0.0.1", port+i) + port = port + i + break + rescue Errno::EADDRINUSE + next + end + } + return tcps, port + end + def readwrite_loop(ctx, ssl) while line = ssl.gets if line =~ /^STARTTLS$/ @@ -78,11 +94,11 @@ class OpenSSL::TestSSL < Test::Unit::TestCase begin ssl = ssls.accept rescue OpenSSL::SSL::SSLError - retry + retry end Thread.start do - Thread.current.abort_on_exception = true + Thread.current.abort_on_exception = true server_proc.call(ctx, ssl) end end @@ -93,7 +109,7 @@ class OpenSSL::TestSSL < Test::Unit::TestCase ctx_proc = args[:ctx_proc] server_proc = args[:server_proc] server_proc ||= method(:readwrite_loop) - + store = OpenSSL::X509::Store.new store.add_cert(@ca_cert) store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT @@ -106,8 +122,7 @@ class OpenSSL::TestSSL < Test::Unit::TestCase ctx_proc.call(ctx) if ctx_proc Socket.do_not_reverse_lookup = true - tcps = nil - port = port0 + tcps, port = choose_port(port0) begin tcps = TCPServer.new("127.0.0.1", port) rescue Errno::EADDRINUSE @@ -120,11 +135,11 @@ class OpenSSL::TestSSL < Test::Unit::TestCase begin server = Thread.new do - Thread.current.abort_on_exception = true + Thread.current.abort_on_exception = true server_loop(ctx, ssls, server_proc) end - $stderr.printf("%s started: pid=%d port=%d\n", SSL_SERVER, pid, port) if $DEBUG + $stderr.printf("%s started: pid=%d port=%d\n", SSL_SERVER, $$, port) if $DEBUG block.call(server, port.to_i) ensure @@ -133,7 +148,7 @@ class OpenSSL::TestSSL < Test::Unit::TestCase server.join(5) if server.alive? server.kill - server.join + server.join(5) flunk("TCPServer was closed and SSLServer is still alive") unless $! end end @@ -180,6 +195,8 @@ class OpenSSL::TestSSL < Test::Unit::TestCase ssl.sync_close = true ssl.connect + assert_raise(ArgumentError) { ssl.sysread(-1) } + # syswrite and sysread ITERATIONS.times{|i| str = "x" * 100 + "\n" @@ -193,6 +210,13 @@ class OpenSSL::TestSSL < Test::Unit::TestCase 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" @@ -213,7 +237,7 @@ class OpenSSL::TestSSL < Test::Unit::TestCase def test_client_auth vflag = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT start_server(PORT, vflag, true){|server, port| - assert_raises(OpenSSL::SSL::SSLError){ + assert_raise(OpenSSL::SSL::SSLError){ sock = TCPSocket.new("127.0.0.1", port) ssl = OpenSSL::SSL::SSLSocket.new(sock) ssl.connect @@ -247,6 +271,82 @@ class OpenSSL::TestSSL < Test::Unit::TestCase } end + def test_client_auth_with_server_store + vflag = OpenSSL::SSL::VERIFY_PEER + + localcacert_file = Tempfile.open("cafile") + localcacert_file << @ca_cert.to_pem + localcacert_file.close + localcacert_path = localcacert_file.path + + ssl_store = OpenSSL::X509::Store.new + ssl_store.purpose = OpenSSL::X509::PURPOSE_ANY + ssl_store.add_file(localcacert_path) + + args = {} + args[:ctx_proc] = proc { |server_ctx| + server_ctx.cert = @svr_cert + server_ctx.key = @svr_key + server_ctx.verify_mode = vflag + server_ctx.cert_store = ssl_store + } + + start_server(PORT, vflag, true, args){|server, port| + ctx = OpenSSL::SSL::SSLContext.new + ctx.cert = @cli_cert + ctx.key = @cli_key + sock = TCPSocket.new("127.0.0.1", port) + ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx) + ssl.sync_close = true + ssl.connect + ssl.puts("foo") + assert_equal("foo\n", ssl.gets) + ssl.close + localcacert_file.unlink + } + end + + def test_client_crl_with_server_store + vflag = OpenSSL::SSL::VERIFY_PEER + + localcacert_file = Tempfile.open("cafile") + localcacert_file << @ca_cert.to_pem + localcacert_file.close + localcacert_path = localcacert_file.path + + ssl_store = OpenSSL::X509::Store.new + ssl_store.purpose = OpenSSL::X509::PURPOSE_ANY + ssl_store.add_file(localcacert_path) + ssl_store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK + + crl = issue_crl([], 1, Time.now, Time.now+1600, [], + @cli_cert, @ca_key, OpenSSL::Digest::SHA1.new) + + ssl_store.add_crl(OpenSSL::X509::CRL.new(crl.to_pem)) + + args = {} + args[:ctx_proc] = proc { |server_ctx| + server_ctx.cert = @svr_cert + server_ctx.key = @svr_key + server_ctx.verify_mode = vflag + server_ctx.cert_store = ssl_store + } + + start_server(PORT, vflag, true, args){|s, p| + ctx = OpenSSL::SSL::SSLContext.new + ctx.cert = @cli_cert + ctx.key = @cli_key + assert_raise(OpenSSL::SSL::SSLError){ + sock = TCPSocket.new("127.0.0.1", p) + ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx) + ssl.sync_close = true + ssl.connect + ssl.close + } + localcacert_file.unlink + } + end + def test_starttls start_server(PORT, OpenSSL::SSL::VERIFY_NONE, false){|server, port| sock = TCPSocket.new("127.0.0.1", port) @@ -352,10 +452,10 @@ class OpenSSL::TestSSL < Test::Unit::TestCase sock = TCPSocket.new("127.0.0.1", port) ssl = OpenSSL::SSL::SSLSocket.new(sock) ssl.connect - assert_raises(sslerr){ssl.post_connection_check("localhost.localdomain")} - assert_raises(sslerr){ssl.post_connection_check("127.0.0.1")} + assert_raise(sslerr){ssl.post_connection_check("localhost.localdomain")} + assert_raise(sslerr){ssl.post_connection_check("127.0.0.1")} assert(ssl.post_connection_check("localhost")) - assert_raises(sslerr){ssl.post_connection_check("foo.example.com")} + assert_raise(sslerr){ssl.post_connection_check("foo.example.com")} cert = ssl.peer_cert assert(!OpenSSL::SSL.verify_certificate_identity(cert, "localhost.localdomain")) @@ -378,8 +478,8 @@ class OpenSSL::TestSSL < Test::Unit::TestCase ssl.connect assert(ssl.post_connection_check("localhost.localdomain")) assert(ssl.post_connection_check("127.0.0.1")) - assert_raises(sslerr){ssl.post_connection_check("localhost")} - assert_raises(sslerr){ssl.post_connection_check("foo.example.com")} + assert_raise(sslerr){ssl.post_connection_check("localhost")} + assert_raise(sslerr){ssl.post_connection_check("foo.example.com")} cert = ssl.peer_cert assert(OpenSSL::SSL.verify_certificate_identity(cert, "localhost.localdomain")) @@ -400,9 +500,9 @@ class OpenSSL::TestSSL < Test::Unit::TestCase ssl = OpenSSL::SSL::SSLSocket.new(sock) ssl.connect assert(ssl.post_connection_check("localhost.localdomain")) - assert_raises(sslerr){ssl.post_connection_check("127.0.0.1")} - assert_raises(sslerr){ssl.post_connection_check("localhost")} - assert_raises(sslerr){ssl.post_connection_check("foo.example.com")} + assert_raise(sslerr){ssl.post_connection_check("127.0.0.1")} + assert_raise(sslerr){ssl.post_connection_check("localhost")} + assert_raise(sslerr){ssl.post_connection_check("foo.example.com")} cert = ssl.peer_cert assert(OpenSSL::SSL.verify_certificate_identity(cert, "localhost.localdomain")) assert(!OpenSSL::SSL.verify_certificate_identity(cert, "127.0.0.1")) diff --git a/test/openssl/test_x509cert.rb b/test/openssl/test_x509cert.rb index a5a75ff1b6..dd52ab9644 100644 --- a/test/openssl/test_x509cert.rb +++ b/test/openssl/test_x509cert.rb @@ -157,19 +157,80 @@ class OpenSSL::TestX509Certificate < Test::Unit::TestCase cert.not_after = Time.now assert_equal(false, cert.verify(@dsa512)) - assert_raises(OpenSSL::X509::CertificateError){ + assert_raise(OpenSSL::X509::CertificateError){ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [], nil, nil, OpenSSL::Digest::DSS1.new) } - assert_raises(OpenSSL::X509::CertificateError){ + assert_raise(OpenSSL::X509::CertificateError){ cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [], nil, nil, OpenSSL::Digest::MD5.new) } - assert_raises(OpenSSL::X509::CertificateError){ + assert_raise(OpenSSL::X509::CertificateError){ cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [], nil, nil, OpenSSL::Digest::SHA1.new) } end + + def test_check_private_key + cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [], + nil, nil, OpenSSL::Digest::SHA1.new) + assert_equal(true, cert.check_private_key(@rsa2048)) + end + + def test_to_text + cert_pem = <