jruby-openssl 0.7.5.dev → 0.7.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/History.txt +44 -14
  2. data/Manifest.txt +135 -80
  3. data/Rakefile +14 -6
  4. data/lib/{openssl.rb → 1.8/openssl.rb} +2 -11
  5. data/lib/{openssl → 1.8/openssl}/bn.rb +2 -2
  6. data/lib/{openssl → 1.8/openssl}/buffering.rb +3 -1
  7. data/lib/{openssl → 1.8/openssl}/cipher.rb +0 -0
  8. data/lib/{openssl → 1.8/openssl}/config.rb +1 -1
  9. data/lib/{openssl → 1.8/openssl}/digest.rb +2 -2
  10. data/lib/{openssl → 1.8/openssl}/pkcs7.rb +0 -0
  11. data/lib/{openssl/ssl.rb → 1.8/openssl/ssl-internal.rb} +2 -2
  12. data/lib/1.8/openssl/ssl.rb +1 -0
  13. data/lib/{openssl/x509.rb → 1.8/openssl/x509-internal.rb} +8 -9
  14. data/lib/1.8/openssl/x509.rb +1 -0
  15. data/lib/1.9/openssl.rb +22 -0
  16. data/lib/1.9/openssl/bn.rb +35 -0
  17. data/lib/1.9/openssl/buffering.rb +448 -0
  18. data/lib/1.9/openssl/cipher.rb +65 -0
  19. data/lib/1.9/openssl/config.rb +313 -0
  20. data/lib/1.9/openssl/digest.rb +72 -0
  21. data/lib/1.9/openssl/ssl-internal.rb +177 -0
  22. data/lib/1.9/openssl/ssl.rb +2 -0
  23. data/lib/1.9/openssl/x509-internal.rb +158 -0
  24. data/lib/1.9/openssl/x509.rb +2 -0
  25. data/lib/{jopenssl.jar → shared/jopenssl.jar} +0 -0
  26. data/lib/{jopenssl → shared/jopenssl}/version.rb +1 -1
  27. data/lib/shared/openssl.rb +18 -0
  28. data/lib/{openssl → shared/openssl}/dummy.rb +0 -0
  29. data/lib/{openssl → shared/openssl}/dummyssl.rb +0 -0
  30. data/lib/shared/openssl/ssl.rb +1 -0
  31. data/lib/shared/openssl/x509.rb +1 -0
  32. data/test/{openssl → 1.8}/ssl_server.rb +0 -0
  33. data/test/{openssl → 1.8}/test_asn1.rb +15 -0
  34. data/test/{openssl → 1.8}/test_cipher.rb +0 -0
  35. data/test/{openssl → 1.8}/test_config.rb +0 -0
  36. data/test/{openssl → 1.8}/test_digest.rb +0 -0
  37. data/test/{openssl → 1.8}/test_ec.rb +0 -0
  38. data/test/{openssl → 1.8}/test_hmac.rb +0 -0
  39. data/test/{openssl → 1.8}/test_ns_spki.rb +0 -0
  40. data/test/{openssl → 1.8}/test_pair.rb +10 -2
  41. data/test/{openssl → 1.8}/test_pkcs7.rb +0 -0
  42. data/test/{openssl → 1.8}/test_pkey_rsa.rb +0 -0
  43. data/test/{openssl → 1.8}/test_ssl.rb +17 -20
  44. data/test/{openssl → 1.8}/test_x509cert.rb +0 -0
  45. data/test/{openssl → 1.8}/test_x509crl.rb +0 -0
  46. data/test/{openssl → 1.8}/test_x509ext.rb +0 -0
  47. data/test/{openssl → 1.8}/test_x509name.rb +0 -0
  48. data/test/{openssl → 1.8}/test_x509req.rb +0 -0
  49. data/test/{openssl → 1.8}/test_x509store.rb +0 -0
  50. data/test/{openssl → 1.8}/utils.rb +0 -0
  51. data/test/1.9/ssl_server.rb +81 -0
  52. data/test/1.9/test_asn1.rb +589 -0
  53. data/test/1.9/test_bn.rb +23 -0
  54. data/test/1.9/test_buffering.rb +88 -0
  55. data/test/1.9/test_cipher.rb +107 -0
  56. data/test/1.9/test_config.rb +288 -0
  57. data/test/1.9/test_digest.rb +118 -0
  58. data/test/1.9/test_engine.rb +15 -0
  59. data/test/1.9/test_hmac.rb +32 -0
  60. data/test/1.9/test_ns_spki.rb +50 -0
  61. data/test/1.9/test_ocsp.rb +47 -0
  62. data/test/1.9/test_pair.rb +257 -0
  63. data/test/1.9/test_pkcs12.rb +209 -0
  64. data/test/1.9/test_pkcs7.rb +151 -0
  65. data/test/1.9/test_pkey_dh.rb +72 -0
  66. data/test/1.9/test_pkey_dsa.rb +224 -0
  67. data/test/1.9/test_pkey_ec.rb +182 -0
  68. data/test/1.9/test_pkey_rsa.rb +244 -0
  69. data/test/1.9/test_ssl.rb +455 -0
  70. data/test/1.9/test_ssl_session.rb +327 -0
  71. data/test/1.9/test_x509cert.rb +217 -0
  72. data/test/1.9/test_x509crl.rb +221 -0
  73. data/test/1.9/test_x509ext.rb +69 -0
  74. data/test/1.9/test_x509name.rb +296 -0
  75. data/test/1.9/test_x509req.rb +150 -0
  76. data/test/1.9/test_x509store.rb +229 -0
  77. data/test/1.9/utils.rb +304 -0
  78. data/test/fixture/purpose/ca/ca_config.rb +1 -1
  79. data/test/fixture/purpose/ca/gen_cert.rb +128 -0
  80. data/test/fixture/purpose/ca/newcerts/4_cert.pem +19 -0
  81. data/test/fixture/purpose/ca/serial +1 -1
  82. data/test/fixture/purpose/sslserver_no_dsig_in_keyUsage.pem +19 -0
  83. data/test/ruby/envutil.rb +208 -0
  84. data/test/ruby/ut_eof.rb +128 -0
  85. data/test/test_java.rb +1 -1
  86. data/test/test_openssl.rb +1 -1
  87. data/test/test_pkcs7.rb +16 -0
  88. data/test/test_pkey_dsa.rb +180 -0
  89. data/test/test_pkey_rsa.rb +298 -0
  90. data/test/test_ssl.rb +1 -1
  91. data/test/test_x509store.rb +8 -0
  92. metadata +121 -75
  93. data/test/test_pkey.rb +0 -204
@@ -0,0 +1,327 @@
1
+ require_relative "utils"
2
+
3
+ if defined?(OpenSSL) && defined?(OpenSSL::SSL::Session)
4
+
5
+ class OpenSSL::TestSSLSession < OpenSSL::SSLTestCase
6
+ def test_session
7
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true) do |server, port|
8
+ sock = TCPSocket.new("127.0.0.1", port)
9
+ ctx = OpenSSL::SSL::SSLContext.new("TLSv1")
10
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
11
+ ssl.sync_close = true
12
+ ssl.connect
13
+ session = ssl.session
14
+ assert(session == OpenSSL::SSL::Session.new(session.to_pem))
15
+ assert(session == OpenSSL::SSL::Session.new(ssl))
16
+ assert_equal(300, session.timeout)
17
+ session.timeout = 5
18
+ assert_equal(5, session.timeout)
19
+ assert_not_nil(session.time)
20
+ # SSL_SESSION_time keeps long value so we can't keep nsec fragment.
21
+ session.time = t1 = Time.now.to_i
22
+ assert_equal(Time.at(t1), session.time)
23
+ if session.respond_to?(:id)
24
+ assert_not_nil(session.id)
25
+ end
26
+ pem = session.to_pem
27
+ assert_match(/\A-----BEGIN SSL SESSION PARAMETERS-----/, pem)
28
+ assert_match(/-----END SSL SESSION PARAMETERS-----\Z/, pem)
29
+ pem.gsub!(/-----(BEGIN|END) SSL SESSION PARAMETERS-----/, '').gsub!(/[\r\n]+/m, '')
30
+ assert_equal(session.to_der, pem.unpack('m*')[0])
31
+ assert_not_nil(session.to_text)
32
+ ssl.close
33
+ end
34
+ end
35
+
36
+ DUMMY_SESSION = <<__EOS__
37
+ -----BEGIN SSL SESSION PARAMETERS-----
38
+ MIIDzQIBAQICAwEEAgA5BCAF219w9ZEV8dNA60cpEGOI34hJtIFbf3bkfzSgMyad
39
+ MQQwyGLbkCxE4OiMLdKKem+pyh8V7ifoP7tCxhdmwoDlJxI1v6nVCjai+FGYuncy
40
+ NNSWoQYCBE4DDWuiAwIBCqOCAo4wggKKMIIBcqADAgECAgECMA0GCSqGSIb3DQEB
41
+ BQUAMD0xEzARBgoJkiaJk/IsZAEZFgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5
42
+ LWxhbmcxCzAJBgNVBAMMAkNBMB4XDTExMDYyMzA5NTQ1MVoXDTExMDYyMzEwMjQ1
43
+ MVowRDETMBEGCgmSJomT8ixkARkWA29yZzEZMBcGCgmSJomT8ixkARkWCXJ1Ynkt
44
+ bGFuZzESMBAGA1UEAwwJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
45
+ iQKBgQDLwsSw1ECnPtT+PkOgHhcGA71nwC2/nL85VBGnRqDxOqjVh7CxaKPERYHs
46
+ k4BPCkE3brtThPWc9kjHEQQ7uf9Y1rbCz0layNqHyywQEVLFmp1cpIt/Q3geLv8Z
47
+ D9pihowKJDyMDiN6ArYUmZczvW4976MU3+l54E6lF/JfFEU5hwIDAQABoxIwEDAO
48
+ BgNVHQ8BAf8EBAMCBaAwDQYJKoZIhvcNAQEFBQADggEBACj5WhoZ/ODVeHpwgq1d
49
+ 8fW/13ICRYHYpv6dzlWihyqclGxbKMlMnaVCPz+4JaVtMz3QB748KJQgL3Llg3R1
50
+ ek+f+n1MBCMfFFsQXJ2gtLB84zD6UCz8aaCWN5/czJCd7xMz7fRLy3TOIW5boXAU
51
+ zIa8EODk+477K1uznHm286ab0Clv+9d304hwmBZgkzLg6+31Of6d6s0E0rwLGiS2
52
+ sOWYg34Y3r4j8BS9Ak4jzpoLY6cJ0QAKCOJCgmjGr4XHpyXMLbicp3ga1uSbwtVO
53
+ gF/gTfpLhJC+y0EQ5x3Ftl88Cq7ZJuLBDMo/TLIfReJMQu/HlrTT7+LwtneSWGmr
54
+ KkSkAgQApQMCAROqgcMEgcAuDkAVfj6QAJMz9yqTzW5wPFyty7CxUEcwKjUqj5UP
55
+ /Yvky1EkRuM/eQfN7ucY+MUvMqv+R8ZSkHPsnjkBN5ChvZXjrUSZKFVjR4eFVz2V
56
+ jismLEJvIFhQh6pqTroRrOjMfTaM5Lwoytr2FTGobN9rnjIRsXeFQW1HLFbXn7Dh
57
+ 8uaQkMwIVVSGRB8T7t6z6WIdWruOjCZ6G5ASI5XoqAHwGezhLodZuvJEfsVyCF9y
58
+ j+RBGfCFrrQbBdnkFI/ztgM=
59
+ -----END SSL SESSION PARAMETERS-----
60
+ __EOS__
61
+
62
+ DUMMY_SESSION_NO_EXT = <<-__EOS__
63
+ -----BEGIN SSL SESSION PARAMETERS-----
64
+ MIIDCAIBAQICAwAEAgA5BCDyAW7rcpzMjDSosH+Tv6sukymeqgq3xQVVMez628A+
65
+ lAQw9TrKzrIqlHEh6ltuQaqv/Aq83AmaAlogYktZgXAjOGnhX7ifJDNLMuCfQq53
66
+ hPAaoQYCBE4iDeeiBAICASyjggKOMIICijCCAXKgAwIBAgIBAjANBgkqhkiG9w0B
67
+ AQUFADA9MRMwEQYKCZImiZPyLGQBGRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVi
68
+ eS1sYW5nMQswCQYDVQQDDAJDQTAeFw0xMTA3MTYyMjE3MTFaFw0xMTA3MTYyMjQ3
69
+ MTFaMEQxEzARBgoJkiaJk/IsZAEZFgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5
70
+ LWxhbmcxEjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
71
+ gYkCgYEAy8LEsNRApz7U/j5DoB4XBgO9Z8Atv5y/OVQRp0ag8Tqo1YewsWijxEWB
72
+ 7JOATwpBN267U4T1nPZIxxEEO7n/WNa2ws9JWsjah8ssEBFSxZqdXKSLf0N4Hi7/
73
+ GQ/aYoaMCiQ8jA4jegK2FJmXM71uPe+jFN/peeBOpRfyXxRFOYcCAwEAAaMSMBAw
74
+ DgYDVR0PAQH/BAQDAgWgMA0GCSqGSIb3DQEBBQUAA4IBAQA3TRzABRG3kz8jEEYr
75
+ tDQqXgsxwTsLhTT5d1yF0D8uFw+y15hJAJnh6GJHjqhWBrF4zNoTApFo+4iIL6g3
76
+ q9C3mUsxIVAHx41DwZBh/FI7J4FqlAoGOguu7892CNVY3ZZjc3AXMTdKjcNoWPzz
77
+ FCdj5fNT24JMMe+ZdGZK97ChahJsdn/6B3j6ze9NK9mfYEbiJhejGTPLOFVHJCGR
78
+ KYYZ3ZcKhLDr9ql4d7cCo1gBtemrmFQGPui7GttNEqmXqUKvV8mYoa8farf5i7T4
79
+ L6a/gp2cVZTaDIS1HjbJsA/Ag7AajZqiN6LfqShNUVsrMZ+5CoV8EkBDTZPJ9MSr
80
+ a3EqpAIEAKUDAgET
81
+ -----END SSL SESSION PARAMETERS-----
82
+ __EOS__
83
+
84
+
85
+ def test_session_time
86
+ sess = OpenSSL::SSL::Session.new(DUMMY_SESSION_NO_EXT)
87
+ sess.time = (now = Time.now)
88
+ assert_equal(now.to_i, sess.time.to_i)
89
+ sess.time = 1
90
+ assert_equal(1, sess.time.to_i)
91
+ sess.time = 1.2345
92
+ assert_equal(1, sess.time.to_i)
93
+ # Can OpenSSL handle t>2038y correctly? Version?
94
+ sess.time = 2**31 - 1
95
+ assert_equal(2**31 - 1, sess.time.to_i)
96
+ end
97
+
98
+ def test_session_timeout
99
+ sess = OpenSSL::SSL::Session.new(DUMMY_SESSION_NO_EXT)
100
+ assert_raise(TypeError) do
101
+ sess.timeout = (now = Time.now)
102
+ end
103
+ sess.timeout = 1
104
+ assert_equal(1, sess.timeout.to_i)
105
+ sess.timeout = 1.2345
106
+ assert_equal(1, sess.timeout.to_i)
107
+ sess.timeout = 2**31 - 1
108
+ assert_equal(2**31 - 1, sess.timeout.to_i)
109
+ end
110
+
111
+ def test_session_exts_read
112
+ assert(OpenSSL::SSL::Session.new(DUMMY_SESSION))
113
+ end if OpenSSL::OPENSSL_VERSION_NUMBER >= 0x009080bf
114
+
115
+ def test_client_session
116
+ last_session = nil
117
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true) do |server, port|
118
+ 2.times do
119
+ sock = TCPSocket.new("127.0.0.1", port)
120
+ # Debian's openssl 0.9.8g-13 failed at assert(ssl.session_reused?),
121
+ # when use default SSLContext. [ruby-dev:36167]
122
+ ctx = OpenSSL::SSL::SSLContext.new("TLSv1")
123
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
124
+ ssl.sync_close = true
125
+ ssl.session = last_session if last_session
126
+ ssl.connect
127
+
128
+ session = ssl.session
129
+ if last_session
130
+ assert(ssl.session_reused?)
131
+
132
+ if session.respond_to?(:id)
133
+ assert_equal(session.id, last_session.id)
134
+ end
135
+ assert_equal(session.to_pem, last_session.to_pem)
136
+ assert_equal(session.to_der, last_session.to_der)
137
+ # Older version of OpenSSL may not be consistent. Look up which versions later.
138
+ assert_equal(session.to_text, last_session.to_text)
139
+ else
140
+ assert(!ssl.session_reused?)
141
+ end
142
+ last_session = session
143
+
144
+ str = "x" * 100 + "\n"
145
+ ssl.puts(str)
146
+ assert_equal(str, ssl.gets)
147
+
148
+ ssl.close
149
+ end
150
+ end
151
+ end
152
+
153
+ def test_server_session
154
+ connections = 0
155
+ saved_session = nil
156
+
157
+ ctx_proc = Proc.new do |ctx, ssl|
158
+ # add test for session callbacks here
159
+ end
160
+
161
+ server_proc = Proc.new do |ctx, ssl|
162
+ session = ssl.session
163
+ stats = ctx.session_cache_stats
164
+
165
+ case connections
166
+ when 0
167
+ assert_equal(stats[:cache_num], 1)
168
+ assert_equal(stats[:cache_hits], 0)
169
+ assert_equal(stats[:cache_misses], 0)
170
+ assert(!ssl.session_reused?)
171
+ when 1
172
+ assert_equal(stats[:cache_num], 1)
173
+ assert_equal(stats[:cache_hits], 1)
174
+ assert_equal(stats[:cache_misses], 0)
175
+ assert(ssl.session_reused?)
176
+ ctx.session_remove(session)
177
+ saved_session = session
178
+ when 2
179
+ assert_equal(stats[:cache_num], 1)
180
+ assert_equal(stats[:cache_hits], 1)
181
+ assert_equal(stats[:cache_misses], 1)
182
+ assert(!ssl.session_reused?)
183
+ ctx.session_add(saved_session)
184
+ when 3
185
+ assert_equal(stats[:cache_num], 2)
186
+ assert_equal(stats[:cache_hits], 2)
187
+ assert_equal(stats[:cache_misses], 1)
188
+ assert(ssl.session_reused?)
189
+ ctx.flush_sessions(Time.now + 5000)
190
+ when 4
191
+ assert_equal(stats[:cache_num], 1)
192
+ assert_equal(stats[:cache_hits], 2)
193
+ assert_equal(stats[:cache_misses], 2)
194
+ assert(!ssl.session_reused?)
195
+ ctx.session_add(saved_session)
196
+ end
197
+ connections += 1
198
+
199
+ readwrite_loop(ctx, ssl)
200
+ end
201
+
202
+ first_session = nil
203
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, :ctx_proc => ctx_proc, :server_proc => server_proc) do |server, port|
204
+ 10.times do |i|
205
+ sock = TCPSocket.new("127.0.0.1", port)
206
+ ctx = OpenSSL::SSL::SSLContext.new
207
+ if defined?(OpenSSL::SSL::OP_NO_TICKET)
208
+ # disable RFC4507 support
209
+ ctx.options = OpenSSL::SSL::OP_NO_TICKET
210
+ end
211
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
212
+ ssl.sync_close = true
213
+ ssl.session = first_session if first_session
214
+ ssl.connect
215
+
216
+ session = ssl.session
217
+ if first_session
218
+ case i
219
+ when 1; assert(ssl.session_reused?)
220
+ when 2; assert(!ssl.session_reused?)
221
+ when 3; assert(ssl.session_reused?)
222
+ when 4; assert(!ssl.session_reused?)
223
+ when 5..10; assert(ssl.session_reused?)
224
+ end
225
+ end
226
+ first_session ||= session
227
+
228
+ str = "x" * 100 + "\n"
229
+ ssl.puts(str)
230
+ assert_equal(str, ssl.gets)
231
+
232
+ ssl.close
233
+ end
234
+ end
235
+ end
236
+
237
+ def test_ctx_client_session_cb
238
+ called = {}
239
+ ctx = OpenSSL::SSL::SSLContext.new("SSLv3")
240
+ ctx.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT
241
+
242
+ ctx.session_new_cb = lambda { |ary|
243
+ sock, sess = ary
244
+ called[:new] = [sock, sess]
245
+ }
246
+
247
+ ctx.session_remove_cb = lambda { |ary|
248
+ ctx, sess = ary
249
+ called[:remove] = [ctx, sess]
250
+ # any resulting value is OK (ignored)
251
+ }
252
+
253
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true) do |server, port|
254
+ sock = TCPSocket.new("127.0.0.1", port)
255
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
256
+ ssl.sync_close = true
257
+ ssl.connect
258
+ assert_equal(1, ctx.session_cache_stats[:cache_num])
259
+ assert_equal(1, ctx.session_cache_stats[:connect_good])
260
+ assert_equal([ssl, ssl.session], called[:new])
261
+ assert(ctx.session_remove(ssl.session))
262
+ assert(!ctx.session_remove(ssl.session))
263
+ assert_equal([ctx, ssl.session], called[:remove])
264
+ ssl.close
265
+ end
266
+ end
267
+
268
+ def test_ctx_server_session_cb
269
+ called = {}
270
+
271
+ ctx_proc = Proc.new { |ctx, ssl|
272
+ ctx.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_SERVER
273
+ last_server_session = nil
274
+
275
+ # get_cb is called whenever a client proposed to resume a session but
276
+ # the session could not be found in the internal session cache.
277
+ ctx.session_get_cb = lambda { |ary|
278
+ sess, data = ary
279
+ if last_server_session
280
+ called[:get2] = [sess, data]
281
+ last_server_session
282
+ else
283
+ called[:get1] = [sess, data]
284
+ last_server_session = sess
285
+ nil
286
+ end
287
+ }
288
+
289
+ ctx.session_new_cb = lambda { |ary|
290
+ sock, sess = ary
291
+ called[:new] = [sock, sess]
292
+ # SSL server doesn't cache sessions so get_cb is called next time.
293
+ ctx.session_remove(sess)
294
+ }
295
+
296
+ ctx.session_remove_cb = lambda { |ary|
297
+ ctx, sess = ary
298
+ called[:remove] = [ctx, sess]
299
+ }
300
+ }
301
+
302
+ server_proc = Proc.new { |c, ssl|
303
+ session = ssl.session
304
+ stats = c.session_cache_stats
305
+ readwrite_loop(c, ssl)
306
+ }
307
+ start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, :ctx_proc => ctx_proc, :server_proc => server_proc) do |server, port|
308
+ last_client_session = nil
309
+ 3.times do
310
+ sock = TCPSocket.new("127.0.0.1", port)
311
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, OpenSSL::SSL::SSLContext.new("SSLv3"))
312
+ ssl.sync_close = true
313
+ ssl.session = last_client_session if last_client_session
314
+ ssl.connect
315
+ last_client_session = ssl.session
316
+ ssl.close
317
+ Thread.pass # try to ensure server calls callbacks
318
+ assert(called.delete(:new))
319
+ assert(called.delete(:remove))
320
+ end
321
+ end
322
+ assert(called[:get1])
323
+ assert(called[:get2])
324
+ end
325
+ end
326
+
327
+ end
@@ -0,0 +1,217 @@
1
+ require_relative "utils"
2
+
3
+ if defined?(OpenSSL)
4
+
5
+ class OpenSSL::TestX509Certificate < Test::Unit::TestCase
6
+ def setup
7
+ @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024
8
+ @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048
9
+ @dsa256 = OpenSSL::TestUtils::TEST_KEY_DSA256
10
+ @dsa512 = OpenSSL::TestUtils::TEST_KEY_DSA512
11
+ @ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
12
+ @ee1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE1")
13
+ @ee2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE2")
14
+ end
15
+
16
+ def teardown
17
+ end
18
+
19
+ def issue_cert(*args)
20
+ OpenSSL::TestUtils.issue_cert(*args)
21
+ end
22
+
23
+ def test_serial
24
+ [1, 2**32, 2**100].each{|s|
25
+ cert = issue_cert(@ca, @rsa2048, s, Time.now, Time.now+3600, [],
26
+ nil, nil, OpenSSL::Digest::SHA1.new)
27
+ assert_equal(s, cert.serial)
28
+ cert = OpenSSL::X509::Certificate.new(cert.to_der)
29
+ assert_equal(s, cert.serial)
30
+ }
31
+ end
32
+
33
+ def test_public_key
34
+ exts = [
35
+ ["basicConstraints","CA:TRUE",true],
36
+ ["subjectKeyIdentifier","hash",false],
37
+ ["authorityKeyIdentifier","keyid:always",false],
38
+ ]
39
+
40
+ sha1 = OpenSSL::Digest::SHA1.new
41
+ dss1 = OpenSSL::Digest::DSS1.new
42
+ [
43
+ [@rsa1024, sha1], [@rsa2048, sha1], [@dsa256, dss1], [@dsa512, dss1],
44
+ ].each{|pk, digest|
45
+ cert = issue_cert(@ca, pk, 1, Time.now, Time.now+3600, exts,
46
+ nil, nil, digest)
47
+ assert_equal(cert.extensions[1].value,
48
+ OpenSSL::TestUtils.get_subject_key_id(cert))
49
+ cert = OpenSSL::X509::Certificate.new(cert.to_der)
50
+ assert_equal(cert.extensions[1].value,
51
+ OpenSSL::TestUtils.get_subject_key_id(cert))
52
+ }
53
+ end
54
+
55
+ def test_validity
56
+ now = Time.now until now && now.usec != 0
57
+ cert = issue_cert(@ca, @rsa2048, 1, now, now+3600, [],
58
+ nil, nil, OpenSSL::Digest::SHA1.new)
59
+ assert_not_equal(now, cert.not_before)
60
+ assert_not_equal(now+3600, cert.not_after)
61
+
62
+ now = Time.at(now.to_i)
63
+ cert = issue_cert(@ca, @rsa2048, 1, now, now+3600, [],
64
+ nil, nil, OpenSSL::Digest::SHA1.new)
65
+ assert_equal(now.getutc, cert.not_before)
66
+ assert_equal((now+3600).getutc, cert.not_after)
67
+
68
+ now = Time.at(0)
69
+ cert = issue_cert(@ca, @rsa2048, 1, now, now, [],
70
+ nil, nil, OpenSSL::Digest::SHA1.new)
71
+ assert_equal(now.getutc, cert.not_before)
72
+ assert_equal(now.getutc, cert.not_after)
73
+
74
+ now = Time.at(0x7fffffff)
75
+ cert = issue_cert(@ca, @rsa2048, 1, now, now, [],
76
+ nil, nil, OpenSSL::Digest::SHA1.new)
77
+ assert_equal(now.getutc, cert.not_before)
78
+ assert_equal(now.getutc, cert.not_after)
79
+ end
80
+
81
+ def test_extension
82
+ ca_exts = [
83
+ ["basicConstraints","CA:TRUE",true],
84
+ ["keyUsage","keyCertSign, cRLSign",true],
85
+ ["subjectKeyIdentifier","hash",false],
86
+ ["authorityKeyIdentifier","keyid:always",false],
87
+ ]
88
+ ca_cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, ca_exts,
89
+ nil, nil, OpenSSL::Digest::SHA1.new)
90
+ ca_cert.extensions.each_with_index{|ext, i|
91
+ assert_equal(ca_exts[i].first, ext.oid)
92
+ assert_equal(ca_exts[i].last, ext.critical?)
93
+ }
94
+
95
+ ee1_exts = [
96
+ ["keyUsage","Non Repudiation, Digital Signature, Key Encipherment",true],
97
+ ["subjectKeyIdentifier","hash",false],
98
+ ["authorityKeyIdentifier","keyid:always",false],
99
+ ["extendedKeyUsage","clientAuth, emailProtection, codeSigning",false],
100
+ ["subjectAltName","email:ee1@ruby-lang.org",false],
101
+ ]
102
+ ee1_cert = issue_cert(@ee1, @rsa1024, 2, Time.now, Time.now+1800, ee1_exts,
103
+ ca_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
104
+ assert_equal(ca_cert.subject.to_der, ee1_cert.issuer.to_der)
105
+ ee1_cert.extensions.each_with_index{|ext, i|
106
+ assert_equal(ee1_exts[i].first, ext.oid)
107
+ assert_equal(ee1_exts[i].last, ext.critical?)
108
+ }
109
+
110
+ ee2_exts = [
111
+ ["keyUsage","Non Repudiation, Digital Signature, Key Encipherment",true],
112
+ ["subjectKeyIdentifier","hash",false],
113
+ ["authorityKeyIdentifier","issuer:always",false],
114
+ ["extendedKeyUsage","clientAuth, emailProtection, codeSigning",false],
115
+ ["subjectAltName","email:ee2@ruby-lang.org",false],
116
+ ]
117
+ ee2_cert = issue_cert(@ee2, @rsa1024, 3, Time.now, Time.now+1800, ee2_exts,
118
+ ca_cert, @rsa2048, OpenSSL::Digest::MD5.new)
119
+ assert_equal(ca_cert.subject.to_der, ee2_cert.issuer.to_der)
120
+ ee2_cert.extensions.each_with_index{|ext, i|
121
+ assert_equal(ee2_exts[i].first, ext.oid)
122
+ assert_equal(ee2_exts[i].last, ext.critical?)
123
+ }
124
+
125
+ end
126
+
127
+ def test_sign_and_verify
128
+ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
129
+ nil, nil, OpenSSL::Digest::SHA1.new)
130
+ assert_equal(false, cert.verify(@rsa1024))
131
+ assert_equal(true, cert.verify(@rsa2048))
132
+ assert_equal(false, certificate_error_returns_false { cert.verify(@dsa256) })
133
+ assert_equal(false, certificate_error_returns_false { cert.verify(@dsa512) })
134
+ cert.serial = 2
135
+ assert_equal(false, cert.verify(@rsa2048))
136
+
137
+ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
138
+ nil, nil, OpenSSL::Digest::MD5.new)
139
+ assert_equal(false, cert.verify(@rsa1024))
140
+ assert_equal(true, cert.verify(@rsa2048))
141
+
142
+ assert_equal(false, certificate_error_returns_false { cert.verify(@dsa256) })
143
+ assert_equal(false, certificate_error_returns_false { cert.verify(@dsa512) })
144
+ cert.subject = @ee1
145
+ assert_equal(false, cert.verify(@rsa2048))
146
+
147
+ cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],
148
+ nil, nil, OpenSSL::Digest::DSS1.new)
149
+ assert_equal(false, certificate_error_returns_false { cert.verify(@rsa1024) })
150
+ assert_equal(false, certificate_error_returns_false { cert.verify(@rsa2048) })
151
+ assert_equal(false, cert.verify(@dsa256))
152
+ assert_equal(true, cert.verify(@dsa512))
153
+ cert.not_after = Time.now
154
+ assert_equal(false, cert.verify(@dsa512))
155
+
156
+ begin
157
+ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
158
+ nil, nil, OpenSSL::Digest::DSS1.new)
159
+ assert_equal(false, cert.verify(@rsa1024))
160
+ assert_equal(true, cert.verify(@rsa2048))
161
+ assert_equal(false, certificate_error_returns_false { cert.verify(@dsa256) })
162
+ assert_equal(false, certificate_error_returns_false { cert.verify(@dsa512) })
163
+ cert.subject = @ee1
164
+ assert_equal(false, cert.verify(@rsa2048))
165
+ rescue OpenSSL::X509::CertificateError
166
+ end
167
+
168
+ assert_raise(OpenSSL::X509::CertificateError){
169
+ cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],
170
+ nil, nil, OpenSSL::Digest::MD5.new)
171
+ }
172
+ end
173
+
174
+ def test_dsig_algorithm_mismatch
175
+ assert_raise(OpenSSL::X509::CertificateError) do
176
+ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
177
+ nil, nil, OpenSSL::Digest::DSS1.new)
178
+ end
179
+ assert_raise(OpenSSL::X509::CertificateError) do
180
+ cert = issue_cert(@ca, @dsa512, 1, Time.now, Time.now+3600, [],
181
+ nil, nil, OpenSSL::Digest::MD5.new)
182
+ end
183
+ end
184
+
185
+ def test_dsa_with_sha2
186
+ begin
187
+ cert = issue_cert(@ca, @dsa256, 1, Time.now, Time.now+3600, [],
188
+ nil, nil, OpenSSL::Digest::SHA256.new)
189
+ assert_equal("dsa_with_SHA256", cert.signature_algorithm)
190
+ rescue OpenSSL::X509::CertificateError
191
+ # dsa_with_sha2 not supported. skip following test.
192
+ return
193
+ end
194
+ # TODO: need more tests for dsa + sha2
195
+
196
+ # SHA1 is allowed from OpenSSL 1.0.0 (0.9.8 requires DSS1)
197
+ cert = issue_cert(@ca, @dsa256, 1, Time.now, Time.now+3600, [],
198
+ nil, nil, OpenSSL::Digest::SHA1.new)
199
+ assert_equal("dsaWithSHA1", cert.signature_algorithm)
200
+ end if defined?(OpenSSL::Digest::SHA256)
201
+
202
+ def test_check_private_key
203
+ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
204
+ nil, nil, OpenSSL::Digest::SHA1.new)
205
+ assert_equal(true, cert.check_private_key(@rsa2048))
206
+ end
207
+
208
+ private
209
+
210
+ def certificate_error_returns_false
211
+ yield
212
+ rescue OpenSSL::X509::CertificateError
213
+ false
214
+ end
215
+ end
216
+
217
+ end