This commit is contained in:
Mikael Vidstedt 2020-07-14 23:29:45 -07:00
commit 1982432db4
992 changed files with 2142 additions and 2081 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -312,15 +312,15 @@ class DerInputBuffer extends ByteArrayInputStream implements Cloneable {
if (generalized) {
type = "Generalized";
year = 1000 * Character.digit((char)buf[pos++], 10);
year += 100 * Character.digit((char)buf[pos++], 10);
year += 10 * Character.digit((char)buf[pos++], 10);
year += Character.digit((char)buf[pos++], 10);
year = 1000 * toDigit(buf[pos++], type);
year += 100 * toDigit(buf[pos++], type);
year += 10 * toDigit(buf[pos++], type);
year += toDigit(buf[pos++], type);
len -= 2; // For the two extra YY
} else {
type = "UTC";
year = 10 * Character.digit((char)buf[pos++], 10);
year += Character.digit((char)buf[pos++], 10);
year = 10 * toDigit(buf[pos++], type);
year += toDigit(buf[pos++], type);
if (year < 50) // origin 2000
year += 2000;
@ -328,17 +328,17 @@ class DerInputBuffer extends ByteArrayInputStream implements Cloneable {
year += 1900; // origin 1900
}
month = 10 * Character.digit((char)buf[pos++], 10);
month += Character.digit((char)buf[pos++], 10);
month = 10 * toDigit(buf[pos++], type);
month += toDigit(buf[pos++], type);
day = 10 * Character.digit((char)buf[pos++], 10);
day += Character.digit((char)buf[pos++], 10);
day = 10 * toDigit(buf[pos++], type);
day += toDigit(buf[pos++], type);
hour = 10 * Character.digit((char)buf[pos++], 10);
hour += Character.digit((char)buf[pos++], 10);
hour = 10 * toDigit(buf[pos++], type);
hour += toDigit(buf[pos++], type);
minute = 10 * Character.digit((char)buf[pos++], 10);
minute += Character.digit((char)buf[pos++], 10);
minute = 10 * toDigit(buf[pos++], type);
minute += toDigit(buf[pos++], type);
len -= 10; // YYMMDDhhmm
@ -350,12 +350,16 @@ class DerInputBuffer extends ByteArrayInputStream implements Cloneable {
millis = 0;
if (len > 2) {
second = 10 * Character.digit((char)buf[pos++], 10);
second += Character.digit((char)buf[pos++], 10);
second = 10 * toDigit(buf[pos++], type);
second += toDigit(buf[pos++], type);
len -= 2;
// handle fractional seconds (if present)
if (buf[pos] == '.' || buf[pos] == ',') {
if (generalized && (buf[pos] == '.' || buf[pos] == ',')) {
len --;
if (len == 0) {
throw new IOException("Parse " + type +
" time, empty fractional part");
}
pos++;
int precision = 0;
while (buf[pos] != 'Z' &&
@ -363,8 +367,13 @@ class DerInputBuffer extends ByteArrayInputStream implements Cloneable {
buf[pos] != '-') {
// Validate all digits in the fractional part but
// store millisecond precision only
int thisDigit = Character.digit((char)buf[pos], 10);
int thisDigit = toDigit(buf[pos], type);
precision++;
len--;
if (len == 0) {
throw new IOException("Parse " + type +
" time, invalid fractional part");
}
pos++;
switch (precision) {
case 1:
@ -382,7 +391,6 @@ class DerInputBuffer extends ByteArrayInputStream implements Cloneable {
throw new IOException("Parse " + type +
" time, empty fractional part");
}
len -= precision;
}
} else
second = 0;
@ -412,10 +420,13 @@ class DerInputBuffer extends ByteArrayInputStream implements Cloneable {
switch (buf[pos++]) {
case '+':
hr = 10 * Character.digit((char)buf[pos++], 10);
hr += Character.digit((char)buf[pos++], 10);
min = 10 * Character.digit((char)buf[pos++], 10);
min += Character.digit((char)buf[pos++], 10);
if (len != 5) {
throw new IOException("Parse " + type + " time, invalid offset");
}
hr = 10 * toDigit(buf[pos++], type);
hr += toDigit(buf[pos++], type);
min = 10 * toDigit(buf[pos++], type);
min += toDigit(buf[pos++], type);
if (hr >= 24 || min >= 60)
throw new IOException("Parse " + type + " time, +hhmm");
@ -424,10 +435,13 @@ class DerInputBuffer extends ByteArrayInputStream implements Cloneable {
break;
case '-':
hr = 10 * Character.digit((char)buf[pos++], 10);
hr += Character.digit((char)buf[pos++], 10);
min = 10 * Character.digit((char)buf[pos++], 10);
min += Character.digit((char)buf[pos++], 10);
if (len != 5) {
throw new IOException("Parse " + type + " time, invalid offset");
}
hr = 10 * toDigit(buf[pos++], type);
hr += toDigit(buf[pos++], type);
min = 10 * toDigit(buf[pos++], type);
min += toDigit(buf[pos++], type);
if (hr >= 24 || min >= 60)
throw new IOException("Parse " + type + " time, -hhmm");
@ -436,6 +450,9 @@ class DerInputBuffer extends ByteArrayInputStream implements Cloneable {
break;
case 'Z':
if (len != 1) {
throw new IOException("Parse " + type + " time, invalid format");
}
break;
default:
@ -443,4 +460,16 @@ class DerInputBuffer extends ByteArrayInputStream implements Cloneable {
}
return new Date(time);
}
/**
* Converts byte (represented as a char) to int.
* @throws IOException if integer is not a valid digit in the specified
* radix (10)
*/
private static int toDigit(byte b, String type) throws IOException {
if (b < '0' || b > '9') {
throw new IOException("Parse " + type + " time, invalid format");
}
return b - '0';
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -31,6 +31,7 @@ import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.Principal;
import java.security.cert.*;
import java.text.Normalizer;
import java.util.*;
import javax.security.auth.x500.X500Principal;
import javax.net.ssl.SNIHostName;
@ -217,8 +218,12 @@ public class HostnameChecker {
(X500Name.commonName_oid);
if (derValue != null) {
try {
if (isMatched(expectedName, derValue.getAsString(),
chainsToPublicCA)) {
String cname = derValue.getAsString();
if (!Normalizer.isNormalized(cname, Normalizer.Form.NFKC)) {
throw new CertificateException("Not a formal name "
+ cname);
}
if (isMatched(expectedName, cname, chainsToPublicCA)) {
return;
}
} catch (IOException e) {

View file

@ -52,6 +52,25 @@ import java.util.concurrent.ConcurrentHashMap;
*/
public final 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
* @serial
@ -118,7 +137,13 @@ public final class ObjectIdentifier implements Serializable {
if (componentLen > comp.length) {
componentLen = comp.length;
}
// Check the estimated size before it is too later.
checkOidSize(componentLen);
init(comp, componentLen);
} else {
checkOidSize(encoding.length);
}
}
@ -203,6 +228,8 @@ public final class ObjectIdentifier implements Serializable {
}
start = end + 1;
count++;
checkOidSize(pos);
} while (end != -1);
checkCount(count);
@ -250,11 +277,13 @@ public final class ObjectIdentifier implements Serializable {
);
int len = in.getDefiniteLength();
checkOidSize(len);
if (len > in.available()) {
throw new IOException("ObjectIdentifier() -- length exceeds" +
throw new IOException("ObjectIdentifier length exceeds " +
"data available. Length: " + len + ", Available: " +
in.available());
}
encoding = new byte[len];
in.getBytes(encoding);
check(encoding);
@ -267,26 +296,32 @@ public final class ObjectIdentifier implements Serializable {
*/
ObjectIdentifier(DerInputBuffer buf) throws IOException {
DerInputStream in = new DerInputStream(buf);
encoding = new byte[in.available()];
int len = in.available();
checkOidSize(len);
encoding = new byte[len];
in.getBytes(encoding);
check(encoding);
}
private void init(int[] components, int length) {
private void init(int[] components, int length) throws IOException {
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)
pos += pack7Oid(components[0]*40+components[1], tmp, pos);
else {
if (components[1] < Integer.MAX_VALUE - components[0] * 40) {
pos += pack7Oid(components[0] * 40 + components[1], tmp, pos);
} else {
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);
}
for (int i=2; i<length; i++) {
for (int i = 2; i < length; i++) {
pos += pack7Oid(components[i], tmp, pos);
checkOidSize(pos);
}
encoding = new byte[pos];
System.arraycopy(tmp, 0, encoding, 0, pos);
}
@ -690,4 +725,13 @@ public final class ObjectIdentifier implements Serializable {
"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 + ")");
}
}
}