1# coding: US-ASCII 2require_relative 'utils' 3 4if defined?(OpenSSL) 5 6class OpenSSL::TestX509Name < Test::Unit::TestCase 7 OpenSSL::ASN1::ObjectId.register( 8 "1.2.840.113549.1.9.1", "emailAddress", "emailAddress") 9 OpenSSL::ASN1::ObjectId.register( 10 "2.5.4.5", "serialNumber", "serialNumber") 11 12 def setup 13 @obj_type_tmpl = Hash.new(OpenSSL::ASN1::PRINTABLESTRING) 14 @obj_type_tmpl.update(OpenSSL::X509::Name::OBJECT_TYPE_TEMPLATE) 15 end 16 17 def teardown 18 end 19 20 def test_s_new 21 dn = [ ["C", "JP"], ["O", "example"], ["CN", "www.example.jp"] ] 22 name = OpenSSL::X509::Name.new(dn) 23 ary = name.to_a 24 assert_equal("/C=JP/O=example/CN=www.example.jp", name.to_s) 25 assert_equal("C", ary[0][0]) 26 assert_equal("O", ary[1][0]) 27 assert_equal("CN", ary[2][0]) 28 assert_equal("JP", ary[0][1]) 29 assert_equal("example", ary[1][1]) 30 assert_equal("www.example.jp", ary[2][1]) 31 assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[0][2]) 32 assert_equal(OpenSSL::ASN1::UTF8STRING, ary[1][2]) 33 assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2]) 34 35 dn = [ 36 ["countryName", "JP"], 37 ["organizationName", "example"], 38 ["commonName", "www.example.jp"] 39 ] 40 name = OpenSSL::X509::Name.new(dn) 41 ary = name.to_a 42 assert_equal("/C=JP/O=example/CN=www.example.jp", name.to_s) 43 assert_equal("C", ary[0][0]) 44 assert_equal("O", ary[1][0]) 45 assert_equal("CN", ary[2][0]) 46 assert_equal("JP", ary[0][1]) 47 assert_equal("example", ary[1][1]) 48 assert_equal("www.example.jp", ary[2][1]) 49 assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[0][2]) 50 assert_equal(OpenSSL::ASN1::UTF8STRING, ary[1][2]) 51 assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2]) 52 53 name = OpenSSL::X509::Name.new(dn, @obj_type_tmpl) 54 ary = name.to_a 55 assert_equal("/C=JP/O=example/CN=www.example.jp", name.to_s) 56 assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[0][2]) 57 assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[1][2]) 58 assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[2][2]) 59 60 dn = [ 61 ["countryName", "JP", OpenSSL::ASN1::PRINTABLESTRING], 62 ["organizationName", "example", OpenSSL::ASN1::PRINTABLESTRING], 63 ["commonName", "www.example.jp", OpenSSL::ASN1::PRINTABLESTRING] 64 ] 65 name = OpenSSL::X509::Name.new(dn) 66 ary = name.to_a 67 assert_equal("/C=JP/O=example/CN=www.example.jp", name.to_s) 68 assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[0][2]) 69 assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[1][2]) 70 assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[2][2]) 71 72 dn = [ 73 ["DC", "org"], 74 ["DC", "ruby-lang"], 75 ["CN", "GOTOU Yuuzou"], 76 ["emailAddress", "gotoyuzo@ruby-lang.org"], 77 ["serialNumber", "123"], 78 ] 79 name = OpenSSL::X509::Name.new(dn) 80 ary = name.to_a 81 assert_equal("/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou/emailAddress=gotoyuzo@ruby-lang.org/serialNumber=123", name.to_s) 82 assert_equal("DC", ary[0][0]) 83 assert_equal("DC", ary[1][0]) 84 assert_equal("CN", ary[2][0]) 85 assert_equal("emailAddress", ary[3][0]) 86 assert_equal("serialNumber", ary[4][0]) 87 assert_equal("org", ary[0][1]) 88 assert_equal("ruby-lang", ary[1][1]) 89 assert_equal("GOTOU Yuuzou", ary[2][1]) 90 assert_equal("gotoyuzo@ruby-lang.org", ary[3][1]) 91 assert_equal("123", ary[4][1]) 92 assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2]) 93 assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2]) 94 assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2]) 95 assert_equal(OpenSSL::ASN1::IA5STRING, ary[3][2]) 96 assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[4][2]) 97 98 name_from_der = OpenSSL::X509::Name.new(name.to_der) 99 assert_equal(name_from_der.to_s, name.to_s) 100 assert_equal(name_from_der.to_a, name.to_a) 101 assert_equal(name_from_der.to_der, name.to_der) 102 end 103 104 def test_unrecognized_oid 105 dn = [ ["1.2.3.4.5.6.7.8.9.7.5.3.1", "Unknown OID 1"], 106 ["1.1.2.3.5.8.13.21.34", "Unknown OID 2"], 107 ["C", "US"], 108 ["postalCode", "60602"], 109 ["ST", "Illinois"], 110 ["L", "Chicago"], 111 #["street", "123 Fake St"], 112 ["O", "Some Company LLC"], 113 ["CN", "mydomain.com"] ] 114 115 name = OpenSSL::X509::Name.new(dn) 116 ary = name.to_a 117 #assert_equal("/1.2.3.4.5.6.7.8.9.7.5.3.1=Unknown OID 1/1.1.2.3.5.8.13.21.34=Unknown OID 2/C=US/postalCode=60602/ST=Illinois/L=Chicago/street=123 Fake St/O=Some Company LLC/CN=mydomain.com", name.to_s) 118 assert_equal("/1.2.3.4.5.6.7.8.9.7.5.3.1=Unknown OID 1/1.1.2.3.5.8.13.21.34=Unknown OID 2/C=US/postalCode=60602/ST=Illinois/L=Chicago/O=Some Company LLC/CN=mydomain.com", name.to_s) 119 assert_equal("1.2.3.4.5.6.7.8.9.7.5.3.1", ary[0][0]) 120 assert_equal("1.1.2.3.5.8.13.21.34", ary[1][0]) 121 assert_equal("C", ary[2][0]) 122 assert_equal("postalCode", ary[3][0]) 123 assert_equal("ST", ary[4][0]) 124 assert_equal("L", ary[5][0]) 125 #assert_equal("street", ary[6][0]) 126 assert_equal("O", ary[6][0]) 127 assert_equal("CN", ary[7][0]) 128 assert_equal("Unknown OID 1", ary[0][1]) 129 assert_equal("Unknown OID 2", ary[1][1]) 130 assert_equal("US", ary[2][1]) 131 assert_equal("60602", ary[3][1]) 132 assert_equal("Illinois", ary[4][1]) 133 assert_equal("Chicago", ary[5][1]) 134 #assert_equal("123 Fake St", ary[6][1]) 135 assert_equal("Some Company LLC", ary[6][1]) 136 assert_equal("mydomain.com", ary[7][1]) 137 end 138 139 def test_unrecognized_oid_parse_encode_equality 140 dn = [ ["1.2.3.4.5.6.7.8.9.7.5.3.2", "Unknown OID1"], 141 ["1.1.2.3.5.8.13.21.35", "Unknown OID2"], 142 ["C", "US"], 143 ["postalCode", "60602"], 144 ["ST", "Illinois"], 145 ["L", "Chicago"], 146 #["street", "123 Fake St"], 147 ["O", "Some Company LLC"], 148 ["CN", "mydomain.com"] ] 149 150 name1 = OpenSSL::X509::Name.new(dn) 151 name2 = OpenSSL::X509::Name.parse(name1.to_s) 152 assert_equal(name1.to_s, name2.to_s) 153 assert_equal(name1.to_a, name2.to_a) 154 end 155 156 def test_s_parse 157 dn = "/DC=org/DC=ruby-lang/CN=www.ruby-lang.org" 158 name = OpenSSL::X509::Name.parse(dn) 159 assert_equal(dn, name.to_s) 160 ary = name.to_a 161 assert_equal("DC", ary[0][0]) 162 assert_equal("DC", ary[1][0]) 163 assert_equal("CN", ary[2][0]) 164 assert_equal("org", ary[0][1]) 165 assert_equal("ruby-lang", ary[1][1]) 166 assert_equal("www.ruby-lang.org", ary[2][1]) 167 assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2]) 168 assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2]) 169 assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2]) 170 171 dn2 = "DC=org, DC=ruby-lang, CN=www.ruby-lang.org" 172 name = OpenSSL::X509::Name.parse(dn2) 173 ary = name.to_a 174 assert_equal(dn, name.to_s) 175 assert_equal("org", ary[0][1]) 176 assert_equal("ruby-lang", ary[1][1]) 177 assert_equal("www.ruby-lang.org", ary[2][1]) 178 179 name = OpenSSL::X509::Name.parse(dn2, @obj_type_tmpl) 180 ary = name.to_a 181 assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2]) 182 assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2]) 183 assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[2][2]) 184 end 185 186 def test_s_parse_rfc2253 187 scanner = OpenSSL::X509::Name::RFC2253DN.method(:scan) 188 189 assert_equal([["C", "JP"]], scanner.call("C=JP")) 190 assert_equal([ 191 ["DC", "org"], 192 ["DC", "ruby-lang"], 193 ["CN", "GOTOU Yuuzou"], 194 ["emailAddress", "gotoyuzo@ruby-lang.org"], 195 ], 196 scanner.call( 197 "emailAddress=gotoyuzo@ruby-lang.org,CN=GOTOU Yuuzou,"+ 198 "DC=ruby-lang,DC=org") 199 ) 200 201 u8 = OpenSSL::ASN1::UTF8STRING 202 assert_equal([ 203 ["DC", "org"], 204 ["DC", "ruby-lang"], 205 ["O", ",=+<>#;"], 206 ["O", ",=+<>#;"], 207 ["OU", ""], 208 ["OU", ""], 209 ["L", "aaa=\"bbb, ccc\""], 210 ["L", "aaa=\"bbb, ccc\""], 211 ["CN", "\345\276\214\350\227\244\350\243\225\350\224\265"], 212 ["CN", "\345\276\214\350\227\244\350\243\225\350\224\265"], 213 ["CN", "\345\276\214\350\227\244\350\243\225\350\224\265"], 214 ["CN", "\345\276\214\350\227\244\350\243\225\350\224\265", u8], 215 ["2.5.4.3", "GOTOU, Yuuzou"], 216 ["2.5.4.3", "GOTOU, Yuuzou"], 217 ["2.5.4.3", "GOTOU, Yuuzou"], 218 ["2.5.4.3", "GOTOU, Yuuzou"], 219 ["CN", "GOTOU \"gotoyuzo\" Yuuzou"], 220 ["CN", "GOTOU \"gotoyuzo\" Yuuzou"], 221 ["1.2.840.113549.1.9.1", "gotoyuzo@ruby-lang.org"], 222 ["emailAddress", "gotoyuzo@ruby-lang.org"], 223 ], 224 scanner.call( 225 "emailAddress=gotoyuzo@ruby-lang.org," + 226 "1.2.840.113549.1.9.1=gotoyuzo@ruby-lang.org," + 227 'CN=GOTOU \"gotoyuzo\" Yuuzou,' + 228 'CN="GOTOU \"gotoyuzo\" Yuuzou",' + 229 '2.5.4.3=GOTOU\,\20Yuuzou,' + 230 '2.5.4.3=GOTOU\, Yuuzou,' + 231 '2.5.4.3="GOTOU, Yuuzou",' + 232 '2.5.4.3="GOTOU\, Yuuzou",' + 233 "CN=#0C0CE5BE8CE897A4E8A395E894B5," + 234 'CN=\E5\BE\8C\E8\97\A4\E8\A3\95\E8\94\B5,' + 235 "CN=\"\xE5\xBE\x8C\xE8\x97\xA4\xE8\xA3\x95\xE8\x94\xB5\"," + 236 "CN=\xE5\xBE\x8C\xE8\x97\xA4\xE8\xA3\x95\xE8\x94\xB5," + 237 'L=aaa\=\"bbb\, ccc\",' + 238 'L="aaa=\"bbb, ccc\"",' + 239 'OU=,' + 240 'OU="",' + 241 'O=\,\=\+\<\>\#\;,' + 242 'O=",=+<>#;",' + 243 "DC=ruby-lang," + 244 "DC=org") 245 ) 246 247 [ 248 "DC=org+DC=jp", 249 "DC=org,DC=ruby-lang+DC=rubyist,DC=www" 250 ].each{|dn| 251 ex = scanner.call(dn) rescue $! 252 dn_r = Regexp.escape(dn) 253 assert_match(/^multi-valued RDN is not supported: #{dn_r}/, ex.message) 254 } 255 256 [ 257 ["DC=org,DC=exapmle,CN", "CN"], 258 ["DC=org,DC=example,", ""], 259 ["DC=org,DC=exapmle,CN=www.example.org;", "CN=www.example.org;"], 260 ["DC=org,DC=exapmle,CN=#www.example.org", "CN=#www.example.org"], 261 ["DC=org,DC=exapmle,CN=#777777.example.org", "CN=#777777.example.org"], 262 ["DC=org,DC=exapmle,CN=\"www.example\".org", "CN=\"www.example\".org"], 263 ["DC=org,DC=exapmle,CN=www.\"example.org\"", "CN=www.\"example.org\""], 264 ["DC=org,DC=exapmle,CN=www.\"example\".org", "CN=www.\"example\".org"], 265 ].each{|dn, msg| 266 ex = scanner.call(dn) rescue $! 267 assert_match(/^malformed RDN: .*=>#{Regexp.escape(msg)}/, ex.message) 268 } 269 270 dn = "CN=www.ruby-lang.org,DC=ruby-lang,DC=org" 271 name = OpenSSL::X509::Name.parse_rfc2253(dn) 272 assert_equal(dn, name.to_s(OpenSSL::X509::Name::RFC2253)) 273 ary = name.to_a 274 assert_equal("DC", ary[0][0]) 275 assert_equal("DC", ary[1][0]) 276 assert_equal("CN", ary[2][0]) 277 assert_equal("org", ary[0][1]) 278 assert_equal("ruby-lang", ary[1][1]) 279 assert_equal("www.ruby-lang.org", ary[2][1]) 280 assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2]) 281 assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2]) 282 assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2]) 283 end 284 285 def test_add_entry 286 dn = [ 287 ["DC", "org"], 288 ["DC", "ruby-lang"], 289 ["CN", "GOTOU Yuuzou"], 290 ["emailAddress", "gotoyuzo@ruby-lang.org"], 291 ["serialNumber", "123"], 292 ] 293 name = OpenSSL::X509::Name.new 294 dn.each{|attr| name.add_entry(*attr) } 295 ary = name.to_a 296 assert_equal("/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou/emailAddress=gotoyuzo@ruby-lang.org/serialNumber=123", name.to_s) 297 assert_equal("DC", ary[0][0]) 298 assert_equal("DC", ary[1][0]) 299 assert_equal("CN", ary[2][0]) 300 assert_equal("emailAddress", ary[3][0]) 301 assert_equal("serialNumber", ary[4][0]) 302 assert_equal("org", ary[0][1]) 303 assert_equal("ruby-lang", ary[1][1]) 304 assert_equal("GOTOU Yuuzou", ary[2][1]) 305 assert_equal("gotoyuzo@ruby-lang.org", ary[3][1]) 306 assert_equal("123", ary[4][1]) 307 assert_equal(OpenSSL::ASN1::IA5STRING, ary[0][2]) 308 assert_equal(OpenSSL::ASN1::IA5STRING, ary[1][2]) 309 assert_equal(OpenSSL::ASN1::UTF8STRING, ary[2][2]) 310 assert_equal(OpenSSL::ASN1::IA5STRING, ary[3][2]) 311 assert_equal(OpenSSL::ASN1::PRINTABLESTRING, ary[4][2]) 312 end 313 314 def test_add_entry_street 315 return if OpenSSL::OPENSSL_VERSION_NUMBER < 0x009080df # 0.9.8m 316 # openssl/crypto/objects/obj_mac.h 1.83 317 dn = [ 318 ["DC", "org"], 319 ["DC", "ruby-lang"], 320 ["CN", "GOTOU Yuuzou"], 321 ["emailAddress", "gotoyuzo@ruby-lang.org"], 322 ["serialNumber", "123"], 323 ["street", "Namiki"], 324 ] 325 name = OpenSSL::X509::Name.new 326 dn.each{|attr| name.add_entry(*attr) } 327 ary = name.to_a 328 assert_equal("/DC=org/DC=ruby-lang/CN=GOTOU Yuuzou/emailAddress=gotoyuzo@ruby-lang.org/serialNumber=123/street=Namiki", name.to_s) 329 assert_equal("Namiki", ary[5][1]) 330 end 331 332 def test_equals2 333 n1 = OpenSSL::X509::Name.parse 'CN=a' 334 n2 = OpenSSL::X509::Name.parse 'CN=a' 335 336 assert_equal n1, n2 337 end 338 339 def test_spaceship 340 n1 = OpenSSL::X509::Name.parse 'CN=a' 341 n2 = OpenSSL::X509::Name.parse 'CN=b' 342 343 assert_equal(-1, n1 <=> n2) 344 end 345 346 def name_hash(name) 347 # OpenSSL 1.0.0 uses SHA1 for canonical encoding (not just a der) of 348 # X509Name for X509_NAME_hash. 349 name.respond_to?(:hash_old) ? name.hash_old : name.hash 350 end 351 352 def test_hash 353 dn = "/DC=org/DC=ruby-lang/CN=www.ruby-lang.org" 354 name = OpenSSL::X509::Name.parse(dn) 355 d = Digest::MD5.digest(name.to_der) 356 expected = (d[0].ord & 0xff) | (d[1].ord & 0xff) << 8 | (d[2].ord & 0xff) << 16 | (d[3].ord & 0xff) << 24 357 assert_equal(expected, name_hash(name)) 358 # 359 dn = "/DC=org/DC=ruby-lang/CN=baz.ruby-lang.org" 360 name = OpenSSL::X509::Name.parse(dn) 361 d = Digest::MD5.digest(name.to_der) 362 expected = (d[0].ord & 0xff) | (d[1].ord & 0xff) << 8 | (d[2].ord & 0xff) << 16 | (d[3].ord & 0xff) << 24 363 assert_equal(expected, name_hash(name)) 364 end 365end 366 367end 368