jruby-openssl-maven 0.7.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. data/History.txt +171 -0
  2. data/License.txt +30 -0
  3. data/Manifest.txt +115 -0
  4. data/README.txt +13 -0
  5. data/Rakefile +79 -0
  6. data/lib/jopenssl.jar +0 -0
  7. data/lib/jopenssl/version.rb +5 -0
  8. data/lib/openssl.rb +76 -0
  9. data/lib/openssl/bn.rb +35 -0
  10. data/lib/openssl/buffering.rb +239 -0
  11. data/lib/openssl/cipher.rb +65 -0
  12. data/lib/openssl/config.rb +316 -0
  13. data/lib/openssl/digest.rb +61 -0
  14. data/lib/openssl/dummy.rb +33 -0
  15. data/lib/openssl/dummyssl.rb +14 -0
  16. data/lib/openssl/pkcs7.rb +25 -0
  17. data/lib/openssl/ssl.rb +179 -0
  18. data/lib/openssl/x509.rb +154 -0
  19. data/test/cert_with_ec_pk.cer +27 -0
  20. data/test/fixture/ca-bundle.crt +2794 -0
  21. data/test/fixture/ca_path/72fa7371.0 +19 -0
  22. data/test/fixture/ca_path/verisign.pem +19 -0
  23. data/test/fixture/cacert.pem +23 -0
  24. data/test/fixture/cert_localhost.pem +19 -0
  25. data/test/fixture/common.pem +48 -0
  26. data/test/fixture/imaps/cacert.pem +60 -0
  27. data/test/fixture/imaps/server.crt +61 -0
  28. data/test/fixture/imaps/server.key +15 -0
  29. data/test/fixture/key_then_cert.pem +34 -0
  30. data/test/fixture/keypair.pem +27 -0
  31. data/test/fixture/localhost_keypair.pem +18 -0
  32. data/test/fixture/max.pem +29 -0
  33. data/test/fixture/purpose/b70a5bc1.0 +24 -0
  34. data/test/fixture/purpose/ca/PASSWD_OF_CA_KEY_IS_1234 +0 -0
  35. data/test/fixture/purpose/ca/ca_config.rb +37 -0
  36. data/test/fixture/purpose/ca/cacert.pem +24 -0
  37. data/test/fixture/purpose/ca/newcerts/2_cert.pem +19 -0
  38. data/test/fixture/purpose/ca/newcerts/3_cert.pem +19 -0
  39. data/test/fixture/purpose/ca/private/cakeypair.pem +30 -0
  40. data/test/fixture/purpose/ca/serial +1 -0
  41. data/test/fixture/purpose/cacert.pem +24 -0
  42. data/test/fixture/purpose/scripts/gen_cert.rb +127 -0
  43. data/test/fixture/purpose/scripts/gen_csr.rb +50 -0
  44. data/test/fixture/purpose/scripts/init_ca.rb +66 -0
  45. data/test/fixture/purpose/sslclient.pem +19 -0
  46. data/test/fixture/purpose/sslclient/csr.pem +10 -0
  47. data/test/fixture/purpose/sslclient/keypair.pem +15 -0
  48. data/test/fixture/purpose/sslclient/sslclient.pem +19 -0
  49. data/test/fixture/purpose/sslserver.pem +19 -0
  50. data/test/fixture/purpose/sslserver/csr.pem +10 -0
  51. data/test/fixture/purpose/sslserver/keypair.pem +15 -0
  52. data/test/fixture/purpose/sslserver/sslserver.pem +19 -0
  53. data/test/fixture/selfcert.pem +23 -0
  54. data/test/fixture/verisign.pem +19 -0
  55. data/test/fixture/verisign_c3.pem +14 -0
  56. data/test/java/pkcs7_mime_enveloped.message +19 -0
  57. data/test/java/pkcs7_mime_signed.message +30 -0
  58. data/test/java/pkcs7_multipart_signed.message +45 -0
  59. data/test/java/test_java_attribute.rb +25 -0
  60. data/test/java/test_java_bio.rb +42 -0
  61. data/test/java/test_java_mime.rb +173 -0
  62. data/test/java/test_java_pkcs7.rb +772 -0
  63. data/test/java/test_java_smime.rb +177 -0
  64. data/test/openssl/ssl_server.rb +99 -0
  65. data/test/openssl/test_asn1.rb +197 -0
  66. data/test/openssl/test_cipher.rb +193 -0
  67. data/test/openssl/test_config.rb +290 -0
  68. data/test/openssl/test_digest.rb +88 -0
  69. data/test/openssl/test_ec.rb +128 -0
  70. data/test/openssl/test_hmac.rb +46 -0
  71. data/test/openssl/test_ns_spki.rb +59 -0
  72. data/test/openssl/test_pair.rb +141 -0
  73. data/test/openssl/test_pkcs7.rb +489 -0
  74. data/test/openssl/test_pkey_rsa.rb +49 -0
  75. data/test/openssl/test_ssl.rb +1035 -0
  76. data/test/openssl/test_x509cert.rb +277 -0
  77. data/test/openssl/test_x509crl.rb +253 -0
  78. data/test/openssl/test_x509ext.rb +99 -0
  79. data/test/openssl/test_x509name.rb +290 -0
  80. data/test/openssl/test_x509req.rb +195 -0
  81. data/test/openssl/test_x509store.rb +246 -0
  82. data/test/openssl/utils.rb +144 -0
  83. data/test/ref/a.out +0 -0
  84. data/test/ref/compile.rb +8 -0
  85. data/test/ref/pkcs1 +0 -0
  86. data/test/ref/pkcs1.c +21 -0
  87. data/test/test_all.rb +1 -0
  88. data/test/test_certificate.rb +123 -0
  89. data/test/test_cipher.rb +197 -0
  90. data/test/test_imaps.rb +107 -0
  91. data/test/test_integration.rb +144 -0
  92. data/test/test_java.rb +98 -0
  93. data/test/test_openssl.rb +4 -0
  94. data/test/test_parse_certificate.rb +27 -0
  95. data/test/test_pkcs7.rb +40 -0
  96. data/test/test_pkey.rb +204 -0
  97. data/test/test_ssl.rb +97 -0
  98. data/test/test_x509store.rb +160 -0
  99. data/test/ut_eof.rb +128 -0
  100. metadata +161 -0
@@ -0,0 +1,99 @@
1
+ begin
2
+ require "openssl"
3
+ require File.join(File.dirname(__FILE__), "utils.rb")
4
+ rescue LoadError
5
+ end
6
+ require "test/unit"
7
+
8
+ if defined?(OpenSSL)
9
+
10
+ class OpenSSL::TestX509Extension < Test::Unit::TestCase
11
+ def setup
12
+ @basic_constraints_value = OpenSSL::ASN1::Sequence([
13
+ OpenSSL::ASN1::Boolean(true), # CA
14
+ OpenSSL::ASN1::Integer(2) # pathlen
15
+ ])
16
+ @basic_constraints = OpenSSL::ASN1::Sequence([
17
+ OpenSSL::ASN1::ObjectId("basicConstraints"),
18
+ OpenSSL::ASN1::Boolean(true),
19
+ OpenSSL::ASN1::OctetString(@basic_constraints_value.to_der),
20
+ ])
21
+ end
22
+
23
+ def teardown
24
+ end
25
+
26
+ def test_new
27
+ ext = OpenSSL::X509::Extension.new(@basic_constraints.to_der)
28
+ assert_equal("basicConstraints", ext.oid)
29
+ assert_equal(true, ext.critical?)
30
+ assert_equal("CA:TRUE, pathlen:2", ext.value)
31
+
32
+ ext = OpenSSL::X509::Extension.new("2.5.29.19",
33
+ @basic_constraints_value.to_der, true)
34
+ assert_equal(@basic_constraints.to_der, ext.to_der)
35
+ end
36
+
37
+ def test_create_by_factory
38
+ ef = OpenSSL::X509::ExtensionFactory.new
39
+
40
+ bc = ef.create_extension("basicConstraints", "critical, CA:TRUE, pathlen:2")
41
+ assert_equal(@basic_constraints.to_der, bc.to_der)
42
+
43
+ bc = ef.create_extension("basicConstraints", "CA:TRUE, pathlen:2", true)
44
+ assert_equal(@basic_constraints.to_der, bc.to_der)
45
+
46
+ begin
47
+ ef.config = OpenSSL::Config.parse(<<-_end_of_cnf_)
48
+ [crlDistPts]
49
+ URI.1 = http://www.example.com/crl
50
+ URI.2 = ldap://ldap.example.com/cn=ca?certificateRevocationList;binary
51
+ _end_of_cnf_
52
+ rescue NotImplementedError
53
+ return
54
+ end
55
+
56
+ cdp = ef.create_extension("crlDistributionPoints", "@crlDistPts")
57
+ assert_equal(false, cdp.critical?)
58
+ assert_equal("crlDistributionPoints", cdp.oid)
59
+ =begin TODO: JRuby-OSSL does not implement some features such as config reference, DER:, etc.
60
+ assert_match(%{URI:http://www\.example\.com/crl}, cdp.value)
61
+ assert_match(
62
+ %r{URI:ldap://ldap\.example\.com/cn=ca\?certificateRevocationList;binary},
63
+ cdp.value)
64
+ =end
65
+
66
+ cdp = ef.create_extension("crlDistributionPoints", "critical, @crlDistPts")
67
+ assert_equal(true, cdp.critical?)
68
+ assert_equal("crlDistributionPoints", cdp.oid)
69
+ =begin TODO: ditto
70
+ assert_match(%{URI:http://www.example.com/crl}, cdp.value)
71
+ assert_match(
72
+ %r{URI:ldap://ldap.example.com/cn=ca\?certificateRevocationList;binary},
73
+ cdp.value)
74
+ =end
75
+ end
76
+
77
+ # JRUBY-3888
78
+ # Problems with subjectKeyIdentifier with non 20-bytes sha1 digested keys
79
+ def test_certificate_with_rare_extension
80
+ cert_file = File.expand_path('../fixture/max.pem', File.dirname(__FILE__))
81
+ cer = OpenSSL::X509::Certificate.new(File.read(cert_file))
82
+ exts = Hash.new
83
+ cer.extensions.each{|ext| exts[ext.oid] = ext.value}
84
+
85
+ assert exts["subjectKeyIdentifier"] == "4C:B9:E1:DC:7A:AC:35:CF"
86
+ end
87
+
88
+ def test_extension_from_20_byte_sha1_digests
89
+ cert_file = File.expand_path('../fixture/common.pem', File.dirname(__FILE__))
90
+ cer = OpenSSL::X509::Certificate.new(File.read(cert_file))
91
+ exts = Hash.new
92
+ cer.extensions.each{|ext| exts[ext.oid] = ext.value}
93
+
94
+ assert exts["subjectKeyIdentifier"] == "B4:AC:83:5D:21:FB:D6:8A:56:7E:B2:49:6D:69:BB:E4:6F:D8:5A:AC"
95
+ end
96
+
97
+ end
98
+
99
+ end
@@ -0,0 +1,290 @@
1
+ begin
2
+ require "openssl"
3
+ rescue LoadError
4
+ end
5
+ require "test/unit"
6
+
7
+ if defined?(OpenSSL)
8
+
9
+ require 'digest/md5'
10
+
11
+ class OpenSSL::TestX509Name < Test::Unit::TestCase
12
+ OpenSSL::ASN1::ObjectId.register(
13
+ "1.2.840.113549.1.9.1", "emailAddress", "emailAddress")
14
+ OpenSSL::ASN1::ObjectId.register(
15
+ "2.5.4.5", "serialNumber", "serialNumber")
16
+
17
+ def setup
18
+ @obj_type_tmpl = Hash.new(OpenSSL::ASN1::PRINTABLESTRING)
19
+ @obj_type_tmpl.update(OpenSSL::X509::Name::OBJECT_TYPE_TEMPLATE)
20
+ end
21
+
22
+ def teardown
23
+ end
24
+
25
+ def test_s_new
26
+ dn = [ ["C", "JP"], ["O", "example"], ["CN", "www.example.jp"] ]
27
+ name = OpenSSL::X509::Name.new(dn)
28
+ ary = name.to_a
29
+ assert_equal("/C=JP/O=example/CN=www.example.jp", name.to_s)
30
+ assert_equal("C", ary[0][0])
31
+ assert_equal("O", ary[1][0])
32
+ assert_equal("CN", ary[2][0])
33
+ assert_equal("JP", ary[0][1])
34
+ assert_equal("example", ary[1][1])
35
+ assert_equal("www.example.jp", ary[2][1])
36
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[0][2])
37
+ assert_equal(OpenSSL::ASN1::UTF8STRING, ary[1][2])
38
+ assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])
39
+
40
+ dn = [
41
+ ["countryName", "JP"],
42
+ ["organizationName", "example"],
43
+ ["commonName", "www.example.jp"]
44
+ ]
45
+ name = OpenSSL::X509::Name.new(dn)
46
+ ary = name.to_a
47
+ assert_equal("/C=JP/O=example/CN=www.example.jp", name.to_s)
48
+ assert_equal("C", ary[0][0])
49
+ assert_equal("O", ary[1][0])
50
+ assert_equal("CN", ary[2][0])
51
+ assert_equal("JP", ary[0][1])
52
+ assert_equal("example", ary[1][1])
53
+ assert_equal("www.example.jp", ary[2][1])
54
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[0][2])
55
+ assert_equal(OpenSSL::ASN1::UTF8STRING, ary[1][2])
56
+ assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])
57
+
58
+ name = OpenSSL::X509::Name.new(dn, @obj_type_tmpl)
59
+ ary = name.to_a
60
+ assert_equal("/C=JP/O=example/CN=www.example.jp", name.to_s)
61
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[0][2])
62
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[1][2])
63
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[2][2])
64
+
65
+ dn = [
66
+ ["countryName", "JP", OpenSSL::ASN1::PRINTABLESTRING],
67
+ ["organizationName", "example", OpenSSL::ASN1::PRINTABLESTRING],
68
+ ["commonName", "www.example.jp", OpenSSL::ASN1::PRINTABLESTRING]
69
+ ]
70
+ name = OpenSSL::X509::Name.new(dn)
71
+ ary = name.to_a
72
+ assert_equal("/C=JP/O=example/CN=www.example.jp", name.to_s)
73
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[0][2])
74
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[1][2])
75
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[2][2])
76
+
77
+ dn = [
78
+ ["DC", "org"],
79
+ ["DC", "ruby-lang"],
80
+ ["CN", "GOTOU Yuuzou"],
81
+ ["emailAddress", "gotoyuzo@ruby-lang.org"],
82
+ ["serialNumber", "123"],
83
+ ]
84
+ name = OpenSSL::X509::Name.new(dn)
85
+ ary = name.to_a
86
+ assert_equal("/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou/emailAddress=gotoyuzo@ruby-lang.org/serialNumber=123", name.to_s)
87
+ assert_equal("DC", ary[0][0])
88
+ assert_equal("DC", ary[1][0])
89
+ assert_equal("CN", ary[2][0])
90
+ assert_equal("emailAddress", ary[3][0])
91
+ assert_equal("serialNumber", ary[4][0])
92
+ assert_equal("org", ary[0][1])
93
+ assert_equal("ruby-lang", ary[1][1])
94
+ assert_equal("GOTOU Yuuzou", ary[2][1])
95
+ assert_equal("gotoyuzo@ruby-lang.org", ary[3][1])
96
+ assert_equal("123", ary[4][1])
97
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])
98
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])
99
+ assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])
100
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[3][2])
101
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[4][2])
102
+
103
+ name_from_der = OpenSSL::X509::Name.new(name.to_der)
104
+ assert_equal(name_from_der.to_s, name.to_s)
105
+ assert_equal(name_from_der.to_a, name.to_a)
106
+ assert_equal(name_from_der.to_der, name.to_der)
107
+ end
108
+
109
+ def test_s_parse
110
+ dn = "/DC=org/DC=ruby-lang/CN=www.ruby-lang.org"
111
+ name = OpenSSL::X509::Name.parse(dn)
112
+ assert_equal(dn, name.to_s)
113
+ ary = name.to_a
114
+ assert_equal("DC", ary[0][0])
115
+ assert_equal("DC", ary[1][0])
116
+ assert_equal("CN", ary[2][0])
117
+ assert_equal("org", ary[0][1])
118
+ assert_equal("ruby-lang", ary[1][1])
119
+ assert_equal("www.ruby-lang.org", ary[2][1])
120
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])
121
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])
122
+ assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])
123
+
124
+ dn2 = "DC=org, DC=ruby-lang, CN=www.ruby-lang.org"
125
+ name = OpenSSL::X509::Name.parse(dn)
126
+ ary = name.to_a
127
+ assert_equal(dn, name.to_s)
128
+ assert_equal("org", ary[0][1])
129
+ assert_equal("ruby-lang", ary[1][1])
130
+ assert_equal("www.ruby-lang.org", ary[2][1])
131
+
132
+ name = OpenSSL::X509::Name.parse(dn, @obj_type_tmpl)
133
+ ary = name.to_a
134
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])
135
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])
136
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[2][2])
137
+ end
138
+
139
+ def test_s_parse_rfc2253
140
+ scanner = OpenSSL::X509::Name::RFC2253DN.method(:scan)
141
+
142
+ assert_equal([["C", "JP"]], scanner.call("C=JP"))
143
+ assert_equal([
144
+ ["DC", "org"],
145
+ ["DC", "ruby-lang"],
146
+ ["CN", "GOTOU Yuuzou"],
147
+ ["emailAddress", "gotoyuzo@ruby-lang.org"],
148
+ ],
149
+ scanner.call(
150
+ "emailAddress=gotoyuzo@ruby-lang.org,CN=GOTOU Yuuzou,"+
151
+ "DC=ruby-lang,DC=org")
152
+ )
153
+
154
+ u8 = OpenSSL::ASN1::UTF8STRING
155
+ assert_equal([
156
+ ["DC", "org"],
157
+ ["DC", "ruby-lang"],
158
+ ["O", ",=+<>#;"],
159
+ ["O", ",=+<>#;"],
160
+ ["OU", ""],
161
+ ["OU", ""],
162
+ ["L", "aaa=\"bbb, ccc\""],
163
+ ["L", "aaa=\"bbb, ccc\""],
164
+ ["CN", "\345\276\214\350\227\244\350\243\225\350\224\265"],
165
+ ["CN", "\345\276\214\350\227\244\350\243\225\350\224\265"],
166
+ ["CN", "\345\276\214\350\227\244\350\243\225\350\224\265"],
167
+ ["CN", "\345\276\214\350\227\244\350\243\225\350\224\265", u8],
168
+ ["2.5.4.3", "GOTOU, Yuuzou"],
169
+ ["2.5.4.3", "GOTOU, Yuuzou"],
170
+ ["2.5.4.3", "GOTOU, Yuuzou"],
171
+ ["2.5.4.3", "GOTOU, Yuuzou"],
172
+ ["CN", "GOTOU \"gotoyuzo\" Yuuzou"],
173
+ ["CN", "GOTOU \"gotoyuzo\" Yuuzou"],
174
+ ["1.2.840.113549.1.9.1", "gotoyuzo@ruby-lang.org"],
175
+ ["emailAddress", "gotoyuzo@ruby-lang.org"],
176
+ ],
177
+ scanner.call(
178
+ "emailAddress=gotoyuzo@ruby-lang.org," +
179
+ "1.2.840.113549.1.9.1=gotoyuzo@ruby-lang.org," +
180
+ 'CN=GOTOU \"gotoyuzo\" Yuuzou,' +
181
+ 'CN="GOTOU \"gotoyuzo\" Yuuzou",' +
182
+ '2.5.4.3=GOTOU\,\20Yuuzou,' +
183
+ '2.5.4.3=GOTOU\, Yuuzou,' +
184
+ '2.5.4.3="GOTOU, Yuuzou",' +
185
+ '2.5.4.3="GOTOU\, Yuuzou",' +
186
+ "CN=#0C0CE5BE8CE897A4E8A395E894B5," +
187
+ 'CN=\E5\BE\8C\E8\97\A4\E8\A3\95\E8\94\B5,' +
188
+ "CN=\"\xE5\xBE\x8C\xE8\x97\xA4\xE8\xA3\x95\xE8\x94\xB5\"," +
189
+ "CN=\xE5\xBE\x8C\xE8\x97\xA4\xE8\xA3\x95\xE8\x94\xB5," +
190
+ 'L=aaa\=\"bbb\, ccc\",' +
191
+ 'L="aaa=\"bbb, ccc\"",' +
192
+ 'OU=,' +
193
+ 'OU="",' +
194
+ 'O=\,\=\+\<\>\#\;,' +
195
+ 'O=",=+<>#;",' +
196
+ "DC=ruby-lang," +
197
+ "DC=org")
198
+ )
199
+
200
+ [
201
+ "DC=org+DC=jp",
202
+ "DC=org,DC=ruby-lang+DC=rubyist,DC=www"
203
+ ].each{|dn|
204
+ ex = scanner.call(dn) rescue $!
205
+ dn_r = Regexp.escape(dn)
206
+ assert_match(/^multi-valued RDN is not supported: #{dn_r}/, ex.message)
207
+ }
208
+
209
+ [
210
+ ["DC=org,DC=exapmle,CN", "CN"],
211
+ ["DC=org,DC=example,", ""],
212
+ ["DC=org,DC=exapmle,CN=www.example.org;", "CN=www.example.org;"],
213
+ ["DC=org,DC=exapmle,CN=#www.example.org", "CN=#www.example.org"],
214
+ ["DC=org,DC=exapmle,CN=#777777.example.org", "CN=#777777.example.org"],
215
+ ["DC=org,DC=exapmle,CN=\"www.example\".org", "CN=\"www.example\".org"],
216
+ ["DC=org,DC=exapmle,CN=www.\"example.org\"", "CN=www.\"example.org\""],
217
+ ["DC=org,DC=exapmle,CN=www.\"example\".org", "CN=www.\"example\".org"],
218
+ ].each{|dn, msg|
219
+ ex = scanner.call(dn) rescue $!
220
+ assert_match(/^malformed RDN: .*=>#{Regexp.escape(msg)}/, ex.message)
221
+ }
222
+
223
+ dn = "CN=www.ruby-lang.org,DC=ruby-lang,DC=org"
224
+ name = OpenSSL::X509::Name.parse_rfc2253(dn)
225
+ assert_equal(dn, name.to_s(OpenSSL::X509::Name::RFC2253))
226
+ ary = name.to_a
227
+ assert_equal("DC", ary[0][0])
228
+ assert_equal("DC", ary[1][0])
229
+ assert_equal("CN", ary[2][0])
230
+ assert_equal("org", ary[0][1])
231
+ assert_equal("ruby-lang", ary[1][1])
232
+ assert_equal("www.ruby-lang.org", ary[2][1])
233
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])
234
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])
235
+ assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])
236
+ end
237
+
238
+ def test_add_entry
239
+ dn = [
240
+ ["DC", "org"],
241
+ ["DC", "ruby-lang"],
242
+ ["CN", "GOTOU Yuuzou"],
243
+ ["emailAddress", "gotoyuzo@ruby-lang.org"],
244
+ ["serialNumber", "123"],
245
+ ]
246
+ name = OpenSSL::X509::Name.new
247
+ dn.each{|attr| name.add_entry(*attr) }
248
+ ary = name.to_a
249
+ assert_equal("/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou/emailAddress=gotoyuzo@ruby-lang.org/serialNumber=123", name.to_s)
250
+ assert_equal("DC", ary[0][0])
251
+ assert_equal("DC", ary[1][0])
252
+ assert_equal("CN", ary[2][0])
253
+ assert_equal("emailAddress", ary[3][0])
254
+ assert_equal("serialNumber", ary[4][0])
255
+ assert_equal("org", ary[0][1])
256
+ assert_equal("ruby-lang", ary[1][1])
257
+ assert_equal("GOTOU Yuuzou", ary[2][1])
258
+ assert_equal("gotoyuzo@ruby-lang.org", ary[3][1])
259
+ assert_equal("123", ary[4][1])
260
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2])
261
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2])
262
+ assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2])
263
+ assert_equal(OpenSSL::ASN1::IA5STRING, ary[3][2])
264
+ assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[4][2])
265
+ end
266
+
267
+ def name_hash(name)
268
+ # OpenSSL 1.0.0 uses SHA1 for canonical encoding (not just a der) of
269
+ # X509Name for X509_NAME_hash.
270
+ name.respond_to?(:hash_old) ? name.hash_old : name.hash
271
+ end
272
+
273
+ def calc_hash(d)
274
+ (d[0] & 0xff) | (d[1] & 0xff) << 8 | (d[2] & 0xff) << 16 | (d[3] & 0xff) << 24
275
+ end
276
+
277
+ def test_hash
278
+ dn = "/DC=org/DC=ruby-lang/CN=www.ruby-lang.org"
279
+ name = OpenSSL::X509::Name.parse(dn)
280
+ d = Digest::MD5.digest(name.to_der)
281
+ assert_equal(calc_hash(d), name_hash(name))
282
+ #
283
+ dn = "/DC=org/DC=ruby-lang/CN=baz.ruby-lang.org"
284
+ name = OpenSSL::X509::Name.parse(dn)
285
+ d = Digest::MD5.digest(name.to_der)
286
+ assert_equal(calc_hash(d), name_hash(name))
287
+ end
288
+ end
289
+
290
+ end
@@ -0,0 +1,195 @@
1
+ begin
2
+ require "openssl"
3
+ require File.join(File.dirname(__FILE__), "utils.rb")
4
+ rescue LoadError
5
+ end
6
+ require "test/unit"
7
+
8
+ if defined?(OpenSSL)
9
+
10
+ class OpenSSL::TestX509Request < Test::Unit::TestCase
11
+ def setup
12
+ @rsa1024 = OpenSSL::TestUtils::TEST_KEY_RSA1024
13
+ @rsa2048 = OpenSSL::TestUtils::TEST_KEY_RSA2048
14
+ @dsa256 = OpenSSL::TestUtils::TEST_KEY_DSA256
15
+ @dsa512 = OpenSSL::TestUtils::TEST_KEY_DSA512
16
+ @dn = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou")
17
+ end
18
+
19
+ def issue_csr(ver, dn, key, digest)
20
+ req = OpenSSL::X509::Request.new
21
+ req.version = ver
22
+ req.subject = dn
23
+ req.public_key = key.public_key
24
+ req.sign(key, digest)
25
+ req
26
+ end
27
+
28
+ def test_public_key
29
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
30
+ assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der)
31
+ req = OpenSSL::X509::Request.new(req.to_der)
32
+ assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der)
33
+
34
+ req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest::DSS1.new)
35
+ assert_equal(@dsa512.public_key.to_der, req.public_key.to_der)
36
+ req = OpenSSL::X509::Request.new(req.to_der)
37
+ assert_equal(@dsa512.public_key.to_der, req.public_key.to_der)
38
+ end
39
+
40
+ def test_version
41
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
42
+ assert_equal(0, req.version)
43
+ req = OpenSSL::X509::Request.new(req.to_der)
44
+ assert_equal(0, req.version)
45
+
46
+ req = issue_csr(1, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
47
+ assert_equal(1, req.version)
48
+ req = OpenSSL::X509::Request.new(req.to_der)
49
+ assert_equal(1, req.version)
50
+ end
51
+
52
+ def test_subject
53
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
54
+ assert_equal(@dn.to_der, req.subject.to_der)
55
+ req = OpenSSL::X509::Request.new(req.to_der)
56
+ assert_equal(@dn.to_der, req.subject.to_der)
57
+ end
58
+
59
+ def create_ext_req(exts)
60
+ ef = OpenSSL::X509::ExtensionFactory.new
61
+ exts = exts.collect{|e| ef.create_extension(*e) }
62
+ return OpenSSL::ASN1::Set([OpenSSL::ASN1::Sequence(exts)])
63
+ end
64
+
65
+ def get_ext_req(ext_req_value)
66
+ set = OpenSSL::ASN1.decode(ext_req_value)
67
+ seq = set.value[0]
68
+ seq.value.collect{|asn1ext|
69
+ OpenSSL::X509::Extension.new(asn1ext).to_a
70
+ }
71
+ end
72
+
73
+ def test_attr
74
+ exts = [
75
+ ["keyUsage", "Digital Signature, Key Encipherment", true],
76
+ ["subjectAltName", "email:gotoyuzo@ruby-lang.org", false],
77
+ ]
78
+ attrval = create_ext_req(exts)
79
+ attrs = [
80
+ OpenSSL::X509::Attribute.new("extReq", attrval),
81
+ OpenSSL::X509::Attribute.new("msExtReq", attrval),
82
+ ]
83
+
84
+ req0 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
85
+ attrs.each{|attr| req0.add_attribute(attr) }
86
+ req1 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
87
+ req1.attributes = attrs
88
+ assert_equal(req0.to_der, req1.to_der)
89
+
90
+ attrs = req0.attributes
91
+ assert_equal(2, attrs.size)
92
+ assert_equal("extReq", attrs[0].oid)
93
+ assert_equal("msExtReq", attrs[1].oid)
94
+ assert_equal(exts, get_ext_req(attrs[0].value))
95
+ assert_equal(exts, get_ext_req(attrs[1].value))
96
+
97
+ req = OpenSSL::X509::Request.new(req0.to_der)
98
+ attrs = req.attributes
99
+ assert_equal(2, attrs.size)
100
+ assert_equal("extReq", attrs[0].oid)
101
+ assert_equal("msExtReq", attrs[1].oid)
102
+ assert_equal(exts, get_ext_req(attrs[0].value))
103
+ assert_equal(exts, get_ext_req(attrs[1].value))
104
+ end
105
+
106
+ def test_sign_and_verify_wrong_key_type
107
+ req_rsa = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
108
+ req_dsa = issue_csr(0, @dn, @dsa512, OpenSSL::Digest::DSS1.new)
109
+ begin
110
+ assert_equal(false, req_rsa.verify(@dsa256))
111
+ rescue OpenSSL::X509::RequestError => e
112
+ # OpenSSL 1.0.0 added checks for pkey OID
113
+ assert_equal('wrong public key type', e.message)
114
+ end
115
+
116
+ begin
117
+ assert_equal(false, req_dsa.verify(@rsa1024))
118
+ rescue OpenSSL::X509::RequestError => e
119
+ # OpenSSL 1.0.0 added checks for pkey OID
120
+ assert_equal('wrong public key type', e.message)
121
+ end
122
+ end
123
+
124
+ def test_sign_and_verify
125
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new)
126
+ assert_equal(true, req.verify(@rsa1024))
127
+ assert_equal(false, req.verify(@rsa2048))
128
+ req.version = 1
129
+ assert_equal(false, req.verify(@rsa1024))
130
+
131
+ req = issue_csr(0, @dn, @rsa2048, OpenSSL::Digest::MD5.new)
132
+ assert_equal(false, req.verify(@rsa1024))
133
+ assert_equal(true, req.verify(@rsa2048))
134
+ req.subject = OpenSSL::X509::Name.parse("/C=JP/CN=FooBar")
135
+ assert_equal(false, req.verify(@rsa2048))
136
+
137
+ req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest::DSS1.new)
138
+ assert_equal(false, req.verify(@dsa256))
139
+ assert_equal(true, req.verify(@dsa512))
140
+ req.public_key = @rsa1024.public_key
141
+ assert_equal(false, req.verify(@dsa512))
142
+
143
+ assert_raise(OpenSSL::X509::RequestError){
144
+ issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::DSS1.new) }
145
+ assert_raise(OpenSSL::X509::RequestError){
146
+ issue_csr(0, @dn, @dsa512, OpenSSL::Digest::MD5.new) }
147
+ end
148
+
149
+ def test_dsig_algorithm_mismatch
150
+ assert_raise(OpenSSL::X509::RequestError) do
151
+ issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::DSS1.new)
152
+ end
153
+ assert_raise(OpenSSL::X509::RequestError) do
154
+ issue_csr(0, @dn, @dsa512, OpenSSL::Digest::MD5.new)
155
+ end
156
+ end
157
+
158
+ def test_create_from_pem
159
+ req = <<END
160
+ -----BEGIN CERTIFICATE REQUEST-----
161
+ MIIBVTCBvwIBADAWMRQwEgYDVQQDDAsxOTIuMTY4LjAuNDCBnzANBgkqhkiG9w0B
162
+ AQEFAAOBjQAwgYkCgYEA0oTTzFLydOTVtBpNdYl4S0356AysVkHlqD/tNEMxQT0l
163
+ dXdNoDKb/3TfM5WMciNxBb8rImJ51vEIf6WaWvPbaawcmhNWA9JmhMIeFCdeXyu/
164
+ XEjiiEOL4MkWf6qfsu6VoPr2YSnR0iiWLgWcnRPuy84+PE1XPPl1qGDA0apWJ9kC
165
+ AwEAAaAAMA0GCSqGSIb3DQEBBAUAA4GBAKdlyDzVrXRLkPdukQUTTy6uwhv35SKL
166
+ FfiKDrHtnFYd7VbynQ1sRre5CknuRrm+E7aEJEwpz6MS+6nqmQ6JwGcm/hlZM/m7
167
+ DVD201pI3p6LIxaRyXE20RYTp0Jj6jv+tNFd0wjVlzgStmcplNo8hu6Dtp1gKETW
168
+ qL7M4i48FXHn
169
+ -----END CERTIFICATE REQUEST-----
170
+ END
171
+ req = OpenSSL::X509::Request.new(req)
172
+
173
+ assert_equal(0, req.version)
174
+ assert_equal(OpenSSL::X509::Name.parse("/CN=192.168.0.4").to_der, req.subject.to_der)
175
+ end
176
+
177
+ def test_create_to_pem
178
+ req_s = <<END
179
+ -----BEGIN CERTIFICATE REQUEST-----
180
+ MIIBVTCBvwIBADAWMRQwEgYDVQQDDAsxOTIuMTY4LjAuNDCBnzANBgkqhkiG9w0B
181
+ AQEFAAOBjQAwgYkCgYEA0oTTzFLydOTVtBpNdYl4S0356AysVkHlqD/tNEMxQT0l
182
+ dXdNoDKb/3TfM5WMciNxBb8rImJ51vEIf6WaWvPbaawcmhNWA9JmhMIeFCdeXyu/
183
+ XEjiiEOL4MkWf6qfsu6VoPr2YSnR0iiWLgWcnRPuy84+PE1XPPl1qGDA0apWJ9kC
184
+ AwEAAaAAMA0GCSqGSIb3DQEBBAUAA4GBAKdlyDzVrXRLkPdukQUTTy6uwhv35SKL
185
+ FfiKDrHtnFYd7VbynQ1sRre5CknuRrm+E7aEJEwpz6MS+6nqmQ6JwGcm/hlZM/m7
186
+ DVD201pI3p6LIxaRyXE20RYTp0Jj6jv+tNFd0wjVlzgStmcplNo8hu6Dtp1gKETW
187
+ qL7M4i48FXHn
188
+ -----END CERTIFICATE REQUEST-----
189
+ END
190
+ req = OpenSSL::X509::Request.new(req_s)
191
+ assert_equal(req_s.gsub(/[\r\n]/, ''), req.to_pem.gsub(/[\r\n]/, ''))
192
+ end
193
+ end
194
+
195
+ end