Skip to content

Commit ebadc7a

Browse files
committed
[fix] authorityKeyIdentifier ext (general-name) value
we've aligned formatting of ext.value with C OpenSSL
1 parent 149001d commit ebadc7a

File tree

5 files changed

+54
-26
lines changed

5 files changed

+54
-26
lines changed

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

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -420,41 +420,50 @@ public RubyString value(final ThreadContext context) {
420420
if ( oid.equals("2.5.29.35") ) { // authorityKeyIdentifier
421421
ASN1Encodable value = getRealValue();
422422

423-
if ( value instanceof ASN1OctetString ) {
423+
if (value instanceof ASN1OctetString) {
424424
value = ASN1.readObject( ((ASN1OctetString) value).getOctets() );
425425
}
426426

427-
final ByteList val = new ByteList(72); val.append(keyid_);
427+
final ByteList val = new ByteList(72);
428428

429-
if ( value instanceof ASN1Sequence ) {
429+
if (value instanceof ASN1Sequence) {
430430
final ASN1Sequence seq = (ASN1Sequence) value;
431431
final int size = seq.size();
432432
if ( size == 0 ) return RubyString.newEmptyString(runtime);
433433

434-
ASN1Primitive keyid = seq.getObjectAt(0).toASN1Primitive();
435-
hexBytes( keyidBytes(keyid), val ).append('\n');
436-
437-
for ( int i = 1; i < size; i++ ) {
438-
final ASN1Encodable issuer = seq.getObjectAt(i);
439-
// NOTE: blindly got OpenSSL tests passing (likely in-complete) :
440-
if ( issuer instanceof ASN1TaggedObject ) {
441-
ASN1Primitive obj = ((ASN1TaggedObject) issuer).getObject();
442-
switch( ((ASN1TaggedObject) issuer).getTagNo() ) {
434+
for ( int i = 0; i < size; i++ ) {
435+
final ASN1Encodable enc = seq.getObjectAt(i);
436+
if (enc instanceof ASN1TaggedObject) {
437+
ASN1Primitive obj = ((ASN1TaggedObject) enc).getObject();
438+
switch( ((ASN1TaggedObject) enc).getTagNo() ) {
439+
case 0 :
440+
ASN1Primitive keyid = obj;
441+
val.append(keyid_);
442+
hexBytes( keyidBytes(keyid), val );
443+
break;
443444
case 1 :
444-
if ( obj instanceof ASN1TaggedObject ) {
445-
formatGeneralName(GeneralName.getInstance(obj), val, true);
445+
GeneralName name;
446+
if (obj instanceof ASN1Sequence) { // GeneralNames -> toASN1Primitive()
447+
GeneralName[] names = GeneralNames.getInstance(obj).getNames();
448+
name = names.length > 0 ? names[0] : null;
449+
} else {
450+
name = GeneralName.getInstance(obj);
446451
}
452+
if (name != null) formatGeneralName(name, val, true);
447453
break;
448454
case 2 : // serial
449455
val.append(new byte[] { 's','e','r','i','a','l',':' });
450456
if (obj instanceof ASN1Integer) {
451457
hexBytes( ((ASN1Integer) obj).getValue().toByteArray(), val);
452458
}
453459
else {
454-
hexBytes( ((ASN1OctetString) obj ).getOctets(), val );
460+
hexBytes( ((ASN1OctetString) obj ).getOctets(), val );
455461
}
456462
break;
457463
}
464+
} else if (size == 1) {
465+
ASN1Primitive keyid = enc.toASN1Primitive();
466+
hexBytes( keyidBytes(keyid), val );
458467
}
459468
val.append('\n');
460469
}

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -403,12 +403,16 @@ private static DLSequence parseBasicConstrains(final String valuex) {
403403
private ASN1Sequence parseAuthorityKeyIdentifier(final ThreadContext context, final String valuex) {
404404
final ASN1EncodableVector vec = new ASN1EncodableVector();
405405

406-
for ( String value : valuex.split(",") ) { // e.g. "keyid:always,issuer:always"
406+
final String[] values = valuex.split(","); // e.g. "keyid:always,issuer:always"
407+
for ( int i = 0; i<values.length; i++ ) {
408+
final String value = values[i];
407409
if ( value.startsWith("keyid") ) { // keyid[:always]
408410
ASN1Encodable publicKeyIdentifier = new DEROctetString(issuerPublicKeyIdentifier(context));
409411
vec.add(new DERTaggedObject(false, 0, publicKeyIdentifier));
412+
413+
if ( i < values.length - 1 && !"issuer:always".equals(values[i + 1]) ) break;
410414
}
411-
else if ( value.startsWith("issuer") ) { // issuer[:always]
415+
if ( value.startsWith("issuer") ) { // issuer[:always]
412416
GeneralName issuerName = new GeneralName(authorityCertIssuer(context));
413417
vec.add(new DERTaggedObject(false, 1, new GeneralNames(issuerName)));
414418

@@ -505,7 +509,7 @@ private static byte[] getSHA1Digest(Ruby runtime, ByteList bytes) {
505509
private ASN1Encodable parseIssuerAltName(final ThreadContext context, final String valuex)
506510
throws IOException {
507511
if ( valuex.startsWith("issuer:copy") ) {
508-
RubyArray exts = (RubyArray) getInstanceVariable("@issuer_certificate").callMethod(context, "extensions");
512+
RubyArray exts = (RubyArray) issuer_cert().callMethod(context, "extensions");
509513
for ( int i = 0; i < exts.size(); i++ ) {
510514
X509Extension ext = (X509Extension) exts.entry(i);
511515
final String oid = ext.getRealObjectID().getId();

src/test/ruby/test_asn1.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ def test_decode
451451

452452
assert OpenSSL::X509::Certificate.new( cert_der ).verify key
453453
# running the same in MRI also fails
454-
#calulated_sig = key.sign(OpenSSL::Digest::SHA1.new, cert_der)
454+
calulated_sig = key.sign(OpenSSL::Digest::SHA1.new, cert_der)
455455
#assert_equal calulated_sig, sig_val.value
456456
end
457457

src/test/ruby/x509/test_x509cert.rb

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,16 @@ def test_cert_extensions # JRUBY-3468
7474
end
7575

7676
def test_aki_extension_to_text
77-
cert = create_self_signed_cert [ %w[CN localhost] ], __method__
77+
cert = create_self_signed_cert [ %w[CN localhost] ], __method__.to_s
7878
keyid = "97:39:9D:C3:FB:CD:BA:8F:54:0C:90:7B:46:3F:EA:D6:43:75:B1:CB"
7979

8080
assert cert.extensions.size > 0
8181
value = cert.extensions.last.value
82-
# assert_equal "keyid:#{keyid}\nDirName:/CN=localhost\nserial:01\n", value
83-
assert value.start_with?("keyid:#{keyid}\n")
84-
assert value.end_with?("\nserial:01\n")
82+
assert_equal "keyid:#{keyid}\nDirName:/CN=localhost\nserial:01\n", value
8583
end
8684

8785
def create_self_signed_cert(cn, comment) # cert generation ripped from WEBrick
88-
rsa = OpenSSL::PKey::RSA.new TEST_KEY_RSA2048
86+
key = OpenSSL::PKey::RSA.new TEST_KEY_RSA2048
8987
cert = OpenSSL::X509::Certificate.new
9088
cert.version = 2
9189
cert.serial = 1
@@ -94,7 +92,7 @@ def create_self_signed_cert(cn, comment) # cert generation ripped from WEBrick
9492
cert.issuer = name
9593
cert.not_before = Time.now
9694
cert.not_after = Time.now + (365*24*60*60)
97-
cert.public_key = rsa.public_key
95+
cert.public_key = key.public_key
9896

9997
ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
10098
ef.issuer_certificate = cert
@@ -107,7 +105,7 @@ def create_self_signed_cert(cn, comment) # cert generation ripped from WEBrick
107105
]
108106
aki = ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always")
109107
cert.add_extension(aki)
110-
cert.sign(rsa, OpenSSL::Digest::SHA1.new)
108+
cert.sign(key, OpenSSL::Digest::SHA1.new)
111109

112110
cert
113111
end

src/test/ruby/x509/test_x509ext.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,23 @@ def test_authority_key_identifier
268268
assert_equal keyid = "keyid:91:0D:0C:A9:43:73:DF:8C:A9:E3:C2:0A:05:E3:CF:BE:A7:38:8D:DD\n", ext.value
269269
assert !ext.critical?
270270
assert_equal [ "authorityKeyIdentifier", keyid, false ], ext.to_a
271+
272+
issuer = "DirName:/CN=localhost\n" + "serial:01\n"
273+
ext = ef.create_extension("authorityKeyIdentifier", "keyid,issuer")
274+
assert_equal keyid, ext.value
275+
assert_equal [ "authorityKeyIdentifier", keyid, false ], ext.to_a
276+
277+
ext = ef.create_extension("authorityKeyIdentifier", "issuer")
278+
assert_equal [ "authorityKeyIdentifier", issuer, false ], ext.to_a
279+
280+
ext = ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always")
281+
assert_equal keyid + issuer, ext.value
282+
assert_equal [ "authorityKeyIdentifier", keyid + issuer, false ], ext.to_a
283+
284+
ext = ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer")
285+
assert_equal keyid, ext.value
286+
assert_equal [ "authorityKeyIdentifier", keyid, false ], ext.to_a
287+
271288
# cert.sign(key, OpenSSL::Digest::SHA1.new)
272289
end
273290

0 commit comments

Comments
 (0)