diff --git a/src/main/java/org/jruby/ext/openssl/ASN1.java b/src/main/java/org/jruby/ext/openssl/ASN1.java index 0dd7e337..f158642e 100644 --- a/src/main/java/org/jruby/ext/openssl/ASN1.java +++ b/src/main/java/org/jruby/ext/openssl/ASN1.java @@ -1063,15 +1063,14 @@ else if ( obj instanceof ASN1GraphicString ) { break; } - if (taggedObj.getTagClass() == BERTags.APPLICATION) { + try { final ASN1Sequence sequence = (ASN1Sequence) taggedObj.getBaseUniversal(false, SEQUENCE); @SuppressWarnings("unchecked") final RubyArray valArr = decodeObjects(context, ASN1, sequence.getObjects()); return ASN1.getClass("ASN1Data").newInstance(context, new IRubyObject[] { valArr, tag, tag_class }, Block.NULL_BLOCK); - } else { - IRubyObject val = decodeObject(context, ASN1, taggedObj.getBaseObject()); - final RubyArray valArr = runtime.newArray(val); - return ASN1.getClass("ASN1Data").newInstance(context, new IRubyObject[] { valArr, tag, tag_class }, Block.NULL_BLOCK); + } catch (IllegalStateException e) { + IRubyObject val = decodeObject(context, ASN1, taggedObj.getBaseObject()).callMethod(context, "value"); + return ASN1.getClass("ASN1Data").newInstance(context, new IRubyObject[] { val, tag, tag_class }, Block.NULL_BLOCK); } } @@ -1397,12 +1396,13 @@ final ASN1TaggedObject toASN1TaggedObject(final ThreadContext context) { vec.add( data ); } return new DERTaggedObject(isExplicitTagging(), tag, new DERSequence(vec)); + } else if (value instanceof ASN1Data) { + return new DERTaggedObject(isExplicitTagging(), tagClass, tag, ((ASN1Data) value).toASN1(context)); + } else if (value instanceof RubyObject) { + return new DERTaggedObject(isExplicitTagging(), tagClass, tag, new DERGeneralString(value.asString().asJavaString())); + } else { + throw context.runtime.newTypeError("no implicit conversion of " + value.getMetaClass().getBaseName() + " into String"); } - - if (!(value instanceof ASN1Data)) { - throw new UnsupportedOperationException("toASN1 " + inspect() + " value: " + value.inspect() + " (" + value.getMetaClass() + ")"); - } - return new DERTaggedObject(isExplicitTagging(), tagClass, tag, ((ASN1Data) value).toASN1(context)); } @JRubyMethod diff --git a/src/test/ruby/test_asn1.rb b/src/test/ruby/test_asn1.rb index 9867a4b3..8e734196 100644 --- a/src/test/ruby/test_asn1.rb +++ b/src/test/ruby/test_asn1.rb @@ -251,6 +251,36 @@ def test_null } end + def test_encode_asn1_data + ai = OpenSSL::ASN1::ASN1Data.new(i = "bla", 0, :APPLICATION) + ai2 = OpenSSL::ASN1.decode(ai.to_der) + assert_equal :APPLICATION, ai2.tag_class + assert_equal 0, ai2.tag + assert_equal i, ai2.value + + ai = OpenSSL::ASN1::ASN1Data.new(i = "bla", 4, :UNIVERSAL) + ai2 = OpenSSL::ASN1.decode(ai.to_der) + assert_equal :UNIVERSAL, ai2.tag_class + assert_equal 4, ai2.tag + assert_equal i, ai2.value + + ai = OpenSSL::ASN1::ASN1Data.new(i = ["bla"], 0, :APPLICATION) + ai2 = OpenSSL::ASN1.decode(ai.to_der) + assert_equal :APPLICATION, ai2.tag_class + assert_equal 0, ai2.tag + assert_equal "bla", ai2.value + + ai = OpenSSL::ASN1::ASN1Data.new(i = ["bla", "bla"], 0, :APPLICATION) + ai2 = OpenSSL::ASN1.decode(ai.to_der) + assert_equal :APPLICATION, ai2.tag_class + assert_equal 0, ai2.tag + assert_equal "blabla", ai2.value + + assert_raise(ArgumentError) { OpenSSL::ASN1::ASN1Data.new(1).to_der } + assert_raise("no implicit conversion of Integer into String") { OpenSSL::ASN1::ASN1Data.new(1, 0, :APPLICATION).to_der } + assert_raise("no implicit conversion of Integer into String") { OpenSSL::ASN1::ASN1Data.new(1, 0, :CONTEXT_SPECIFIC).to_der } + end + def test_encode_nil #Primitives raise TypeError, Constructives NoMethodError @@ -1161,7 +1191,7 @@ def test_decode # This is from the upstream MRI tests, might be superseded by `test_bit_string_infinite_length`? def test_bitstring # TODO: Import Issue - # fails expected but was <0> + # fails expected but was <0> #encode_decode_test B(%w{ 03 01 00 }), OpenSSL::ASN1::BitString.new(B(%w{})) # TODO: Import Issue # fails with expected but was <0>