jruby-openssl-maven 0.7.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. data/History.txt +171 -0
  2. data/License.txt +30 -0
  3. data/Manifest.txt +115 -0
  4. data/README.txt +13 -0
  5. data/Rakefile +79 -0
  6. data/lib/jopenssl.jar +0 -0
  7. data/lib/jopenssl/version.rb +5 -0
  8. data/lib/openssl.rb +76 -0
  9. data/lib/openssl/bn.rb +35 -0
  10. data/lib/openssl/buffering.rb +239 -0
  11. data/lib/openssl/cipher.rb +65 -0
  12. data/lib/openssl/config.rb +316 -0
  13. data/lib/openssl/digest.rb +61 -0
  14. data/lib/openssl/dummy.rb +33 -0
  15. data/lib/openssl/dummyssl.rb +14 -0
  16. data/lib/openssl/pkcs7.rb +25 -0
  17. data/lib/openssl/ssl.rb +179 -0
  18. data/lib/openssl/x509.rb +154 -0
  19. data/test/cert_with_ec_pk.cer +27 -0
  20. data/test/fixture/ca-bundle.crt +2794 -0
  21. data/test/fixture/ca_path/72fa7371.0 +19 -0
  22. data/test/fixture/ca_path/verisign.pem +19 -0
  23. data/test/fixture/cacert.pem +23 -0
  24. data/test/fixture/cert_localhost.pem +19 -0
  25. data/test/fixture/common.pem +48 -0
  26. data/test/fixture/imaps/cacert.pem +60 -0
  27. data/test/fixture/imaps/server.crt +61 -0
  28. data/test/fixture/imaps/server.key +15 -0
  29. data/test/fixture/key_then_cert.pem +34 -0
  30. data/test/fixture/keypair.pem +27 -0
  31. data/test/fixture/localhost_keypair.pem +18 -0
  32. data/test/fixture/max.pem +29 -0
  33. data/test/fixture/purpose/b70a5bc1.0 +24 -0
  34. data/test/fixture/purpose/ca/PASSWD_OF_CA_KEY_IS_1234 +0 -0
  35. data/test/fixture/purpose/ca/ca_config.rb +37 -0
  36. data/test/fixture/purpose/ca/cacert.pem +24 -0
  37. data/test/fixture/purpose/ca/newcerts/2_cert.pem +19 -0
  38. data/test/fixture/purpose/ca/newcerts/3_cert.pem +19 -0
  39. data/test/fixture/purpose/ca/private/cakeypair.pem +30 -0
  40. data/test/fixture/purpose/ca/serial +1 -0
  41. data/test/fixture/purpose/cacert.pem +24 -0
  42. data/test/fixture/purpose/scripts/gen_cert.rb +127 -0
  43. data/test/fixture/purpose/scripts/gen_csr.rb +50 -0
  44. data/test/fixture/purpose/scripts/init_ca.rb +66 -0
  45. data/test/fixture/purpose/sslclient.pem +19 -0
  46. data/test/fixture/purpose/sslclient/csr.pem +10 -0
  47. data/test/fixture/purpose/sslclient/keypair.pem +15 -0
  48. data/test/fixture/purpose/sslclient/sslclient.pem +19 -0
  49. data/test/fixture/purpose/sslserver.pem +19 -0
  50. data/test/fixture/purpose/sslserver/csr.pem +10 -0
  51. data/test/fixture/purpose/sslserver/keypair.pem +15 -0
  52. data/test/fixture/purpose/sslserver/sslserver.pem +19 -0
  53. data/test/fixture/selfcert.pem +23 -0
  54. data/test/fixture/verisign.pem +19 -0
  55. data/test/fixture/verisign_c3.pem +14 -0
  56. data/test/java/pkcs7_mime_enveloped.message +19 -0
  57. data/test/java/pkcs7_mime_signed.message +30 -0
  58. data/test/java/pkcs7_multipart_signed.message +45 -0
  59. data/test/java/test_java_attribute.rb +25 -0
  60. data/test/java/test_java_bio.rb +42 -0
  61. data/test/java/test_java_mime.rb +173 -0
  62. data/test/java/test_java_pkcs7.rb +772 -0
  63. data/test/java/test_java_smime.rb +177 -0
  64. data/test/openssl/ssl_server.rb +99 -0
  65. data/test/openssl/test_asn1.rb +197 -0
  66. data/test/openssl/test_cipher.rb +193 -0
  67. data/test/openssl/test_config.rb +290 -0
  68. data/test/openssl/test_digest.rb +88 -0
  69. data/test/openssl/test_ec.rb +128 -0
  70. data/test/openssl/test_hmac.rb +46 -0
  71. data/test/openssl/test_ns_spki.rb +59 -0
  72. data/test/openssl/test_pair.rb +141 -0
  73. data/test/openssl/test_pkcs7.rb +489 -0
  74. data/test/openssl/test_pkey_rsa.rb +49 -0
  75. data/test/openssl/test_ssl.rb +1035 -0
  76. data/test/openssl/test_x509cert.rb +277 -0
  77. data/test/openssl/test_x509crl.rb +253 -0
  78. data/test/openssl/test_x509ext.rb +99 -0
  79. data/test/openssl/test_x509name.rb +290 -0
  80. data/test/openssl/test_x509req.rb +195 -0
  81. data/test/openssl/test_x509store.rb +246 -0
  82. data/test/openssl/utils.rb +144 -0
  83. data/test/ref/a.out +0 -0
  84. data/test/ref/compile.rb +8 -0
  85. data/test/ref/pkcs1 +0 -0
  86. data/test/ref/pkcs1.c +21 -0
  87. data/test/test_all.rb +1 -0
  88. data/test/test_certificate.rb +123 -0
  89. data/test/test_cipher.rb +197 -0
  90. data/test/test_imaps.rb +107 -0
  91. data/test/test_integration.rb +144 -0
  92. data/test/test_java.rb +98 -0
  93. data/test/test_openssl.rb +4 -0
  94. data/test/test_parse_certificate.rb +27 -0
  95. data/test/test_pkcs7.rb +40 -0
  96. data/test/test_pkey.rb +204 -0
  97. data/test/test_ssl.rb +97 -0
  98. data/test/test_x509store.rb +160 -0
  99. data/test/ut_eof.rb +128 -0
  100. metadata +161 -0
@@ -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,1035 @@
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
+ require 'tempfile'
10
+
11
+ if defined?(OpenSSL)
12
+
13
+ class OpenSSL::TestSSL < Test::Unit::TestCase
14
+ RUBY = ENV["RUBY"] || File.join(
15
+ ::Config::CONFIG["bindir"],
16
+ ::Config::CONFIG["ruby_install_name"] + ::Config::CONFIG["EXEEXT"]
17
+ )
18
+ SSL_SERVER = File.join(File.dirname(__FILE__), "ssl_server.rb")
19
+ PORT = 20443
20
+ ITERATIONS = ($0 == __FILE__) ? 100 : 10
21
+
22
+ # NOT USED: Disable in-proc process launching and either run jruby with
23
+ # specified args or yield args to a given block
24
+ def jruby_oop(*args)
25
+ prev_in_process = JRuby.runtime.instance_config.run_ruby_in_process
26
+ JRuby.runtime.instance_config.run_ruby_in_process = false
27
+ if block_given?
28
+ yield args
29
+ else
30
+ `#{RUBY} #{args.join(' ')}`
31
+ end
32
+ ensure
33
+ JRuby.runtime.instance_config.run_ruby_in_process = prev_in_process
34
+ end
35
+
36
+ def setup
37
+ @ca_key = OpenSSL::TestUtils::TEST_KEY_RSA2048
38
+ @svr_key = OpenSSL::TestUtils::TEST_KEY_RSA1024
39
+ @cli_key = OpenSSL::TestUtils::TEST_KEY_DSA256
40
+ @ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
41
+ @svr = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
42
+ @cli = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
43
+
44
+ now = Time.at(Time.now.to_i)
45
+ ca_exts = [
46
+ ["basicConstraints","CA:TRUE",true],
47
+ ["keyUsage","cRLSign,keyCertSign",true],
48
+ ]
49
+ ee_exts = [
50
+ ["keyUsage","keyEncipherment,digitalSignature",true],
51
+ ]
52
+ @ca_cert = issue_cert(@ca, @ca_key, 1, now, now+3600, ca_exts,
53
+ nil, nil, OpenSSL::Digest::SHA1.new)
54
+ @svr_cert = issue_cert(@svr, @svr_key, 2, now, now+1800, ee_exts,
55
+ @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
56
+ @cli_cert = issue_cert(@cli, @cli_key, 3, now, now+1800, ee_exts,
57
+ @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
58
+ @server = nil
59
+ end
60
+
61
+ def teardown
62
+ end
63
+
64
+ def issue_cert(*arg)
65
+ OpenSSL::TestUtils.issue_cert(*arg)
66
+ end
67
+
68
+ def issue_crl(*arg)
69
+ OpenSSL::TestUtils.issue_crl(*arg)
70
+ end
71
+
72
+ def choose_port(port)
73
+ tcps = nil
74
+ 100.times{ |i|
75
+ begin
76
+ tcps = TCPServer.new("127.0.0.1", port+i)
77
+ port = port + i
78
+ break
79
+ rescue Errno::EADDRINUSE
80
+ next
81
+ end
82
+ }
83
+ return tcps, port
84
+ end
85
+
86
+ def readwrite_loop(ctx, ssl)
87
+ while line = ssl.gets
88
+ if line =~ /^STARTTLS$/
89
+ ssl.accept
90
+ next
91
+ end
92
+ ssl.write(line)
93
+ end
94
+ rescue OpenSSL::SSL::SSLError
95
+ rescue IOError
96
+ ensure
97
+ ssl.close rescue nil
98
+ end
99
+
100
+ def server_loop(ctx, ssls, server_proc)
101
+ loop do
102
+ ssl = nil
103
+ begin
104
+ ssl = ssls.accept
105
+ rescue OpenSSL::SSL::SSLError
106
+ retry
107
+ end
108
+
109
+ Thread.start do
110
+ Thread.current.abort_on_exception = true
111
+ server_proc.call(ctx, ssl)
112
+ end
113
+ end
114
+ rescue Errno::EBADF, IOError, Errno::EINVAL, Errno::ECONNABORTED
115
+ end
116
+
117
+ def start_server(port0, verify_mode, start_immediately, args = {}, &block)
118
+ ctx_proc = args[:ctx_proc]
119
+ server_proc = args[:server_proc]
120
+ server_proc ||= method(:readwrite_loop)
121
+
122
+ store = OpenSSL::X509::Store.new
123
+ store.add_cert(@ca_cert)
124
+ store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
125
+ ctx = OpenSSL::SSL::SSLContext.new
126
+ ctx.cert_store = store
127
+ #ctx.extra_chain_cert = [ ca_cert ]
128
+ ctx.cert = @svr_cert
129
+ ctx.key = @svr_key
130
+ ctx.verify_mode = verify_mode
131
+ ctx_proc.call(ctx) if ctx_proc
132
+
133
+ Socket.do_not_reverse_lookup = true
134
+ tcps, port = choose_port(port0)
135
+
136
+ ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
137
+ ssls.start_immediately = start_immediately
138
+
139
+ begin
140
+ server = Thread.new do
141
+ Thread.current.abort_on_exception = true
142
+ server_loop(ctx, ssls, server_proc)
143
+ end
144
+
145
+ $stderr.printf("%s started: pid=%d port=%d\n", SSL_SERVER, $$, port) if $DEBUG
146
+
147
+ block.call(server, port.to_i)
148
+ ensure
149
+ tcps.close if (tcps)
150
+ if (server)
151
+ server.join(5)
152
+ if server.alive?
153
+ server.kill
154
+ server.join
155
+ flunk("TCPServer was closed and SSLServer is still alive") unless $!
156
+ end
157
+ end
158
+ end
159
+ end
160
+
161
+ def starttls(ssl)
162
+ ssl.puts("STARTTLS")
163
+
164
+ sleep 1 # When this line is eliminated, process on Cygwin blocks
165
+ # forever at ssl.connect. But I don't know why it does.
166
+
167
+ ssl.connect
168
+ end
169
+
170
+ def test_ctx_setup
171
+ ctx = OpenSSL::SSL::SSLContext.new
172
+ assert_equal(ctx.setup, true)
173
+ assert_equal(ctx.setup, nil)
174
+ end
175
+
176
+ def test_connect_and_close
177
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
178
+ sock = TCPSocket.new("127.0.0.1", port)
179
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
180
+ assert(ssl.connect)
181
+ ssl.close
182
+ assert(!sock.closed?)
183
+ sock.close
184
+
185
+ sock = TCPSocket.new("127.0.0.1", port)
186
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
187
+ ssl.sync_close = true # !!
188
+ assert(ssl.connect)
189
+ ssl.close
190
+ assert(sock.closed?)
191
+ }
192
+ end
193
+
194
+ def test_read_and_write
195
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
196
+ sock = TCPSocket.new("127.0.0.1", port)
197
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
198
+ ssl.sync_close = true
199
+ ssl.connect
200
+
201
+ assert_raise(ArgumentError) { ssl.sysread(-1) }
202
+
203
+ # syswrite and sysread
204
+ ITERATIONS.times{|i|
205
+ str = "x" * 100 + "\n"
206
+ ssl.syswrite(str)
207
+ assert_equal(str, ssl.sysread(str.size))
208
+
209
+ str = "x" * i * 100 + "\n"
210
+ buf = ""
211
+ ssl.syswrite(str)
212
+ assert_equal(buf.object_id, ssl.sysread(str.size, buf).object_id)
213
+ assert_equal(str, buf)
214
+ }
215
+
216
+ # puts and gets
217
+ ITERATIONS.times{
218
+ str = "x" * 100 + "\n"
219
+ ssl.puts(str)
220
+ assert_equal(str, ssl.gets)
221
+ }
222
+
223
+ # read and write
224
+ ITERATIONS.times{|i|
225
+ str = "x" * 100 + "\n"
226
+ ssl.write(str)
227
+ assert_equal(str, ssl.read(str.size))
228
+
229
+ str = "x" * i * 100 + "\n"
230
+ buf = ""
231
+ ssl.write(str)
232
+ assert_equal(buf.object_id, ssl.read(str.size, buf).object_id)
233
+ assert_equal(str, buf)
234
+ }
235
+
236
+ ssl.close
237
+ }
238
+ end
239
+
240
+ def test_sysread_chunks
241
+ args = {}
242
+ args[:server_proc] = proc { |ctx, ssl|
243
+ while line = ssl.gets
244
+ if line =~ /^STARTTLS$/
245
+ ssl.accept
246
+ next
247
+ end
248
+ ssl.write("0" * 800)
249
+ ssl.write("1" * 200)
250
+ ssl.close
251
+ break
252
+ end
253
+ }
254
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, args){|server, port|
255
+ sock = TCPSocket.new("127.0.0.1", port)
256
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
257
+ ssl.sync_close = true
258
+ ssl.connect
259
+ ssl.syswrite("hello\n")
260
+ assert_equal("0" * 200, ssl.sysread(200))
261
+ assert_equal("0" * 200, ssl.sysread(200))
262
+ assert_equal("0" * 200, ssl.sysread(200))
263
+ assert_equal("0" * 200, ssl.sysread(200))
264
+ assert_equal("1" * 200, ssl.sysread(200))
265
+ ssl.close
266
+ }
267
+ end
268
+
269
+ def test_sysread_buffer
270
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
271
+ sock = TCPSocket.new("127.0.0.1", port)
272
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
273
+ ssl.sync_close = true
274
+ ssl.connect
275
+ ITERATIONS.times{|i|
276
+ # the given buffer is cleared before concatenating.
277
+ # NB: SSLSocket#readpartial depends sysread.
278
+ str = "x" * i * 100 + "\n"
279
+ ssl.syswrite(str)
280
+ buf = "asdf"
281
+ assert_equal(buf.object_id, ssl.sysread(0, buf).object_id)
282
+ assert_equal("", buf)
283
+
284
+ buf = "asdf"
285
+ read = ssl.sysread(str.size, buf)
286
+ assert(!read.empty?)
287
+ assert_equal(buf.object_id, read.object_id)
288
+ assert_equal(str, buf)
289
+
290
+ ssl.syswrite(str)
291
+ read = ssl.sysread(str.size, nil)
292
+ assert(!read.empty?)
293
+ assert_equal(str, read)
294
+ }
295
+ ssl.close
296
+ }
297
+ end
298
+
299
+ def test_client_auth
300
+ vflag = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
301
+ start_server(PORT, vflag, true){|server, port|
302
+ assert_raise(OpenSSL::SSL::SSLError){
303
+ sock = TCPSocket.new("127.0.0.1", port)
304
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
305
+ ssl.connect
306
+ }
307
+
308
+ ctx = OpenSSL::SSL::SSLContext.new
309
+ ctx.key = @cli_key
310
+ ctx.cert = @cli_cert
311
+ sock = TCPSocket.new("127.0.0.1", port)
312
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
313
+ ssl.sync_close = true
314
+ ssl.connect
315
+ ssl.puts("foo")
316
+ assert_equal("foo\n", ssl.gets)
317
+ ssl.close
318
+
319
+ called = nil
320
+ ctx = OpenSSL::SSL::SSLContext.new
321
+ ctx.client_cert_cb = Proc.new{ |sslconn|
322
+ called = true
323
+ [@cli_cert, @cli_key]
324
+ }
325
+ sock = TCPSocket.new("127.0.0.1", port)
326
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
327
+ ssl.sync_close = true
328
+ ssl.connect
329
+ assert(called)
330
+ ssl.puts("foo")
331
+ assert_equal("foo\n", ssl.gets)
332
+ ssl.close
333
+ }
334
+ end
335
+
336
+ def test_client_auth_with_server_store
337
+ vflag = OpenSSL::SSL::VERIFY_PEER
338
+
339
+ localcacert_file = Tempfile.open("cafile")
340
+ localcacert_file << @ca_cert.to_pem
341
+ localcacert_file.close
342
+ localcacert_path = localcacert_file.path
343
+
344
+ ssl_store = OpenSSL::X509::Store.new
345
+ ssl_store.purpose = OpenSSL::X509::PURPOSE_ANY
346
+ ssl_store.add_file(localcacert_path)
347
+
348
+ args = {}
349
+ args[:ctx_proc] = proc { |server_ctx|
350
+ server_ctx.cert = @svr_cert
351
+ server_ctx.key = @svr_key
352
+ server_ctx.verify_mode = vflag
353
+ server_ctx.cert_store = ssl_store
354
+ }
355
+
356
+ start_server(PORT, vflag, true, args){|server, port|
357
+ ctx = OpenSSL::SSL::SSLContext.new
358
+ ctx.cert = @cli_cert
359
+ ctx.key = @cli_key
360
+ sock = TCPSocket.new("127.0.0.1", port)
361
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
362
+ ssl.sync_close = true
363
+ ssl.connect
364
+ ssl.puts("foo")
365
+ assert_equal("foo\n", ssl.gets)
366
+ ssl.close
367
+ localcacert_file.unlink
368
+ }
369
+ end
370
+
371
+ def test_client_crl_with_server_store
372
+ vflag = OpenSSL::SSL::VERIFY_PEER
373
+
374
+ localcacert_file = Tempfile.open("cafile")
375
+ localcacert_file << @ca_cert.to_pem
376
+ localcacert_file.close
377
+ localcacert_path = localcacert_file.path
378
+
379
+ ssl_store = OpenSSL::X509::Store.new
380
+ ssl_store.purpose = OpenSSL::X509::PURPOSE_ANY
381
+ ssl_store.add_file(localcacert_path)
382
+ ssl_store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK
383
+
384
+ crl = issue_crl([], 1, Time.now, Time.now+1600, [],
385
+ @cli_cert, @ca_key, OpenSSL::Digest::SHA1.new)
386
+
387
+ ssl_store.add_crl(OpenSSL::X509::CRL.new(crl.to_pem))
388
+
389
+ args = {}
390
+ args[:ctx_proc] = proc { |server_ctx|
391
+ server_ctx.cert = @svr_cert
392
+ server_ctx.key = @svr_key
393
+ server_ctx.verify_mode = vflag
394
+ server_ctx.cert_store = ssl_store
395
+ }
396
+
397
+ start_server(PORT, vflag, true, args){|s, p|
398
+ ctx = OpenSSL::SSL::SSLContext.new
399
+ ctx.cert = @cli_cert
400
+ ctx.key = @cli_key
401
+ assert_raise(OpenSSL::SSL::SSLError){
402
+ sock = TCPSocket.new("127.0.0.1", p)
403
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
404
+ ssl.sync_close = true
405
+ ssl.connect
406
+ ssl.close
407
+ }
408
+ localcacert_file.unlink
409
+ }
410
+ end
411
+
412
+ def test_starttls
413
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, false){|server, port|
414
+ sock = TCPSocket.new("127.0.0.1", port)
415
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
416
+ ssl.sync_close = true
417
+ str = "x" * 1000 + "\n"
418
+
419
+ ITERATIONS.times{
420
+ ssl.puts(str)
421
+ assert_equal(str, ssl.gets)
422
+ }
423
+
424
+ starttls(ssl)
425
+
426
+ ITERATIONS.times{
427
+ ssl.puts(str)
428
+ assert_equal(str, ssl.gets)
429
+ }
430
+
431
+ ssl.close
432
+ }
433
+ end
434
+
435
+ def test_parallel
436
+ GC.start
437
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
438
+ ssls = []
439
+ 10.times{
440
+ sock = TCPSocket.new("127.0.0.1", port)
441
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
442
+ ssl.connect
443
+ ssl.sync_close = true
444
+ ssls << ssl
445
+ }
446
+ str = "x" * 1000 + "\n"
447
+ ITERATIONS.times{
448
+ ssls.each{|ssl|
449
+ ssl.puts(str)
450
+ assert_equal(str, ssl.gets)
451
+ }
452
+ }
453
+ ssls.each{|ssl| ssl.close }
454
+ }
455
+ end
456
+
457
+ def test_verify_result
458
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
459
+ sock = TCPSocket.new("127.0.0.1", port)
460
+ ctx = OpenSSL::SSL::SSLContext.new
461
+ ctx.set_params
462
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
463
+ assert_raise(OpenSSL::SSL::SSLError){ ssl.connect }
464
+ assert_equal(OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN, ssl.verify_result)
465
+
466
+ sock = TCPSocket.new("127.0.0.1", port)
467
+ ctx = OpenSSL::SSL::SSLContext.new
468
+ ctx.set_params(
469
+ :verify_callback => Proc.new do |preverify_ok, store_ctx|
470
+ store_ctx.error = OpenSSL::X509::V_OK
471
+ true
472
+ end
473
+ )
474
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
475
+ ssl.connect
476
+ assert_equal(OpenSSL::X509::V_OK, ssl.verify_result)
477
+
478
+ sock = TCPSocket.new("127.0.0.1", port)
479
+ ctx = OpenSSL::SSL::SSLContext.new
480
+ ctx.set_params(
481
+ :verify_callback => Proc.new do |preverify_ok, store_ctx|
482
+ store_ctx.error = OpenSSL::X509::V_ERR_APPLICATION_VERIFICATION
483
+ false
484
+ end
485
+ )
486
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
487
+ assert_raise(OpenSSL::SSL::SSLError){ ssl.connect }
488
+ assert_equal(OpenSSL::X509::V_ERR_APPLICATION_VERIFICATION, ssl.verify_result)
489
+ }
490
+ end
491
+
492
+ def test_extra_chain_cert
493
+ start_server(PORT, OpenSSL::SSL::VERIFY_PEER, true){|server, port|
494
+ sock = TCPSocket.new("127.0.0.1", port)
495
+ ctx = OpenSSL::SSL::SSLContext.new
496
+ ctx.set_params
497
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
498
+ assert_raise(OpenSSL::SSL::SSLError){ ssl.connect }
499
+ assert_equal(OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN, ssl.verify_result)
500
+ }
501
+ # server returns a chain w/o root cert so the client verification fails
502
+ # with UNABLE_TO_GET_ISSUER_CERT_LOCALLY not SELF_SIGNED_CERT_IN_CHAIN.
503
+ args = {}
504
+ args[:ctx_proc] = proc { |server_ctx|
505
+ server_ctx.cert = @svr_cert
506
+ server_ctx.key = @svr_key
507
+ server_ctx.extra_chain_cert = [@svr_cert]
508
+ }
509
+ start_server(PORT, OpenSSL::SSL::VERIFY_PEER, true, args){|server, port|
510
+ sock = TCPSocket.new("127.0.0.1", port)
511
+ ctx = OpenSSL::SSL::SSLContext.new
512
+ ctx.set_params
513
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
514
+ assert_raise(OpenSSL::SSL::SSLError){ ssl.connect }
515
+ assert_equal(OpenSSL::X509::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, ssl.verify_result)
516
+ }
517
+ end
518
+
519
+ def test_client_ca
520
+ args = {}
521
+ vflag = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
522
+
523
+ # client_ca as a cert
524
+ args[:ctx_proc] = proc { |server_ctx|
525
+ server_ctx.cert = @svr_cert
526
+ server_ctx.key = @svr_key
527
+ server_ctx.client_ca = @ca_cert
528
+ }
529
+ start_server(PORT, vflag, true, args){|server, port|
530
+ ctx = OpenSSL::SSL::SSLContext.new
531
+ ctx.key = @cli_key
532
+ ctx.cert = @cli_cert
533
+ sock = TCPSocket.new("127.0.0.1", port)
534
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
535
+ ssl.sync_close = true
536
+ ssl.connect
537
+ ssl.puts("foo")
538
+ assert_equal("foo\n", ssl.gets)
539
+ }
540
+
541
+ # client_ca as an array
542
+ args[:ctx_proc] = proc { |server_ctx|
543
+ server_ctx.cert = @svr_cert
544
+ server_ctx.key = @svr_key
545
+ server_ctx.client_ca = [@ca_cert, @svr_cert]
546
+ }
547
+ start_server(PORT, vflag, true, args){|server, port|
548
+ ctx = OpenSSL::SSL::SSLContext.new
549
+ ctx.key = @cli_key
550
+ ctx.cert = @cli_cert
551
+ sock = TCPSocket.new("127.0.0.1", port)
552
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
553
+ ssl.sync_close = true
554
+ ssl.connect
555
+ ssl.puts("foo")
556
+ assert_equal("foo\n", ssl.gets)
557
+ }
558
+ end
559
+
560
+ def test_sslctx_ssl_version_client
561
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
562
+ sock = TCPSocket.new("127.0.0.1", port)
563
+ ctx = OpenSSL::SSL::SSLContext.new
564
+ ctx.set_params
565
+ ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
566
+ ctx.ssl_version = "TLSv1"
567
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
568
+ assert_nothing_raised do
569
+ ssl.connect
570
+ end
571
+ ssl.puts("hello TLSv1")
572
+ ssl.close
573
+ sock.close
574
+ #
575
+ sock = TCPSocket.new("127.0.0.1", port)
576
+ ctx.ssl_version = "SSLv3"
577
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
578
+ assert_nothing_raised do
579
+ ssl.connect
580
+ end
581
+ ssl.puts("hello SSLv3")
582
+ ssl.close
583
+ sock.close
584
+ #
585
+ sock = TCPSocket.new("127.0.0.1", port)
586
+ ctx.ssl_version = "SSLv3_server"
587
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
588
+ assert_raise(OpenSSL::SSL::SSLError) do
589
+ ssl.connect
590
+ end
591
+ sock.close
592
+ #
593
+ sock = TCPSocket.new("127.0.0.1", port)
594
+ ctx.ssl_version = "TLSv1_client"
595
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
596
+ assert_nothing_raised do
597
+ ssl.connect
598
+ end
599
+ ssl.puts("hello TLSv1_client")
600
+ ssl.close
601
+ sock.close
602
+ }
603
+ end
604
+
605
+ def test_sslctx_ssl_version
606
+ args = {}
607
+ args[:ctx_proc] = proc { |server_ctx|
608
+ server_ctx.ssl_version = "TLSv1"
609
+ }
610
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, args){|server, port|
611
+ sock = TCPSocket.new("127.0.0.1", port)
612
+ ctx = OpenSSL::SSL::SSLContext.new
613
+ ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
614
+ ctx.ssl_version = "TLSv1"
615
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
616
+ assert_nothing_raised do
617
+ ssl.connect
618
+ end
619
+ ssl.puts("hello TLSv1")
620
+ ssl.close
621
+ sock.close
622
+ #
623
+ sock = TCPSocket.new("127.0.0.1", port)
624
+ ctx.ssl_version = "SSLv3"
625
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
626
+ assert_raise(OpenSSL::SSL::SSLError) do
627
+ ssl.connect
628
+ end
629
+ }
630
+ end
631
+
632
+ def test_verify_depth
633
+ vflag = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
634
+ args = {}
635
+ # depth == 1 => OK
636
+ args[:ctx_proc] = proc { |server_ctx|
637
+ server_ctx.cert = @svr_cert
638
+ server_ctx.key = @svr_key
639
+ server_ctx.verify_mode = vflag
640
+ server_ctx.verify_depth = 1
641
+ }
642
+ start_server(PORT, vflag, true, args){|server, port|
643
+ ctx = OpenSSL::SSL::SSLContext.new
644
+ ctx.key = @cli_key
645
+ ctx.cert = @cli_cert
646
+ sock = TCPSocket.new("127.0.0.1", port)
647
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
648
+ assert_nothing_raised do
649
+ ssl.connect
650
+ end
651
+ ssl.close
652
+ }
653
+ # depth == 0 => error
654
+ error = nil
655
+ args[:ctx_proc] = proc { |server_ctx|
656
+ server_ctx.cert = @svr_cert
657
+ server_ctx.key = @svr_key
658
+ server_ctx.verify_mode = vflag
659
+ server_ctx.verify_depth = 0
660
+ server_ctx.verify_callback = proc { |preverify_ok, store_ctx|
661
+ error = store_ctx.error
662
+ preverify_ok
663
+ }
664
+ }
665
+ start_server(PORT, vflag, true, args){|server, port|
666
+ ctx = OpenSSL::SSL::SSLContext.new
667
+ ctx.key = @cli_key
668
+ ctx.cert = @cli_cert
669
+ sock = TCPSocket.new("127.0.0.1", port)
670
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
671
+ assert_raises(OpenSSL::SSL::SSLError) do
672
+ ssl.connect
673
+ end
674
+ ssl.close
675
+ }
676
+ assert_equal OpenSSL::X509::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, error
677
+ end
678
+
679
+ def test_sslctx_set_params
680
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
681
+ sock = TCPSocket.new("127.0.0.1", port)
682
+ ctx = OpenSSL::SSL::SSLContext.new
683
+ ctx.set_params
684
+ assert_equal(OpenSSL::SSL::VERIFY_PEER, ctx.verify_mode)
685
+ assert_equal(OpenSSL::SSL::OP_ALL, ctx.options)
686
+ ciphers = ctx.ciphers
687
+ ciphers_versions = ciphers.collect{|_, v, _, _| v }
688
+ ciphers_names = ciphers.collect{|v, _, _, _| v }
689
+ assert(ciphers_names.all?{|v| /ADH/ !~ v })
690
+ assert(ciphers_versions.all?{|v| /SSLv2/ !~ v })
691
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
692
+ assert_raise(OpenSSL::SSL::SSLError){ ssl.connect }
693
+ assert_equal(OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN, ssl.verify_result)
694
+ }
695
+ end
696
+
697
+ def test_sslctx_ciphers
698
+ c = OpenSSL::SSL::SSLContext.new
699
+
700
+ c.ciphers = 'DEFAULT'
701
+ default = c.ciphers
702
+ assert(default.size > 0)
703
+
704
+ c.ciphers = 'ALL'
705
+ all = c.ciphers
706
+ assert(all.size > 0)
707
+
708
+ c.ciphers = 'LOW'
709
+ low = c.ciphers
710
+ assert(low.size > 0)
711
+
712
+ c.ciphers = 'MEDIUM'
713
+ medium = c.ciphers
714
+ assert(medium.size > 0)
715
+
716
+ c.ciphers = 'HIGH'
717
+ high = c.ciphers
718
+ assert(high.size > 0)
719
+
720
+ c.ciphers = 'EXP'
721
+ exp = c.ciphers
722
+ assert(exp.size > 0)
723
+
724
+ # -
725
+ c.ciphers = 'ALL:-LOW'
726
+ assert_equal(all - low, c.ciphers)
727
+ c.ciphers = 'ALL:-MEDIUM'
728
+ assert_equal(all - medium, c.ciphers)
729
+ c.ciphers = 'ALL:-HIGH'
730
+ assert_equal(all - high, c.ciphers)
731
+ c.ciphers = 'ALL:-EXP'
732
+ assert_equal(all - exp, c.ciphers)
733
+ c.ciphers = 'ALL:-LOW:-MEDIUM'
734
+ assert_equal(all - low - medium, c.ciphers)
735
+ c.ciphers = 'ALL:-LOW:-MEDIUM:-HIGH'
736
+ assert_equal(all - low - medium - high, c.ciphers)
737
+ assert_raise(OpenSSL::SSL::SSLError) do
738
+ # should be empty for OpenSSL/0.9.8l. check OpenSSL changes if this test fail.
739
+ c.ciphers = 'ALL:-LOW:-MEDIUM:-HIGH:-EXP'
740
+ end
741
+
742
+ # !
743
+ c.ciphers = 'ALL:-LOW:LOW'
744
+ assert_equal(all.sort, c.ciphers.sort)
745
+ c.ciphers = 'ALL:!LOW:LOW'
746
+ assert_equal(all - low, c.ciphers)
747
+ c.ciphers = 'ALL:!LOW:+LOW'
748
+ assert_equal(all - low, c.ciphers)
749
+
750
+ # +
751
+ c.ciphers = 'HIGH:LOW:+LOW'
752
+ assert_equal(high + low, c.ciphers)
753
+ c.ciphers = 'HIGH:LOW:+HIGH'
754
+ assert_equal(low + high, c.ciphers)
755
+
756
+ # name+name
757
+ c.ciphers = 'RC4'
758
+ rc4 = c.ciphers
759
+ c.ciphers = 'RSA'
760
+ rsa = c.ciphers
761
+ c.ciphers = 'RC4+RSA'
762
+ assert_equal(rc4&rsa, c.ciphers)
763
+ c.ciphers = 'RSA+RC4'
764
+ assert_equal(rc4&rsa, c.ciphers)
765
+ c.ciphers = 'ALL:RSA+RC4'
766
+ assert_equal(all + ((rc4&rsa) - all), c.ciphers)
767
+ end
768
+
769
+ def test_sslctx_options
770
+ args = {}
771
+ args[:ctx_proc] = proc { |server_ctx|
772
+ # TLSv1 only
773
+ server_ctx.options = OpenSSL::SSL::OP_NO_SSLv2|OpenSSL::SSL::OP_NO_SSLv3
774
+ }
775
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, args){|server, port|
776
+ sock = TCPSocket.new("127.0.0.1", port)
777
+ ctx = OpenSSL::SSL::SSLContext.new
778
+ ctx.set_params
779
+ ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
780
+ ctx.options = OpenSSL::SSL::OP_NO_TLSv1
781
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
782
+ assert_raise(OpenSSL::SSL::SSLError, Errno::ECONNRESET) do
783
+ ssl.connect
784
+ end
785
+ ssl.close
786
+ sock.close
787
+ #
788
+ sock = TCPSocket.new("127.0.0.1", port)
789
+ ctx = OpenSSL::SSL::SSLContext.new
790
+ ctx.set_params
791
+ ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
792
+ ctx.options = OpenSSL::SSL::OP_NO_SSLv3
793
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
794
+ assert_nothing_raised do
795
+ ssl.connect
796
+ end
797
+ ssl.close
798
+ sock.close
799
+ }
800
+ end
801
+
802
+ def test_post_connection_check
803
+ sslerr = OpenSSL::SSL::SSLError
804
+
805
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
806
+ sock = TCPSocket.new("127.0.0.1", port)
807
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
808
+ ssl.connect
809
+ assert_raise(sslerr){ssl.post_connection_check("localhost.localdomain")}
810
+ assert_raise(sslerr){ssl.post_connection_check("127.0.0.1")}
811
+ assert(ssl.post_connection_check("localhost"))
812
+ assert_raise(sslerr){ssl.post_connection_check("foo.example.com")}
813
+
814
+ cert = ssl.peer_cert
815
+ assert(!OpenSSL::SSL.verify_certificate_identity(cert, "localhost.localdomain"))
816
+ assert(!OpenSSL::SSL.verify_certificate_identity(cert, "127.0.0.1"))
817
+ assert(OpenSSL::SSL.verify_certificate_identity(cert, "localhost"))
818
+ assert(!OpenSSL::SSL.verify_certificate_identity(cert, "foo.example.com"))
819
+ }
820
+
821
+ now = Time.now
822
+ exts = [
823
+ ["keyUsage","keyEncipherment,digitalSignature",true],
824
+ ["subjectAltName","DNS:localhost.localdomain",false],
825
+ ["subjectAltName","IP:127.0.0.1",false],
826
+ ]
827
+ @svr_cert = issue_cert(@svr, @svr_key, 4, now, now+1800, exts,
828
+ @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
829
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
830
+ sock = TCPSocket.new("127.0.0.1", port)
831
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
832
+ ssl.connect
833
+ assert(ssl.post_connection_check("localhost.localdomain"))
834
+ assert(ssl.post_connection_check("127.0.0.1"))
835
+ assert_raise(sslerr){ssl.post_connection_check("localhost")}
836
+ assert_raise(sslerr){ssl.post_connection_check("foo.example.com")}
837
+
838
+ cert = ssl.peer_cert
839
+ assert(OpenSSL::SSL.verify_certificate_identity(cert, "localhost.localdomain"))
840
+ assert(OpenSSL::SSL.verify_certificate_identity(cert, "127.0.0.1"))
841
+ assert(!OpenSSL::SSL.verify_certificate_identity(cert, "localhost"))
842
+ assert(!OpenSSL::SSL.verify_certificate_identity(cert, "foo.example.com"))
843
+ }
844
+
845
+ now = Time.now
846
+ exts = [
847
+ ["keyUsage","keyEncipherment,digitalSignature",true],
848
+ ["subjectAltName","DNS:*.localdomain",false],
849
+ ]
850
+ @svr_cert = issue_cert(@svr, @svr_key, 5, now, now+1800, exts,
851
+ @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
852
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true){|server, port|
853
+ sock = TCPSocket.new("127.0.0.1", port)
854
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
855
+ ssl.connect
856
+ assert(ssl.post_connection_check("localhost.localdomain"))
857
+ assert_raise(sslerr){ssl.post_connection_check("127.0.0.1")}
858
+ assert_raise(sslerr){ssl.post_connection_check("localhost")}
859
+ assert_raise(sslerr){ssl.post_connection_check("foo.example.com")}
860
+ cert = ssl.peer_cert
861
+ assert(OpenSSL::SSL.verify_certificate_identity(cert, "localhost.localdomain"))
862
+ assert(!OpenSSL::SSL.verify_certificate_identity(cert, "127.0.0.1"))
863
+ assert(!OpenSSL::SSL.verify_certificate_identity(cert, "localhost"))
864
+ assert(!OpenSSL::SSL.verify_certificate_identity(cert, "foo.example.com"))
865
+ }
866
+ end
867
+
868
+ def TODO_implement_SSLSession_test_client_session
869
+ last_session = nil
870
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true) do |server, port|
871
+ 2.times do
872
+ sock = TCPSocket.new("127.0.0.1", port)
873
+ # Debian's openssl 0.9.8g-13 failed at assert(ssl.session_reused?),
874
+ # when use default SSLContext. [ruby-dev:36167]
875
+ ctx = OpenSSL::SSL::SSLContext.new("TLSv1")
876
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
877
+ ssl.sync_close = true
878
+ ssl.session = last_session if last_session
879
+ ssl.connect
880
+
881
+ session = ssl.session
882
+ if last_session
883
+ assert(ssl.session_reused?)
884
+
885
+ if session.respond_to?(:id)
886
+ assert_equal(session.id, last_session.id)
887
+ end
888
+ assert_equal(session.to_pem, last_session.to_pem)
889
+ assert_equal(session.to_der, last_session.to_der)
890
+ # Older version of OpenSSL may not be consistent. Look up which versions later.
891
+ assert_equal(session.to_text, last_session.to_text)
892
+ else
893
+ assert(!ssl.session_reused?)
894
+ end
895
+ last_session = session
896
+
897
+ str = "x" * 100 + "\n"
898
+ ssl.puts(str)
899
+ assert_equal(str, ssl.gets)
900
+
901
+ ssl.close
902
+ end
903
+ end
904
+ end
905
+
906
+ def TODO_implement_SSLSession_test_server_session
907
+ connections = 0
908
+ saved_session = nil
909
+
910
+ ctx_proc = Proc.new do |ctx, ssl|
911
+ # add test for session callbacks here
912
+ end
913
+
914
+ server_proc = Proc.new do |ctx, ssl|
915
+ session = ssl.session
916
+ stats = ctx.session_cache_stats
917
+
918
+ case connections
919
+ when 0
920
+ assert_equal(stats[:cache_num], 1)
921
+ assert_equal(stats[:cache_hits], 0)
922
+ assert_equal(stats[:cache_misses], 0)
923
+ assert(!ssl.session_reused?)
924
+ when 1
925
+ assert_equal(stats[:cache_num], 1)
926
+ assert_equal(stats[:cache_hits], 1)
927
+ assert_equal(stats[:cache_misses], 0)
928
+ assert(ssl.session_reused?)
929
+ ctx.session_remove(session)
930
+ saved_session = session
931
+ when 2
932
+ assert_equal(stats[:cache_num], 1)
933
+ assert_equal(stats[:cache_hits], 1)
934
+ assert_equal(stats[:cache_misses], 1)
935
+ assert(!ssl.session_reused?)
936
+ ctx.session_add(saved_session)
937
+ when 3
938
+ assert_equal(stats[:cache_num], 2)
939
+ assert_equal(stats[:cache_hits], 2)
940
+ assert_equal(stats[:cache_misses], 1)
941
+ assert(ssl.session_reused?)
942
+ ctx.flush_sessions(Time.now + 5000)
943
+ when 4
944
+ assert_equal(stats[:cache_num], 1)
945
+ assert_equal(stats[:cache_hits], 2)
946
+ assert_equal(stats[:cache_misses], 2)
947
+ assert(!ssl.session_reused?)
948
+ ctx.session_add(saved_session)
949
+ end
950
+ connections += 1
951
+
952
+ readwrite_loop(ctx, ssl)
953
+ end
954
+
955
+ first_session = nil
956
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, :ctx_proc => ctx_proc, :server_proc => server_proc) do |server, port|
957
+ 10.times do |i|
958
+ sock = TCPSocket.new("127.0.0.1", port)
959
+ ctx = OpenSSL::SSL::SSLContext.new
960
+ if defined?(OpenSSL::SSL::OP_NO_TICKET)
961
+ # disable RFC4507 support
962
+ ctx.options = OpenSSL::SSL::OP_NO_TICKET
963
+ end
964
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
965
+ ssl.sync_close = true
966
+ ssl.session = first_session if first_session
967
+ ssl.connect
968
+
969
+ session = ssl.session
970
+ if first_session
971
+ case i
972
+ when 1; assert(ssl.session_reused?)
973
+ when 2; assert(!ssl.session_reused?)
974
+ when 3; assert(ssl.session_reused?)
975
+ when 4; assert(!ssl.session_reused?)
976
+ when 5..10; assert(ssl.session_reused?)
977
+ end
978
+ end
979
+ first_session ||= session
980
+
981
+ str = "x" * 100 + "\n"
982
+ ssl.puts(str)
983
+ assert_equal(str, ssl.gets)
984
+
985
+ ssl.close
986
+ end
987
+ end
988
+ end
989
+
990
+ def test_tlsext_hostname
991
+ return unless OpenSSL::SSL::SSLSocket.instance_methods.include?("hostname")
992
+
993
+ ctx_proc = Proc.new do |ctx, ssl|
994
+ foo_ctx = ctx.dup
995
+
996
+ ctx.servername_cb = Proc.new do |ssl2, hostname|
997
+ case hostname
998
+ when 'foo.example.com'
999
+ foo_ctx
1000
+ when 'bar.example.com'
1001
+ nil
1002
+ else
1003
+ raise "unknown hostname #{hostname.inspect}"
1004
+ end
1005
+ end
1006
+ end
1007
+
1008
+ server_proc = Proc.new do |ctx, ssl|
1009
+ readwrite_loop(ctx, ssl)
1010
+ end
1011
+
1012
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, :ctx_proc => ctx_proc, :server_proc => server_proc) do |server, port|
1013
+ 2.times do |i|
1014
+ sock = TCPSocket.new("127.0.0.1", port)
1015
+ ctx = OpenSSL::SSL::SSLContext.new
1016
+ if defined?(OpenSSL::SSL::OP_NO_TICKET)
1017
+ # disable RFC4507 support
1018
+ ctx.options = OpenSSL::SSL::OP_NO_TICKET
1019
+ end
1020
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
1021
+ ssl.sync_close = true
1022
+ ssl.hostname = (i & 1 == 0) ? 'foo.example.com' : 'bar.example.com'
1023
+ ssl.connect
1024
+
1025
+ str = "x" * 100 + "\n"
1026
+ ssl.puts(str)
1027
+ assert_equal(str, ssl.gets)
1028
+
1029
+ ssl.close
1030
+ end
1031
+ end
1032
+ end
1033
+ end
1034
+
1035
+ end