jruby-openssl 0.6 → 0.7

Sign up to get free protection for your applications and to get access to all the features.
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