mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8215712: Parsing extension failure may alert decode_error
Reviewed-by: jnimeh
This commit is contained in:
parent
ef335c75e3
commit
36af90acc0
21 changed files with 313 additions and 429 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
|
@ -72,19 +72,22 @@ final class AlpnExtension {
|
|||
Arrays.asList(applicationProtocols));
|
||||
}
|
||||
|
||||
private AlpnSpec(ByteBuffer buffer) throws IOException {
|
||||
private AlpnSpec(HandshakeContext hc,
|
||||
ByteBuffer buffer) throws IOException {
|
||||
// ProtocolName protocol_name_list<2..2^16-1>, RFC 7301.
|
||||
if (buffer.remaining() < 2) {
|
||||
throw new SSLProtocolException(
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid application_layer_protocol_negotiation: " +
|
||||
"insufficient data (length=" + buffer.remaining() + ")");
|
||||
"insufficient data (length=" + buffer.remaining() + ")"));
|
||||
}
|
||||
|
||||
int listLen = Record.getInt16(buffer);
|
||||
if (listLen < 2 || listLen != buffer.remaining()) {
|
||||
throw new SSLProtocolException(
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid application_layer_protocol_negotiation: " +
|
||||
"incorrect list length (length=" + listLen + ")");
|
||||
"incorrect list length (length=" + listLen + ")"));
|
||||
}
|
||||
|
||||
List<String> protocolNames = new LinkedList<>();
|
||||
|
@ -92,9 +95,10 @@ final class AlpnExtension {
|
|||
// opaque ProtocolName<1..2^8-1>, RFC 7301.
|
||||
byte[] bytes = Record.getBytes8(buffer);
|
||||
if (bytes.length == 0) {
|
||||
throw new SSLProtocolException(
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid application_layer_protocol_negotiation " +
|
||||
"extension: empty application protocol name");
|
||||
"extension: empty application protocol name"));
|
||||
}
|
||||
|
||||
String appProtocol = new String(bytes, StandardCharsets.UTF_8);
|
||||
|
@ -113,9 +117,9 @@ final class AlpnExtension {
|
|||
|
||||
private static final class AlpnStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
return (new AlpnSpec(buffer)).toString();
|
||||
return (new AlpnSpec(hc, buffer)).toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
@ -282,12 +286,7 @@ final class AlpnExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
AlpnSpec spec;
|
||||
try {
|
||||
spec = new AlpnSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
AlpnSpec spec = new AlpnSpec(shc, buffer);
|
||||
|
||||
// Update the context.
|
||||
if (noAPSelector) { // noAlpnProtocols is false
|
||||
|
@ -463,12 +462,7 @@ final class AlpnExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
AlpnSpec spec;
|
||||
try {
|
||||
spec = new AlpnSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
AlpnSpec spec = new AlpnSpec(chc, buffer);
|
||||
|
||||
// Only one application protocol is allowed.
|
||||
if (spec.applicationProtocols.size() != 1) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 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
|
||||
|
@ -56,9 +56,10 @@ final class CertSignAlgsExtension {
|
|||
private static final
|
||||
class CertSignatureSchemesStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
return (new SignatureSchemesSpec(buffer)).toString();
|
||||
return (new SignatureSchemesSpec(hc, buffer))
|
||||
.toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
@ -149,12 +150,7 @@ final class CertSignAlgsExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
SignatureSchemesSpec spec;
|
||||
try {
|
||||
spec = new SignatureSchemesSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
SignatureSchemesSpec spec = new SignatureSchemesSpec(shc, buffer);
|
||||
|
||||
// Update the context.
|
||||
shc.handshakeExtensions.put(
|
||||
|
@ -292,12 +288,7 @@ final class CertSignAlgsExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
SignatureSchemesSpec spec;
|
||||
try {
|
||||
spec = new SignatureSchemesSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
SignatureSchemesSpec spec = new SignatureSchemesSpec(chc, buffer);
|
||||
|
||||
// Update the context.
|
||||
chc.handshakeExtensions.put(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 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
|
||||
|
@ -63,11 +63,13 @@ public class CookieExtension {
|
|||
static class CookieSpec implements SSLExtensionSpec {
|
||||
final byte[] cookie;
|
||||
|
||||
private CookieSpec(ByteBuffer m) throws IOException {
|
||||
private CookieSpec(HandshakeContext hc,
|
||||
ByteBuffer m) throws IOException {
|
||||
// opaque cookie<1..2^16-1>;
|
||||
if (m.remaining() < 3) {
|
||||
throw new SSLProtocolException(
|
||||
"Invalid cookie extension: insufficient data");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid cookie extension: insufficient data"));
|
||||
}
|
||||
|
||||
this.cookie = Record.getBytes16(m);
|
||||
|
@ -90,9 +92,9 @@ public class CookieExtension {
|
|||
|
||||
private static final class CookieStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
return (new CookieSpec(buffer)).toString();
|
||||
return (new CookieSpec(hc, buffer)).toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
@ -159,13 +161,7 @@ public class CookieExtension {
|
|||
return; // ignore the extension
|
||||
}
|
||||
|
||||
CookieSpec spec;
|
||||
try {
|
||||
spec = new CookieSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
CookieSpec spec = new CookieSpec(shc, buffer);
|
||||
shc.handshakeExtensions.put(SSLExtension.CH_COOKIE, spec);
|
||||
|
||||
// No impact on session resumption.
|
||||
|
@ -264,13 +260,7 @@ public class CookieExtension {
|
|||
return; // ignore the extension
|
||||
}
|
||||
|
||||
CookieSpec spec;
|
||||
try {
|
||||
spec = new CookieSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
CookieSpec spec = new CookieSpec(chc, buffer);
|
||||
chc.handshakeExtensions.put(SSLExtension.HRR_COOKIE, spec);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
|
@ -64,11 +64,13 @@ final class ECPointFormatsExtension {
|
|||
this.formats = formats;
|
||||
}
|
||||
|
||||
private ECPointFormatsSpec(ByteBuffer m) throws IOException {
|
||||
private ECPointFormatsSpec(HandshakeContext hc,
|
||||
ByteBuffer m) throws IOException {
|
||||
if (!m.hasRemaining()) {
|
||||
throw new SSLProtocolException(
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid ec_point_formats extension: " +
|
||||
"insufficient data");
|
||||
"insufficient data"));
|
||||
}
|
||||
|
||||
this.formats = Record.getBytes8(m);
|
||||
|
@ -117,9 +119,9 @@ final class ECPointFormatsExtension {
|
|||
|
||||
private static final class ECPointFormatsStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
return (new ECPointFormatsSpec(buffer)).toString();
|
||||
return (new ECPointFormatsSpec(hc, buffer)).toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
@ -227,12 +229,7 @@ final class ECPointFormatsExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
ECPointFormatsSpec spec;
|
||||
try {
|
||||
spec = new ECPointFormatsSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
ECPointFormatsSpec spec = new ECPointFormatsSpec(shc, buffer);
|
||||
|
||||
// per RFC 4492, uncompressed points must always be supported.
|
||||
if (!spec.hasUncompressedFormat()) {
|
||||
|
@ -276,12 +273,7 @@ final class ECPointFormatsExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
ECPointFormatsSpec spec;
|
||||
try {
|
||||
spec = new ECPointFormatsSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
ECPointFormatsSpec spec = new ECPointFormatsSpec(chc, buffer);
|
||||
|
||||
// per RFC 4492, uncompressed points must always be supported.
|
||||
if (!spec.hasUncompressedFormat()) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Red Hat, Inc. and/or its affiliates.
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 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
|
||||
|
@ -68,12 +68,14 @@ final class ExtendedMasterSecretExtension {
|
|||
// blank
|
||||
}
|
||||
|
||||
private ExtendedMasterSecretSpec(ByteBuffer m) throws IOException {
|
||||
private ExtendedMasterSecretSpec(HandshakeContext hc,
|
||||
ByteBuffer m) throws IOException {
|
||||
// Parse the extension.
|
||||
if (m.hasRemaining()) {
|
||||
throw new SSLProtocolException(
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid extended_master_secret extension data: " +
|
||||
"not empty");
|
||||
"not empty"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,9 +88,9 @@ final class ExtendedMasterSecretExtension {
|
|||
private static final
|
||||
class ExtendedMasterSecretStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
return (new ExtendedMasterSecretSpec(buffer)).toString();
|
||||
return (new ExtendedMasterSecretSpec(hc, buffer)).toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
@ -168,13 +170,8 @@ final class ExtendedMasterSecretExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
ExtendedMasterSecretSpec spec;
|
||||
try {
|
||||
spec = new ExtendedMasterSecretSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
ExtendedMasterSecretSpec spec =
|
||||
new ExtendedMasterSecretSpec(shc, buffer);
|
||||
if (shc.isResumption && shc.resumingSession != null &&
|
||||
!shc.resumingSession.useExtendedMasterSecret) {
|
||||
// For abbreviated handshake request, If the original
|
||||
|
@ -323,13 +320,8 @@ final class ExtendedMasterSecretExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
ExtendedMasterSecretSpec spec;
|
||||
try {
|
||||
spec = new ExtendedMasterSecretSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
ExtendedMasterSecretSpec spec =
|
||||
new ExtendedMasterSecretSpec(chc, buffer);
|
||||
if (chc.isResumption && chc.resumingSession != null &&
|
||||
!chc.resumingSession.useExtendedMasterSecret) {
|
||||
throw chc.conContext.fatal(Alert.UNSUPPORTED_EXTENSION,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
|
@ -137,21 +137,24 @@ final class KeyShareExtension {
|
|||
this.clientShares = clientShares;
|
||||
}
|
||||
|
||||
private CHKeyShareSpec(ByteBuffer buffer) throws IOException {
|
||||
private CHKeyShareSpec(HandshakeContext handshakeContext,
|
||||
ByteBuffer buffer) throws IOException {
|
||||
// struct {
|
||||
// KeyShareEntry client_shares<0..2^16-1>;
|
||||
// } KeyShareClientHello;
|
||||
if (buffer.remaining() < 2) {
|
||||
throw new SSLProtocolException(
|
||||
throw handshakeContext.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid key_share extension: " +
|
||||
"insufficient data (length=" + buffer.remaining() + ")");
|
||||
"insufficient data (length=" + buffer.remaining() + ")"));
|
||||
}
|
||||
|
||||
int listLen = Record.getInt16(buffer);
|
||||
if (listLen != buffer.remaining()) {
|
||||
throw new SSLProtocolException(
|
||||
throw handshakeContext.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid key_share extension: " +
|
||||
"incorrect list length (length=" + listLen + ")");
|
||||
"incorrect list length (length=" + listLen + ")"));
|
||||
}
|
||||
|
||||
List<KeyShareEntry> keyShares = new LinkedList<>();
|
||||
|
@ -159,8 +162,9 @@ final class KeyShareExtension {
|
|||
int namedGroupId = Record.getInt16(buffer);
|
||||
byte[] keyExchange = Record.getBytes16(buffer);
|
||||
if (keyExchange.length == 0) {
|
||||
throw new SSLProtocolException(
|
||||
"Invalid key_share extension: empty key_exchange");
|
||||
throw handshakeContext.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid key_share extension: empty key_exchange"));
|
||||
}
|
||||
|
||||
keyShares.add(new KeyShareEntry(namedGroupId, keyExchange));
|
||||
|
@ -189,9 +193,10 @@ final class KeyShareExtension {
|
|||
|
||||
private static final class CHKeyShareStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(
|
||||
HandshakeContext handshakeContext, ByteBuffer buffer) {
|
||||
try {
|
||||
return (new CHKeyShareSpec(buffer)).toString();
|
||||
return (new CHKeyShareSpec(handshakeContext, buffer)).toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
@ -324,13 +329,7 @@ final class KeyShareExtension {
|
|||
}
|
||||
|
||||
// Parse the extension
|
||||
CHKeyShareSpec spec;
|
||||
try {
|
||||
spec = new CHKeyShareSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
CHKeyShareSpec spec = new CHKeyShareSpec(shc, buffer);
|
||||
List<SSLCredentials> credentials = new LinkedList<>();
|
||||
for (KeyShareEntry entry : spec.clientShares) {
|
||||
NamedGroup ng = NamedGroup.valueOf(entry.namedGroupId);
|
||||
|
@ -383,22 +382,25 @@ final class KeyShareExtension {
|
|||
this.serverShare = serverShare;
|
||||
}
|
||||
|
||||
private SHKeyShareSpec(ByteBuffer buffer) throws IOException {
|
||||
private SHKeyShareSpec(HandshakeContext handshakeContext,
|
||||
ByteBuffer buffer) throws IOException {
|
||||
// struct {
|
||||
// KeyShareEntry server_share;
|
||||
// } KeyShareServerHello;
|
||||
if (buffer.remaining() < 5) { // 5: minimal server_share
|
||||
throw new SSLProtocolException(
|
||||
throw handshakeContext.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid key_share extension: " +
|
||||
"insufficient data (length=" + buffer.remaining() + ")");
|
||||
"insufficient data (length=" + buffer.remaining() + ")"));
|
||||
}
|
||||
|
||||
int namedGroupId = Record.getInt16(buffer);
|
||||
byte[] keyExchange = Record.getBytes16(buffer);
|
||||
|
||||
if (buffer.hasRemaining()) {
|
||||
throw new SSLProtocolException(
|
||||
"Invalid key_share extension: unknown extra data");
|
||||
throw handshakeContext.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid key_share extension: unknown extra data"));
|
||||
}
|
||||
|
||||
this.serverShare = new KeyShareEntry(namedGroupId, keyExchange);
|
||||
|
@ -427,9 +429,10 @@ final class KeyShareExtension {
|
|||
|
||||
private static final class SHKeyShareStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext handshakeContext,
|
||||
ByteBuffer buffer) {
|
||||
try {
|
||||
return (new SHKeyShareSpec(buffer)).toString();
|
||||
return (new SHKeyShareSpec(handshakeContext, buffer)).toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
@ -581,13 +584,7 @@ final class KeyShareExtension {
|
|||
}
|
||||
|
||||
// Parse the extension
|
||||
SHKeyShareSpec spec;
|
||||
try {
|
||||
spec = new SHKeyShareSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
SHKeyShareSpec spec = new SHKeyShareSpec(chc, buffer);
|
||||
KeyShareEntry keyShare = spec.serverShare;
|
||||
NamedGroup ng = NamedGroup.valueOf(keyShare.namedGroupId);
|
||||
if (ng == null || !SupportedGroups.isActivatable(
|
||||
|
@ -660,14 +657,16 @@ final class KeyShareExtension {
|
|||
this.selectedGroup = serverGroup.id;
|
||||
}
|
||||
|
||||
private HRRKeyShareSpec(ByteBuffer buffer) throws IOException {
|
||||
private HRRKeyShareSpec(HandshakeContext handshakeContext,
|
||||
ByteBuffer buffer) throws IOException {
|
||||
// struct {
|
||||
// NamedGroup selected_group;
|
||||
// } KeyShareHelloRetryRequest;
|
||||
if (buffer.remaining() != 2) {
|
||||
throw new SSLProtocolException(
|
||||
throw handshakeContext.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid key_share extension: " +
|
||||
"improper data (length=" + buffer.remaining() + ")");
|
||||
"improper data (length=" + buffer.remaining() + ")"));
|
||||
}
|
||||
|
||||
this.selectedGroup = Record.getInt16(buffer);
|
||||
|
@ -687,9 +686,10 @@ final class KeyShareExtension {
|
|||
|
||||
private static final class HRRKeyShareStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext handshakeContext,
|
||||
ByteBuffer buffer) {
|
||||
try {
|
||||
return (new HRRKeyShareSpec(buffer)).toString();
|
||||
return (new HRRKeyShareSpec(handshakeContext, buffer)).toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
@ -833,22 +833,16 @@ final class KeyShareExtension {
|
|||
}
|
||||
|
||||
// Parse the extension
|
||||
HRRKeyShareSpec spec;
|
||||
try {
|
||||
spec = new HRRKeyShareSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
HRRKeyShareSpec spec = new HRRKeyShareSpec(chc, buffer);
|
||||
NamedGroup serverGroup = NamedGroup.valueOf(spec.selectedGroup);
|
||||
if (serverGroup == null) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Unsupported HelloRetryRequest selected group: " +
|
||||
NamedGroup.nameOf(spec.selectedGroup));
|
||||
}
|
||||
|
||||
if (!chc.clientRequestedNamedGroups.contains(serverGroup)) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Unexpected HelloRetryRequest selected group: " +
|
||||
serverGroup.name);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
|
@ -71,10 +71,12 @@ final class MaxFragExtension {
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
private MaxFragLenSpec(ByteBuffer buffer) throws IOException {
|
||||
private MaxFragLenSpec(HandshakeContext hc,
|
||||
ByteBuffer buffer) throws IOException {
|
||||
if (buffer.remaining() != 1) {
|
||||
throw new SSLProtocolException(
|
||||
"Invalid max_fragment_length extension data");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid max_fragment_length extension data"));
|
||||
}
|
||||
|
||||
this.id = buffer.get();
|
||||
|
@ -88,9 +90,9 @@ final class MaxFragExtension {
|
|||
|
||||
private static final class MaxFragLenStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
return (new MaxFragLenSpec(buffer)).toString();
|
||||
return (new MaxFragLenSpec(hc, buffer)).toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
@ -249,13 +251,7 @@ final class MaxFragExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
MaxFragLenSpec spec;
|
||||
try {
|
||||
spec = new MaxFragLenSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
MaxFragLenSpec spec = new MaxFragLenSpec(shc, buffer);
|
||||
MaxFragLenEnum mfle = MaxFragLenEnum.valueOf(spec.id);
|
||||
if (mfle == null) {
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
|
@ -363,13 +359,7 @@ final class MaxFragExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
MaxFragLenSpec spec;
|
||||
try {
|
||||
spec = new MaxFragLenSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
MaxFragLenSpec spec = new MaxFragLenSpec(chc, buffer);
|
||||
if (spec.id != requestedSpec.id) {
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"The maximum fragment length response is not requested");
|
||||
|
@ -535,13 +525,7 @@ final class MaxFragExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
MaxFragLenSpec spec;
|
||||
try {
|
||||
spec = new MaxFragLenSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
MaxFragLenSpec spec = new MaxFragLenSpec(chc, buffer);
|
||||
if (spec.id != requestedSpec.id) {
|
||||
throw chc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"The maximum fragment length response is not requested");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
|
@ -36,6 +36,7 @@ import java.util.Collection;
|
|||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.net.ssl.SSLPeerUnverifiedException;
|
||||
import javax.net.ssl.SSLProtocolException;
|
||||
import static sun.security.ssl.ClientAuthType.CLIENT_AUTH_REQUIRED;
|
||||
import sun.security.ssl.ClientHello.ClientHelloMessage;
|
||||
import sun.security.ssl.SSLExtension.ExtensionConsumer;
|
||||
|
@ -105,23 +106,25 @@ final class PreSharedKeyExtension {
|
|||
this.binders = binders;
|
||||
}
|
||||
|
||||
CHPreSharedKeySpec(HandshakeContext context,
|
||||
CHPreSharedKeySpec(HandshakeContext hc,
|
||||
ByteBuffer m) throws IOException {
|
||||
// struct {
|
||||
// PskIdentity identities<7..2^16-1>;
|
||||
// PskBinderEntry binders<33..2^16-1>;
|
||||
// } OfferedPsks;
|
||||
if (m.remaining() < 44) {
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient data (length=" + m.remaining() + ")");
|
||||
"insufficient data (length=" + m.remaining() + ")"));
|
||||
}
|
||||
|
||||
int idEncodedLength = Record.getInt16(m);
|
||||
if (idEncodedLength < 7) {
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient identities (length=" + idEncodedLength + ")");
|
||||
"insufficient identities (length=" + idEncodedLength + ")"));
|
||||
}
|
||||
|
||||
identities = new ArrayList<>();
|
||||
|
@ -129,9 +132,10 @@ final class PreSharedKeyExtension {
|
|||
while (idReadLength < idEncodedLength) {
|
||||
byte[] id = Record.getBytes16(m);
|
||||
if (id.length < 1) {
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient identity (length=" + id.length + ")");
|
||||
"insufficient identity (length=" + id.length + ")"));
|
||||
}
|
||||
int obfuscatedTicketAge = Record.getInt32(m);
|
||||
|
||||
|
@ -141,18 +145,20 @@ final class PreSharedKeyExtension {
|
|||
}
|
||||
|
||||
if (m.remaining() < 35) {
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient binders data (length=" +
|
||||
m.remaining() + ")");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient binders data (length=" +
|
||||
m.remaining() + ")"));
|
||||
}
|
||||
|
||||
int bindersEncodedLen = Record.getInt16(m);
|
||||
if (bindersEncodedLen < 33) {
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient binders (length=" +
|
||||
bindersEncodedLen + ")");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient binders (length=" +
|
||||
bindersEncodedLen + ")"));
|
||||
}
|
||||
|
||||
binders = new ArrayList<>();
|
||||
|
@ -160,10 +166,11 @@ final class PreSharedKeyExtension {
|
|||
while (bindersReadLength < bindersEncodedLen) {
|
||||
byte[] binder = Record.getBytes8(m);
|
||||
if (binder.length < 32) {
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient binder entry (length=" +
|
||||
binder.length + ")");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient binder entry (length=" +
|
||||
binder.length + ")"));
|
||||
}
|
||||
binders.add(binder);
|
||||
bindersReadLength += 1 + binder.length;
|
||||
|
@ -251,15 +258,9 @@ final class PreSharedKeyExtension {
|
|||
private static final
|
||||
class CHPreSharedKeyStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
// As the HandshakeContext parameter of CHPreSharedKeySpec
|
||||
// constructor is used for fatal alert only, we can use
|
||||
// null HandshakeContext here as we don't care about exception.
|
||||
//
|
||||
// Please take care of this code if the CHPreSharedKeySpec
|
||||
// constructor is updated in the future.
|
||||
return (new CHPreSharedKeySpec(null, buffer)).toString();
|
||||
return (new CHPreSharedKeySpec(hc, buffer)).toString();
|
||||
} catch (Exception ex) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ex.getMessage();
|
||||
|
@ -275,13 +276,14 @@ final class PreSharedKeyExtension {
|
|||
this.selectedIdentity = selectedIdentity;
|
||||
}
|
||||
|
||||
SHPreSharedKeySpec(HandshakeContext context,
|
||||
SHPreSharedKeySpec(HandshakeContext hc,
|
||||
ByteBuffer m) throws IOException {
|
||||
if (m.remaining() < 2) {
|
||||
throw context.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient selected_identity (length=" +
|
||||
m.remaining() + ")");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid pre_shared_key extension: " +
|
||||
"insufficient selected_identity (length=" +
|
||||
m.remaining() + ")"));
|
||||
}
|
||||
this.selectedIdentity = Record.getInt16(m);
|
||||
}
|
||||
|
@ -312,15 +314,9 @@ final class PreSharedKeyExtension {
|
|||
private static final
|
||||
class SHPreSharedKeyStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
// As the HandshakeContext parameter of SHPreSharedKeySpec
|
||||
// constructor is used for fatal alert only, we can use
|
||||
// null HandshakeContext here as we don't care about exception.
|
||||
//
|
||||
// Please take care of this code if the SHPreSharedKeySpec
|
||||
// constructor is updated in the future.
|
||||
return (new SHPreSharedKeySpec(null, buffer)).toString();
|
||||
return (new SHPreSharedKeySpec(hc, buffer)).toString();
|
||||
} catch (Exception ex) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ex.getMessage();
|
||||
|
@ -351,12 +347,7 @@ final class PreSharedKeyExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
CHPreSharedKeySpec pskSpec = null;
|
||||
try {
|
||||
pskSpec = new CHPreSharedKeySpec(shc, buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
CHPreSharedKeySpec pskSpec = new CHPreSharedKeySpec(shc, buffer);
|
||||
|
||||
// The "psk_key_exchange_modes" extension should have been loaded.
|
||||
if (!shc.handshakeExtensions.containsKey(
|
||||
|
@ -388,7 +379,7 @@ final class PreSharedKeyExtension {
|
|||
requestedId.identity.length > SessionId.MAX_LENGTH &&
|
||||
sessionCache.statelessEnabled()) {
|
||||
ByteBuffer b =
|
||||
new SessionTicketSpec(requestedId.identity).
|
||||
new SessionTicketSpec(shc, requestedId.identity).
|
||||
decrypt(shc);
|
||||
if (b != null) {
|
||||
try {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 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
|
||||
|
@ -95,11 +95,13 @@ final class PskKeyExchangeModesExtension {
|
|||
this.modes = modes;
|
||||
}
|
||||
|
||||
PskKeyExchangeModesSpec(ByteBuffer m) throws IOException {
|
||||
PskKeyExchangeModesSpec(HandshakeContext hc,
|
||||
ByteBuffer m) throws IOException {
|
||||
if (m.remaining() < 2) {
|
||||
throw new SSLProtocolException(
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid psk_key_exchange_modes extension: " +
|
||||
"insufficient data");
|
||||
"insufficient data"));
|
||||
}
|
||||
|
||||
this.modes = Record.getBytes8(m);
|
||||
|
@ -151,9 +153,9 @@ final class PskKeyExchangeModesExtension {
|
|||
private static final
|
||||
class PskKeyExchangeModesStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
return (new PskKeyExchangeModesSpec(buffer)).toString();
|
||||
return (new PskKeyExchangeModesSpec(hc, buffer)).toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
@ -197,12 +199,8 @@ final class PskKeyExchangeModesExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
PskKeyExchangeModesSpec spec;
|
||||
try {
|
||||
spec = new PskKeyExchangeModesSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
PskKeyExchangeModesSpec spec =
|
||||
new PskKeyExchangeModesSpec(shc, buffer);
|
||||
|
||||
// Update the context.
|
||||
shc.handshakeExtensions.put(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
|
@ -74,12 +74,14 @@ final class RenegoInfoExtension {
|
|||
renegotiatedConnection, renegotiatedConnection.length);
|
||||
}
|
||||
|
||||
private RenegotiationInfoSpec(ByteBuffer m) throws IOException {
|
||||
private RenegotiationInfoSpec(HandshakeContext hc,
|
||||
ByteBuffer m) throws IOException {
|
||||
// Parse the extension.
|
||||
if (!m.hasRemaining() || m.remaining() < 1) {
|
||||
throw new SSLProtocolException(
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid renegotiation_info extension data: " +
|
||||
"insufficient data");
|
||||
"insufficient data"));
|
||||
}
|
||||
this.renegotiatedConnection = Record.getBytes8(m);
|
||||
}
|
||||
|
@ -105,9 +107,9 @@ final class RenegoInfoExtension {
|
|||
private static final
|
||||
class RenegotiationInfoStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
return (new RenegotiationInfoSpec(buffer)).toString();
|
||||
return (new RenegotiationInfoSpec(hc, buffer)).toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
@ -220,13 +222,7 @@ final class RenegoInfoExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
RenegotiationInfoSpec spec;
|
||||
try {
|
||||
spec = new RenegotiationInfoSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
RenegotiationInfoSpec spec = new RenegotiationInfoSpec(shc, buffer);
|
||||
if (!shc.conContext.isNegotiated) {
|
||||
// initial handshaking.
|
||||
if (spec.renegotiatedConnection.length != 0) {
|
||||
|
@ -433,14 +429,7 @@ final class RenegoInfoExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
RenegotiationInfoSpec spec;
|
||||
try {
|
||||
spec = new RenegotiationInfoSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
|
||||
RenegotiationInfoSpec spec = new RenegotiationInfoSpec(chc, buffer);
|
||||
if (!chc.conContext.isNegotiated) { // initial handshake
|
||||
// If the extension is present, set the secure_renegotiation
|
||||
// flag to TRUE. The client MUST then verify that the
|
||||
|
|
|
@ -641,7 +641,8 @@ enum SSLExtension implements SSLStringizer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String toString(ByteBuffer byteBuffer) {
|
||||
public String toString(
|
||||
HandshakeContext handshakeContext, ByteBuffer byteBuffer) {
|
||||
MessageFormat messageFormat = new MessageFormat(
|
||||
"\"{0} ({1})\": '{'\n" +
|
||||
"{2}\n" +
|
||||
|
@ -654,7 +655,7 @@ enum SSLExtension implements SSLStringizer {
|
|||
String encoded = hexEncoder.encode(byteBuffer.duplicate());
|
||||
extData = encoded;
|
||||
} else {
|
||||
extData = stringizer.toString(byteBuffer);
|
||||
extData = stringizer.toString(handshakeContext, byteBuffer);
|
||||
}
|
||||
|
||||
Object[] messageFields = {
|
||||
|
|
|
@ -346,7 +346,8 @@ final class SSLExtensions {
|
|||
}
|
||||
if (ext != null) {
|
||||
builder.append(
|
||||
ext.toString(ByteBuffer.wrap(en.getValue())));
|
||||
ext.toString(handshakeMessage.handshakeContext,
|
||||
ByteBuffer.wrap(en.getValue())));
|
||||
} else {
|
||||
builder.append(toString(en.getKey(), en.getValue()));
|
||||
}
|
||||
|
@ -359,7 +360,8 @@ final class SSLExtensions {
|
|||
builder.append(",\n");
|
||||
}
|
||||
builder.append(
|
||||
en.getKey().toString(ByteBuffer.wrap(en.getValue())));
|
||||
en.getKey().toString(handshakeMessage.handshakeContext,
|
||||
ByteBuffer.wrap(en.getValue())));
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 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
|
||||
|
@ -37,5 +37,5 @@ interface SSLStringizer {
|
|||
* Note that the implementation MUST not change the internal status of
|
||||
* the {@code buffer}.
|
||||
*/
|
||||
String toString(ByteBuffer buffer);
|
||||
String toString(HandshakeContext handshakeContext, ByteBuffer buffer);
|
||||
}
|
||||
|
|
|
@ -49,8 +49,6 @@ import sun.security.ssl.SSLCipher.SSLWriteCipher;
|
|||
import sun.security.ssl.SSLHandshake.HandshakeMessage;
|
||||
import sun.security.ssl.SupportedVersionsExtension.SHSupportedVersionsSpec;
|
||||
|
||||
import static sun.security.ssl.SSLExtension.SH_SESSION_TICKET;
|
||||
|
||||
/**
|
||||
* Pack of the ServerHello/HelloRetryRequest handshake message.
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
|
@ -93,16 +93,19 @@ final class ServerNameExtension {
|
|||
new ArrayList<>(serverNames));
|
||||
}
|
||||
|
||||
private CHServerNamesSpec(ByteBuffer buffer) throws IOException {
|
||||
private CHServerNamesSpec(HandshakeContext hc,
|
||||
ByteBuffer buffer) throws IOException {
|
||||
if (buffer.remaining() < 2) {
|
||||
throw new SSLProtocolException(
|
||||
"Invalid server_name extension: insufficient data");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid server_name extension: insufficient data"));
|
||||
}
|
||||
|
||||
int sniLen = Record.getInt16(buffer);
|
||||
if ((sniLen == 0) || sniLen != buffer.remaining()) {
|
||||
throw new SSLProtocolException(
|
||||
"Invalid server_name extension: incomplete data");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid server_name extension: incomplete data"));
|
||||
}
|
||||
|
||||
Map<Integer, SNIServerName> sniMap = new LinkedHashMap<>();
|
||||
|
@ -121,8 +124,9 @@ final class ServerNameExtension {
|
|||
byte[] encoded = Record.getBytes16(buffer);
|
||||
if (nameType == StandardConstants.SNI_HOST_NAME) {
|
||||
if (encoded.length == 0) {
|
||||
throw new SSLProtocolException(
|
||||
"Empty HostName in server_name extension");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Empty HostName in server_name extension"));
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -134,7 +138,8 @@ final class ServerNameExtension {
|
|||
(new String(encoded, StandardCharsets.UTF_8)) +
|
||||
", value={" +
|
||||
Utilities.toHexString(encoded) + "}");
|
||||
throw (SSLProtocolException)spe.initCause(iae);
|
||||
throw hc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
(SSLProtocolException)spe.initCause(iae));
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
|
@ -144,15 +149,17 @@ final class ServerNameExtension {
|
|||
"Illegal server name, type=(" + nameType +
|
||||
"), value={" +
|
||||
Utilities.toHexString(encoded) + "}");
|
||||
throw (SSLProtocolException)spe.initCause(iae);
|
||||
throw hc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
(SSLProtocolException)spe.initCause(iae));
|
||||
}
|
||||
}
|
||||
|
||||
// check for duplicated server name type
|
||||
if (sniMap.put(serverName.getType(), serverName) != null) {
|
||||
throw new SSLProtocolException(
|
||||
throw hc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
new SSLProtocolException(
|
||||
"Duplicated server name of type " +
|
||||
serverName.getType());
|
||||
serverName.getType()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,9 +190,9 @@ final class ServerNameExtension {
|
|||
|
||||
private static final class CHServerNamesStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
return (new CHServerNamesSpec(buffer)).toString();
|
||||
return (new CHServerNamesSpec(hc, buffer)).toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
@ -291,12 +298,7 @@ final class ServerNameExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
CHServerNamesSpec spec;
|
||||
try {
|
||||
spec = new CHServerNamesSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
CHServerNamesSpec spec = new CHServerNamesSpec(shc, buffer);
|
||||
|
||||
// Update the context.
|
||||
shc.handshakeExtensions.put(CH_SERVER_NAME, spec);
|
||||
|
@ -390,10 +392,12 @@ final class ServerNameExtension {
|
|||
// blank
|
||||
}
|
||||
|
||||
private SHServerNamesSpec(ByteBuffer buffer) throws IOException {
|
||||
private SHServerNamesSpec(HandshakeContext hc,
|
||||
ByteBuffer buffer) throws IOException {
|
||||
if (buffer.remaining() != 0) {
|
||||
throw new SSLProtocolException(
|
||||
"Invalid ServerHello server_name extension: not empty");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid ServerHello server_name extension: not empty"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -405,9 +409,9 @@ final class ServerNameExtension {
|
|||
|
||||
private static final class SHServerNamesStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
return (new SHServerNamesSpec(buffer)).toString();
|
||||
return (new SHServerNamesSpec(hc, buffer)).toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 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
|
||||
|
@ -237,18 +237,21 @@ final class SessionTicketExtension {
|
|||
data = zero;
|
||||
}
|
||||
|
||||
SessionTicketSpec(byte[] b) throws IOException {
|
||||
this(ByteBuffer.wrap(b));
|
||||
SessionTicketSpec(HandshakeContext hc, byte[] b) throws IOException {
|
||||
this(hc, ByteBuffer.wrap(b));
|
||||
}
|
||||
|
||||
SessionTicketSpec(ByteBuffer buf) throws IOException {
|
||||
SessionTicketSpec(HandshakeContext hc,
|
||||
ByteBuffer buf) throws IOException {
|
||||
if (buf == null) {
|
||||
throw new SSLProtocolException(
|
||||
"SessionTicket buffer too small");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"SessionTicket buffer too small"));
|
||||
}
|
||||
if (buf.remaining() > 65536) {
|
||||
throw new SSLProtocolException(
|
||||
"SessionTicket buffer too large. " + buf.remaining());
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"SessionTicket buffer too large. " + buf.remaining()));
|
||||
}
|
||||
|
||||
data = buf;
|
||||
|
@ -366,12 +369,10 @@ final class SessionTicketExtension {
|
|||
}
|
||||
|
||||
static final class SessionTicketStringizer implements SSLStringizer {
|
||||
SessionTicketStringizer() {}
|
||||
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
return new SessionTicketSpec(buffer).toString();
|
||||
return new SessionTicketSpec(hc, buffer).toString();
|
||||
} catch (IOException e) {
|
||||
return e.getMessage();
|
||||
}
|
||||
|
@ -455,16 +456,7 @@ final class SessionTicketExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
SessionTicketSpec spec;
|
||||
try {
|
||||
spec = new SessionTicketSpec(buffer);
|
||||
} catch (IOException | RuntimeException e) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine("SessionTicket data invalid. Doing full " +
|
||||
"handshake.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
SessionTicketSpec spec = new SessionTicketSpec(shc, buffer);
|
||||
ByteBuffer b = spec.decrypt(shc);
|
||||
if (b != null) {
|
||||
shc.resumingSession = new SSLSessionImpl(shc, b);
|
||||
|
@ -531,14 +523,8 @@ final class SessionTicketExtension {
|
|||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (new SessionTicketSpec(buffer) == null) {
|
||||
return;
|
||||
}
|
||||
chc.statelessResumption = true;
|
||||
} catch (IOException e) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, e);
|
||||
}
|
||||
SessionTicketSpec spec = new SessionTicketSpec(chc, buffer);
|
||||
chc.statelessResumption = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
|
@ -82,21 +82,25 @@ final class SignatureAlgorithmsExtension {
|
|||
}
|
||||
}
|
||||
|
||||
SignatureSchemesSpec(ByteBuffer buffer) throws IOException {
|
||||
SignatureSchemesSpec(HandshakeContext hc,
|
||||
ByteBuffer buffer) throws IOException {
|
||||
if (buffer.remaining() < 2) { // 2: the length of the list
|
||||
throw new SSLProtocolException(
|
||||
"Invalid signature_algorithms: insufficient data");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid signature_algorithms: insufficient data"));
|
||||
}
|
||||
|
||||
byte[] algs = Record.getBytes16(buffer);
|
||||
if (buffer.hasRemaining()) {
|
||||
throw new SSLProtocolException(
|
||||
"Invalid signature_algorithms: unknown extra data");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid signature_algorithms: unknown extra data"));
|
||||
}
|
||||
|
||||
if (algs == null || algs.length == 0 || (algs.length & 0x01) != 0) {
|
||||
throw new SSLProtocolException(
|
||||
"Invalid signature_algorithms: incomplete data");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid signature_algorithms: incomplete data"));
|
||||
}
|
||||
|
||||
int[] schemes = new int[algs.length / 2];
|
||||
|
@ -144,9 +148,9 @@ final class SignatureAlgorithmsExtension {
|
|||
private static final
|
||||
class SignatureSchemesStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
return (new SignatureSchemesSpec(buffer)).toString();
|
||||
return (new SignatureSchemesSpec(hc, buffer)).toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
@ -234,12 +238,7 @@ final class SignatureAlgorithmsExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
SignatureSchemesSpec spec;
|
||||
try {
|
||||
spec = new SignatureSchemesSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
SignatureSchemesSpec spec = new SignatureSchemesSpec(shc, buffer);
|
||||
|
||||
// Update the context.
|
||||
shc.handshakeExtensions.put(
|
||||
|
@ -458,12 +457,7 @@ final class SignatureAlgorithmsExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
SignatureSchemesSpec spec;
|
||||
try {
|
||||
spec = new SignatureSchemesSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
SignatureSchemesSpec spec = new SignatureSchemesSpec(chc, buffer);
|
||||
|
||||
List<SignatureScheme> knownSignatureSchemes = new LinkedList<>();
|
||||
for (int id : spec.signatureSchemes) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
|
@ -78,21 +78,25 @@ final class SupportedGroupsExtension {
|
|||
}
|
||||
}
|
||||
|
||||
private SupportedGroupsSpec(ByteBuffer m) throws IOException {
|
||||
private SupportedGroupsSpec(HandshakeContext hc,
|
||||
ByteBuffer m) throws IOException {
|
||||
if (m.remaining() < 2) { // 2: the length of the list
|
||||
throw new SSLProtocolException(
|
||||
"Invalid supported_groups extension: insufficient data");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid supported_groups extension: insufficient data"));
|
||||
}
|
||||
|
||||
byte[] ngs = Record.getBytes16(m);
|
||||
if (m.hasRemaining()) {
|
||||
throw new SSLProtocolException(
|
||||
"Invalid supported_groups extension: unknown extra data");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid supported_groups extension: unknown extra data"));
|
||||
}
|
||||
|
||||
if ((ngs == null) || (ngs.length == 0) || (ngs.length % 2 != 0)) {
|
||||
throw new SSLProtocolException(
|
||||
"Invalid supported_groups extension: incomplete data");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid supported_groups extension: incomplete data"));
|
||||
}
|
||||
|
||||
int[] ids = new int[ngs.length / 2];
|
||||
|
@ -138,9 +142,9 @@ final class SupportedGroupsExtension {
|
|||
private static final
|
||||
class SupportedGroupsStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
return (new SupportedGroupsSpec(buffer)).toString();
|
||||
return (new SupportedGroupsSpec(hc, buffer)).toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
@ -414,12 +418,7 @@ final class SupportedGroupsExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
SupportedGroupsSpec spec;
|
||||
try {
|
||||
spec = new SupportedGroupsSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
SupportedGroupsSpec spec = new SupportedGroupsSpec(shc, buffer);
|
||||
|
||||
// Update the context.
|
||||
List<NamedGroup> knownNamedGroups = new LinkedList<>();
|
||||
|
@ -535,12 +534,7 @@ final class SupportedGroupsExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
SupportedGroupsSpec spec;
|
||||
try {
|
||||
spec = new SupportedGroupsSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
SupportedGroupsSpec spec = new SupportedGroupsSpec(chc, buffer);
|
||||
|
||||
// Update the context.
|
||||
List<NamedGroup> knownNamedGroups =
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 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
|
||||
|
@ -73,22 +73,26 @@ final class SupportedVersionsExtension {
|
|||
this.requestedProtocols = requestedProtocols;
|
||||
}
|
||||
|
||||
private CHSupportedVersionsSpec(ByteBuffer m) throws IOException {
|
||||
private CHSupportedVersionsSpec(HandshakeContext hc,
|
||||
ByteBuffer m) throws IOException {
|
||||
if (m.remaining() < 3) { // 1: the length of the list
|
||||
// +2: one version at least
|
||||
throw new SSLProtocolException(
|
||||
"Invalid supported_versions extension: insufficient data");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid supported_versions extension: insufficient data"));
|
||||
}
|
||||
|
||||
byte[] vbs = Record.getBytes8(m); // Get the version bytes.
|
||||
if (m.hasRemaining()) {
|
||||
throw new SSLProtocolException(
|
||||
"Invalid supported_versions extension: unknown extra data");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid supported_versions extension: unknown extra data"));
|
||||
}
|
||||
|
||||
if (vbs == null || vbs.length == 0 || (vbs.length & 0x01) != 0) {
|
||||
throw new SSLProtocolException(
|
||||
"Invalid supported_versions extension: incomplete data");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid supported_versions extension: incomplete data"));
|
||||
}
|
||||
|
||||
int[] protocols = new int[vbs.length >> 1];
|
||||
|
@ -136,9 +140,9 @@ final class SupportedVersionsExtension {
|
|||
private static final
|
||||
class CHSupportedVersionsStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
return (new CHSupportedVersionsSpec(buffer)).toString();
|
||||
return (new CHSupportedVersionsSpec(hc, buffer)).toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
@ -221,12 +225,8 @@ final class SupportedVersionsExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
CHSupportedVersionsSpec spec;
|
||||
try {
|
||||
spec = new CHSupportedVersionsSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
CHSupportedVersionsSpec spec =
|
||||
new CHSupportedVersionsSpec(shc, buffer);
|
||||
|
||||
// Update the context.
|
||||
shc.handshakeExtensions.put(CH_SUPPORTED_VERSIONS, spec);
|
||||
|
@ -249,10 +249,12 @@ final class SupportedVersionsExtension {
|
|||
this.selectedVersion = selectedVersion.id;
|
||||
}
|
||||
|
||||
private SHSupportedVersionsSpec(ByteBuffer m) throws IOException {
|
||||
private SHSupportedVersionsSpec(HandshakeContext hc,
|
||||
ByteBuffer m) throws IOException {
|
||||
if (m.remaining() != 2) { // 2: the selected version
|
||||
throw new SSLProtocolException(
|
||||
"Invalid supported_versions: insufficient data");
|
||||
throw hc.conContext.fatal(Alert.DECODE_ERROR,
|
||||
new SSLProtocolException(
|
||||
"Invalid supported_versions: insufficient data"));
|
||||
}
|
||||
|
||||
byte major = m.get();
|
||||
|
@ -275,9 +277,9 @@ final class SupportedVersionsExtension {
|
|||
private static final
|
||||
class SHSupportedVersionsStringizer implements SSLStringizer {
|
||||
@Override
|
||||
public String toString(ByteBuffer buffer) {
|
||||
public String toString(HandshakeContext hc, ByteBuffer buffer) {
|
||||
try {
|
||||
return (new SHSupportedVersionsSpec(buffer)).toString();
|
||||
return (new SHSupportedVersionsSpec(hc, buffer)).toString();
|
||||
} catch (IOException ioe) {
|
||||
// For debug logging only, so please swallow exceptions.
|
||||
return ioe.getMessage();
|
||||
|
@ -363,12 +365,8 @@ final class SupportedVersionsExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
SHSupportedVersionsSpec spec;
|
||||
try {
|
||||
spec = new SHSupportedVersionsSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
SHSupportedVersionsSpec spec =
|
||||
new SHSupportedVersionsSpec(chc, buffer);
|
||||
|
||||
// Update the context.
|
||||
chc.handshakeExtensions.put(SH_SUPPORTED_VERSIONS, spec);
|
||||
|
@ -452,12 +450,8 @@ final class SupportedVersionsExtension {
|
|||
}
|
||||
|
||||
// Parse the extension.
|
||||
SHSupportedVersionsSpec spec;
|
||||
try {
|
||||
spec = new SHSupportedVersionsSpec(buffer);
|
||||
} catch (IOException ioe) {
|
||||
throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
SHSupportedVersionsSpec spec =
|
||||
new SHSupportedVersionsSpec(chc, buffer);
|
||||
|
||||
// Update the context.
|
||||
chc.handshakeExtensions.put(HRR_SUPPORTED_VERSIONS, spec);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 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
|
||||
|
@ -43,7 +43,7 @@ import javax.net.ssl.SSLSocket;
|
|||
/**
|
||||
* SSL/(D)TLS transportation context.
|
||||
*/
|
||||
class TransportContext implements ConnectionContext {
|
||||
final class TransportContext implements ConnectionContext {
|
||||
final SSLTransport transport;
|
||||
|
||||
// registered plaintext consumers
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue