Skip to content

Commit 1ec1af3

Browse files
committed
[compat] align ASN1 ObjectId handling with MRI
1 parent c92c3a0 commit 1ec1af3

3 files changed

Lines changed: 45 additions & 33 deletions

File tree

‎src/main/java/org/jruby/ext/openssl/ASN1.java‎

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,15 @@ private static ASN1ObjectIdentifier toObjectID(final String oid, final boolean s
766766
}
767767
}
768768

769+
static ASN1ObjectIdentifier oid(final Ruby runtime, final IRubyObject value) {
770+
final String oid = value.convertToString().toString();
771+
try {
772+
return getObjectID(runtime, oid);
773+
} catch (IllegalArgumentException e) {
774+
throw newASN1Error(runtime, "invalid OBJECT ID " + oid + ": " + e.getMessage());
775+
}
776+
}
777+
769778
static String shortName(final Ruby runtime, final ASN1ObjectIdentifier oid) {
770779
final String name = oid2name(runtime, oid, true);
771780
return name == null ? oid.getId() : name;
@@ -920,16 +929,16 @@ public static RubyString ln(final ThreadContext context, final IRubyObject self)
920929

921930
@JRubyMethod
922931
public static RubyString oid(final ThreadContext context, final IRubyObject self) {
923-
final Ruby runtime = context.runtime;
924-
return runtime.newString( getObjectID(runtime, self.callMethod(context, "value").toString()).getId() );
932+
return context.runtime.newString(ASN1.oid(context.runtime, self.callMethod(context, "value")).getId());
925933
}
926934

927935
@JRubyMethod(name = "==")
928936
public static IRubyObject eq(final ThreadContext context, final IRubyObject self, final IRubyObject other) {
929-
if (!other.getMetaClass().equals(_ASN1(context.runtime).getClass("ObjectId"))) {
930-
return context.runtime.getFalse();
937+
final Ruby runtime = context.runtime;
938+
if (!other.getMetaClass().equals(_ASN1(runtime).getClass("ObjectId"))) {
939+
return runtime.getFalse();
931940
}
932-
return self.callMethod(context, "value").op_eqq(context, other.callMethod(context, "value"));
941+
return oid(context, self).op_eqq(context, oid(context, other));
933942
}
934943

935944
private static RubyString name(final ThreadContext context, IRubyObject value,
@@ -2063,15 +2072,13 @@ static void initializeImpl(final ThreadContext context,
20632072
final String baseName = self.getMetaClass().getRealClass().getBaseName();
20642073
switch (baseName) {
20652074
case "ObjectId":
2066-
final String name;
2067-
try {
2068-
name = oid2Sym( runtime, getObjectID(runtime, value.toString()), true );
2069-
}
2070-
catch (IllegalArgumentException e) {
2071-
// e.g. in case of nil "string not an OID"
2072-
throw newASN1Error(runtime, e.getMessage());
2075+
if ( value instanceof RubyString ) {
2076+
try {
2077+
final String name = oid2Sym( runtime, getObjectID(runtime, value.toString()), true );
2078+
if ( name != null ) value = runtime.newString(name);
2079+
}
2080+
catch (IllegalArgumentException ignored) {}
20732081
}
2074-
if ( name != null ) value = runtime.newString(name);
20752082
break;
20762083
case "BitString":
20772084
self.setInstanceVariable("@unused_bits", runtime.newFixnum(0));
@@ -2155,11 +2162,7 @@ private ASN1Encodable toASN1Primitive(final ThreadContext context) {
21552162

21562163
final IRubyObject val = value(context);
21572164
if ( type == ASN1ObjectIdentifier.class ) {
2158-
try {
2159-
return getObjectID(context.runtime, val.toString());
2160-
} catch (IllegalArgumentException e) {
2161-
throw newASN1Error(context.runtime, e.getMessage());
2162-
}
2165+
return oid(context.runtime, val);
21632166
}
21642167
if ( type == DERNull.class || type == ASN1Null.class ) {
21652168
return DERNull.INSTANCE;

‎src/main/java/org/jruby/ext/openssl/Timestamp.java‎

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@
9595
import org.jruby.runtime.Visibility;
9696
import org.jruby.runtime.builtin.IRubyObject;
9797

98-
import static org.jruby.ext.openssl.ASN1.newASN1Error;
9998
import static org.jruby.ext.openssl.PKCS7._PKCS7;
10099
import static org.jruby.ext.openssl.X509._X509;
101100
import static org.jruby.ext.openssl.x509store.X509Utils.X509_PURPOSE_TIMESTAMP_SIGN;
@@ -146,14 +145,6 @@ static RaiseException newTimestampError(final Ruby runtime, final String message
146145
return newError(runtime, _TimestampError(runtime), message);
147146
}
148147

149-
static ASN1ObjectIdentifier oid(final Ruby runtime, final IRubyObject value) {
150-
try {
151-
return ASN1.getObjectID(runtime, value.convertToString().asJavaString());
152-
} catch (IllegalArgumentException e) {
153-
throw newASN1Error(runtime, e);
154-
}
155-
}
156-
157148
public static final class Request extends RubyObject {
158149

159150
private TimeStampReq timeStampReq;
@@ -238,7 +229,7 @@ public IRubyObject algorithm(ThreadContext context) {
238229

239230
@JRubyMethod(name = "algorithm=")
240231
public IRubyObject set_algorithm(final IRubyObject value) {
241-
algorithm = oid(getRuntime(), value);
232+
algorithm = ASN1.oid(getRuntime(), value);
242233
markChanged();
243234
return value;
244235
}
@@ -291,7 +282,7 @@ public IRubyObject policy_id(ThreadContext context) {
291282
@JRubyMethod(name = "policy_id=")
292283
public IRubyObject set_policy_id(final IRubyObject value) {
293284
if (value.isNil()) throw getRuntime().newTypeError(value, "String");
294-
policyId = oid(getRuntime(), value);
285+
policyId = ASN1.oid(getRuntime(), value);
295286
markChanged();
296287
return value;
297288
}
@@ -737,7 +728,7 @@ public IRubyObject create_timestamp(final ThreadContext context, final IRubyObje
737728
if (provider != null) digestBuilder.setProvider(provider);
738729
final DigestCalculatorProvider digestProvider = digestBuilder.build();
739730
final DigestCalculator digestCalculator = digestProvider.get(new AlgorithmIdentifier(TSPAlgorithms.SHA256));
740-
final ASN1ObjectIdentifier policy = req.policyId != null ? req.policyId : oid(runtime, defaultPolicy);
731+
final ASN1ObjectIdentifier policy = req.policyId != null ? req.policyId : ASN1.oid(runtime, defaultPolicy);
741732
final TimeStampTokenGenerator tokenGenerator = new TimeStampTokenGenerator(signer, digestCalculator, policy);
742733
if (req.certRequested) {
743734
tokenGenerator.addCertificates(new JcaCertStore(Collections.singletonList(auxCert)));
@@ -810,7 +801,7 @@ private Set<ASN1ObjectIdentifier> acceptedAlgorithms(final Ruby runtime, final I
810801
for (int i = 0; i < values.size(); i++) {
811802
final IRubyObject value = values.eltInternal(i);
812803
final String name = value instanceof Digest ? ((Digest) value).getShortAlgorithm() : value.convertToString().asJavaString();
813-
result.add(oid(runtime, runtime.newString(name)));
804+
result.add(ASN1.oid(runtime, runtime.newString(name)));
814805
}
815806
return result;
816807
}

‎test/test_asn1.rb‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,8 +376,13 @@ def test_object_identifier
376376
assert_raise(OpenSSL::ASN1::ASN1Error) {
377377
OpenSSL::ASN1.decode(B(%w{ 06 01 80 }))
378378
}
379-
assert_raise(OpenSSL::ASN1::ASN1Error) { OpenSSL::ASN1::ObjectId.new("3.0".b).to_der }
380-
assert_raise(OpenSSL::ASN1::ASN1Error) { OpenSSL::ASN1::ObjectId.new("0.40".b).to_der }
379+
invalid_oid = OpenSSL::ASN1::ObjectId.new("3.0".b)
380+
assert_equal "3.0".b, invalid_oid.value
381+
assert_raise(OpenSSL::ASN1::ASN1Error) { invalid_oid.oid }
382+
assert_raise(OpenSSL::ASN1::ASN1Error) { invalid_oid.to_der }
383+
invalid_oid = OpenSSL::ASN1::ObjectId.new("0.40".b)
384+
assert_equal "0.40".b, invalid_oid.value
385+
assert_raise(OpenSSL::ASN1::ASN1Error) { invalid_oid.to_der }
381386

382387
oid = (0...100).to_a.join(".").b
383388
obj = OpenSSL::ASN1::ObjectId.new(oid)
@@ -410,6 +415,19 @@ def test_object_identifier
410415
oid = OpenSSL::ASN1::ObjectId.new("2.5.29.14")
411416
assert_equal true, oid == OpenSSL::ASN1::ObjectId.new("2.5.29.14")
412417
assert_equal false, oid == OpenSSL::ASN1::ObjectId.new("2.5.29.35")
418+
419+
oid.value = "subjectKeyIdentifier"
420+
assert_equal true, oid == OpenSSL::ASN1::ObjectId.new("2.5.29.14")
421+
422+
nil_oid = OpenSSL::ASN1::ObjectId.new(nil)
423+
assert_nil nil_oid.value
424+
assert_raise(TypeError) { nil_oid.to_der }
425+
426+
string_value = Object.new
427+
string_value.define_singleton_method(:to_str) { "1.2.3" }
428+
oid = OpenSSL::ASN1::ObjectId.new(string_value)
429+
assert_same string_value, oid.value
430+
assert_equal "1.2.3", oid.oid
413431
end
414432

415433
def test_instantiate

0 commit comments

Comments
 (0)