diff --git a/src/main/java/org/jruby/ext/openssl/ASN1.java b/src/main/java/org/jruby/ext/openssl/ASN1.java index 3e7417e4..a10a2f3f 100644 --- a/src/main/java/org/jruby/ext/openssl/ASN1.java +++ b/src/main/java/org/jruby/ext/openssl/ASN1.java @@ -739,26 +739,19 @@ public static void createASN1(final Ruby runtime, final RubyModule OpenSSL, fina } static ASN1ObjectIdentifier getObjectID(final Ruby runtime, final String nameOrOid) - throws IllegalArgumentException { + throws RaiseException { final String name = nameOrOid.toLowerCase(); ASN1ObjectIdentifier objectId = getOIDLookup(runtime).get( name ); if ( objectId != null ) return objectId; final String objectIdStr = ASN1Registry.getOIDLookup().get( name ); - if ( objectIdStr != null ) return toObjectID(objectIdStr, false); + if ( objectIdStr != null ) return new ASN1ObjectIdentifier(objectIdStr); - return new ASN1ObjectIdentifier( nameOrOid ); - } - - static ASN1ObjectIdentifier toObjectID(final String oid, final boolean silent) - throws IllegalArgumentException { try { - return new ASN1ObjectIdentifier(oid); - } - catch (IllegalArgumentException e) { - if ( silent ) return null; - throw e; + return new ASN1ObjectIdentifier( nameOrOid ); + } catch (IllegalArgumentException e) { + throw newASN1Error(runtime, "invalid OBJECT ID " + nameOrOid + ": " + e.getMessage()); } } @@ -920,7 +913,7 @@ public static IRubyObject eq(final ThreadContext context, final IRubyObject self if (!other.getMetaClass().equals(_ASN1(context.runtime).getClass("ObjectId"))) { return context.runtime.getFalse(); } - return self.callMethod(context, "value").op_eqq(context, other.callMethod(context, "value")); + return self.callMethod(context, "oid").op_eqq(context, other.callMethod(context, "oid")); } private static RubyString name(final ThreadContext context, IRubyObject value, @@ -1776,17 +1769,6 @@ static void initializeImpl(final ThreadContext context, // NOTE: Primitive only final String baseName = self.getMetaClass().getRealClass().getBaseName(); switch (baseName) { - case "ObjectId": - final String name; - try { - name = oid2Sym( runtime, getObjectID(runtime, value.toString()), true ); - } - catch (IllegalArgumentException e) { - // e.g. in case of nil "string not an OID" - throw runtime.newTypeError(e.getMessage()); - } - if ( name != null ) value = runtime.newString(name); - break; case "BitString": self.setInstanceVariable("@unused_bits", runtime.newFixnum(0)); break; @@ -1858,7 +1840,9 @@ private ASN1Encodable toASN1Primitive(final ThreadContext context) { final IRubyObject val = value(context); if ( type == ASN1ObjectIdentifier.class ) { - return getObjectID(context.runtime, val.toString()); + final String oidStr = val.convertToString().toString(); + + return getObjectID(context.runtime, oidStr); } if ( type == DERNull.class || type == ASN1Null.class ) { return DERNull.INSTANCE; diff --git a/src/test/ruby/test_asn1.rb b/src/test/ruby/test_asn1.rb index 0cc59e27..747bf159 100644 --- a/src/test/ruby/test_asn1.rb +++ b/src/test/ruby/test_asn1.rb @@ -232,6 +232,67 @@ def test_enumerated 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_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 } + + oid = (0...100).to_a.join(".").b + obj = OpenSSL::ASN1::ObjectId.new(oid) + assert_equal oid, obj.oid + end + + def test_object_identifier_equality + aki = [ + OpenSSL::ASN1::ObjectId.new("authorityKeyIdentifier"), + OpenSSL::ASN1::ObjectId.new("X509v3 Authority Key Identifier"), + OpenSSL::ASN1::ObjectId.new("2.5.29.35") + ] + + ski = [ + OpenSSL::ASN1::ObjectId.new("subjectKeyIdentifier"), + OpenSSL::ASN1::ObjectId.new("X509v3 Subject Key Identifier"), + OpenSSL::ASN1::ObjectId.new("2.5.29.14") + ] + + aki.each do |a| + aki.each do |b| + puts "#{a.value} == #{b.value}" + assert_equal true, a == b + end + + ski.each do |b| + puts "#{a.value} != #{b.value}" + assert_equal false, a == b + end + end + + obj1 = OpenSSL::ASN1::ObjectId.new("1.2.34.56789.10") + obj2 = OpenSSL::ASN1::ObjectId.new("1.2.34.56789.10") + obj3 = OpenSSL::ASN1::ObjectId.new("1.2.34.56789.11") + # TODO: OidToNid and NidToOid logic is done in a bespoke manner in jruby-openssl. + # this should use the BC APIs to translated registered names to OID. They are a bit + # scattered all over though (BCStyle.attrNameToOID, SECNamedCurves.getOID, X509Name hashtables...) + # omit "OID 1.2.34.56789.10 is registered" if obj1.sn + assert_equal true, obj1 == obj2 + assert_equal false, obj1 == obj3 + + assert_equal false, OpenSSL::ASN1::ObjectId.new("authorityKeyIdentifier") == nil + end + def test_encode_nested_sequence_to_der data_sequence = ::OpenSSL::ASN1::Sequence([::OpenSSL::ASN1::Integer(0)]) asn1 = ::OpenSSL::ASN1::Sequence(data_sequence) @@ -312,67 +373,6 @@ def test_encode_data_integer assert_equal OpenSSL::BN.new(90), int.value end - 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 - # TODO: Import Issue - # Fails with: expected but was ) - #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 })) - #} - # expected but was ) - #assert_raise(OpenSSL::ASN1::ASN1Error) { OpenSSL::ASN1::ObjectId.new("3.0".b).to_der } - # exception was expected but none was thrown. - #assert_raise(OpenSSL::ASN1::ASN1Error) { OpenSSL::ASN1::ObjectId.new("0.40".b).to_der } - - oid = (0...100).to_a.join(".").b - obj = OpenSSL::ASN1::ObjectId.new(oid) - assert_equal oid, obj.oid - - aki = [ - OpenSSL::ASN1::ObjectId.new("authorityKeyIdentifier"), - OpenSSL::ASN1::ObjectId.new("X509v3 Authority Key Identifier"), - OpenSSL::ASN1::ObjectId.new("2.5.29.35") - ] - - ski = [ - OpenSSL::ASN1::ObjectId.new("subjectKeyIdentifier"), - OpenSSL::ASN1::ObjectId.new("X509v3 Subject Key Identifier"), - OpenSSL::ASN1::ObjectId.new("2.5.29.14") - ] - - aki.each do |a| - # TODO: Import Issue - # None of these are equivalent to each other - #aki.each do |b| - # assert a == b - #end - - ski.each do |b| - refute a == b - end - end - - # TODO: Import Issue - # exception was expected but none was thrown. - #assert_raise(TypeError) { - # OpenSSL::ASN1::ObjectId.new("authorityKeyIdentifier") == nil - #} - - oid = OpenSSL::ASN1::ObjectId.new("2.5.29.14") - assert_equal true, oid == OpenSSL::ASN1::ObjectId.new("2.5.29.14") - assert_equal false, oid == OpenSSL::ASN1::ObjectId.new("2.5.29.35") - end - def test_instantiate # nothing shall raise : OpenSSL::ASN1::Null.new(nil)