diff options
Diffstat (limited to 'test/openssl/test_asn1.rb')
-rw-r--r-- | test/openssl/test_asn1.rb | 636 |
1 files changed, 367 insertions, 269 deletions
diff --git a/test/openssl/test_asn1.rb b/test/openssl/test_asn1.rb index 91ae2cfd0c..3e7f8c13ce 100644 --- a/test/openssl/test_asn1.rb +++ b/test/openssl/test_asn1.rb @@ -1,10 +1,12 @@ # frozen_string_literal: false require_relative 'utils' +if defined?(OpenSSL) + class OpenSSL::TestASN1 < OpenSSL::TestCase - def test_decode + def test_decode_x509_certificate subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCA") - key = OpenSSL::TestUtils::TEST_KEY_RSA1024 + key = Fixtures.pkey("rsa1024") now = Time.at(Time.now.to_i) # suppress usec s = 0xdeadbeafdeadbeafdeadbeafdeadbeaf exts = [ @@ -128,9 +130,9 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase assert_equal(OpenSSL::ASN1::Sequence, spkey.class) assert_equal(2, spkey.value.size) assert_equal(OpenSSL::ASN1::Integer, spkey.value[0].class) - assert_equal(143085709396403084580358323862163416700436550432664688288860593156058579474547937626086626045206357324274536445865308750491138538454154232826011964045825759324933943290377903384882276841880081931690695505836279972214003660451338124170055999155993192881685495391496854691199517389593073052473319331505702779271, spkey.value[0].value) + assert_equal(cert.public_key.n, spkey.value[0].value) assert_equal(OpenSSL::ASN1::Integer, spkey.value[1].class) - assert_equal(65537, spkey.value[1].value) + assert_equal(cert.public_key.e, spkey.value[1].value) extensions = tbs_cert.value[7] assert_equal(:CONTEXT_SPECIFIC, extensions.tag_class) @@ -191,66 +193,8 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase assert_equal(cululated_sig, sig_val.value) end - def test_encode_boolean - encode_decode_test(OpenSSL::ASN1::Boolean, [true, false]) - end - - def test_encode_integer - encode_decode_test(OpenSSL::ASN1::Integer, [72, -127, -128, 128, -1, 0, 1, -(2**12345), 2**12345]) - end - - def test_encode_nil - m = OpenSSL::ASN1 - [ - m::Boolean, m::Integer, m::BitString, m::OctetString, - m::ObjectId, m::Enumerated, m::UTF8String, m::UTCTime, - m::GeneralizedTime, m::Sequence, m::Set - ].each do |klass| - #Primitives raise TypeError, Constructives NoMethodError - assert_raise(TypeError, NoMethodError) { klass.send(:new, nil).to_der } - end - end - - def encode_decode_test(type, values) - values.each do |v| - assert_equal(v, OpenSSL::ASN1.decode(type.new(v).to_der).value) - end - end - - def test_decode_pem #should fail gracefully (cf. [ruby-dev:44542]) - pem = <<-_EOS_ ------BEGIN CERTIFICATE----- -MIIC8zCCAdugAwIBAgIBATANBgkqhkiG9w0BAQUFADA9MRMwEQYKCZImiZPyLGQB -GRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMQswCQYDVQQDDAJDQTAe -Fw0xMTA5MjUxMzQ4MjZaFw0xMTA5MjUxNDQ4MjZaMD0xEzARBgoJkiaJk/IsZAEZ -FgNvcmcxGTAXBgoJkiaJk/IsZAEZFglydWJ5LWxhbmcxCzAJBgNVBAMMAkNBMIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuV9ht9J7k4NBs38jOXvvTKY9 -gW8nLICSno5EETR1cuF7i4pNs9I1QJGAFAX0BEO4KbzXmuOvfCpD3CU+Slp1enen -fzq/t/e/1IRW0wkJUJUFQign4CtrkJL+P07yx18UjyPlBXb81ApEmAB5mrJVSrWm -qbjs07JbuS4QQGGXLc+Su96DkYKmSNVjBiLxVVSpyZfAY3hD37d60uG+X8xdW5v6 -8JkRFIhdGlb6JL8fllf/A/blNwdJOhVr9mESHhwGjwfSeTDPfd8ZLE027E5lyAVX -9KZYcU00mOX+fdxOSnGqS/8JDRh0EPHDL15RcJjV2J6vZjPb0rOYGDoMcH+94wID -AQABMA0GCSqGSIb3DQEBBQUAA4IBAQAiAtrIr1pLX4GYN5klviWKb8HC9ICYuAFI -NfE3FwqzErEVXotuMe3yPVyB3Bv6rjYY/x5EtS5+WPTbHlvHZTkfcsnTpizcn4mW -dJ6dDRaFCHt1YKKjUxqBt9lvvrc3nReYZN/P+s1mrDhWzGf8iPZgf8sFUHgnaK7W -CXRVXmPFgCDRNpDDVQ0MQkr509yYfTH+dujNzqTCwSvkyZFyQ7Oe8Yj0VR6kquG3 -rEzBQ0F9dUyqQ9gyRg8KHhDfv9HzT1d/rnUZMkoombwYBRIUChGCYV0GnJcan2Zm -/93PnPG1IvPjYNd5VlV+sXSnaxQn974HRCsMv7jA8BD6IgSaX6WK ------END CERTIFICATE----- - _EOS_ - assert_raise(OpenSSL::ASN1::ASN1Error) { OpenSSL::ASN1.decode(pem) } - assert_raise(OpenSSL::ASN1::ASN1Error) { OpenSSL::ASN1.decode_all(pem) } - end - - def test_primitive_cannot_set_infinite_length - prim = OpenSSL::ASN1::Integer.new(50) - assert_equal false, prim.infinite_length - assert_not_respond_to prim, :infinite_length= - end - def test_decode_all - expected = %w{ 02 01 01 02 01 02 02 01 03 } - raw = [expected.join('')].pack('H*') + raw = B(%w{ 02 01 01 02 01 02 02 01 03 }) ary = OpenSSL::ASN1.decode_all(raw) assert_equal(3, ary.size) ary.each_with_index do |asn1, i| @@ -259,288 +203,401 @@ rEzBQ0F9dUyqQ9gyRg8KHhDfv9HzT1d/rnUZMkoombwYBRIUChGCYV0GnJcan2Zm end end - def test_decode_utctime - expected = Time.at 1374535380 - assert_equal expected, OpenSSL::ASN1.decode("\x17\v1307222323Z").value - - expected += 17 - assert_equal expected, OpenSSL::ASN1.decode("\x17\r130722232317Z").value - end - - def test_encode_utctime_2k38 - encoded = OpenSSL::ASN1::UTCTime(2 ** 31 - 1).to_der - assert_equal 2 ** 31 - 1, OpenSSL::ASN1.decode(encoded).value.to_i - - encoded = OpenSSL::ASN1::UTCTime(2 ** 31).to_der - assert_equal 2 ** 31, OpenSSL::ASN1.decode(encoded).value.to_i + def test_object_id_register + oid = "1.2.34.56789" + pend "OID 1.2.34.56789 is already registered" if OpenSSL::ASN1::ObjectId(oid).sn + assert_equal true, OpenSSL::ASN1::ObjectId.register(oid, "ossl-test-sn", "ossl-test-ln") + obj = OpenSSL::ASN1::ObjectId(oid) + assert_equal oid, obj.oid + assert_equal "ossl-test-sn", obj.sn + assert_equal "ossl-test-ln", obj.ln + obj = encode_decode_test B(%w{ 06 05 2A 22 83 BB 55 }), OpenSSL::ASN1::ObjectId("ossl-test-ln") + assert_equal "ossl-test-sn", obj.value end - def test_decode_generalisedtime - expected = Time.at 1481225640 - assert_equal expected, OpenSSL::ASN1.decode("\x18\x0D201612081934Z").value - - expected += 29 - assert_equal expected, OpenSSL::ASN1.decode("\x18\x0F20161208193429Z").value + def test_end_of_content + encode_decode_test B(%w{ 00 00 }), OpenSSL::ASN1::EndOfContent.new + assert_raise(OpenSSL::ASN1::ASN1Error) { + OpenSSL::ASN1.decode(B(%w{ 00 01 00 })) + } end - def test_decode_enumerated - encoded = OpenSSL::ASN1.Enumerated(0).to_der - assert_equal "\x0a\x01\x00".b, encoded - assert_equal encoded, OpenSSL::ASN1.decode(encoded).to_der + def test_boolean + encode_decode_test B(%w{ 01 01 00 }), OpenSSL::ASN1::Boolean.new(false) + encode_decode_test B(%w{ 01 01 FF }), OpenSSL::ASN1::Boolean.new(true) + decode_test B(%w{ 01 01 01 }), OpenSSL::ASN1::Boolean.new(true) + assert_raise(OpenSSL::ASN1::ASN1Error) { + OpenSSL::ASN1.decode(B(%w{ 01 02 00 00 })) + } end - def test_create_inf_length_primitive - expected = %w{ 24 80 04 01 61 00 00 } - raw = [expected.join('')].pack('H*') - content = [OpenSSL::ASN1::OctetString.new("a"), OpenSSL::ASN1::EndOfContent.new] - cons = OpenSSL::ASN1::Constructive.new(content, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL) - cons.infinite_length = true - assert_equal(nil, cons.tagging) - assert_equal(raw, cons.to_der) - asn1 = OpenSSL::ASN1.decode(raw) - assert(asn1.infinite_length) - assert_equal(raw, asn1.to_der) + def test_integer + encode_decode_test B(%w{ 02 01 00 }), OpenSSL::ASN1::Integer.new(0) + encode_decode_test B(%w{ 02 01 48 }), OpenSSL::ASN1::Integer.new(72) + encode_decode_test B(%w{ 02 02 00 80 }), OpenSSL::ASN1::Integer.new(128) + encode_decode_test B(%w{ 02 01 81 }), OpenSSL::ASN1::Integer.new(-127) + encode_decode_test B(%w{ 02 01 80 }), OpenSSL::ASN1::Integer.new(-128) + encode_decode_test B(%w{ 02 01 FF }), OpenSSL::ASN1::Integer.new(-1) + encode_decode_test B(%w{ 02 09 01 00 00 00 00 00 00 00 00 }), OpenSSL::ASN1::Integer.new(2 ** 64) + encode_decode_test B(%w{ 02 09 FF 00 00 00 00 00 00 00 00 }), OpenSSL::ASN1::Integer.new(-(2 ** 64)) + # FIXME: OpenSSL < 1.1.0 does not fail + # assert_raise(OpenSSL::ASN1::ASN1Error) { + # OpenSSL::ASN1.decode(B(%w{ 02 02 00 7F })) + # } + # assert_raise(OpenSSL::ASN1::ASN1Error) { + # OpenSSL::ASN1.decode(B(%w{ 02 02 FF 80 })) + # } + end + + def test_enumerated + encode_decode_test B(%w{ 0A 01 00 }), OpenSSL::ASN1::Enumerated.new(0) + encode_decode_test B(%w{ 0A 01 48 }), OpenSSL::ASN1::Enumerated.new(72) + encode_decode_test B(%w{ 0A 02 00 80 }), OpenSSL::ASN1::Enumerated.new(128) + encode_decode_test B(%w{ 0A 09 01 00 00 00 00 00 00 00 00 }), OpenSSL::ASN1::Enumerated.new(2 ** 64) + end + + def test_bitstring + encode_decode_test B(%w{ 03 01 00 }), OpenSSL::ASN1::BitString.new(B(%w{})) + encode_decode_test B(%w{ 03 02 00 01 }), OpenSSL::ASN1::BitString.new(B(%w{ 01 })) + obj = OpenSSL::ASN1::BitString.new(B(%w{ F0 })) + obj.unused_bits = 4 + encode_decode_test B(%w{ 03 02 04 F0 }), obj + assert_raise(OpenSSL::ASN1::ASN1Error) { + OpenSSL::ASN1.decode(B(%w{ 03 00 })) + } + # OpenSSL < OpenSSL_1_0_1k and LibreSSL ignore the error + # assert_raise(OpenSSL::ASN1::ASN1Error) { + # OpenSSL::ASN1.decode(B(%w{ 03 03 08 FF 00 })) + # } + # OpenSSL does not seem to prohibit this, though X.690 8.6.2.3 (15/08) does + # assert_raise(OpenSSL::ASN1::ASN1Error) { + # OpenSSL::ASN1.decode(B(%w{ 03 01 04 })) + # } + assert_raise(OpenSSL::ASN1::ASN1Error) { + obj = OpenSSL::ASN1::BitString.new(B(%w{ FF FF })) + obj.unused_bits = 8 + obj.to_der + } end - def test_cons_without_inf_length_forbidden - assert_raise(OpenSSL::ASN1::ASN1Error) do - val = OpenSSL::ASN1::OctetString.new('a') - cons = OpenSSL::ASN1::Constructive.new([val], OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL) - cons.to_der - end + def test_string_basic + test = -> (tag, klass) { + encode_decode_test tag.chr + B(%w{ 00 }), klass.new(B(%w{})) + encode_decode_test tag.chr + B(%w{ 02 00 01 }), klass.new(B(%w{ 00 01 })) + } + test.(4, OpenSSL::ASN1::OctetString) + test.(12, OpenSSL::ASN1::UTF8String) + test.(18, OpenSSL::ASN1::NumericString) + test.(19, OpenSSL::ASN1::PrintableString) + test.(20, OpenSSL::ASN1::T61String) + test.(21, OpenSSL::ASN1::VideotexString) + test.(22, OpenSSL::ASN1::IA5String) + test.(25, OpenSSL::ASN1::GraphicString) + test.(26, OpenSSL::ASN1::ISO64String) + test.(27, OpenSSL::ASN1::GeneralString) + test.(28, OpenSSL::ASN1::UniversalString) + test.(30, OpenSSL::ASN1::BMPString) + end + + def test_null + encode_decode_test B(%w{ 05 00 }), OpenSSL::ASN1::Null.new(nil) + assert_raise(OpenSSL::ASN1::ASN1Error) { + OpenSSL::ASN1.decode(B(%w{ 05 01 00 })) + } end - def test_cons_without_array_forbidden - assert_raise(OpenSSL::ASN1::ASN1Error) do - val = OpenSSL::ASN1::OctetString.new('a') - cons = OpenSSL::ASN1::Constructive.new(val, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL) - cons.infinite_length = true - cons.to_der + def test_object_identifier + encode_decode_test B(%w{ 06 01 00 }), OpenSSL::ASN1::ObjectId.new("0.0".b) + encode_decode_test B(%w{ 06 01 28 }), OpenSSL::ASN1::ObjectId.new("1.0".b) + encode_decode_test B(%w{ 06 03 88 37 03 }), OpenSSL::ASN1::ObjectId.new("2.999.3".b) + encode_decode_test B(%w{ 06 05 2A 22 83 BB 55 }), OpenSSL::ASN1::ObjectId.new("1.2.34.56789".b) + obj = encode_decode_test B(%w{ 06 09 60 86 48 01 65 03 04 02 01 }), OpenSSL::ASN1::ObjectId.new("sha256") + assert_equal "2.16.840.1.101.3.4.2.1", obj.oid + assert_equal "SHA256", obj.sn + assert_equal "sha256", obj.ln + assert_raise(OpenSSL::ASN1::ASN1Error) { + OpenSSL::ASN1.decode(B(%w{ 06 00 })) + } + assert_raise(OpenSSL::ASN1::ASN1Error) { + OpenSSL::ASN1.decode(B(%w{ 06 01 80 })) + } + assert_raise(OpenSSL::ASN1::ASN1Error) { OpenSSL::ASN1::ObjectId.new("3.0".b).to_der } + assert_raise(OpenSSL::ASN1::ASN1Error) { OpenSSL::ASN1::ObjectId.new("0.40".b).to_der } + + begin + oid = (0...100).to_a.join(".").b + obj = OpenSSL::ASN1::ObjectId.new(oid) + assert_equal oid, obj.oid + rescue OpenSSL::ASN1::ASN1Error + pend "OBJ_obj2txt() not working (LibreSSL?)" if $!.message =~ /OBJ_obj2txt/ + raise end end - def test_parse_empty_sequence - expected = %w{ A0 07 30 02 30 00 02 01 00 } - raw = [expected.join('')].pack('H*') - asn1 = OpenSSL::ASN1.decode(raw) - assert_equal(raw, asn1.to_der) - assert_equal(2, asn1.value.size) - seq = asn1.value[0] - assert_equal(1, seq.value.size) - inner_seq = seq.value[0] - assert_equal(0, inner_seq.value.size) - end + def test_sequence + encode_decode_test B(%w{ 30 00 }), OpenSSL::ASN1::Sequence.new([]) + encode_decode_test B(%w{ 30 07 05 00 30 00 04 01 00 }), OpenSSL::ASN1::Sequence.new([ + OpenSSL::ASN1::Null.new(nil), + OpenSSL::ASN1::Sequence.new([]), + OpenSSL::ASN1::OctetString.new(B(%w{ 00 })) + ]) + + expected = OpenSSL::ASN1::Sequence.new([OpenSSL::ASN1::OctetString.new(B(%w{ 00 }))]) + expected.indefinite_length = true + encode_decode_test B(%w{ 30 80 04 01 00 00 00 }), expected + + # OpenSSL::ASN1::EndOfContent can only be at the end + obj = OpenSSL::ASN1::Sequence.new([ + OpenSSL::ASN1::EndOfContent.new, + OpenSSL::ASN1::OctetString.new(B(%w{ 00 })), + OpenSSL::ASN1::EndOfContent.new, + ]) + obj.indefinite_length = true + assert_raise(OpenSSL::ASN1::ASN1Error) { obj.to_der } + + # The last EOC in value is ignored if indefinite length form is used + expected = OpenSSL::ASN1::Sequence.new([ + OpenSSL::ASN1::OctetString.new(B(%w{ 00 })), + OpenSSL::ASN1::EndOfContent.new + ]) + expected.indefinite_length = true + encode_test B(%w{ 30 80 04 01 00 00 00 }), expected + end + + def test_set + encode_decode_test B(%w{ 31 00 }), OpenSSL::ASN1::Set.new([]) + encode_decode_test B(%w{ 31 07 05 00 30 00 04 01 00 }), OpenSSL::ASN1::Set.new([ + OpenSSL::ASN1::Null.new(nil), + OpenSSL::ASN1::Sequence.new([]), + OpenSSL::ASN1::OctetString.new(B(%w{ 00 })) + ]) + expected = OpenSSL::ASN1::Set.new([OpenSSL::ASN1::OctetString.new(B(%w{ 00 }))]) + expected.indefinite_length = true + encode_decode_test B(%w{ 31 80 04 01 00 00 00 }), expected + end + + def test_utctime + encode_decode_test B(%w{ 17 0D }) + "160908234339Z".b, + OpenSSL::ASN1::UTCTime.new(Time.utc(2016, 9, 8, 23, 43, 39)) + # possible range of UTCTime is 1969-2068 currently + encode_decode_test B(%w{ 17 0D }) + "690908234339Z".b, + OpenSSL::ASN1::UTCTime.new(Time.utc(1969, 9, 8, 23, 43, 39)) + decode_test B(%w{ 17 0B }) + "6909082343Z".b, + OpenSSL::ASN1::UTCTime.new(Time.utc(1969, 9, 8, 23, 43, 0)) + # not implemented + # decode_test B(%w{ 17 11 }) + "500908234339+0930".b, + # OpenSSL::ASN1::UTCTime.new(Time.new(1950, 9, 8, 23, 43, 39, "+09:30")) + # decode_test B(%w{ 17 0F }) + "5009082343-0930".b, + # OpenSSL::ASN1::UTCTime.new(Time.new(1950, 9, 8, 23, 43, 0, "-09:30")) + # assert_raise(OpenSSL::ASN1::ASN1Error) { + # OpenSSL::ASN1.decode(B(%w{ 17 0C }) + "500908234339".b) + # } + # assert_raise(OpenSSL::ASN1::ASN1Error) { + # OpenSSL::ASN1.decode(B(%w{ 17 0D }) + "500908234339Y".b) + # } + end + + def test_generalizedtime + encode_decode_test B(%w{ 18 0F }) + "20161208193429Z".b, + OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 29)) + encode_decode_test B(%w{ 18 0F }) + "99990908234339Z".b, + OpenSSL::ASN1::GeneralizedTime.new(Time.utc(9999, 9, 8, 23, 43, 39)) + decode_test B(%w{ 18 0D }) + "201612081934Z".b, + OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 0)) + # not implemented + # decode_test B(%w{ 18 13 }) + "20161208193439+0930".b, + # OpenSSL::ASN1::GeneralizedTime.new(Time.new(2016, 12, 8, 19, 34, 39, "+09:30")) + # decode_test B(%w{ 18 11 }) + "201612081934-0930".b, + # OpenSSL::ASN1::GeneralizedTime.new(Time.new(2016, 12, 8, 19, 34, 0, "-09:30")) + # decode_test B(%w{ 18 11 }) + "201612081934-09".b, + # OpenSSL::ASN1::GeneralizedTime.new(Time.new(2016, 12, 8, 19, 34, 0, "-09:00")) + # decode_test B(%w{ 18 0D }) + "2016120819.5Z".b, + # OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 30, 0)) + # decode_test B(%w{ 18 0D }) + "2016120819,5Z".b, + # OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 30, 0)) + # decode_test B(%w{ 18 0F }) + "201612081934.5Z".b, + # OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 30)) + # decode_test B(%w{ 18 11 }) + "20161208193439.5Z".b, + # OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 39.5)) + # assert_raise(OpenSSL::ASN1::ASN1Error) { + # OpenSSL::ASN1.decode(B(%w{ 18 0D }) + "201612081934Y".b) + # } + end + + def test_basic_asn1data + encode_test B(%w{ 00 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 0, :UNIVERSAL) + encode_test B(%w{ 01 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 1, :UNIVERSAL) + encode_decode_test B(%w{ 41 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 1, :APPLICATION) + encode_decode_test B(%w{ 81 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 1, :CONTEXT_SPECIFIC) + encode_decode_test B(%w{ C1 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 1, :PRIVATE) + encode_decode_test B(%w{ 1F 20 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 32, :UNIVERSAL) + encode_decode_test B(%w{ 1F C0 20 00 }), OpenSSL::ASN1::ASN1Data.new(B(%w{}), 8224, :UNIVERSAL) + encode_decode_test B(%w{ 41 02 AB CD }), OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD }), 1, :APPLICATION) + encode_decode_test B(%w{ 41 81 80 } + %w{ AB CD } * 64), OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD } * 64), 1, :APPLICATION) + encode_decode_test B(%w{ 41 82 01 00 } + %w{ AB CD } * 128), OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD } * 128), 1, :APPLICATION) + encode_decode_test B(%w{ 61 00 }), OpenSSL::ASN1::ASN1Data.new([], 1, :APPLICATION) + obj = OpenSSL::ASN1::ASN1Data.new([OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD }), 2, :PRIVATE)], 1, :APPLICATION) + obj.indefinite_length = true + encode_decode_test B(%w{ 61 80 C2 02 AB CD 00 00 }), obj + obj = OpenSSL::ASN1::ASN1Data.new([ + OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD }), 2, :PRIVATE), + OpenSSL::ASN1::EndOfContent.new + ], 1, :APPLICATION) + obj.indefinite_length = true + encode_test B(%w{ 61 80 C2 02 AB CD 00 00 }), obj + obj = OpenSSL::ASN1::ASN1Data.new(B(%w{ AB CD }), 1, :UNIVERSAL) + obj.indefinite_length = true + assert_raise(OpenSSL::ASN1::ASN1Error) { obj.to_der } + end + + def test_basic_primitive + encode_test B(%w{ 00 00 }), OpenSSL::ASN1::Primitive.new(B(%w{}), 0) + encode_test B(%w{ 01 00 }), OpenSSL::ASN1::Primitive.new(B(%w{}), 1, nil, :UNIVERSAL) + encode_test B(%w{ 81 00 }), OpenSSL::ASN1::Primitive.new(B(%w{}), 1, nil, :CONTEXT_SPECIFIC) + encode_test B(%w{ 01 02 AB CD }), OpenSSL::ASN1::Primitive.new(B(%w{ AB CD }), 1) + assert_raise(TypeError) { OpenSSL::ASN1::Primitive.new([], 1).to_der } - def test_parse_tagged_0_infinite - expected = %w{ 30 80 02 01 01 80 01 02 00 00 } - raw = [expected.join('')].pack('H*') - asn1 = OpenSSL::ASN1.decode(raw) - assert_equal(3, asn1.value.size) - int = asn1.value[0] - assert_universal(OpenSSL::ASN1::INTEGER, int) - tagged = asn1.value[1] - assert_equal(0, tagged.tag) - assert_universal(OpenSSL::ASN1::EOC, asn1.value[2]) - assert_equal(raw, asn1.to_der) - end - - def test_seq_infinite_length - content = [ OpenSSL::ASN1::Null.new(nil), - OpenSSL::ASN1::EndOfContent.new ] - cons = OpenSSL::ASN1::Sequence.new(content) - cons.infinite_length = true - expected = %w{ 30 80 05 00 00 00 } - raw = [expected.join('')].pack('H*') - assert_equal(raw, cons.to_der) - assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der) - end - - def test_set_infinite_length - content = [ OpenSSL::ASN1::Null.new(nil), - OpenSSL::ASN1::EndOfContent.new() ] - cons = OpenSSL::ASN1::Set.new(content) - cons.infinite_length = true - expected = %w{ 31 80 05 00 00 00 } - raw = [expected.join('')].pack('H*') - assert_equal(raw, cons.to_der) - assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der) + prim = OpenSSL::ASN1::Integer.new(50) + assert_equal false, prim.indefinite_length + assert_not_respond_to prim, :indefinite_length= end - def test_octet_string_infinite_length - octets = [ OpenSSL::ASN1::OctetString.new('aaa'), - OpenSSL::ASN1::EndOfContent.new() ] - cons = OpenSSL::ASN1::Constructive.new(octets, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL) - cons.infinite_length = true - expected = %w{ 24 80 04 03 61 61 61 00 00 } - raw = [expected.join('')].pack('H*') - assert_equal(raw, cons.to_der) - assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der) + def test_basic_constructed + octet_string = OpenSSL::ASN1::OctetString.new(B(%w{ AB CD })) + encode_test B(%w{ 20 00 }), OpenSSL::ASN1::Constructive.new([], 0) + encode_test B(%w{ 21 00 }), OpenSSL::ASN1::Constructive.new([], 1, nil, :UNIVERSAL) + encode_test B(%w{ A1 00 }), OpenSSL::ASN1::Constructive.new([], 1, nil, :CONTEXT_SPECIFIC) + encode_test B(%w{ 21 04 04 02 AB CD }), OpenSSL::ASN1::Constructive.new([octet_string], 1) + obj = OpenSSL::ASN1::Constructive.new([octet_string], 1) + obj.indefinite_length = true + encode_decode_test B(%w{ 21 80 04 02 AB CD 00 00 }), obj + obj = OpenSSL::ASN1::Constructive.new([octet_string, OpenSSL::ASN1::EndOfContent.new], 1) + obj.indefinite_length = true + encode_test B(%w{ 21 80 04 02 AB CD 00 00 }), obj end def test_prim_explicit_tagging oct_str = OpenSSL::ASN1::OctetString.new("a", 0, :EXPLICIT) - expected = %w{ A0 03 04 01 61 } - raw = [expected.join('')].pack('H*') - assert_equal(raw, oct_str.to_der) - assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der) - end + encode_test B(%w{ A0 03 04 01 61 }), oct_str + oct_str2 = OpenSSL::ASN1::OctetString.new("a", 1, :EXPLICIT, :APPLICATION) + encode_test B(%w{ 61 03 04 01 61 }), oct_str2 - def test_prim_explicit_tagging_tag_class - oct_str = OpenSSL::ASN1::OctetString.new("a", 0, :EXPLICIT) - oct_str2 = OpenSSL::ASN1::OctetString.new("a", 0, :EXPLICIT, :CONTEXT_SPECIFIC) - assert_equal(oct_str.to_der, oct_str2.to_der) + decoded = OpenSSL::ASN1.decode(oct_str2.to_der) + assert_equal :APPLICATION, decoded.tag_class + assert_equal 1, decoded.tag + assert_equal 1, decoded.value.size + inner = decoded.value[0] + assert_equal OpenSSL::ASN1::OctetString, inner.class + assert_equal B(%w{ 61 }), inner.value end def test_prim_implicit_tagging int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT) - expected = %w{ 80 01 01 } - raw = [expected.join('')].pack('H*') - assert_equal(raw, int.to_der) - assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der) - end + encode_test B(%w{ 80 01 01 }), int + int2 = OpenSSL::ASN1::Integer.new(1, 1, :IMPLICIT, :APPLICATION) + encode_test B(%w{ 41 01 01 }), int2 + decoded = OpenSSL::ASN1.decode(int2.to_der) + assert_equal :APPLICATION, decoded.tag_class + assert_equal 1, decoded.tag + assert_equal B(%w{ 01 }), decoded.value - def test_prim_implicit_tagging_tag_class - int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT) - int2 = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT, :CONTEXT_SPECIFIC); - assert_equal(int.to_der, int2.to_der) + # Special behavior: Encoding universal types with non-default 'tag' + # attribute and nil tagging method. + int3 = OpenSSL::ASN1::Integer.new(1, 1) + encode_test B(%w{ 01 01 01 }), int3 end def test_cons_explicit_tagging content = [ OpenSSL::ASN1::PrintableString.new('abc') ] seq = OpenSSL::ASN1::Sequence.new(content, 2, :EXPLICIT) - expected = %w{ A2 07 30 05 13 03 61 62 63 } - raw = [expected.join('')].pack('H*') - assert_equal(raw, seq.to_der) - assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der) - end + encode_test B(%w{ A2 07 30 05 13 03 61 62 63 }), seq + seq2 = OpenSSL::ASN1::Sequence.new(content, 3, :EXPLICIT, :APPLICATION) + encode_test B(%w{ 63 07 30 05 13 03 61 62 63 }), seq2 - def test_cons_explicit_tagging_inf_length - content = [ OpenSSL::ASN1::PrintableString.new('abc') , - OpenSSL::ASN1::EndOfContent.new() ] - seq = OpenSSL::ASN1::Sequence.new(content, 2, :EXPLICIT) - seq.infinite_length = true - expected = %w{ A2 80 30 80 13 03 61 62 63 00 00 00 00 } - raw = [expected.join('')].pack('H*') - assert_equal(raw, seq.to_der) - assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der) + content3 = [ OpenSSL::ASN1::PrintableString.new('abc'), + OpenSSL::ASN1::EndOfContent.new() ] + seq3 = OpenSSL::ASN1::Sequence.new(content3, 2, :EXPLICIT) + seq3.indefinite_length = true + encode_test B(%w{ A2 80 30 80 13 03 61 62 63 00 00 00 00 }), seq3 end def test_cons_implicit_tagging content = [ OpenSSL::ASN1::Null.new(nil) ] seq = OpenSSL::ASN1::Sequence.new(content, 1, :IMPLICIT) - expected = %w{ A1 02 05 00 } - raw = [expected.join('')].pack('H*') - assert_equal(raw, seq.to_der) - assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der) - end + encode_test B(%w{ A1 02 05 00 }), seq + seq2 = OpenSSL::ASN1::Sequence.new(content, 1, :IMPLICIT, :APPLICATION) + encode_test B(%w{ 61 02 05 00 }), seq2 - def test_cons_implicit_tagging_inf_length - content = [ OpenSSL::ASN1::Null.new(nil), - OpenSSL::ASN1::EndOfContent.new() ] - seq = OpenSSL::ASN1::Sequence.new(content, 1, :IMPLICIT) - seq.infinite_length = true - expected = %w{ A1 80 05 00 00 00 } - raw = [expected.join('')].pack('H*') - assert_equal(raw, seq.to_der) - assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der) - end + content3 = [ OpenSSL::ASN1::Null.new(nil), + OpenSSL::ASN1::EndOfContent.new() ] + seq3 = OpenSSL::ASN1::Sequence.new(content3, 1, :IMPLICIT) + seq3.indefinite_length = true + encode_test B(%w{ A1 80 05 00 00 00 }), seq3 - def test_octet_string_infinite_length_explicit_tagging - octets = [ OpenSSL::ASN1::OctetString.new('aaa'), - OpenSSL::ASN1::EndOfContent.new() ] - cons = OpenSSL::ASN1::Constructive.new(octets, 1, :EXPLICIT) - cons.infinite_length = true - expected = %w{ A1 80 24 80 04 03 61 61 61 00 00 00 00 } - raw = [expected.join('')].pack('H*') - assert_equal(raw, cons.to_der) - assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der) + # Special behavior: Encoding universal types with non-default 'tag' + # attribute and nil tagging method. + seq4 = OpenSSL::ASN1::Sequence.new([], 1) + encode_test B(%w{ 21 00 }), seq4 end - def test_octet_string_infinite_length_implicit_tagging + def test_octet_string_constructed_tagging + octets = [ OpenSSL::ASN1::OctetString.new('aaa') ] + cons = OpenSSL::ASN1::Constructive.new(octets, 0, :IMPLICIT) + encode_test B(%w{ A0 05 04 03 61 61 61 }), cons + octets = [ OpenSSL::ASN1::OctetString.new('aaa'), OpenSSL::ASN1::EndOfContent.new() ] cons = OpenSSL::ASN1::Constructive.new(octets, 0, :IMPLICIT) - cons.infinite_length = true - expected = %w{ A0 80 04 03 61 61 61 00 00 } - raw = [expected.join('')].pack('H*') - assert_equal(raw, cons.to_der) - assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der) + cons.indefinite_length = true + encode_test B(%w{ A0 80 04 03 61 61 61 00 00 }), cons end - def test_recursive_octet_string_infinite_length + def test_recursive_octet_string_indefinite_length octets_sub1 = [ OpenSSL::ASN1::OctetString.new("\x01"), OpenSSL::ASN1::EndOfContent.new() ] octets_sub2 = [ OpenSSL::ASN1::OctetString.new("\x02"), OpenSSL::ASN1::EndOfContent.new() ] container1 = OpenSSL::ASN1::Constructive.new(octets_sub1, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL) - container1.infinite_length = true + container1.indefinite_length = true container2 = OpenSSL::ASN1::Constructive.new(octets_sub2, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL) - container2.infinite_length = true + container2.indefinite_length = true octets3 = OpenSSL::ASN1::OctetString.new("\x03") octets = [ container1, container2, octets3, OpenSSL::ASN1::EndOfContent.new() ] cons = OpenSSL::ASN1::Constructive.new(octets, OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL) - cons.infinite_length = true - expected = %w{ 24 80 24 80 04 01 01 00 00 24 80 04 01 02 00 00 04 01 03 00 00 } - raw = [expected.join('')].pack('H*') + cons.indefinite_length = true + raw = B(%w{ 24 80 24 80 04 01 01 00 00 24 80 04 01 02 00 00 04 01 03 00 00 }) assert_equal(raw, cons.to_der) assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der) end - def test_bit_string_infinite_length - content = [ OpenSSL::ASN1::BitString.new("\x01"), - OpenSSL::ASN1::EndOfContent.new() ] - cons = OpenSSL::ASN1::Constructive.new(content, OpenSSL::ASN1::BIT_STRING, nil, :UNIVERSAL) - cons.infinite_length = true - expected = %w{ 23 80 03 02 00 01 00 00 } - raw = [expected.join('')].pack('H*') - assert_equal(raw, cons.to_der) - assert_equal(raw, OpenSSL::ASN1.decode(raw).to_der) - end - - def test_primitive_inf_length - assert_raise(OpenSSL::ASN1::ASN1Error) do - spec = %w{ 02 80 02 01 01 00 00 } - raw = [spec.join('')].pack('H*') - OpenSSL::ASN1.decode(raw) - OpenSSL::ASN1.decode_all(raw) - end - end - def test_recursive_octet_string_parse - test = %w{ 24 80 24 80 04 01 01 00 00 24 80 04 01 02 00 00 04 01 03 00 00 } - raw = [test.join('')].pack('H*') + raw = B(%w{ 24 80 24 80 04 01 01 00 00 24 80 04 01 02 00 00 04 01 03 00 00 }) asn1 = OpenSSL::ASN1.decode(raw) assert_equal(OpenSSL::ASN1::Constructive, asn1.class) assert_universal(OpenSSL::ASN1::OCTET_STRING, asn1) - assert_equal(true, asn1.infinite_length) - assert_equal(4, asn1.value.size) + assert_equal(true, asn1.indefinite_length) + assert_equal(3, asn1.value.size) nested1 = asn1.value[0] assert_equal(OpenSSL::ASN1::Constructive, nested1.class) assert_universal(OpenSSL::ASN1::OCTET_STRING, nested1) - assert_equal(true, nested1.infinite_length) - assert_equal(2, nested1.value.size) + assert_equal(true, nested1.indefinite_length) + assert_equal(1, nested1.value.size) oct1 = nested1.value[0] assert_universal(OpenSSL::ASN1::OCTET_STRING, oct1) - assert_equal(false, oct1.infinite_length) - assert_universal(OpenSSL::ASN1::EOC, nested1.value[1]) - assert_equal(false, nested1.value[1].infinite_length) + assert_equal(false, oct1.indefinite_length) nested2 = asn1.value[1] assert_equal(OpenSSL::ASN1::Constructive, nested2.class) assert_universal(OpenSSL::ASN1::OCTET_STRING, nested2) - assert_equal(true, nested2.infinite_length) - assert_equal(2, nested2.value.size) + assert_equal(true, nested2.indefinite_length) + assert_equal(1, nested2.value.size) oct2 = nested2.value[0] assert_universal(OpenSSL::ASN1::OCTET_STRING, oct2) - assert_equal(false, oct2.infinite_length) - assert_universal(OpenSSL::ASN1::EOC, nested2.value[1]) - assert_equal(false, nested2.value[1].infinite_length) + assert_equal(false, oct2.indefinite_length) oct3 = asn1.value[2] assert_universal(OpenSSL::ASN1::OCTET_STRING, oct3) - assert_equal(false, oct3.infinite_length) - assert_universal(OpenSSL::ASN1::EOC, asn1.value[3]) - assert_equal(false, asn1.value[3].infinite_length) + assert_equal(false, oct3.indefinite_length) end def test_decode_constructed_overread @@ -575,6 +632,46 @@ rEzBQ0F9dUyqQ9gyRg8KHhDfv9HzT1d/rnUZMkoombwYBRIUChGCYV0GnJcan2Zm private + def B(ary) + [ary.join].pack("H*") + end + + def assert_asn1_equal(a, b) + assert_equal a.class, b.class + assert_equal a.tag, b.tag + assert_equal a.tag_class, b.tag_class + assert_equal a.indefinite_length, b.indefinite_length + assert_equal a.unused_bits, b.unused_bits if a.respond_to?(:unused_bits) + case a.value + when Array + a.value.each_with_index { |ai, i| + assert_asn1_equal ai, b.value[i] + } + else + if OpenSSL::ASN1::ObjectId === a + assert_equal a.oid, b.oid + else + assert_equal a.value, b.value + end + end + assert_equal a.to_der, b.to_der + end + + def encode_test(der, obj) + assert_equal der, obj.to_der + end + + def decode_test(der, obj) + decoded = OpenSSL::ASN1.decode(der) + assert_asn1_equal obj, decoded + decoded + end + + def encode_decode_test(der, obj) + encode_test(der, obj) + decode_test(der, obj) + end + def assert_universal(tag, asn1) assert_equal(tag, asn1.tag) if asn1.respond_to?(:tagging) @@ -582,5 +679,6 @@ rEzBQ0F9dUyqQ9gyRg8KHhDfv9HzT1d/rnUZMkoombwYBRIUChGCYV0GnJcan2Zm end assert_equal(:UNIVERSAL, asn1.tag_class) end +end -end if defined?(OpenSSL::TestUtils) +end |