This commit is contained in:
Jesper Wilhelmsson 2018-08-29 19:48:28 +02:00
commit d40735db17
25 changed files with 1004 additions and 130 deletions

View file

@ -191,12 +191,12 @@ final class CertSignAlgsExtension {
}
// update the context
List<SignatureScheme> shemes =
List<SignatureScheme> schemes =
SignatureScheme.getSupportedAlgorithms(
shc.algorithmConstraints, shc.negotiatedProtocol,
spec.signatureSchemes);
shc.peerRequestedCertSignSchemes = shemes;
shc.handshakeSession.setPeerSupportedSignatureAlgorithms(shemes);
shc.peerRequestedCertSignSchemes = schemes;
shc.handshakeSession.setPeerSupportedSignatureAlgorithms(schemes);
if (!shc.isResumption && shc.negotiatedProtocol.useTLS13PlusSpec()) {
if (shc.sslConfig.clientAuthType !=
@ -337,12 +337,12 @@ final class CertSignAlgsExtension {
}
// update the context
List<SignatureScheme> shemes =
List<SignatureScheme> schemes =
SignatureScheme.getSupportedAlgorithms(
chc.algorithmConstraints, chc.negotiatedProtocol,
spec.signatureSchemes);
chc.peerRequestedCertSignSchemes = shemes;
chc.handshakeSession.setPeerSupportedSignatureAlgorithms(shemes);
chc.peerRequestedCertSignSchemes = schemes;
chc.handshakeSession.setPeerSupportedSignatureAlgorithms(schemes);
}
}
}

View file

@ -1031,8 +1031,8 @@ final class CertificateMessage {
// Don't select a signature scheme unless we will be able to
// produce a CertificateVerify message later
if (SignatureScheme.getPreferableAlgorithm(
hc.peerRequestedSignatureSchemes,
ss, hc.negotiatedProtocol) == null) {
hc.peerRequestedSignatureSchemes,
ss, hc.negotiatedProtocol) == null) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.warning(

View file

@ -50,7 +50,7 @@ public class HandshakeOutStream extends ByteArrayOutputStream {
this.outputRecord = outputRecord;
}
// Complete a handshakin message writing. Called by HandshakeMessage.
// Complete a handshaking message write. Called by HandshakeMessage.
void complete() throws IOException {
if (size() < 4) { // 4: handshake message header size
// internal_error alert will be triggered

View file

@ -379,10 +379,10 @@ enum SSLCipher {
private final Map.Entry<WriteCipherGenerator,
ProtocolVersion[]>[] writeCipherGenerators;
// Map of Ciphers listed in jdk.tls.KeyLimit
// Map of Ciphers listed in jdk.tls.keyLimits
private static final HashMap<String, Long> cipherLimits = new HashMap<>();
// Keywords found on the jdk.tls.KeyLimit security property.
// Keywords found on the jdk.tls.keyLimits security property.
final static String tag[] = {"KEYUPDATE"};
static {
@ -407,7 +407,7 @@ enum SSLCipher {
index = 0;
} else {
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
SSLLogger.fine("jdk.net.keyLimits: Unknown action: " +
SSLLogger.fine("jdk.tls.keyLimits: Unknown action: " +
entry);
}
continue;
@ -423,17 +423,18 @@ enum SSLCipher {
size = Long.parseLong(values[2]);
}
if (size < 1 || size > max) {
throw new NumberFormatException("Length exceeded limits");
throw new NumberFormatException(
"Length exceeded limits");
}
} catch (NumberFormatException e) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
SSLLogger.fine("jdk.net.keyLimits: " + e.getMessage() +
SSLLogger.fine("jdk.tls.keyLimits: " + e.getMessage() +
": " + entry);
}
continue;
}
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
SSLLogger.fine("jdk.net.keyLimits: entry = " + entry +
SSLLogger.fine("jdk.tls.keyLimits: entry = " + entry +
". " + values[0] + ":" + tag[index] + " = " + size);
}
cipherLimits.put(values[0] + ":" + tag[index], size);

View file

@ -127,9 +127,7 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
}
// See if the handshaker needs to report back some SSLException.
if (conContext.outputRecord.isEmpty()) {
checkTaskThrown();
} // Otherwise, deliver cached records before throwing task exception.
checkTaskThrown();
// check parameters
checkParams(srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength);
@ -896,18 +894,58 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
return true;
}
/*
* Depending on whether the error was just a warning and the
* handshaker wasn't closed, or fatal and the handshaker is now
* null, report back the Exception that happened in the delegated
* task(s).
*/
private synchronized void checkTaskThrown() throws SSLException {
Exception exc = null;
// First check the handshake context.
HandshakeContext hc = conContext.handshakeContext;
if (hc != null && hc.delegatedThrown != null) {
try {
throw getTaskThrown(hc.delegatedThrown);
} finally {
hc.delegatedThrown = null;
if ((hc != null) && (hc.delegatedThrown != null)) {
exc = hc.delegatedThrown;
hc.delegatedThrown = null;
}
/*
* hc.delegatedThrown and conContext.delegatedThrown are most likely
* the same, but it's possible we could have had a non-fatal
* exception and thus the new HandshakeContext is still valid
* (alert warning). If so, then we may have a secondary exception
* waiting to be reported from the TransportContext, so we will
* need to clear that on a successive call. Otherwise, clear it now.
*/
if (conContext.delegatedThrown != null) {
if (exc != null) {
// hc object comparison
if (conContext.delegatedThrown == exc) {
// clear if/only if both are the same
conContext.delegatedThrown = null;
} // otherwise report the hc delegatedThrown
} else {
// Nothing waiting in HandshakeContext, but one is in the
// TransportContext.
exc = conContext.delegatedThrown;
conContext.delegatedThrown = null;
}
}
if (conContext.isBroken && conContext.closeReason != null) {
throw getTaskThrown(conContext.closeReason);
// Anything to report?
if (exc == null) {
return;
}
// If it wasn't a RuntimeException/SSLException, need to wrap it.
if (exc instanceof SSLException) {
throw (SSLException)exc;
} else if (exc instanceof RuntimeException) {
throw (RuntimeException)exc;
} else {
throw getTaskThrown(exc);
}
}
@ -963,20 +1001,41 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
} catch (PrivilegedActionException pae) {
// Get the handshake context again in case the
// handshaking has completed.
Exception reportedException = pae.getException();
// Report to both the TransportContext...
if (engine.conContext.delegatedThrown == null) {
engine.conContext.delegatedThrown = reportedException;
}
// ...and the HandshakeContext in case condition
// wasn't fatal and the handshakeContext is still
// around.
hc = engine.conContext.handshakeContext;
if (hc != null) {
hc.delegatedThrown = pae.getException();
hc.delegatedThrown = reportedException;
} else if (engine.conContext.closeReason != null) {
// Update the reason in case there was a previous.
engine.conContext.closeReason =
getTaskThrown(pae.getException());
getTaskThrown(reportedException);
}
} catch (RuntimeException rte) {
// Get the handshake context again in case the
// handshaking has completed.
// Report to both the TransportContext...
if (engine.conContext.delegatedThrown == null) {
engine.conContext.delegatedThrown = rte;
}
// ...and the HandshakeContext in case condition
// wasn't fatal and the handshakeContext is still
// around.
hc = engine.conContext.handshakeContext;
if (hc != null) {
hc.delegatedThrown = rte;
} else if (engine.conContext.closeReason != null) {
// Update the reason in case there was a previous.
engine.conContext.closeReason = rte;
}
}
@ -1000,13 +1059,6 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
@Override
public Void run() throws Exception {
while (!context.delegatedActions.isEmpty()) {
// Report back the task SSLException
if (context.delegatedThrown != null) {
Exception delegatedThrown = context.delegatedThrown;
context.delegatedThrown = null;
throw getTaskThrown(delegatedThrown);
}
Map.Entry<Byte, ByteBuffer> me =
context.delegatedActions.poll();
if (me != null) {

View file

@ -167,9 +167,10 @@ interface SSLTransport {
if (plainText == null) {
plainText = Plaintext.PLAINTEXT_NULL;
} else {
// File the destination buffers.
if (dsts != null && dstsLength > 0 &&
plainText.contentType == ContentType.APPLICATION_DATA.id) {
// Fill the destination buffers.
if ((dsts != null) && (dstsLength > 0) &&
(plainText.contentType ==
ContentType.APPLICATION_DATA.id)) {
ByteBuffer fragment = plainText.fragment;
int remains = fragment.remaining();

View file

@ -40,6 +40,7 @@ import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLProtocolException;
import sun.security.ssl.CipherSuite.KeyExchange;
import sun.security.ssl.ClientHello.ClientHelloMessage;
import sun.security.ssl.SSLCipher.SSLReadCipher;
@ -139,8 +140,11 @@ final class ServerHello {
this.serverRandom = new RandomCookie(m);
this.sessionId = new SessionId(Record.getBytes8(m));
sessionId.checkLength(serverVersion.id);
try {
sessionId.checkLength(serverVersion.id);
} catch (SSLProtocolException ex) {
handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, ex);
}
int cipherSuiteId = Record.getInt16(m);
this.cipherSuite = CipherSuite.valueOf(cipherSuiteId);

View file

@ -362,16 +362,16 @@ final class SignatureAlgorithmsExtension {
// certificates and server key exchange), it MUST send the
// signature_algorithms extension, listing the algorithms it
// is willing to accept.
List<SignatureScheme> shemes = Arrays.asList(
List<SignatureScheme> schemes = Arrays.asList(
SignatureScheme.RSA_PKCS1_SHA1,
SignatureScheme.DSA_SHA1,
SignatureScheme.ECDSA_SHA1
);
shc.peerRequestedSignatureSchemes = shemes;
shc.peerRequestedSignatureSchemes = schemes;
if (shc.peerRequestedCertSignSchemes == null ||
shc.peerRequestedCertSignSchemes.isEmpty()) {
shc.peerRequestedCertSignSchemes = shemes;
shc.peerRequestedCertSignSchemes.isEmpty()) {
shc.peerRequestedCertSignSchemes = schemes;
}
// Use the default peer signature algorithms.

View file

@ -403,8 +403,8 @@ enum SignatureScheme {
for (SignatureScheme ss : schemes) {
if (ss.isAvailable &&
ss.handshakeSupportedProtocols.contains(version) &&
certScheme.keyAlgorithm.equalsIgnoreCase(ss.keyAlgorithm)) {
ss.handshakeSupportedProtocols.contains(version) &&
certScheme.keyAlgorithm.equalsIgnoreCase(ss.keyAlgorithm)) {
return ss;
}

View file

@ -63,6 +63,7 @@ class TransportContext implements ConnectionContext {
boolean isInputCloseNotified = false;
boolean peerUserCanceled = false;
Exception closeReason = null;
Exception delegatedThrown = null;
// negotiated security parameters
SSLSessionImpl conSession;
@ -364,12 +365,12 @@ class TransportContext implements ConnectionContext {
}
}
// terminal handshake context
// terminate the handshake context
if (handshakeContext != null) {
handshakeContext = null;
}
// terminal the transport
// terminate the transport
try {
transport.shutdown();
} catch (IOException ioe) {

View file

@ -73,7 +73,7 @@ enum X509Authentication implements SSLAuthentication {
}
static X509Authentication valueOf(SignatureScheme signatureScheme) {
for (X509Authentication au: X509Authentication.values()) {
for (X509Authentication au : X509Authentication.values()) {
if (au.keyType.equals(signatureScheme.keyAlgorithm)) {
return au;
}
@ -291,9 +291,9 @@ enum X509Authentication implements SSLAuthentication {
((ECPublicKey)serverPublicKey).getParams();
NamedGroup namedGroup = NamedGroup.valueOf(params);
if ((namedGroup == null) ||
(!SupportedGroups.isSupported(namedGroup)) ||
((shc.clientRequestedNamedGroups != null) &&
!shc.clientRequestedNamedGroups.contains(namedGroup))) {
(!SupportedGroups.isSupported(namedGroup)) ||
((shc.clientRequestedNamedGroups != null) &&
!shc.clientRequestedNamedGroups.contains(namedGroup))) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
SSLLogger.warning(