jruby-openssl 0.6 → 0.7

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