mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 23:34:52 +02:00
8272243: Improve DER parsing
Reviewed-by: weijun, rhalade
This commit is contained in:
parent
e062dff1bf
commit
ddb106be7a
3 changed files with 113 additions and 57 deletions
|
@ -65,22 +65,32 @@ public class BitArray {
|
|||
repn = new byte[(length + BITS_PER_UNIT - 1)/BITS_PER_UNIT];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BitArray of the specified size, initialized from the
|
||||
* specified byte array. The most significant bit of {@code a[0]} gets
|
||||
* index zero in the BitArray. The array must be large enough to specify
|
||||
* a value for every bit of the BitArray. i.e. {@code 8*a.length <= length}.
|
||||
*/
|
||||
public BitArray(int length, byte[] a) throws IllegalArgumentException {
|
||||
this(length, a, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BitArray of the specified size, initialized from the
|
||||
* specified byte array. The most significant bit of {@code a[0]} gets
|
||||
* index zero in the BitArray. The array a must be large enough
|
||||
* to specify a value for every bit in the BitArray. In other words,
|
||||
* {@code 8*a.length <= length}.
|
||||
* specified byte array starting at the specified offset. The most
|
||||
* significant bit of {@code a[ofs]} gets index zero in the BitArray.
|
||||
* The array must be large enough to specify a value for every bit of
|
||||
* the BitArray, i.e. {@code 8*(a.length - ofs) <= length}.
|
||||
*/
|
||||
public BitArray(int length, byte[] a) throws IllegalArgumentException {
|
||||
public BitArray(int length, byte[] a, int ofs)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
if (length < 0) {
|
||||
throw new IllegalArgumentException("Negative length for BitArray");
|
||||
}
|
||||
if (a.length * BITS_PER_UNIT < length) {
|
||||
throw new IllegalArgumentException("Byte array too short to represent " +
|
||||
"bit array of given length");
|
||||
if ((a.length - ofs) * BITS_PER_UNIT < length) {
|
||||
throw new IllegalArgumentException
|
||||
("Byte array too short to represent " + length + "-bit array");
|
||||
}
|
||||
|
||||
this.length = length;
|
||||
|
@ -95,7 +105,7 @@ public class BitArray {
|
|||
2. zero out extra bits in the last byte
|
||||
*/
|
||||
repn = new byte[repLength];
|
||||
System.arraycopy(a, 0, repn, 0, repLength);
|
||||
System.arraycopy(a, ofs, repn, 0, repLength);
|
||||
if (repLength > 0) {
|
||||
repn[repLength - 1] &= bitMask;
|
||||
}
|
||||
|
@ -268,7 +278,7 @@ public class BitArray {
|
|||
public BitArray truncate() {
|
||||
for (int i=length-1; i>=0; i--) {
|
||||
if (get(i)) {
|
||||
return new BitArray(i+1, Arrays.copyOf(repn, (i + BITS_PER_UNIT)/BITS_PER_UNIT));
|
||||
return new BitArray(i+1, repn, 0);
|
||||
}
|
||||
}
|
||||
return new BitArray(1);
|
||||
|
|
|
@ -692,6 +692,28 @@ public class DerValue {
|
|||
};
|
||||
}
|
||||
|
||||
// check the number of pad bits, validate the pad bits in the bytes
|
||||
// if enforcing DER (i.e. allowBER == false), and return the number of
|
||||
// bits of the resulting BitString
|
||||
private static int checkPaddedBits(int numOfPadBits, byte[] data,
|
||||
int start, int end, boolean allowBER) throws IOException {
|
||||
// number of pad bits should be from 0(min) to 7(max).
|
||||
if ((numOfPadBits < 0) || (numOfPadBits > 7)) {
|
||||
throw new IOException("Invalid number of padding bits");
|
||||
}
|
||||
int lenInBits = ((end - start) << 3) - numOfPadBits;
|
||||
if (lenInBits < 0) {
|
||||
throw new IOException("Not enough bytes in BitString");
|
||||
}
|
||||
|
||||
// padding bits should be all zeros for DER
|
||||
if (!allowBER && numOfPadBits != 0 &&
|
||||
(data[end - 1] & (0xff >>> (8 - numOfPadBits))) != 0) {
|
||||
throw new IOException("Invalid value of padding bits");
|
||||
}
|
||||
return lenInBits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ASN.1 BIT STRING value, with the tag assumed implicit
|
||||
* based on the parameter. The bit string must be byte-aligned.
|
||||
|
@ -708,18 +730,17 @@ public class DerValue {
|
|||
}
|
||||
if (end == start) {
|
||||
throw new IOException("Invalid encoding: zero length bit string");
|
||||
}
|
||||
int numOfPadBits = buffer[start];
|
||||
if ((numOfPadBits < 0) || (numOfPadBits > 7)) {
|
||||
throw new IOException("Invalid number of padding bits");
|
||||
}
|
||||
// minus the first byte which indicates the number of padding bits
|
||||
byte[] retval = Arrays.copyOfRange(buffer, start + 1, end);
|
||||
if (numOfPadBits != 0) {
|
||||
// get rid of the padding bits
|
||||
retval[end - start - 2] &= (byte)((0xff << numOfPadBits));
|
||||
|
||||
}
|
||||
data.pos = data.end; // Compatibility. Reach end.
|
||||
|
||||
int numOfPadBits = buffer[start];
|
||||
checkPaddedBits(numOfPadBits, buffer, start + 1, end, allowBER);
|
||||
byte[] retval = Arrays.copyOfRange(buffer, start + 1, end);
|
||||
if (allowBER && numOfPadBits != 0) {
|
||||
// fix the potential non-zero padding bits
|
||||
retval[retval.length - 1] &= (byte)((0xff << numOfPadBits));
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -742,16 +763,11 @@ public class DerValue {
|
|||
throw new IOException("Invalid encoding: zero length bit string");
|
||||
}
|
||||
data.pos = data.end; // Compatibility. Reach end.
|
||||
|
||||
int numOfPadBits = buffer[start];
|
||||
if ((numOfPadBits < 0) || (numOfPadBits > 7)) {
|
||||
throw new IOException("Invalid number of padding bits");
|
||||
}
|
||||
if (end == start + 1) {
|
||||
return new BitArray(0);
|
||||
} else {
|
||||
return new BitArray(((end - start - 1) << 3) - numOfPadBits,
|
||||
Arrays.copyOfRange(buffer, start + 1, end));
|
||||
}
|
||||
int len = checkPaddedBits(numOfPadBits, buffer, start + 1, end,
|
||||
allowBER);
|
||||
return new BitArray(len, buffer, start + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue