jruby-openssl 0.7.5.dev → 0.7.5

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 (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,150 @@
1
+ require_relative "utils"
2
+
3
+ if defined?(OpenSSL)
4
+
5
+ class OpenSSL::TestX509Request < 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
+ @dn = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou")
12
+ end
13
+
14
+ def issue_csr(ver, dn, key, digest)
15
+ req = OpenSSL::X509::Request.new
16
+ req.version = ver
17
+ req.subject = dn
18
+ req.public_key = key.public_key
19
+ req.sign(key, digest)
20
+ req
21
+ end
22
+
23
+ def test_public_key
24
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
25
+ assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der)
26
+ req = OpenSSL::X509::Request.new(req.to_der)
27
+ assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der)
28
+
29
+ req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest::DSS1.new)
30
+ assert_equal(@dsa512.public_key.to_der, req.public_key.to_der)
31
+ req = OpenSSL::X509::Request.new(req.to_der)
32
+ assert_equal(@dsa512.public_key.to_der, req.public_key.to_der)
33
+ end
34
+
35
+ def test_version
36
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
37
+ assert_equal(0, req.version)
38
+ req = OpenSSL::X509::Request.new(req.to_der)
39
+ assert_equal(0, req.version)
40
+
41
+ req = issue_csr(1, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
42
+ assert_equal(1, req.version)
43
+ req = OpenSSL::X509::Request.new(req.to_der)
44
+ assert_equal(1, req.version)
45
+ end
46
+
47
+ def test_subject
48
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
49
+ assert_equal(@dn.to_der, req.subject.to_der)
50
+ req = OpenSSL::X509::Request.new(req.to_der)
51
+ assert_equal(@dn.to_der, req.subject.to_der)
52
+ end
53
+
54
+ def create_ext_req(exts)
55
+ ef = OpenSSL::X509::ExtensionFactory.new
56
+ exts = exts.collect{|e| ef.create_extension(*e) }
57
+ return OpenSSL::ASN1::Set([OpenSSL::ASN1::Sequence(exts)])
58
+ end
59
+
60
+ def get_ext_req(ext_req_value)
61
+ set = OpenSSL::ASN1.decode(ext_req_value)
62
+ seq = set.value[0]
63
+ seq.value.collect{|asn1ext|
64
+ OpenSSL::X509::Extension.new(asn1ext).to_a
65
+ }
66
+ end
67
+
68
+ def test_attr
69
+ exts = [
70
+ ["keyUsage", "Digital Signature, Key Encipherment", true],
71
+ ["subjectAltName", "email:gotoyuzo@ruby-lang.org", false],
72
+ ]
73
+ attrval = create_ext_req(exts)
74
+ attrs = [
75
+ OpenSSL::X509::Attribute.new("extReq", attrval),
76
+ OpenSSL::X509::Attribute.new("msExtReq", attrval),
77
+ ]
78
+
79
+ req0 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
80
+ attrs.each{|attr| req0.add_attribute(attr) }
81
+ req1 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
82
+ req1.attributes = attrs
83
+ assert_equal(req0.to_der, req1.to_der)
84
+
85
+ attrs = req0.attributes
86
+ assert_equal(2, attrs.size)
87
+ assert_equal("extReq", attrs[0].oid)
88
+ assert_equal("msExtReq", attrs[1].oid)
89
+ assert_equal(exts, get_ext_req(attrs[0].value))
90
+ assert_equal(exts, get_ext_req(attrs[1].value))
91
+
92
+ req = OpenSSL::X509::Request.new(req0.to_der)
93
+ attrs = req.attributes
94
+ assert_equal(2, attrs.size)
95
+ assert_equal("extReq", attrs[0].oid)
96
+ assert_equal("msExtReq", attrs[1].oid)
97
+ assert_equal(exts, get_ext_req(attrs[0].value))
98
+ assert_equal(exts, get_ext_req(attrs[1].value))
99
+ end
100
+
101
+ def test_sign_and_verify
102
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
103
+ assert_equal(true, req.verify(@rsa1024))
104
+ assert_equal(false, req.verify(@rsa2048))
105
+ assert_equal(false, request_error_returns_false { req.verify(@dsa256) })
106
+ assert_equal(false, request_error_returns_false { req.verify(@dsa512) })
107
+ req.version = 1
108
+ assert_equal(false, req.verify(@rsa1024))
109
+
110
+ req = issue_csr(0, @dn, @rsa2048, OpenSSL::Digest::MD5.new)
111
+ assert_equal(false, req.verify(@rsa1024))
112
+ assert_equal(true, req.verify(@rsa2048))
113
+ assert_equal(false, request_error_returns_false { req.verify(@dsa256) })
114
+ assert_equal(false, request_error_returns_false { req.verify(@dsa512) })
115
+ req.subject = OpenSSL::X509::Name.parse("/C=JP/CN=FooBar")
116
+ assert_equal(false, req.verify(@rsa2048))
117
+
118
+ req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest::DSS1.new)
119
+ assert_equal(false, request_error_returns_false { req.verify(@rsa1024) })
120
+ assert_equal(false, request_error_returns_false { req.verify(@rsa2048) })
121
+ assert_equal(false, req.verify(@dsa256))
122
+ assert_equal(true, req.verify(@dsa512))
123
+ req.public_key = @rsa1024.public_key
124
+ assert_equal(false, req.verify(@dsa512))
125
+
126
+ begin
127
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::DSS1.new)
128
+ assert_equal(true, req.verify(@rsa1024))
129
+ assert_equal(false, req.verify(@rsa2048))
130
+ assert_equal(false, request_error_returns_false { req.verify(@dsa256) })
131
+ assert_equal(false, request_error_returns_false { req.verify(@dsa512) })
132
+ req.version = 1
133
+ assert_equal(false, req.verify(@rsa1024))
134
+ rescue OpenSSL::X509::RequestError
135
+ end
136
+
137
+ assert_raise(OpenSSL::X509::RequestError){
138
+ issue_csr(0, @dn, @dsa512, OpenSSL::Digest::MD5.new) }
139
+ end
140
+
141
+ private
142
+
143
+ def request_error_returns_false
144
+ yield
145
+ rescue OpenSSL::X509::RequestError
146
+ false
147
+ end
148
+ end
149
+
150
+ end
@@ -0,0 +1,229 @@
1
+ require_relative "utils"
2
+
3
+ if defined?(OpenSSL)
4
+
5
+ class OpenSSL::TestX509Store < 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
+ @ca1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA1")
12
+ @ca2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA2")
13
+ @ee1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE1")
14
+ @ee2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE2")
15
+ end
16
+
17
+ def teardown
18
+ end
19
+
20
+ def test_nosegv_on_cleanup
21
+ cert = OpenSSL::X509::Certificate.new
22
+ store = OpenSSL::X509::Store.new
23
+ ctx = OpenSSL::X509::StoreContext.new(store, cert, [])
24
+ ctx.cleanup
25
+ ctx.verify
26
+ end
27
+
28
+ def issue_cert(*args)
29
+ OpenSSL::TestUtils.issue_cert(*args)
30
+ end
31
+
32
+ def issue_crl(*args)
33
+ OpenSSL::TestUtils.issue_crl(*args)
34
+ end
35
+
36
+ def test_verify
37
+ now = Time.at(Time.now.to_i)
38
+ ca_exts = [
39
+ ["basicConstraints","CA:TRUE",true],
40
+ ["keyUsage","cRLSign,keyCertSign",true],
41
+ ]
42
+ ee_exts = [
43
+ ["keyUsage","keyEncipherment,digitalSignature",true],
44
+ ]
45
+ ca1_cert = issue_cert(@ca1, @rsa2048, 1, now, now+3600, ca_exts,
46
+ nil, nil, OpenSSL::Digest::SHA1.new)
47
+ ca2_cert = issue_cert(@ca2, @rsa1024, 2, now, now+1800, ca_exts,
48
+ ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
49
+ ee1_cert = issue_cert(@ee1, @dsa256, 10, now, now+1800, ee_exts,
50
+ ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)
51
+ ee2_cert = issue_cert(@ee2, @dsa512, 20, now, now+1800, ee_exts,
52
+ ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)
53
+ ee3_cert = issue_cert(@ee2, @dsa512, 30, now-100, now-1, ee_exts,
54
+ ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)
55
+ ee4_cert = issue_cert(@ee2, @dsa512, 40, now+1000, now+2000, ee_exts,
56
+ ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)
57
+
58
+ revoke_info = []
59
+ crl1 = issue_crl(revoke_info, 1, now, now+1800, [],
60
+ ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
61
+ revoke_info = [ [2, now, 1], ]
62
+ crl1_2 = issue_crl(revoke_info, 2, now, now+1800, [],
63
+ ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
64
+ revoke_info = [ [20, now, 1], ]
65
+ crl2 = issue_crl(revoke_info, 1, now, now+1800, [],
66
+ ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)
67
+ revoke_info = []
68
+ crl2_2 = issue_crl(revoke_info, 2, now-100, now-1, [],
69
+ ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new)
70
+
71
+ assert_equal(true, ca1_cert.verify(ca1_cert.public_key)) # self signed
72
+ assert_equal(true, ca2_cert.verify(ca1_cert.public_key)) # issued by ca1
73
+ assert_equal(true, ee1_cert.verify(ca2_cert.public_key)) # issued by ca2
74
+ assert_equal(true, ee2_cert.verify(ca2_cert.public_key)) # issued by ca2
75
+ assert_equal(true, ee3_cert.verify(ca2_cert.public_key)) # issued by ca2
76
+ assert_equal(true, crl1.verify(ca1_cert.public_key)) # issued by ca1
77
+ assert_equal(true, crl1_2.verify(ca1_cert.public_key)) # issued by ca1
78
+ assert_equal(true, crl2.verify(ca2_cert.public_key)) # issued by ca2
79
+ assert_equal(true, crl2_2.verify(ca2_cert.public_key)) # issued by ca2
80
+
81
+ store = OpenSSL::X509::Store.new
82
+ assert_equal(false, store.verify(ca1_cert))
83
+ assert_not_equal(OpenSSL::X509::V_OK, store.error)
84
+
85
+ assert_equal(false, store.verify(ca2_cert))
86
+ assert_not_equal(OpenSSL::X509::V_OK, store.error)
87
+
88
+ store.add_cert(ca1_cert)
89
+ assert_equal(true, store.verify(ca2_cert))
90
+ assert_equal(OpenSSL::X509::V_OK, store.error)
91
+ assert_equal("ok", store.error_string)
92
+ chain = store.chain
93
+ assert_equal(2, chain.size)
94
+ assert_equal(@ca2.to_der, chain[0].subject.to_der)
95
+ assert_equal(@ca1.to_der, chain[1].subject.to_der)
96
+
97
+ store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
98
+ assert_equal(false, store.verify(ca2_cert))
99
+ assert_not_equal(OpenSSL::X509::V_OK, store.error)
100
+
101
+ store.purpose = OpenSSL::X509::PURPOSE_CRL_SIGN
102
+ assert_equal(true, store.verify(ca2_cert))
103
+ assert_equal(OpenSSL::X509::V_OK, store.error)
104
+
105
+ store.add_cert(ca2_cert)
106
+ store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
107
+ assert_equal(true, store.verify(ee1_cert))
108
+ assert_equal(true, store.verify(ee2_cert))
109
+ assert_equal(OpenSSL::X509::V_OK, store.error)
110
+ assert_equal("ok", store.error_string)
111
+ chain = store.chain
112
+ assert_equal(3, chain.size)
113
+ assert_equal(@ee2.to_der, chain[0].subject.to_der)
114
+ assert_equal(@ca2.to_der, chain[1].subject.to_der)
115
+ assert_equal(@ca1.to_der, chain[2].subject.to_der)
116
+ assert_equal(false, store.verify(ee3_cert))
117
+ assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error)
118
+ assert_match(/expire/i, store.error_string)
119
+ assert_equal(false, store.verify(ee4_cert))
120
+ assert_equal(OpenSSL::X509::V_ERR_CERT_NOT_YET_VALID, store.error)
121
+ assert_match(/not yet valid/i, store.error_string)
122
+
123
+ store = OpenSSL::X509::Store.new
124
+ store.add_cert(ca1_cert)
125
+ store.add_cert(ca2_cert)
126
+ store.time = now + 1500
127
+ assert_equal(true, store.verify(ca1_cert))
128
+ assert_equal(true, store.verify(ca2_cert))
129
+ assert_equal(true, store.verify(ee4_cert))
130
+ store.time = now + 1900
131
+ assert_equal(true, store.verify(ca1_cert))
132
+ assert_equal(false, store.verify(ca2_cert))
133
+ assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error)
134
+ assert_equal(false, store.verify(ee4_cert))
135
+ assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error)
136
+ store.time = now + 4000
137
+ assert_equal(false, store.verify(ee1_cert))
138
+ assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error)
139
+ assert_equal(false, store.verify(ee4_cert))
140
+ assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error)
141
+
142
+ # the underlying X509 struct caches the result of the last
143
+ # verification for signature and not-before. so the following code
144
+ # rebuilds new objects to avoid site effect.
145
+ store.time = Time.now - 4000
146
+ assert_equal(false, store.verify(OpenSSL::X509::Certificate.new(ca2_cert)))
147
+ assert_equal(OpenSSL::X509::V_ERR_CERT_NOT_YET_VALID, store.error)
148
+ assert_equal(false, store.verify(OpenSSL::X509::Certificate.new(ee1_cert)))
149
+ assert_equal(OpenSSL::X509::V_ERR_CERT_NOT_YET_VALID, store.error)
150
+
151
+ return unless defined?(OpenSSL::X509::V_FLAG_CRL_CHECK)
152
+
153
+ store = OpenSSL::X509::Store.new
154
+ store.purpose = OpenSSL::X509::PURPOSE_ANY
155
+ store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK
156
+ store.add_cert(ca1_cert)
157
+ store.add_crl(crl1) # revoke no cert
158
+ store.add_crl(crl2) # revoke ee2_cert
159
+ assert_equal(true, store.verify(ca1_cert))
160
+ assert_equal(true, store.verify(ca2_cert))
161
+ assert_equal(true, store.verify(ee1_cert, [ca2_cert]))
162
+ assert_equal(false, store.verify(ee2_cert, [ca2_cert]))
163
+
164
+ store = OpenSSL::X509::Store.new
165
+ store.purpose = OpenSSL::X509::PURPOSE_ANY
166
+ store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK
167
+ store.add_cert(ca1_cert)
168
+ store.add_crl(crl1_2) # revoke ca2_cert
169
+ store.add_crl(crl2) # revoke ee2_cert
170
+ assert_equal(true, store.verify(ca1_cert))
171
+ assert_equal(false, store.verify(ca2_cert))
172
+ assert_equal(true, store.verify(ee1_cert, [ca2_cert]),
173
+ "This test is expected to be success with OpenSSL 0.9.7c or later.")
174
+ assert_equal(false, store.verify(ee2_cert, [ca2_cert]))
175
+
176
+ store.flags =
177
+ OpenSSL::X509::V_FLAG_CRL_CHECK|OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
178
+ assert_equal(true, store.verify(ca1_cert))
179
+ assert_equal(false, store.verify(ca2_cert))
180
+ assert_equal(false, store.verify(ee1_cert, [ca2_cert]))
181
+ assert_equal(false, store.verify(ee2_cert, [ca2_cert]))
182
+
183
+ store = OpenSSL::X509::Store.new
184
+ store.purpose = OpenSSL::X509::PURPOSE_ANY
185
+ store.flags =
186
+ OpenSSL::X509::V_FLAG_CRL_CHECK|OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
187
+ store.add_cert(ca1_cert)
188
+ store.add_cert(ca2_cert)
189
+ store.add_crl(crl1)
190
+ store.add_crl(crl2_2) # issued by ca2 but expired.
191
+ assert_equal(true, store.verify(ca1_cert))
192
+ assert_equal(true, store.verify(ca2_cert))
193
+ assert_equal(false, store.verify(ee1_cert))
194
+ assert_equal(OpenSSL::X509::V_ERR_CRL_HAS_EXPIRED, store.error)
195
+ assert_equal(false, store.verify(ee2_cert))
196
+ end
197
+
198
+ def test_set_errors
199
+ now = Time.now
200
+ ca1_cert = issue_cert(@ca1, @rsa2048, 1, now, now+3600, [],
201
+ nil, nil, OpenSSL::Digest::SHA1.new)
202
+ store = OpenSSL::X509::Store.new
203
+ store.add_cert(ca1_cert)
204
+ assert_raise(OpenSSL::X509::StoreError){
205
+ store.add_cert(ca1_cert) # add same certificate twice
206
+ }
207
+
208
+ revoke_info = []
209
+ crl1 = issue_crl(revoke_info, 1, now, now+1800, [],
210
+ ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
211
+ revoke_info = [ [2, now, 1], ]
212
+ crl2 = issue_crl(revoke_info, 2, now+1800, now+3600, [],
213
+ ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new)
214
+ store.add_crl(crl1)
215
+ if /0\.9\.8.*-rhel/ =~ OpenSSL::OPENSSL_VERSION
216
+ # RedHat is distributing a patched version of OpenSSL that allows
217
+ # multiple CRL for a key (multi-crl.patch)
218
+ assert_nothing_raised do
219
+ store.add_crl(crl2) # add CRL issued by same CA twice.
220
+ end
221
+ else
222
+ assert_raise(OpenSSL::X509::StoreError){
223
+ store.add_crl(crl2) # add CRL issued by same CA twice.
224
+ }
225
+ end
226
+ end
227
+ end
228
+
229
+ end
@@ -0,0 +1,304 @@
1
+ begin
2
+ require "openssl"
3
+ rescue LoadError
4
+ end
5
+ require "test/unit"
6
+ require "digest/md5"
7
+ require 'tempfile'
8
+ require "rbconfig"
9
+ require "socket"
10
+ require_relative '../ruby/envutil'
11
+
12
+ module OpenSSL::TestUtils
13
+ TEST_KEY_RSA1024 = OpenSSL::PKey::RSA.new <<-_end_of_pem_
14
+ -----BEGIN RSA PRIVATE KEY-----
15
+ MIICXgIBAAKBgQDLwsSw1ECnPtT+PkOgHhcGA71nwC2/nL85VBGnRqDxOqjVh7Cx
16
+ aKPERYHsk4BPCkE3brtThPWc9kjHEQQ7uf9Y1rbCz0layNqHyywQEVLFmp1cpIt/
17
+ Q3geLv8ZD9pihowKJDyMDiN6ArYUmZczvW4976MU3+l54E6lF/JfFEU5hwIDAQAB
18
+ AoGBAKSl/MQarye1yOysqX6P8fDFQt68VvtXkNmlSiKOGuzyho0M+UVSFcs6k1L0
19
+ maDE25AMZUiGzuWHyaU55d7RXDgeskDMakD1v6ZejYtxJkSXbETOTLDwUWTn618T
20
+ gnb17tU1jktUtU67xK/08i/XodlgnQhs6VoHTuCh3Hu77O6RAkEA7+gxqBuZR572
21
+ 74/akiW/SuXm0SXPEviyO1MuSRwtI87B02D0qgV8D1UHRm4AhMnJ8MCs1809kMQE
22
+ JiQUCrp9mQJBANlt2ngBO14us6NnhuAseFDTBzCHXwUUu1YKHpMMmxpnGqaldGgX
23
+ sOZB3lgJsT9VlGf3YGYdkLTNVbogQKlKpB8CQQDiSwkb4vyQfDe8/NpU5Not0fII
24
+ 8jsDUCb+opWUTMmfbxWRR3FBNu8wnym/m19N4fFj8LqYzHX4KY0oVPu6qvJxAkEA
25
+ wa5snNekFcqONLIE4G5cosrIrb74sqL8GbGb+KuTAprzj5z1K8Bm0UW9lTjVDjDi
26
+ qRYgZfZSL+x1P/54+xTFSwJAY1FxA/N3QPCXCjPh5YqFxAMQs2VVYTfg+t0MEcJD
27
+ dPMQD5JX6g5HKnHFg2mZtoXQrWmJSn7p8GJK8yNTopEErA==
28
+ -----END RSA PRIVATE KEY-----
29
+ _end_of_pem_
30
+
31
+ TEST_KEY_RSA2048 = OpenSSL::PKey::RSA.new <<-_end_of_pem_
32
+ -----BEGIN RSA PRIVATE KEY-----
33
+ MIIEpAIBAAKCAQEAuV9ht9J7k4NBs38jOXvvTKY9gW8nLICSno5EETR1cuF7i4pN
34
+ s9I1QJGAFAX0BEO4KbzXmuOvfCpD3CU+Slp1enenfzq/t/e/1IRW0wkJUJUFQign
35
+ 4CtrkJL+P07yx18UjyPlBXb81ApEmAB5mrJVSrWmqbjs07JbuS4QQGGXLc+Su96D
36
+ kYKmSNVjBiLxVVSpyZfAY3hD37d60uG+X8xdW5v68JkRFIhdGlb6JL8fllf/A/bl
37
+ NwdJOhVr9mESHhwGjwfSeTDPfd8ZLE027E5lyAVX9KZYcU00mOX+fdxOSnGqS/8J
38
+ DRh0EPHDL15RcJjV2J6vZjPb0rOYGDoMcH+94wIDAQABAoIBAAzsamqfYQAqwXTb
39
+ I0CJtGg6msUgU7HVkOM+9d3hM2L791oGHV6xBAdpXW2H8LgvZHJ8eOeSghR8+dgq
40
+ PIqAffo4x1Oma+FOg3A0fb0evyiACyrOk+EcBdbBeLo/LcvahBtqnDfiUMQTpy6V
41
+ seSoFCwuN91TSCeGIsDpRjbG1vxZgtx+uI+oH5+ytqJOmfCksRDCkMglGkzyfcl0
42
+ Xc5CUhIJ0my53xijEUQl19rtWdMnNnnkdbG8PT3LZlOta5Do86BElzUYka0C6dUc
43
+ VsBDQ0Nup0P6rEQgy7tephHoRlUGTYamsajGJaAo1F3IQVIrRSuagi7+YpSpCqsW
44
+ wORqorkCgYEA7RdX6MDVrbw7LePnhyuaqTiMK+055/R1TqhB1JvvxJ1CXk2rDL6G
45
+ 0TLHQ7oGofd5LYiemg4ZVtWdJe43BPZlVgT6lvL/iGo8JnrncB9Da6L7nrq/+Rvj
46
+ XGjf1qODCK+LmreZWEsaLPURIoR/Ewwxb9J2zd0CaMjeTwafJo1CZvcCgYEAyCgb
47
+ aqoWvUecX8VvARfuA593Lsi50t4MEArnOXXcd1RnXoZWhbx5rgO8/ATKfXr0BK/n
48
+ h2GF9PfKzHFm/4V6e82OL7gu/kLy2u9bXN74vOvWFL5NOrOKPM7Kg+9I131kNYOw
49
+ Ivnr/VtHE5s0dY7JChYWE1F3vArrOw3T00a4CXUCgYEA0SqY+dS2LvIzW4cHCe9k
50
+ IQqsT0yYm5TFsUEr4sA3xcPfe4cV8sZb9k/QEGYb1+SWWZ+AHPV3UW5fl8kTbSNb
51
+ v4ng8i8rVVQ0ANbJO9e5CUrepein2MPL0AkOATR8M7t7dGGpvYV0cFk8ZrFx0oId
52
+ U0PgYDotF/iueBWlbsOM430CgYEAqYI95dFyPI5/AiSkY5queeb8+mQH62sdcCCr
53
+ vd/w/CZA/K5sbAo4SoTj8dLk4evU6HtIa0DOP63y071eaxvRpTNqLUOgmLh+D6gS
54
+ Cc7TfLuFrD+WDBatBd5jZ+SoHccVrLR/4L8jeodo5FPW05A+9gnKXEXsTxY4LOUC
55
+ 9bS4e1kCgYAqVXZh63JsMwoaxCYmQ66eJojKa47VNrOeIZDZvd2BPVf30glBOT41
56
+ gBoDG3WMPZoQj9pb7uMcrnvs4APj2FIhMU8U15LcPAj59cD6S6rWnAxO8NFK7HQG
57
+ 4Jxg3JNNf8ErQoCHb1B3oVdXJkmbJkARoDpBKmTCgKtP8ADYLmVPQw==
58
+ -----END RSA PRIVATE KEY-----
59
+ _end_of_pem_
60
+
61
+ TEST_KEY_DSA256 = OpenSSL::PKey::DSA.new <<-_end_of_pem_
62
+ -----BEGIN DSA PRIVATE KEY-----
63
+ MIH3AgEAAkEAhk2libbY2a8y2Pt21+YPYGZeW6wzaW2yfj5oiClXro9XMR7XWLkE
64
+ 9B7XxLNFCS2gmCCdMsMW1HulaHtLFQmB2wIVAM43JZrcgpu6ajZ01VkLc93gu/Ed
65
+ AkAOhujZrrKV5CzBKutKLb0GVyVWmdC7InoNSMZEeGU72rT96IjM59YzoqmD0pGM
66
+ 3I1o4cGqg1D1DfM1rQlnN1eSAkBq6xXfEDwJ1mLNxF6q8Zm/ugFYWR5xcX/3wFiT
67
+ b4+EjHP/DbNh9Vm5wcfnDBJ1zKvrMEf2xqngYdrV/3CiGJeKAhRvL57QvJZcQGvn
68
+ ISNX5cMzFHRW3Q==
69
+ -----END DSA PRIVATE KEY-----
70
+ _end_of_pem_
71
+
72
+ TEST_KEY_DSA512 = OpenSSL::PKey::DSA.new <<-_end_of_pem_
73
+ -----BEGIN DSA PRIVATE KEY-----
74
+ MIH4AgEAAkEA5lB4GvEwjrsMlGDqGsxrbqeFRh6o9OWt6FgTYiEEHaOYhkIxv0Ok
75
+ RZPDNwOG997mDjBnvDJ1i56OmS3MbTnovwIVAJgub/aDrSDB4DZGH7UyarcaGy6D
76
+ AkB9HdFw/3td8K4l1FZHv7TCZeJ3ZLb7dF3TWoGUP003RCqoji3/lHdKoVdTQNuR
77
+ S/m6DlCwhjRjiQ/lBRgCLCcaAkEAjN891JBjzpMj4bWgsACmMggFf57DS0Ti+5++
78
+ Q1VB8qkJN7rA7/2HrCR3gTsWNb1YhAsnFsoeRscC+LxXoXi9OAIUBG98h4tilg6S
79
+ 55jreJD3Se3slps=
80
+ -----END DSA PRIVATE KEY-----
81
+ _end_of_pem_
82
+
83
+ if defined?(OpenSSL::PKey::EC)
84
+
85
+ TEST_KEY_EC_P256V1 = OpenSSL::PKey::EC.new <<-_end_of_pem_
86
+ -----BEGIN EC PRIVATE KEY-----
87
+ MHcCAQEEIID49FDqcf1O1eO8saTgG70UbXQw9Fqwseliit2aWhH1oAoGCCqGSM49
88
+ AwEHoUQDQgAEFglk2c+oVUIKQ64eZG9bhLNPWB7lSZ/ArK41eGy5wAzU/0G51Xtt
89
+ CeBUl+MahZtn9fO1JKdF4qJmS39dXnpENg==
90
+ -----END EC PRIVATE KEY-----
91
+ _end_of_pem_
92
+
93
+ end
94
+
95
+ TEST_KEY_DH512 = OpenSSL::PKey::DH.new <<-_end_of_pem_
96
+ -----BEGIN DH PARAMETERS-----
97
+ MEYCQQDmWXGPqk76sKw/edIOdhAQD4XzjJ+AR/PTk2qzaGs+u4oND2yU5D2NN4wr
98
+ aPgwHyJBiK1/ebK3tYcrSKrOoRyrAgEC
99
+ -----END DH PARAMETERS-----
100
+ _end_of_pem_
101
+
102
+ module_function
103
+
104
+ def issue_cert(dn, key, serial, not_before, not_after, extensions,
105
+ issuer, issuer_key, digest)
106
+ cert = OpenSSL::X509::Certificate.new
107
+ issuer = cert unless issuer
108
+ issuer_key = key unless issuer_key
109
+ cert.version = 2
110
+ cert.serial = serial
111
+ cert.subject = dn
112
+ cert.issuer = issuer.subject
113
+ cert.public_key = key.public_key
114
+ cert.not_before = not_before
115
+ cert.not_after = not_after
116
+ ef = OpenSSL::X509::ExtensionFactory.new
117
+ ef.subject_certificate = cert
118
+ ef.issuer_certificate = issuer
119
+ extensions.each{|oid, value, critical|
120
+ cert.add_extension(ef.create_extension(oid, value, critical))
121
+ }
122
+ cert.sign(issuer_key, digest)
123
+ cert
124
+ end
125
+
126
+ def issue_crl(revoke_info, serial, lastup, nextup, extensions,
127
+ issuer, issuer_key, digest)
128
+ crl = OpenSSL::X509::CRL.new
129
+ crl.issuer = issuer.subject
130
+ crl.version = 1
131
+ crl.last_update = lastup
132
+ crl.next_update = nextup
133
+ revoke_info.each{|rserial, time, reason_code|
134
+ revoked = OpenSSL::X509::Revoked.new
135
+ revoked.serial = rserial
136
+ revoked.time = time
137
+ enum = OpenSSL::ASN1::Enumerated(reason_code)
138
+ ext = OpenSSL::X509::Extension.new("CRLReason", enum)
139
+ revoked.add_extension(ext)
140
+ crl.add_revoked(revoked)
141
+ }
142
+ ef = OpenSSL::X509::ExtensionFactory.new
143
+ ef.issuer_certificate = issuer
144
+ ef.crl = crl
145
+ crlnum = OpenSSL::ASN1::Integer(serial)
146
+ crl.add_extension(OpenSSL::X509::Extension.new("crlNumber", crlnum))
147
+ extensions.each{|oid, value, critical|
148
+ crl.add_extension(ef.create_extension(oid, value, critical))
149
+ }
150
+ crl.sign(issuer_key, digest)
151
+ crl
152
+ end
153
+
154
+ def get_subject_key_id(cert)
155
+ asn1_cert = OpenSSL::ASN1.decode(cert)
156
+ tbscert = asn1_cert.value[0]
157
+ pkinfo = tbscert.value[6]
158
+ publickey = pkinfo.value[1]
159
+ pkvalue = publickey.value
160
+ OpenSSL::Digest::SHA1.hexdigest(pkvalue).scan(/../).join(":").upcase
161
+ end
162
+
163
+ def silent
164
+ begin
165
+ back, $VERBOSE = $VERBOSE, nil
166
+ yield
167
+ ensure
168
+ $VERBOSE = back
169
+ end
170
+ end
171
+
172
+ class OpenSSL::SSLTestCase < Test::Unit::TestCase
173
+ RUBY = EnvUtil.rubybin
174
+ SSL_SERVER = File.join(File.dirname(__FILE__), "ssl_server.rb")
175
+ PORT = 20443
176
+ ITERATIONS = ($0 == __FILE__) ? 100 : 10
177
+
178
+ def setup
179
+ @ca_key = OpenSSL::TestUtils::TEST_KEY_RSA2048
180
+ @svr_key = OpenSSL::TestUtils::TEST_KEY_RSA1024
181
+ @cli_key = OpenSSL::TestUtils::TEST_KEY_DSA256
182
+ @ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA")
183
+ @svr = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
184
+ @cli = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost")
185
+ now = Time.at(Time.now.to_i)
186
+ ca_exts = [
187
+ ["basicConstraints","CA:TRUE",true],
188
+ ["keyUsage","cRLSign,keyCertSign",true],
189
+ ]
190
+ ee_exts = [
191
+ ["keyUsage","keyEncipherment,digitalSignature",true],
192
+ ]
193
+ @ca_cert = issue_cert(@ca, @ca_key, 1, now, now+3600, ca_exts, nil, nil, OpenSSL::Digest::SHA1.new)
194
+ @svr_cert = issue_cert(@svr, @svr_key, 2, now, now+1800, ee_exts, @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
195
+ @cli_cert = issue_cert(@cli, @cli_key, 3, now, now+1800, ee_exts, @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new)
196
+ @server = nil
197
+ end
198
+
199
+ def teardown
200
+ end
201
+
202
+ def issue_cert(*arg)
203
+ OpenSSL::TestUtils.issue_cert(*arg)
204
+ end
205
+
206
+ def issue_crl(*arg)
207
+ OpenSSL::TestUtils.issue_crl(*arg)
208
+ end
209
+
210
+ def readwrite_loop(ctx, ssl)
211
+ while line = ssl.gets
212
+ if line =~ /^STARTTLS$/
213
+ ssl.accept
214
+ next
215
+ end
216
+ ssl.write(line)
217
+ end
218
+ rescue OpenSSL::SSL::SSLError
219
+ rescue IOError
220
+ ensure
221
+ ssl.close rescue nil
222
+ end
223
+
224
+ def server_loop(ctx, ssls, server_proc)
225
+ loop do
226
+ ssl = nil
227
+ begin
228
+ ssl = ssls.accept
229
+ rescue OpenSSL::SSL::SSLError
230
+ retry
231
+ end
232
+
233
+ Thread.start do
234
+ Thread.current.abort_on_exception = true
235
+ server_proc.call(ctx, ssl)
236
+ end
237
+ end
238
+ rescue Errno::EBADF, IOError, Errno::EINVAL, Errno::ECONNABORTED, Errno::ENOTSOCK
239
+ end
240
+
241
+ DHParam = OpenSSL::PKey::DH.new(128)
242
+ def start_server(port0, verify_mode, start_immediately, args = {}, &block)
243
+ ctx_proc = args[:ctx_proc]
244
+ server_proc = args[:server_proc]
245
+ server_proc ||= method(:readwrite_loop)
246
+
247
+ store = OpenSSL::X509::Store.new
248
+ store.add_cert(@ca_cert)
249
+ store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
250
+ ctx = OpenSSL::SSL::SSLContext.new
251
+ ctx.cert_store = store
252
+ #ctx.extra_chain_cert = [ ca_cert ]
253
+ ctx.cert = @svr_cert
254
+ ctx.key = @svr_key
255
+ ctx.tmp_dh_callback = proc { DHParam }
256
+ ctx.verify_mode = verify_mode
257
+ ctx_proc.call(ctx) if ctx_proc
258
+
259
+ Socket.do_not_reverse_lookup = true
260
+ tcps = nil
261
+ port = port0
262
+ begin
263
+ tcps = TCPServer.new("127.0.0.1", port)
264
+ rescue Errno::EADDRINUSE
265
+ port += 1
266
+ retry
267
+ end
268
+
269
+ ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx)
270
+ ssls.start_immediately = start_immediately
271
+
272
+ begin
273
+ server = Thread.new do
274
+ Thread.current.abort_on_exception = true
275
+ server_loop(ctx, ssls, server_proc)
276
+ end
277
+
278
+ $stderr.printf("%s started: pid=%d port=%d\n", SSL_SERVER, $$, port) if $DEBUG
279
+
280
+ block.call(server, port.to_i)
281
+ ensure
282
+ # TODO: as a workaround, stop TCPServer#accept by close, not by shutdown.
283
+ # JRuby's IO cannot handle shutdown correctly for now.
284
+ tcps.close if (tcps)
285
+ if (server)
286
+ server.join(5)
287
+ if server.alive?
288
+ server.kill
289
+ server.join
290
+ flunk("TCPServer was closed and SSLServer is still alive") unless $!
291
+ end
292
+ end
293
+ end
294
+ end
295
+
296
+ def starttls(ssl)
297
+ ssl.puts("STARTTLS")
298
+ sleep 1 # When this line is eliminated, process on Cygwin blocks
299
+ # forever at ssl.connect. But I don't know why it does.
300
+ ssl.connect
301
+ end
302
+ end
303
+
304
+ end if defined?(OpenSSL)