提交 e0a6b962 编写于 作者: X xuelei

8236191: Enhance OID processing

Reviewed-by: jnimeh, weijun, ahgross, rhalade
上级 753e7990
...@@ -53,6 +53,26 @@ import java.util.Arrays; ...@@ -53,6 +53,26 @@ import java.util.Arrays;
public final public final
class ObjectIdentifier implements Serializable class ObjectIdentifier implements Serializable
{ {
/*
* The maximum encoded OID length, excluding the ASN.1 encoding tag and
* length.
*
* In theory, there is no maximum size for OIDs. However, there are some
* limitation in practice.
*
* RFC 5280 mandates support for OIDs that have arc elements with values
* that are less than 2^28 (that is, they MUST be between 0 and
* 268,435,455, inclusive), and implementations MUST be able to handle
* OIDs with up to 20 elements (inclusive). Per RFC 5280, an encoded
* OID should be less than 80 bytes for safe interoperability.
*
* This class could be used for protocols other than X.509 certificates.
* To be safe, a relatively large but still reasonable value is chosen
* as the restriction in JDK.
*/
private static final int MAXIMUM_OID_SIZE = 4096; // 2^12
/** /**
* We use the DER value (no tag, no length) as the internal format * We use the DER value (no tag, no length) as the internal format
* @serial * @serial
...@@ -115,7 +135,13 @@ class ObjectIdentifier implements Serializable ...@@ -115,7 +135,13 @@ class ObjectIdentifier implements Serializable
if (componentLen > comp.length) { if (componentLen > comp.length) {
componentLen = comp.length; componentLen = comp.length;
} }
// Check the estimated size before it is too later.
checkOidSize(componentLen);
init(comp, componentLen); init(comp, componentLen);
} else {
checkOidSize(encoding.length);
} }
} }
...@@ -198,6 +224,8 @@ class ObjectIdentifier implements Serializable ...@@ -198,6 +224,8 @@ class ObjectIdentifier implements Serializable
} }
start = end + 1; start = end + 1;
count++; count++;
checkOidSize(pos);
} while (end != -1); } while (end != -1);
checkCount(count); checkCount(count);
...@@ -260,11 +288,13 @@ class ObjectIdentifier implements Serializable ...@@ -260,11 +288,13 @@ class ObjectIdentifier implements Serializable
); );
int len = in.getDefiniteLength(); int len = in.getDefiniteLength();
checkOidSize(len);
if (len > in.available()) { if (len > in.available()) {
throw new IOException("ObjectIdentifier() -- length exceeds" + throw new IOException("ObjectIdentifier length exceeds " +
"data available. Length: " + len + ", Available: " + "data available. Length: " + len + ", Available: " +
in.available()); in.available());
} }
encoding = new byte[len]; encoding = new byte[len];
in.getBytes(encoding); in.getBytes(encoding);
check(encoding); check(encoding);
...@@ -278,26 +308,32 @@ class ObjectIdentifier implements Serializable ...@@ -278,26 +308,32 @@ class ObjectIdentifier implements Serializable
ObjectIdentifier (DerInputBuffer buf) throws IOException ObjectIdentifier (DerInputBuffer buf) throws IOException
{ {
DerInputStream in = new DerInputStream(buf); DerInputStream in = new DerInputStream(buf);
encoding = new byte[in.available()]; int len = in.available();
checkOidSize(len);
encoding = new byte[len];
in.getBytes(encoding); in.getBytes(encoding);
check(encoding); check(encoding);
} }
private void init(int[] components, int length) { private void init(int[] components, int length) throws IOException {
int pos = 0; int pos = 0;
byte[] tmp = new byte[length*5+1]; // +1 for empty input byte[] tmp = new byte[length * 5 + 1]; // +1 for empty input
if (components[1] < Integer.MAX_VALUE - components[0]*40) if (components[1] < Integer.MAX_VALUE - components[0] * 40) {
pos += pack7Oid(components[0]*40+components[1], tmp, pos); pos += pack7Oid(components[0] * 40 + components[1], tmp, pos);
else { } else {
BigInteger big = BigInteger.valueOf(components[1]); BigInteger big = BigInteger.valueOf(components[1]);
big = big.add(BigInteger.valueOf(components[0]*40)); big = big.add(BigInteger.valueOf(components[0] * 40));
pos += pack7Oid(big, tmp, pos); pos += pack7Oid(big, tmp, pos);
} }
for (int i=2; i<length; i++) { for (int i = 2; i < length; i++) {
pos += pack7Oid(components[i], tmp, pos); pos += pack7Oid(components[i], tmp, pos);
checkOidSize(pos);
} }
encoding = new byte[pos]; encoding = new byte[pos];
System.arraycopy(tmp, 0, encoding, 0, pos); System.arraycopy(tmp, 0, encoding, 0, pos);
} }
...@@ -660,4 +696,13 @@ class ObjectIdentifier implements Serializable ...@@ -660,4 +696,13 @@ class ObjectIdentifier implements Serializable
"oid component #" + (i+1) + " must be non-negative "); "oid component #" + (i+1) + " must be non-negative ");
} }
} }
private static void checkOidSize(int oidLength) throws IOException {
if (oidLength > MAXIMUM_OID_SIZE) {
throw new IOException(
"ObjectIdentifier encoded length exceeds " +
"the restriction in JDK (OId length(>=): " + oidLength +
", Restriction: " + MAXIMUM_OID_SIZE + ")");
}
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册