Skip to content

Commit

Permalink
[fix] ASN.1 BitString pad bits being out of range
Browse files Browse the repository at this point in the history
has been surfacing on CI a few times as:
```
Java::JavaLang::IllegalArgumentException: pad bits cannot be greater
than 7 or less than 0
org.bouncycastle.asn1.ASN1BitString.<init>(Unknown Source)
org.bouncycastle.asn1.DERBitString.<init>(Unknown Source)
org.jruby.ext.openssl.ASN1$Primitive.toASN1Primitive(ASN1.java:1687)
org.jruby.ext.openssl.ASN1$Primitive.toASN1(ASN1.java:1620)
org.jruby.ext.openssl.ASN1$Constructive.addEntry(ASN1.java:1991)
org.jruby.ext.openssl.ASN1$Constructive.toASN1EncodableVector(ASN1.java:1955)
org.jruby.ext.openssl.ASN1$Constructive.toASN1(ASN1.java:1838)
org.jruby.ext.openssl.ASN1$Constructive.addEntry(ASN1.java:1994)
org.jruby.ext.openssl.ASN1$Constructive.toASN1EncodableVector(ASN1.java:1955)
org.jruby.ext.openssl.ASN1$Constructive.toASN1(ASN1.java:1838)
org.jruby.ext.openssl.ASN1$ASN1Data.toDER(ASN1.java:1421)
```
  • Loading branch information
kares committed Jun 11, 2024
1 parent 969f7dc commit 55f71cb
Showing 1 changed file with 8 additions and 14 deletions.
22 changes: 8 additions & 14 deletions src/main/java/org/jruby/ext/openssl/ASN1.java
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,7 @@ static IRubyObject decodeObject(final ThreadContext context,

if ( obj instanceof ASN1BitString ) {
final ASN1BitString derObj = (ASN1BitString) obj;
RubyString str = runtime.newString( new ByteList(derObj.getBytes(), false) );
RubyString str = runtime.newString(new ByteList(derObj.getBytes(), false));
IRubyObject bitString = ASN1.getClass("BitString").newInstance(context, str, Block.NULL_BLOCK);
bitString.getInstanceVariables().setInstanceVariable("@unused_bits", runtime.newFixnum(derObj.getPadBits()));
return bitString;
Expand Down Expand Up @@ -1669,22 +1669,16 @@ private ASN1Encodable toASN1Primitive(final ThreadContext context) {
return new DEROctetString( val.asString().getBytes() );
}
if ( type == DERBitString.class ) {
final byte[] bs = val.asString().getBytes();
int unused = 0;
for ( int i = (bs.length - 1); i > -1; i-- ) {
if (bs[i] == 0) unused += 8;
else {
byte v2 = bs[i];
int x = 8;
while ( v2 != 0 ) {
v2 <<= 1;
x--;
}
unused += x;
final byte[] data = val.asString().getBytes();
int padBits = 0; // padBits < 8 && padBits >= 0
for (int i = (data.length - 1); i > -1; i--) {
int b = Byte.toUnsignedInt(data[i]);
if (b != 0) {
padBits = Integer.numberOfTrailingZeros(b);
break;
}
}
return new DERBitString(bs, unused);
return new DERBitString(data, padBits);
}
if ( type == DERIA5String.class ) {
return new DERIA5String( val.asString().toString() );
Expand Down

0 comments on commit 55f71cb

Please sign in to comment.