8215712: Parsing extension failure may alert decode_error

Reviewed-by: jnimeh
This commit is contained in:
Xue-Lei Andrew Fan 2020-03-22 09:30:16 -07:00
parent ef335c75e3
commit 36af90acc0
21 changed files with 313 additions and 429 deletions

View file

@ -121,7 +121,8 @@ final class CertStatusExtension {
this.statusRequest = statusRequest;
}
private CertStatusRequestSpec(ByteBuffer buffer) throws IOException {
private CertStatusRequestSpec(HandshakeContext hc,
ByteBuffer buffer) throws IOException {
// Is it a empty extension_data?
if (buffer.remaining() == 0) {
// server response
@ -130,8 +131,9 @@ final class CertStatusExtension {
}
if (buffer.remaining() < 1) {
throw new SSLProtocolException(
"Invalid status_request extension: insufficient data");
throw hc.conContext.fatal(Alert.DECODE_ERROR,
new SSLProtocolException(
"Invalid status_request extension: insufficient data"));
}
byte statusType = (byte)Record.getInt8(buffer);
@ -178,10 +180,12 @@ final class CertStatusExtension {
this.statusResponse = resp;
}
private CertStatusResponseSpec(ByteBuffer buffer) throws IOException {
private CertStatusResponseSpec(HandshakeContext hc,
ByteBuffer buffer) throws IOException {
if (buffer.remaining() < 2) {
throw new SSLProtocolException(
"Invalid status_request extension: insufficient data");
throw hc.conContext.fatal(Alert.DECODE_ERROR,
new SSLProtocolException(
"Invalid status_request extension: insufficient data"));
}
// Get the status type (1 byte) and response data (vector)
@ -212,9 +216,9 @@ final class CertStatusExtension {
private static final
class CertStatusRequestStringizer implements SSLStringizer {
@Override
public String toString(ByteBuffer buffer) {
public String toString(HandshakeContext hc, ByteBuffer buffer) {
try {
return (new CertStatusRequestSpec(buffer)).toString();
return (new CertStatusRequestSpec(hc, buffer)).toString();
} catch (IOException ioe) {
// For debug logging only, so please swallow exceptions.
return ioe.getMessage();
@ -225,9 +229,9 @@ final class CertStatusExtension {
private static final
class CertStatusRespStringizer implements SSLStringizer {
@Override
public String toString(ByteBuffer buffer) {
public String toString(HandshakeContext hc, ByteBuffer buffer) {
try {
return (new CertStatusResponseSpec(buffer)).toString();
return (new CertStatusResponseSpec(hc, buffer)).toString();
} catch (IOException ioe) {
// For debug logging only, so please swallow exceptions.
return ioe.getMessage();
@ -599,12 +603,7 @@ final class CertStatusExtension {
}
// Parse the extension.
CertStatusRequestSpec spec;
try {
spec = new CertStatusRequestSpec(buffer);
} catch (IOException ioe) {
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
}
CertStatusRequestSpec spec = new CertStatusRequestSpec(shc, buffer);
// Update the context.
shc.handshakeExtensions.put(SSLExtension.CH_STATUS_REQUEST, spec);
@ -776,7 +775,8 @@ final class CertStatusExtension {
this.certStatusRequests = certStatusRequests;
}
private CertStatusRequestV2Spec(ByteBuffer message) throws IOException {
private CertStatusRequestV2Spec(HandshakeContext hc,
ByteBuffer message) throws IOException {
// Is it a empty extension_data?
if (message.remaining() == 0) {
// server response
@ -787,15 +787,17 @@ final class CertStatusExtension {
if (message.remaining() < 5) { // 2: certificate_status_req_list
// +1: status_type
// +2: request_length
throw new SSLProtocolException(
"Invalid status_request_v2 extension: insufficient data");
throw hc.conContext.fatal(Alert.DECODE_ERROR,
new SSLProtocolException(
"Invalid status_request_v2 extension: insufficient data"));
}
int listLen = Record.getInt16(message);
if (listLen <= 0) {
throw new SSLProtocolException(
throw hc.conContext.fatal(Alert.DECODE_ERROR,
new SSLProtocolException(
"certificate_status_req_list length must be positive " +
"(received length: " + listLen + ")");
"(received length: " + listLen + ")"));
}
int remaining = listLen;
@ -805,10 +807,12 @@ final class CertStatusExtension {
int requestLen = Record.getInt16(message);
if (message.remaining() < requestLen) {
throw new SSLProtocolException(
throw hc.conContext.fatal(
Alert.DECODE_ERROR,
new SSLProtocolException(
"Invalid status_request_v2 extension: " +
"insufficient data (request_length=" + requestLen +
", remining=" + message.remaining() + ")");
", remining=" + message.remaining() + ")"));
}
byte[] encoded = new byte[requestLen];
@ -823,9 +827,11 @@ final class CertStatusExtension {
if (encoded.length < 4) {
// 2: length of responder_id_list
// +2: length of request_extensions
throw new SSLProtocolException(
throw hc.conContext.fatal(
Alert.DECODE_ERROR,
new SSLProtocolException(
"Invalid status_request_v2 extension: " +
"insufficient data");
"insufficient data"));
}
statusRequests.add(
new OCSPStatusRequest(statusType, encoded));
@ -874,9 +880,9 @@ final class CertStatusExtension {
private static final
class CertStatusRequestsStringizer implements SSLStringizer {
@Override
public String toString(ByteBuffer buffer) {
public String toString(HandshakeContext hc, ByteBuffer buffer) {
try {
return (new CertStatusRequestV2Spec(buffer)).toString();
return (new CertStatusRequestV2Spec(hc, buffer)).toString();
} catch (IOException ioe) {
// For debug logging only, so please swallow exceptions.
return ioe.getMessage();
@ -957,12 +963,7 @@ final class CertStatusExtension {
}
// Parse the extension.
CertStatusRequestV2Spec spec;
try {
spec = new CertStatusRequestV2Spec(buffer);
} catch (IOException ioe) {
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
}
CertStatusRequestV2Spec spec = new CertStatusRequestV2Spec(shc, buffer);
// Update the context.
shc.handshakeExtensions.put(SSLExtension.CH_STATUS_REQUEST_V2,
@ -1185,12 +1186,7 @@ final class CertStatusExtension {
ClientHandshakeContext chc = (ClientHandshakeContext)context;
// Parse the extension.
CertStatusResponseSpec spec;
try {
spec = new CertStatusResponseSpec(buffer);
} catch (IOException ioe) {
throw chc.conContext.fatal(Alert.DECODE_ERROR, ioe);
}
CertStatusResponseSpec spec = new CertStatusResponseSpec(chc, buffer);
if (chc.sslContext.isStaplingEnabled(true)) {
// Activate stapling