JRuby-OpenSSL 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,49 @@
1
+ begin
2
+ require "openssl"
3
+ require File.join(File.dirname(__FILE__), "utils.rb")
4
+ rescue LoadError
5
+ end
6
+ require 'test/unit'
7
+
8
+ if defined?(OpenSSL)
9
+
10
+ class OpenSSL::TestPKeyRSA < Test::Unit::TestCase
11
+ def test_padding
12
+ key = OpenSSL::PKey::RSA.new(512, 3)
13
+
14
+ # Need right size for raw mode
15
+ plain0 = "x" * (512/8)
16
+ cipher = key.private_encrypt(plain0, OpenSSL::PKey::RSA::NO_PADDING)
17
+ plain1 = key.public_decrypt(cipher, OpenSSL::PKey::RSA::NO_PADDING)
18
+ assert_equal(plain0, plain1)
19
+
20
+ # Need smaller size for pkcs1 mode
21
+ plain0 = "x" * (512/8 - 11)
22
+ cipher1 = key.private_encrypt(plain0, OpenSSL::PKey::RSA::PKCS1_PADDING)
23
+ plain1 = key.public_decrypt(cipher1, OpenSSL::PKey::RSA::PKCS1_PADDING)
24
+ assert_equal(plain0, plain1)
25
+
26
+ cipherdef = key.private_encrypt(plain0) # PKCS1_PADDING is default
27
+ plain1 = key.public_decrypt(cipherdef)
28
+ assert_equal(plain0, plain1)
29
+ assert_equal(cipher1, cipherdef)
30
+
31
+ # Failure cases
32
+ assert_raise(ArgumentError){ key.private_encrypt() }
33
+ assert_raise(ArgumentError){ key.private_encrypt("hi", 1, nil) }
34
+ assert_raise(OpenSSL::PKey::RSAError){ key.private_encrypt(plain0, 666) }
35
+ end
36
+
37
+ def test_private
38
+ key = OpenSSL::PKey::RSA.new(512, 3)
39
+ assert(key.private?)
40
+ key2 = OpenSSL::PKey::RSA.new(key.to_der)
41
+ assert(key2.private?)
42
+ key3 = key.public_key
43
+ assert(!key3.private?)
44
+ key4 = OpenSSL::PKey::RSA.new(key3.to_der)
45
+ assert(!key4.private?)
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,284 @@
1
+ begin
2
+ require "openssl"
3
+ require File.join(File.dirname(__FILE__), "utils.rb")
4
+ rescue LoadError
5
+ end
6
+ require "rbconfig"
7
+ require "socket"
8
+ require "test/unit"
9
+
10
+ if defined?(OpenSSL)
11
+
12
+ class OpenSSL::TestSSL < Test::Unit::TestCase
13
+ RUBY = ENV["RUBY"] || File.join(
14
+ ::Config::CONFIG["bindir"],
15
+ ::Config::CONFIG["ruby_install_name"] + ::Config::CONFIG["EXEEXT"]
16
+ )
17
+ SSL_SERVER = File.join(File.dirname(__FILE__), "ssl_server.rb")
18
+ PORT = 20443
19
+ ITERATIONS = ($0 == __FILE__) ? 5 : 5
20
+
21
+ def setup
22
+ @ca_key = OpenSSL::TestUtils::TEST_KEY_RSA2048
23
+ @svr_key = OpenSSL::TestUtils::TEST_KEY_RSA1024
24
+ @cli_key = OpenSSL::TestUtils::TEST_KEY_DSA256
25
+ @ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
26
+ @svr = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
27
+ @cli = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
28
+
29
+ now = Time.at(Time.now.to_i)
30
+ ca_exts = [
31
+ ["basicConstraints","CA:TRUE",true],
32
+ ["keyUsage","cRLSign,keyCertSign",true],
33
+ ]
34
+ ee_exts = [
35
+ ["keyUsage","keyEncipherment,digitalSignature",true],
36
+ ]
37
+ @ca_cert = issue_cert(@ca, @ca_key, 1, now, now+3600, ca_exts,
38
+ nil, nil, OpenSSL::Digest::SHA1.new)
39
+ @svr_cert = issue_cert(@svr, @svr_key, 2, now, now+1800, ee_exts,
40
+ @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
41
+ @cli_cert = issue_cert(@cli, @cli_key, 3, now, now+1800, ee_exts,
42
+ @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
43
+ @server = nil
44
+ end
45
+
46
+ def teardown
47
+ end
48
+
49
+ def issue_cert(*arg)
50
+ OpenSSL::TestUtils.issue_cert(*arg)
51
+ end
52
+
53
+ def issue_crl(*arg)
54
+ OpenSSL::TestUtils.issue_crl(*arg)
55
+ end
56
+
57
+ def start_server(port0, verify_mode, start_immediately, &block)
58
+ server = nil
59
+ begin
60
+ cmd = [RUBY]
61
+ cmd << "-d" if $DEBUG
62
+ cmd << SSL_SERVER << port0.to_s << verify_mode.to_s
63
+ cmd << (start_immediately ? "yes" : "no")
64
+ server = IO.popen(cmd.join(" "), "w+")
65
+ server.write(@ca_cert.to_pem)
66
+ server.write(@svr_cert.to_pem)
67
+ server.write(@svr_key.to_pem)
68
+ pid = Integer(server.gets)
69
+ if port = server.gets
70
+ if $DEBUG
71
+ $stderr.printf("%s started: pid=%d port=%d\n", SSL_SERVER, pid, port)
72
+ end
73
+ block.call(server, port.to_i)
74
+ end
75
+ ensure
76
+ if server
77
+ Process.kill(:KILL, pid)
78
+ server.close
79
+ end
80
+ end
81
+ end
82
+
83
+ def starttls(ssl)
84
+ ssl.puts("STARTTLS")
85
+
86
+ sleep 1 # When this line is eliminated, process on Cygwin blocks
87
+ # forever at ssl.connect. But I don't know why it does.
88
+
89
+ ssl.connect
90
+ end
91
+
92
+ def test_connect_and_close
93
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|s, p|
94
+ sock = TCPSocket.new("127.0.0.1", p)
95
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
96
+ assert(ssl.connect)
97
+ ssl.close
98
+ assert(!sock.closed?)
99
+ sock.close
100
+
101
+ sock = TCPSocket.new("127.0.0.1", p)
102
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
103
+ ssl.sync_close = true # !!
104
+ assert(ssl.connect)
105
+ ssl.close
106
+ assert(sock.closed?)
107
+ }
108
+ end
109
+
110
+ def test_read_and_write
111
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|s, p|
112
+ sock = TCPSocket.new("127.0.0.1", p)
113
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
114
+ ssl.sync_close = true
115
+ ssl.connect
116
+
117
+ # syswrite and sysread
118
+ ITERATIONS.times{|i|
119
+ str = "x" * 100 + "\n"
120
+ ssl.syswrite(str)
121
+ assert_equal(str, ssl.sysread(str.size))
122
+
123
+ str = "x" * i * 100 + "\n"
124
+ buf = ""
125
+ ssl.syswrite(str)
126
+ assert_equal(buf.object_id, ssl.sysread(str.size, buf).object_id)
127
+ assert_equal(str, buf)
128
+ }
129
+
130
+ # puts and gets
131
+ ITERATIONS.times{
132
+ str = "x" * 100 + "\n"
133
+ ssl.puts(str)
134
+ assert_equal(str, ssl.gets)
135
+ }
136
+
137
+ # read and write
138
+ ITERATIONS.times{|i|
139
+ str = "x" * 100 + "\n"
140
+ ssl.write(str)
141
+ assert_equal(str, ssl.read(str.size))
142
+
143
+ str = "x" * i * 100 + "\n"
144
+ buf = ""
145
+ ssl.write(str)
146
+ assert_equal(buf.object_id, ssl.read(str.size, buf).object_id)
147
+ assert_equal(str, buf)
148
+ }
149
+
150
+ ssl.close
151
+ }
152
+ end
153
+
154
+ def test_client_auth
155
+ vflag = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
156
+ start_server(PORT, vflag, true){|s, p|
157
+ assert_raises(OpenSSL::SSL::SSLError){
158
+ sock = TCPSocket.new("127.0.0.1", p)
159
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
160
+ ssl.connect
161
+ }
162
+ ctx = OpenSSL::SSL::SSLContext.new
163
+ ctx.key = @cli_key
164
+ ctx.cert = @cli_cert
165
+ sock = TCPSocket.new("127.0.0.1", p)
166
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
167
+ ssl.sync_close = true
168
+ ssl.connect
169
+ ssl.puts("foo")
170
+ assert_equal("foo\n", ssl.gets)
171
+ ssl.close
172
+
173
+ called = nil
174
+ ctx = OpenSSL::SSL::SSLContext.new
175
+ ctx.client_cert_cb = Proc.new{|ssl|
176
+ called = true
177
+ [@cli_cert, @cli_key]
178
+ }
179
+ sock = TCPSocket.new("127.0.0.1", p)
180
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
181
+ ssl.sync_close = true
182
+ ssl.connect
183
+ # assert(called)
184
+ ssl.puts("foo")
185
+ assert_equal("foo\n", ssl.gets)
186
+ ssl.close
187
+ }
188
+ end
189
+
190
+ def test_starttls
191
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, false){|s, p|
192
+ sock = TCPSocket.new("127.0.0.1", p)
193
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
194
+ ssl.sync_close = true
195
+ str = "x" * 1000 + "\n"
196
+ ITERATIONS.times{
197
+ ssl.puts(str)
198
+ assert_equal(str, ssl.gets)
199
+ }
200
+
201
+ starttls(ssl)
202
+
203
+ ITERATIONS.times{
204
+ ssl.puts(str)
205
+ assert_equal(str, ssl.gets)
206
+ }
207
+
208
+ ssl.close
209
+ }
210
+ end
211
+
212
+ def test_parallel
213
+ GC.start
214
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|s, p|
215
+ ssls = []
216
+ 10.times{
217
+ sock = TCPSocket.new("127.0.0.1", p)
218
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
219
+ ssl.connect
220
+ ssl.sync_close = true
221
+ ssls << ssl
222
+ }
223
+ str = "x" * 1000 + "\n"
224
+ ITERATIONS.times{
225
+ ssls.each{|ssl|
226
+ ssl.puts(str)
227
+ assert_equal(str, ssl.gets)
228
+ }
229
+ }
230
+ ssls.each{|ssl| ssl.close }
231
+ }
232
+ end
233
+
234
+ def test_post_connection_check
235
+ sslerr = OpenSSL::SSL::SSLError
236
+
237
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|s, p|
238
+ sock = TCPSocket.new("127.0.0.1", p)
239
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
240
+ ssl.connect
241
+ assert_raises(sslerr){ssl.post_connection_check("localhost.localdomain")}
242
+ assert_raises(sslerr){ssl.post_connection_check("127.0.0.1")}
243
+ assert(ssl.post_connection_check("localhost"))
244
+ assert_raises(sslerr){ssl.post_connection_check("foo.example.com")}
245
+ }
246
+
247
+ now = Time.now
248
+ exts = [
249
+ ["keyUsage","keyEncipherment,digitalSignature",true],
250
+ ["subjectAltName","DNS:localhost.localdomain",false],
251
+ ["subjectAltName","IP:127.0.0.1",false],
252
+ ]
253
+ @svr_cert = issue_cert(@svr, @svr_key, 4, now, now+1800, exts,
254
+ @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
255
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|s, p|
256
+ sock = TCPSocket.new("127.0.0.1", p)
257
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
258
+ ssl.connect
259
+ assert(ssl.post_connection_check("localhost.localdomain"))
260
+ assert(ssl.post_connection_check("127.0.0.1"))
261
+ assert_raises(sslerr){ssl.post_connection_check("localhost")}
262
+ assert_raises(sslerr){ssl.post_connection_check("foo.example.com")}
263
+ }
264
+
265
+ now = Time.now
266
+ exts = [
267
+ ["keyUsage","keyEncipherment,digitalSignature",true],
268
+ ["subjectAltName","DNS:*.localdomain",false],
269
+ ]
270
+ @svr_cert = issue_cert(@svr, @svr_key, 5, now, now+1800, exts,
271
+ @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
272
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|s, p|
273
+ sock = TCPSocket.new("127.0.0.1", p)
274
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
275
+ ssl.connect
276
+ assert(ssl.post_connection_check("localhost.localdomain"))
277
+ assert_raises(sslerr){ssl.post_connection_check("127.0.0.1")}
278
+ assert_raises(sslerr){ssl.post_connection_check("localhost")}
279
+ assert_raises(sslerr){ssl.post_connection_check("foo.example.com")}
280
+ }
281
+ end
282
+ end
283
+
284
+ end
@@ -0,0 +1,174 @@
1
+ begin
2
+ require "openssl"
3
+ require File.join(File.dirname(__FILE__), "utils.rb")
4
+ rescue LoadError
5
+ end
6
+ require "test/unit"
7
+
8
+ if defined?(OpenSSL)
9
+
10
+ class OpenSSL::TestX509Certificate < Test::Unit::TestCase
11
+ def setup
12
+ @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024
13
+ @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048
14
+ @dsa256 = OpenSSL::TestUtils::TEST_KEY_DSA256
15
+ @dsa512 = OpenSSL::TestUtils::TEST_KEY_DSA512
16
+ @ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
17
+ @ee1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE1")
18
+ @ee2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE2")
19
+ end
20
+
21
+ def teardown
22
+ end
23
+
24
+ def issue_cert(*args)
25
+ OpenSSL::TestUtils.issue_cert(*args)
26
+ end
27
+
28
+ def test_serial
29
+ [1, 2**32, 2**100].each{|s|
30
+ cert = issue_cert(@ca, @rsa2048, s, Time.now, Time.now+3600, [],
31
+ nil, nil, OpenSSL::Digest::SHA1.new)
32
+ assert_equal(s, cert.serial)
33
+ cert = OpenSSL::X509::Certificate.new(cert.to_der)
34
+ assert_equal(s, cert.serial)
35
+ }
36
+ end
37
+
38
+ def test_public_key
39
+ exts = [
40
+ ["basicConstraints","CA:TRUE",true],
41
+ ["subjectKeyIdentifier","hash",false],
42
+ ["authorityKeyIdentifier","keyid:always",false],
43
+ ]
44
+
45
+ sha1 = OpenSSL::Digest::SHA1.new
46
+ dss1 = OpenSSL::Digest::DSS1.new
47
+ [
48
+ [@rsa1024, sha1], [@rsa2048, sha1], [@dsa256, dss1], [@dsa512, dss1],
49
+ ].each{|pk, digest|
50
+ cert = issue_cert(@ca, pk, 1, Time.now, Time.now+3600, exts,
51
+ nil, nil, digest)
52
+ assert_equal(cert.extensions[1].value,OpenSSL::TestUtils.get_subject_key_id(cert))
53
+ cert = OpenSSL::X509::Certificate.new(cert.to_der)
54
+ assert_equal(cert.extensions[1].value,
55
+ OpenSSL::TestUtils.get_subject_key_id(cert))
56
+ }
57
+ end
58
+
59
+ def test_validity
60
+ now = Time.now until now && now.usec != 0
61
+ cert = issue_cert(@ca, @rsa2048, 1, now, now+3600, [],
62
+ nil, nil, OpenSSL::Digest::SHA1.new)
63
+ assert_not_equal(now, cert.not_before)
64
+ assert_not_equal(now+3600, cert.not_after)
65
+
66
+ now = Time.at(now.to_i)
67
+ cert = issue_cert(@ca, @rsa2048, 1, now, now+3600, [],
68
+ nil, nil, OpenSSL::Digest::SHA1.new)
69
+ assert_equal(now.getutc, cert.not_before)
70
+ assert_equal((now+3600).getutc, cert.not_after)
71
+
72
+ now = Time.at(0)
73
+ cert = issue_cert(@ca, @rsa2048, 1, now, now, [],
74
+ nil, nil, OpenSSL::Digest::SHA1.new)
75
+ assert_equal(now.getutc, cert.not_before)
76
+ assert_equal(now.getutc, cert.not_after)
77
+
78
+ now = Time.at(0x7fffffff)
79
+ cert = issue_cert(@ca, @rsa2048, 1, now, now, [],
80
+ nil, nil, OpenSSL::Digest::SHA1.new)
81
+ assert_equal(now.getutc, cert.not_before)
82
+ assert_equal(now.getutc, cert.not_after)
83
+ end
84
+
85
+ def test_extension
86
+ ca_exts = [
87
+ ["basicConstraints","CA:TRUE",true],
88
+ ["keyUsage","keyCertSign, cRLSign",true],
89
+ ["subjectKeyIdentifier","hash",false],
90
+ ["authorityKeyIdentifier","keyid:always",false],
91
+ ]
92
+ ca_cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, ca_exts,
93
+ nil, nil, OpenSSL::Digest::SHA1.new)
94
+ ca_cert.extensions.each_with_index{|ext, i|
95
+ assert_equal(ca_exts[i].first, ext.oid)
96
+ assert_equal(ca_exts[i].last, ext.critical?)
97
+ }
98
+
99
+ ee1_exts = [
100
+ ["keyUsage","Non Repudiation, Digital Signature, Key Encipherment",true],
101
+ ["subjectKeyIdentifier","hash",false],
102
+ ["authorityKeyIdentifier","keyid:always",false],
103
+ ["extendedKeyUsage","clientAuth, emailProtection, codeSigning",false],
104
+ ["subjectAltName","email:ee1@ruby-lang.org",false],
105
+ ]
106
+ ee1_cert = issue_cert(@ee1, @rsa1024, 2, Time.now, Time.now+1800, ee1_exts,
107
+ ca_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
108
+ assert_equal(ca_cert.subject.to_der, ee1_cert.issuer.to_der)
109
+ ee1_cert.extensions.each_with_index{|ext, i|
110
+ assert_equal(ee1_exts[i].first, ext.oid)
111
+ assert_equal(ee1_exts[i].last, ext.critical?)
112
+ }
113
+
114
+ ee2_exts = [
115
+ ["keyUsage","Non Repudiation, Digital Signature, Key Encipherment",true],
116
+ ["subjectKeyIdentifier","hash",false],
117
+ ["authorityKeyIdentifier","issuer:always",false],
118
+ ["extendedKeyUsage","clientAuth, emailProtection, codeSigning",false],
119
+ ["subjectAltName","email:ee2@ruby-lang.org",false],
120
+ ]
121
+ ee2_cert = issue_cert(@ee2, @rsa1024, 3, Time.now, Time.now+1800, ee2_exts,
122
+ ca_cert, @rsa2048, OpenSSL::Digest::MD5.new)
123
+ assert_equal(ca_cert.subject.to_der, ee2_cert.issuer.to_der)
124
+ ee2_cert.extensions.each_with_index{|ext, i|
125
+ assert_equal(ee2_exts[i].first, ext.oid)
126
+ assert_equal(ee2_exts[i].last, ext.critical?)
127
+ }
128
+
129
+ end
130
+
131
+ def test_sign_and_verify
132
+ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
133
+ nil, nil, OpenSSL::Digest::SHA1.new)
134
+ assert_equal(false, cert.verify(@rsa1024))
135
+ assert_equal(true, cert.verify(@rsa2048))
136
+ assert_equal(false, cert.verify(@dsa256))
137
+ assert_equal(false, cert.verify(@dsa512))
138
+ cert.serial = 2
139
+ assert_equal(false, cert.verify(@rsa2048))
140
+
141
+ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
142
+ nil, nil, OpenSSL::Digest::MD5.new)
143
+ assert_equal(false, cert.verify(@rsa1024))
144
+ assert_equal(true, cert.verify(@rsa2048))
145
+ assert_equal(false, cert.verify(@dsa256))
146
+ assert_equal(false, cert.verify(@dsa512))
147
+ cert.subject = @ee1
148
+ assert_equal(false, cert.verify(@rsa2048))
149
+
150
+ cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],
151
+ nil, nil, OpenSSL::Digest::DSS1.new)
152
+ assert_equal(false, cert.verify(@rsa1024))
153
+ assert_equal(false, cert.verify(@rsa2048))
154
+ assert_equal(false, cert.verify(@dsa256))
155
+ assert_equal(true, cert.verify(@dsa512))
156
+ cert.not_after = Time.now
157
+ assert_equal(false, cert.verify(@dsa512))
158
+
159
+ assert_raises(OpenSSL::X509::CertificateError){
160
+ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
161
+ nil, nil, OpenSSL::Digest::DSS1.new)
162
+ }
163
+ assert_raises(OpenSSL::X509::CertificateError){
164
+ cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],
165
+ nil, nil, OpenSSL::Digest::MD5.new)
166
+ }
167
+ assert_raises(OpenSSL::X509::CertificateError){
168
+ cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],
169
+ nil, nil, OpenSSL::Digest::SHA1.new)
170
+ }
171
+ end
172
+ end
173
+
174
+ end