Skip to content

Commit a16adad

Browse files
committed
[feat] implement OpenSSL::X509::Name#to_utf8
1 parent f83689e commit a16adad

File tree

2 files changed

+46
-35
lines changed

2 files changed

+46
-35
lines changed

src/main/java/org/jruby/ext/openssl/StringHelper.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.ArrayList;
3030
import java.util.Locale;
3131

32+
import org.jcodings.specific.ASCIIEncoding;
3233
import org.jcodings.specific.UTF8Encoding;
3334
import org.joda.time.DateTime;
3435
import org.joda.time.DateTimeZone;
@@ -61,6 +62,10 @@ static RubyString newString(final Ruby runtime, final byte[] bytes, final int co
6162
return RubyString.newString(runtime, byteList);
6263
}
6364

65+
static RubyString newString(final Ruby runtime, final CharSequence chars) {
66+
return new RubyString(runtime, runtime.getString(), chars, ASCIIEncoding.INSTANCE);
67+
}
68+
6469
static ByteList setByteListShared(final RubyString str) {
6570
str.setByteListShared();
6671
return str.getByteList();

src/main/java/org/jruby/ext/openssl/X509Name.java

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,9 @@ static RubyClass _Name(final Ruby runtime) {
167167

168168
public X509Name(Ruby runtime, RubyClass type) {
169169
super(runtime,type);
170-
oids = new ArrayList<ASN1ObjectIdentifier>();
171-
values = new ArrayList<ASN1Encodable>();
172-
types = new ArrayList<RubyInteger>();
170+
oids = new ArrayList<>(4);
171+
values = new ArrayList<>(4);
172+
types = new ArrayList<>(4);
173173
}
174174

175175
private final List<ASN1ObjectIdentifier> oids;
@@ -256,15 +256,11 @@ private void addType(final Ruby runtime, final ASN1Encodable value) {
256256
}
257257
}
258258

259-
private void addEntry(ASN1ObjectIdentifier oid, RubyString value, RubyInteger type)
260-
throws IOException {
259+
private void addEntry(ASN1ObjectIdentifier oid, RubyString value, RubyInteger type) throws RuntimeException {
261260
this.name = null;
262261
this.canonicalName = null;
263262
this.oids.add(oid);
264-
final ASN1Encodable convertedValue = getNameEntryConverted().
265-
getConvertedValue(oid, value.toString()
266-
);
267-
this.values.add( convertedValue );
263+
this.values.add( getNameEntryConverted().getConvertedValue(oid, value.toString()) );
268264
this.types.add(type);
269265
}
270266

@@ -379,8 +375,9 @@ public IRubyObject add_entry(final ThreadContext context,
379375
try {
380376
addEntry(objectId, value.asString(), (RubyInteger) type);
381377
}
382-
catch (IOException e) {
383-
throw newNameError(runtime, "invalid value", e);
378+
catch (RuntimeException e) {
379+
String msg = e.getMessage(); // X509DefaultEntryConverted: "can't recode value for oid " + oid.getId()
380+
throw newNameError(runtime, msg == null ? "invalid value" : msg, e);
384381
}
385382
return this;
386383
}
@@ -396,32 +393,34 @@ private static IRubyObject getDefaultType(final ThreadContext context, final Rub
396393
@SuppressWarnings("unchecked")
397394
@JRubyMethod(name = "to_s", rest = true)
398395
public IRubyObject to_s(IRubyObject[] args) {
399-
final Ruby runtime = getRuntime();
400-
401396
int flag = 0;
402397
if ( args.length > 0 && ! args[0].isNil() ) {
403398
flag = RubyNumeric.fix2int( args[0] );
404399
}
405-
406-
/* Should follow parameters like this:
407-
if 0 (COMPAT):
408-
irb(main):025:0> x.to_s(OpenSSL::X509::Name::COMPAT)
409-
=> "CN=ola.bini, O=sweden/streetAddress=sweden, O=sweden/2.5.4.43343=sweden"
410-
irb(main):026:0> x.to_s(OpenSSL::X509::Name::ONELINE)
411-
=> "CN = ola.bini, O = sweden, streetAddress = sweden, O = sweden, 2.5.4.43343 = sweden"
412-
irb(main):027:0> x.to_s(OpenSSL::X509::Name::MULTILINE)
413-
=> "commonName = ola.bini\norganizationName = sweden\nstreetAddress = sweden\norganizationName = sweden\n2.5.4.43343 = sweden"
414-
irb(main):028:0> x.to_s(OpenSSL::X509::Name::RFC2253)
415-
=> "2.5.4.43343=#0C0673776564656E,O=sweden,streetAddress=sweden,O=sweden,CN=ola.bini"
416-
else
417-
=> /CN=ola.bini/O=sweden/streetAddress=sweden/O=sweden/2.5.4.43343=sweden
418-
*/
419-
400+
final Ruby runtime = getRuntime();
401+
// NOTE: historically we haven't screwed this up as ASCII-8BIT as C-OpenSSL does
402+
return RubyString.newString(runtime, toFormat(runtime, flag));
403+
}
404+
405+
/* Should follow parameters like this:
406+
if 0 (COMPAT):
407+
irb(main):025:0> x.to_s(OpenSSL::X509::Name::COMPAT)
408+
=> "CN=ola.bini, O=sweden/streetAddress=sweden, O=sweden/2.5.4.43343=sweden"
409+
irb(main):026:0> x.to_s(OpenSSL::X509::Name::ONELINE)
410+
=> "CN = ola.bini, O = sweden, streetAddress = sweden, O = sweden, 2.5.4.43343 = sweden"
411+
irb(main):027:0> x.to_s(OpenSSL::X509::Name::MULTILINE)
412+
=> "commonName = ola.bini\norganizationName = sweden\nstreetAddress = sweden\norganizationName = sweden\n2.5.4.43343 = sweden"
413+
irb(main):028:0> x.to_s(OpenSSL::X509::Name::RFC2253)
414+
=> "2.5.4.43343=#0C0673776564656E,O=sweden,streetAddress=sweden,O=sweden,CN=ola.bini"
415+
else
416+
=> /CN=ola.bini/O=sweden/streetAddress=sweden/O=sweden/2.5.4.43343=sweden
417+
*/
418+
private StringBuilder toFormat(final Ruby runtime, final int format) {
420419
final Iterator<ASN1ObjectIdentifier> oidsIter;
421420
final Iterator<Object> valuesIter;
422-
if ( flag == RFC2253 ) {
423-
ArrayList<ASN1ObjectIdentifier> reverseOids = new ArrayList<ASN1ObjectIdentifier>(oids);
424-
ArrayList<Object> reverseValues = new ArrayList<Object>(values);
421+
if ( format == RFC2253 ) {
422+
ArrayList<ASN1ObjectIdentifier> reverseOids = new ArrayList<>(oids);
423+
ArrayList<Object> reverseValues = new ArrayList<>(values);
425424
Collections.reverse(reverseOids);
426425
Collections.reverse(reverseValues);
427426
oidsIter = reverseOids.iterator();
@@ -432,13 +431,13 @@ public IRubyObject to_s(IRubyObject[] args) {
432431
}
433432

434433
final StringBuilder str = new StringBuilder(48); String sep = "";
435-
while( oidsIter.hasNext() ) {
434+
while (oidsIter.hasNext()) {
436435
final ASN1ObjectIdentifier oid = oidsIter.next();
437436
String oName = name(runtime, oid);
438437
if ( oName == null ) oName = oid.toString();
439438
final Object value = valuesIter.next();
440439

441-
switch(flag) {
440+
switch (format) {
442441
case RFC2253:
443442
str.append(sep).append(oName).append('=').append(value);
444443
sep = ",";
@@ -462,7 +461,12 @@ public IRubyObject to_s(IRubyObject[] args) {
462461
}
463462
}
464463

465-
return runtime.newString( str.toString() );
464+
return str;
465+
}
466+
467+
@JRubyMethod
468+
public IRubyObject to_utf8(ThreadContext context) {
469+
return StringHelper.newUTF8String(context.runtime, toFormat(context.runtime, RFC2253));
466470
}
467471

468472
@Override
@@ -488,7 +492,9 @@ public RubyArray to_a() {
488492
final String value = valuesIter.next().toString();
489493
final IRubyObject type = typesIter.next();
490494
final IRubyObject[] entry = new IRubyObject[] {
491-
runtime.newString(oName), runtime.newString(value), type
495+
StringHelper.newUTF8String(runtime, oName),
496+
StringHelper.newUTF8String(runtime, value),
497+
type
492498
};
493499
entries.append( runtime.newArrayNoCopy(entry) );
494500
}

0 commit comments

Comments
 (0)