aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/helper.rb25
-rw-r--r--test/test_builtin_types.rb132
-rw-r--r--test/test_helper.rb50
-rw-r--r--test/test_parser.rb413
4 files changed, 620 insertions, 0 deletions
diff --git a/test/helper.rb b/test/helper.rb
new file mode 100644
index 0000000..d628122
--- /dev/null
+++ b/test/helper.rb
@@ -0,0 +1,25 @@
+require "asn1kit"
+require "test/unit"
+require "pp"
+
+class ASN1KitTestCase < Test::Unit::TestCase
+ def B(ary)
+ [ary.join].pack("H*")
+ end
+
+ def assert_raise_with_message(exception, pattern, msg = nil, &block)
+ unless pattern.is_a?(String) or pattern.is_a?(Regexp)
+ raise TypeError, "expected message must be a kind of String or Regexp"
+ end
+
+ msg ||= "Exception %s with message %p is raised" % [exception, pattern]
+ raised = assert_raise(exception, msg) { yield }
+
+ if pattern.is_a?(Regexp)
+ assert_match(pattern, raised.message, msg)
+ else
+ assert_equal(pattern, raised.message, msg)
+ end
+ raised
+ end
+end
diff --git a/test/test_builtin_types.rb b/test/test_builtin_types.rb
new file mode 100644
index 0000000..89cdf0b
--- /dev/null
+++ b/test/test_builtin_types.rb
@@ -0,0 +1,132 @@
+# coding: ASCII-8BIT
+require_relative "helper"
+
+class BuiltinTypesTest < ASN1KitTestCase
+ def test_boolean
+ v1 = ASN1Kit::Boolean.new(true)
+ assert_equal true, v1.value
+ assert_equal B(%w{ 01 01 FF }), v1.to_der
+
+ v2 = ASN1Kit::Boolean.new(false)
+ assert_equal false, v2.value
+ assert_equal B(%w{ 01 01 00 }), v2.to_der
+ end
+
+ def test_integer
+ assert_equal B(%w{ 02 01 00 }), ASN1Kit::Integer.new(0).to_der
+ assert_equal B(%w{ 02 01 01 }), ASN1Kit::Integer.new(1).to_der
+ assert_equal B(%w{ 02 02 00 80 }), ASN1Kit::Integer.new(128).to_der
+ assert_equal B(%w{ 02 02 01 00 }), ASN1Kit::Integer.new(256).to_der
+ assert_equal B(%w{ 02 03 0F 42 40 }), ASN1Kit::Integer.new(1_000_000).to_der
+ assert_equal B(%w{ 02 01 FF }), ASN1Kit::Integer.new(-1).to_der
+ assert_equal B(%w{ 02 01 80 }), ASN1Kit::Integer.new(-128).to_der
+ assert_equal B(%w{ 02 02 FF 00 }), ASN1Kit::Integer.new(-256).to_der
+ assert_equal B(%w{ 02 03 F0 BD C0 }), ASN1Kit::Integer.new(-1_000_000).to_der
+
+ v1 = ASN1Kit::Integer.new(123)
+ assert_equal 123, v1.value
+ assert_equal nil, v1.name
+
+ t1 = ASN1Kit::Integer[["a", 123], ["b", 234]]
+ assert_compare t1, :<, ASN1Kit::Integer
+ assert_equal ["a", "b"], t1.named_numbers.sort
+ assert_equal 123, t1.named_number("a")
+ assert_equal 234, t1.named_number("b")
+
+ v2 = t1.new("a")
+ assert_equal 123, v2.value
+ assert_equal "a", v2.name
+
+ v3 = t1.new(234)
+ assert_equal 234, v3.value
+ assert_equal "b", v3.name
+ end
+
+ def test_enumerated
+ t1 = ASN1Kit::Enumerated["a" => 0, "b" => 1_000_000]
+ assert_equal ["a", "b"], t1.enumerations.sort
+ assert_equal 0, t1.value_for("a")
+ assert_equal 1_000_000, t1.value_for("b")
+
+ v1 = t1.new("a")
+ assert_equal "a", v1.name
+ assert_equal 0, v1.value
+ assert_equal B(%w{ 0A 01 00 }), v1.to_der
+
+ v2 = t1.new("b")
+ assert_equal B(%w{ 0A 03 0F 42 40 }), v2.to_der
+ end
+
+ def test_real
+ end
+
+ def test_bitstring
+ v1 = ASN1Kit::BitString.new("\xC0", 2)
+ assert_equal "\xC0", v1.string
+ assert_equal 2, v1.bit_length
+ assert_equal B(%w{ 03 02 06 C0 }), v1.to_der
+
+ v2 = ASN1Kit::BitString.new("\xF0\xFF", 16)
+ assert_equal "\xF0\xFF", v2.string
+ assert_equal 16, v2.bit_length
+ assert_equal B(%w{ 03 03 00 F0 FF }), v2.to_der
+
+ t1 = ASN1Kit::BitString[["a", 0], ["b", 3]]
+ assert_compare t1, :<, ASN1Kit::BitString
+
+ v3 = t1.new("\xC0", 8)
+ assert_equal true, v3.set?("a")
+ assert_equal true, v3.set?(0)
+ assert_equal true, v3.set?(1)
+ assert_equal false, v3.set?(2)
+ assert_equal false, v3.set?("b")
+ assert_equal false, v3.set?(3)
+ assert_equal B(%w{ 03 02 00 C0 }), v3.to_der
+
+ v4 = t1.new_with_names("b")
+ assert_equal 4, v4.bit_length
+ assert_equal B(%w{ 03 02 04 10 }), v4.to_der
+ end
+
+ def test_octetstring
+ v1 = ASN1Kit::OctetString.new("abc")
+ assert_equal "abc", v1.value
+ assert_equal B(%w{ 04 03 61 62 63 }), v1.to_der
+ end
+
+ def test_null
+ v1 = ASN1Kit::Null.new
+ assert_equal B(%w{ 05 00 }), v1.to_der
+ end
+
+ def test_sequence
+ seq = ASN1Kit::Sequence[
+ ASN1Kit::Sequence::ComponentType.new("a", ASN1Kit::Integer),
+ ASN1Kit::Sequence::ComponentType.new("b", ASN1Kit::Boolean),
+ ]
+ obj = seq.new("a" => ASN1Kit::Integer.new(1),
+ "b" => ASN1Kit::Boolean.new(true))
+ assert_equal B(%w{ 30 06 02 01 01 01 01 FF }), obj.to_der
+ end
+
+ def test_object_identifier
+ v1 = ASN1Kit::ObjectIdentifier.new([2, 999, 3])
+ assert_equal "2.999.3", v1.dot_notation
+ assert_equal B(%w{ 06 03 88 37 03 }), v1.to_der
+
+ v2 = ASN1Kit::ObjectIdentifier.from_dot_notation("2.999.3")
+ assert_equal "2.999.3", v2.dot_notation
+ assert_equal B(%w{ 06 03 88 37 03 }), v2.to_der
+ end
+
+ def test_relative_object_identifier
+ v1 = ASN1Kit::RelativeOID.new([8571, 3, 2])
+ assert_equal "8571.3.2", v1.dot_notation
+ assert_equal B(%w{ 0D 04 C2 7B 03 02 }), v1.to_der
+
+ v2 = ASN1Kit::RelativeOID.from_dot_notation("8571.3.2")
+ assert_equal "8571.3.2", v1.dot_notation
+ assert_equal B(%w{ 0D 04 C2 7B 03 02 }), v2.to_der
+ end
+
+end
diff --git a/test/test_helper.rb b/test/test_helper.rb
new file mode 100644
index 0000000..e60deda
--- /dev/null
+++ b/test/test_helper.rb
@@ -0,0 +1,50 @@
+require_relative "helper"
+
+class HelperTest < ASN1KitTestCase
+ def test_B
+ assert_equal "\x40\x80".b, B(%w{ 40 80 })
+ end
+
+ TestError = Class.new(StandardError)
+ def test_assert_raise_with_message
+ assert_nothing_raised {
+ assert_raise_with_message(TestError, "abc") {
+ raise TestError, "abc"
+ }
+ }
+
+ assert_nothing_raised {
+ assert_raise_with_message(TestError, /c$/) {
+ raise TestError, "abc"
+ }
+ }
+
+ klass = Test::Unit::AssertionFailedError
+ ex = assert_raise {
+ assert_raise_with_message(TestError, "abc") {
+ raise RuntimeError, "abc"
+ }
+ }
+ assert_kind_of klass, ex
+ assert_match (/TestError/), ex.message
+ assert_match (/RuntimeError/), ex.message
+
+ ex = assert_raise {
+ assert_raise_with_message(TestError, "abc") {
+ raise TestError, "xyz"
+ }
+ }
+ assert_kind_of klass, ex
+ assert_match (/abc/), ex.message
+ assert_match (/xyz/), ex.message
+
+ ex = assert_raise {
+ assert_raise_with_message(TestError, /^a/) {
+ raise TestError, "xbc"
+ }
+ }
+ assert_kind_of klass, ex
+ assert_match (/\/\^a\//), ex.message
+ assert_match (/xbc/), ex.message
+ end
+end
diff --git a/test/test_parser.rb b/test/test_parser.rb
new file mode 100644
index 0000000..86b6c6d
--- /dev/null
+++ b/test/test_parser.rb
@@ -0,0 +1,413 @@
+require_relative "helper"
+
+class ParserTest < ASN1KitTestCase
+ def test_comment
+ mod = ASN1Kit.parse(<<~EOS)
+ M DEFINITIONS ::= BEGIN
+ -- T ::= BOOLEAN
+ END
+ EOS
+ assert_equal nil, mod["T"]
+
+ mod = ASN1Kit.parse(<<~EOS)
+ M DEFINITIONS ::= BEGIN
+ /*
+ * T1 ::= BOOLEAN
+ * T2 ::= INTEGER
+ */
+ END
+ EOS
+ assert_equal nil, mod["T1"]
+ assert_equal nil, mod["T2"]
+
+ mod = ASN1Kit.parse(<<~EOS)
+ M DEFINITIONS ::= BEGIN
+ /*
+ * /*
+ * * T ::= BOOLEAN
+ * */
+ */
+ END
+ EOS
+ assert_equal nil, mod["T"]
+ end
+
+ def test_module
+ mod1 = ASN1Kit.parse(<<~EOS)
+ M1 DEFINITIONS ::= BEGIN END
+ EOS
+ assert_equal "M1", mod1.name
+ assert_equal nil, mod1.oid
+
+ mod2 = ASN1Kit.parse(<<~EOS)
+ M2 { 1 2 3 abc(4) } DEFINITIONS ::= BEGIN END
+ EOS
+ assert_equal "M2", mod2.name
+ assert_instance_of ASN1Kit::ObjectIdentifier, mod2.oid
+ assert_equal "1.2.3.4", mod2.oid.dot_notation
+ end
+
+ def test_boolean
+ mod = ASN1Kit.parse(<<~EOS)
+ M DEFINITIONS ::= BEGIN
+ T ::= BOOLEAN
+ v1 BOOLEAN ::= TRUE
+ v2 T ::= FALSE
+ END
+ EOS
+
+ t = mod["T"]
+ assert_compare t, :<, ASN1Kit::Boolean
+
+ v1 = mod["v1"]
+ assert_instance_of ASN1Kit::Boolean, v1
+ assert_equal true, v1.value
+
+ v2 = mod["v2"]
+ assert_instance_of t, v2
+ assert_equal false, v2.value
+ end
+
+ def test_integer
+ mod = ASN1Kit.parse(<<~EOS)
+ M DEFINITIONS ::= BEGIN
+ T1 ::= INTEGER
+ T2 ::= INTEGER { a(123), b(-2) }
+ v1 INTEGER ::= 123
+ v2 INTEGER ::= -123
+ v3 INTEGER { v1(3) } ::= v1
+ v4 T2 ::= v1
+ END
+ EOS
+
+ t1 = mod["T1"]
+ assert_compare t1, :<, ASN1Kit::Integer
+ assert_equal [], t1.named_numbers
+
+ t2 = mod["T2"]
+ assert_compare t2, :<, ASN1Kit::Integer
+ assert_equal ["a", "b"], t2.named_numbers.sort
+ assert_equal 123, t2.named_number("a")
+ assert_equal (-2), t2.named_number("b")
+
+ v1 = mod["v1"]
+ assert_instance_of ASN1Kit::Integer, v1
+ assert_equal 123, v1.value
+
+ v2 = mod["v2"]
+ assert_instance_of ASN1Kit::Integer, v2
+ assert_equal (-123), v2.value
+
+ v3 = mod["v3"]
+ assert_compare v3.class, :<, ASN1Kit::Integer
+ assert_equal ["v1"], v3.class.named_numbers
+ assert_equal 3, v3.value
+ assert_equal "v1", v3.name
+
+ v4 = mod["v4"]
+ assert_instance_of t2, v4
+ assert_equal 123, v4.value
+ assert_equal "a", v4.name
+ end
+
+ def test_enumerated
+ mod = ASN1Kit.parse(<<~EOS)
+ M DEFINITIONS ::= BEGIN
+ T1 ::= ENUMERATED { a, b }
+ T2 ::= ENUMERATED { a(2), b(1) }
+ T3 ::= ENUMERATED { a, b(0) }
+ T4 ::= ENUMERATED { a, b, ..., c(5) }
+ T5 ::= ENUMERATED { a, b(3), ..., c }
+ T6 ::= ENUMERATED { a, b(3), ..., c(1) }
+ T7 ::= ENUMERATED { a, b(3), ..., c(1), d }
+ v1 T1 ::= b
+ v2 T1 ::= v1
+ END
+ EOS
+
+ t1 = mod["T1"]
+ assert_compare t1, :<, ASN1Kit::Enumerated
+ assert_equal ["a", "b"], t1.enumerations.sort
+ assert_equal 0, t1.value_for("a")
+ assert_equal 1, t1.value_for("b")
+ assert_equal false, t1.extensible?
+
+ t2 = mod["T2"]
+ assert_equal 2, t2.value_for("a")
+ assert_equal 1, t2.value_for("b")
+
+ t3 = mod["T3"]
+ assert_equal 1, t3.value_for("a")
+ assert_equal 0, t3.value_for("b")
+
+ t4 = mod["T4"]
+ assert_equal 0, t4.value_for("a")
+ assert_equal 1, t4.value_for("b")
+ assert_equal 5, t4.value_for("c")
+ assert_equal true, t4.extensible?
+
+ t5 = mod["T5"]
+ assert_equal 0, t5.value_for("a")
+ assert_equal 3, t5.value_for("b")
+ assert_equal 2, t5.value_for("c")
+
+ t6 = mod["T6"]
+ assert_equal 0, t6.value_for("a")
+ assert_equal 3, t6.value_for("b")
+ assert_equal 1, t6.value_for("c")
+
+ t7 = mod["T7"]
+ assert_equal 0, t7.value_for("a")
+ assert_equal 3, t7.value_for("b")
+ assert_equal 1, t7.value_for("c")
+ assert_equal 2, t7.value_for("d")
+
+ v1 = mod["v1"]
+ assert_instance_of t1, v1
+ assert_equal 1, v1.value
+ assert_equal "b", v1.name
+
+ v2 = mod["v2"]
+ assert_instance_of t1, v2
+ assert_equal 1, v2.value
+
+
+ mod2 = ASN1Kit.parse(<<~EOS)
+ M2 DEFINITIONS EXTENSIBILITY IMPLIED ::= BEGIN
+ T1 ::= ENUMERATED { a, b }
+ T2 ::= ENUMERATED { a, b, ... }
+ END
+ EOS
+
+ assert_equal true, mod2["T1"].extensible?
+ assert_equal true, mod2["T2"].extensible?
+ end
+
+ def test_real
+ # FIXME: NumericRealValue is not tested
+ mod = ASN1Kit.parse(<<~EOS)
+ M DEFINITIONS ::= BEGIN
+ T ::= REAL
+ v1 REAL ::= PLUS-INFINITY
+ v2 REAL ::= MINUS-INFINITY
+ v3 REAL ::= NOT-A-NUMBER
+ v4 T ::= v1
+ END
+ EOS
+
+ t = mod["T"]
+ assert_compare t, :<, ASN1Kit::Real
+
+ v1 = mod["v1"]
+ assert_instance_of ASN1Kit::Real, v1
+ assert_equal true, v1.plus_infinity?
+
+ v2 = mod["v2"]
+ assert_equal true, v2.minus_infinity?
+
+ v3 = mod["v3"]
+ assert_equal true, v3.not_a_number?
+
+ v4 = mod["v4"]
+ assert_instance_of t, v4
+ assert_equal true, v4.plus_infinity?
+ end
+
+ def test_bitstring
+ mod = ASN1Kit.parse(<<~EOS)
+ M DEFINITIONS ::= BEGIN
+ a INTEGER ::= 1
+ T1 ::= BIT STRING
+ T2 ::= BIT STRING { a(3), b(a) }
+ v1 BIT STRING ::= '011'B
+ v2 T2 ::= '42'H
+ v3 T2 ::= { }
+ v4 T2 ::= { a }
+ END
+ EOS
+
+ t1 = mod["T1"]
+ assert_compare t1, :<, ASN1Kit::BitString
+ assert_equal [], t1.named_bits
+
+ t2 = mod["T2"]
+ assert_compare t2, :<, ASN1Kit::BitString
+ assert_equal ["a", "b"], t2.named_bits.sort
+ assert_equal 3, t2.named_bit("a")
+ assert_equal 1, t2.named_bit("b")
+
+ v1 = mod["v1"]
+ assert_instance_of ASN1Kit::BitString, v1
+ assert_equal "\x60".b, v1.string
+ assert_equal 3, v1.bit_length
+
+ v2 = mod["v2"]
+ assert_instance_of t2, v2
+ assert_equal "\x42".b, v2.string
+ assert_equal 8, v2.bit_length
+
+ v3 = mod["v3"]
+ assert_instance_of t2, v3
+ assert_equal "".b, v3.string
+ assert_equal 0, v3.bit_length
+
+ v4 = mod["v4"]
+ assert_instance_of t2, v4
+ assert_equal "\x10".b, v4.string
+ assert_equal 4, v4.bit_length
+ end
+
+ def test_octetstring
+ mod = ASN1Kit.parse(<<~EOS)
+ M DEFINITIONS ::= BEGIN
+ T ::= OCTET STRING
+ v1 OCTET STRING ::= '01100000 00000001'B
+ v2 T ::= '4'H
+ END
+ EOS
+
+ t = mod["T"]
+ assert_compare t, :<, ASN1Kit::OctetString
+
+ v1 = mod["v1"]
+ assert_instance_of ASN1Kit::OctetString, v1
+ assert_equal "\x60\x01".b, v1.value
+
+ v2 = mod["v2"]
+ assert_instance_of t, v2
+ assert_equal "\x40".b, v2.value
+ end
+
+ def test_null
+ mod = ASN1Kit.parse(<<~EOS)
+ M DEFINITIONS ::= BEGIN
+ T ::= NULL
+ v1 NULL ::= NULL
+ v2 T ::= NULL
+ END
+ EOS
+
+ t = mod["T"]
+ assert_compare t, :<, ASN1Kit::Null
+
+ v1 = mod["v1"]
+ assert_instance_of ASN1Kit::Null, v1
+
+ v2 = mod["v2"]
+ assert_instance_of t, v2
+ end
+
+ def test_sequence
+ mod = ASN1Kit.parse(<<~EOS)
+ M DEFINITIONS ::= BEGIN
+ T1 ::= SEQUENCE { a NULL, b INTEGER }
+ T2 ::= SEQUENCE { a NULL, b INTEGER OPTIONAL }
+ v1 T1 ::= { b 1, a NULL }
+ END
+ EOS
+
+ t1 = mod["T1"]
+ assert_compare t1, :<, ASN1Kit::Sequence
+ assert_equal ["a", "b"], t1.component_types.sort
+ assert_same ASN1Kit::Null, t1.component_type("a")
+ assert_same ASN1Kit::Integer, t1.component_type("b")
+
+ t2 = mod["T2"]
+ assert_compare t2, :<, ASN1Kit::Sequence
+ assert_equal ["a", "b"], t2.component_types.sort
+ assert_same ASN1Kit::Null, t2.component_type("a")
+ assert_same ASN1Kit::Integer, t2.component_type("b")
+
+ v1 = mod["v1"]
+ assert_instance_of t1, v1
+ assert_instance_of ASN1Kit::Null, v1["a"]
+ assert_instance_of ASN1Kit::Integer, v1["b"]
+ assert_equal 1, v1["b"].value
+ end
+
+ def test_object_identifier
+ mod = ASN1Kit.parse(<<~EOS)
+ M DEFINITIONS ::= BEGIN
+ T ::= OBJECT IDENTIFIER
+ v1 T ::= { 0 1 2 }
+ v2 OBJECT IDENTIFIER ::= v1
+ v3 OBJECT IDENTIFIER ::= { v1 3 }
+ v4 OBJECT IDENTIFIER ::= { iso(1) 1 }
+ v5 OBJECT IDENTIFIER ::= { iso 1 }
+ END
+ EOS
+
+ t = mod["T"]
+ assert_compare t, :<, ASN1Kit::ObjectIdentifier
+
+ v1 = mod["v1"]
+ assert_instance_of t, v1
+ assert_equal "0.1.2", v1.dot_notation
+
+ v2 = mod["v2"]
+ assert_instance_of ASN1Kit::ObjectIdentifier, v2
+ assert_equal "0.1.2", v2.dot_notation
+
+ v3 = mod["v3"]
+ assert_equal "0.1.2.3", v3.dot_notation
+
+ v4 = mod["v4"]
+ assert_equal "1.1", v4.dot_notation
+
+ v5 = mod["v5"]
+ assert_equal "1.1", v5.dot_notation
+ end
+
+ def test_relative_object_identifier
+ mod = ASN1Kit.parse(<<~EOS)
+ M DEFINITIONS ::= BEGIN
+ T ::= RELATIVE-OID
+ v1 T ::= { 1 2 3 }
+ v2 RELATIVE-OID ::= v1
+ v3 RELATIVE-OID ::= { 0 v1 4 }
+ v4 RELATIVE-OID ::= { iso(1) }
+ v5 OBJECT IDENTIFIER ::= { 0 v1 4 }
+ END
+ EOS
+
+ t = mod["T"]
+ assert_compare t, :<, ASN1Kit::RelativeOID
+
+ v1 = mod["v1"]
+ assert_instance_of t, v1
+ assert_equal "1.2.3", v1.dot_notation
+
+ v2 = mod["v2"]
+ assert_instance_of ASN1Kit::RelativeOID, v2
+ assert_equal "1.2.3", v2.dot_notation
+
+ v3 = mod["v3"]
+ assert_equal "0.1.2.3.4", v3.dot_notation
+
+ v4 = mod["v4"]
+ assert_equal "1", v4.dot_notation
+
+ v5 = mod["v5"]
+ assert_equal "0.1.2.3.4", v5.dot_notation
+
+ assert_parse_error(<<~EOS)
+ M DEFINITIONS ::= BEGIN
+ v RELATIVE-OID ::= { iso }
+ END
+ EOS
+ end
+
+ private
+
+ def assert_parse_error(source, pattern = nil)
+ if pattern
+ assert_raise_with_message(ASN1Kit::ParseError, pattern) {
+ ASN1Kit.parse(source)
+ }
+ else
+ assert_raise(ASN1Kit::ParseError) {
+ ASN1Kit.parse(source)
+ }
+ end
+ end
+end