提交 8c4a771b 编写于 作者: X xuelei

6898739: TLS renegotiation issue

Summary: the interim fix disables TLS/SSL renegotiation
Reviewed-by: mullan, chegar, wetmore
上级 fe0a582b
...@@ -93,13 +93,17 @@ final class ClientHandshaker extends Handshaker { ...@@ -93,13 +93,17 @@ final class ClientHandshaker extends Handshaker {
* Constructors * Constructors
*/ */
ClientHandshaker(SSLSocketImpl socket, SSLContextImpl context, ClientHandshaker(SSLSocketImpl socket, SSLContextImpl context,
ProtocolList enabledProtocols) { ProtocolList enabledProtocols,
ProtocolVersion activeProtocolVersion) {
super(socket, context, enabledProtocols, true, true); super(socket, context, enabledProtocols, true, true);
this.activeProtocolVersion = activeProtocolVersion;
} }
ClientHandshaker(SSLEngineImpl engine, SSLContextImpl context, ClientHandshaker(SSLEngineImpl engine, SSLContextImpl context,
ProtocolList enabledProtocols) { ProtocolList enabledProtocols,
ProtocolVersion activeProtocolVersion) {
super(engine, context, enabledProtocols, true, true); super(engine, context, enabledProtocols, true, true);
this.activeProtocolVersion = activeProtocolVersion;
} }
/* /*
...@@ -275,7 +279,42 @@ final class ClientHandshaker extends Handshaker { ...@@ -275,7 +279,42 @@ final class ClientHandshaker extends Handshaker {
// sent the "client hello" but the server's not seen it. // sent the "client hello" but the server's not seen it.
// //
if (state < HandshakeMessage.ht_client_hello) { if (state < HandshakeMessage.ht_client_hello) {
kickstart(); if (!renegotiable) { // renegotiation is not allowed.
if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) {
// response with a no_negotiation warning,
warningSE(Alerts.alert_no_negotiation);
// invalidate the handshake so that the caller can
// dispose this object.
invalidated = true;
// If there is still unread block in the handshake
// input stream, it would be truncated with the disposal
// and the next handshake message will become incomplete.
//
// However, according to SSL/TLS specifications, no more
// handshake message could immediately follow ClientHello
// or HelloRequest. But in case of any improper messages,
// we'd better check to ensure there is no remaining bytes
// in the handshake input stream.
if (input.available() > 0) {
fatalSE(Alerts.alert_unexpected_message,
"HelloRequest followed by an unexpected " +
"handshake message");
}
} else {
// For SSLv3, send the handshake_failure fatal error.
// Note that SSLv3 does not define a no_negotiation alert
// like TLSv1. However we cannot ignore the message
// simply, otherwise the other side was waiting for a
// response that would never come.
fatalSE(Alerts.alert_handshake_failure,
"renegotiation is not allowed");
}
} else {
kickstart();
}
} }
} }
......
/* /*
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -60,9 +60,12 @@ import sun.security.ssl.CipherSuite.*; ...@@ -60,9 +60,12 @@ import sun.security.ssl.CipherSuite.*;
*/ */
abstract class Handshaker { abstract class Handshaker {
// current protocol version // protocol version being established using this Handshaker
ProtocolVersion protocolVersion; ProtocolVersion protocolVersion;
// the currently active protocol version during a renegotiation
ProtocolVersion activeProtocolVersion;
// list of enabled protocols // list of enabled protocols
ProtocolList enabledProtocols; ProtocolList enabledProtocols;
...@@ -124,6 +127,13 @@ abstract class Handshaker { ...@@ -124,6 +127,13 @@ abstract class Handshaker {
/* Class and subclass dynamic debugging support */ /* Class and subclass dynamic debugging support */
static final Debug debug = Debug.getInstance("ssl"); static final Debug debug = Debug.getInstance("ssl");
// By default, disable the unsafe legacy session renegotiation
static final boolean renegotiable = Debug.getBooleanProperty(
"sun.security.ssl.allowUnsafeRenegotiation", false);
// need to dispose the object when it is invalidated
boolean invalidated;
Handshaker(SSLSocketImpl c, SSLContextImpl context, Handshaker(SSLSocketImpl c, SSLContextImpl context,
ProtocolList enabledProtocols, boolean needCertVerify, ProtocolList enabledProtocols, boolean needCertVerify,
boolean isClient) { boolean isClient) {
...@@ -144,6 +154,7 @@ abstract class Handshaker { ...@@ -144,6 +154,7 @@ abstract class Handshaker {
this.sslContext = context; this.sslContext = context;
this.isClient = isClient; this.isClient = isClient;
enableNewSession = true; enableNewSession = true;
invalidated = false;
setCipherSuite(CipherSuite.C_NULL); setCipherSuite(CipherSuite.C_NULL);
...@@ -489,7 +500,9 @@ abstract class Handshaker { ...@@ -489,7 +500,9 @@ abstract class Handshaker {
*/ */
void processLoop() throws IOException { void processLoop() throws IOException {
while (input.available() > 0) { // need to read off 4 bytes at least to get the handshake
// message type and length.
while (input.available() >= 4) {
byte messageType; byte messageType;
int messageLen; int messageLen;
......
/* /*
* Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -433,11 +433,12 @@ final public class SSLEngineImpl extends SSLEngine { ...@@ -433,11 +433,12 @@ final public class SSLEngineImpl extends SSLEngine {
connectionState = cs_RENEGOTIATE; connectionState = cs_RENEGOTIATE;
} }
if (roleIsServer) { if (roleIsServer) {
handshaker = new ServerHandshaker handshaker = new ServerHandshaker(this, sslContext,
(this, sslContext, enabledProtocols, doClientAuth); enabledProtocols, doClientAuth,
connectionState == cs_RENEGOTIATE, protocolVersion);
} else { } else {
handshaker = new ClientHandshaker handshaker = new ClientHandshaker(this, sslContext,
(this, sslContext, enabledProtocols); enabledProtocols, protocolVersion);
} }
handshaker.enabledCipherSuites = enabledCipherSuites; handshaker.enabledCipherSuites = enabledCipherSuites;
handshaker.setEnableSessionCreation(enableSessionCreation); handshaker.setEnableSessionCreation(enableSessionCreation);
...@@ -639,6 +640,10 @@ final public class SSLEngineImpl extends SSLEngine { ...@@ -639,6 +640,10 @@ final public class SSLEngineImpl extends SSLEngine {
break; break;
case cs_DATA: case cs_DATA:
if (!Handshaker.renegotiable) {
throw new SSLHandshakeException("renegotiation is not allowed");
}
// initialize the handshaker, move to cs_RENEGOTIATE // initialize the handshaker, move to cs_RENEGOTIATE
initHandshaker(); initHandshaker();
break; break;
...@@ -966,7 +971,13 @@ final public class SSLEngineImpl extends SSLEngine { ...@@ -966,7 +971,13 @@ final public class SSLEngineImpl extends SSLEngine {
handshaker.process_record(inputRecord, expectingFinished); handshaker.process_record(inputRecord, expectingFinished);
expectingFinished = false; expectingFinished = false;
if (handshaker.isDone()) { if (handshaker.invalidated) {
handshaker = null;
// if state is cs_RENEGOTIATE, revert it to cs_DATA
if (connectionState == cs_RENEGOTIATE) {
connectionState = cs_DATA;
}
} else if (handshaker.isDone()) {
sess = handshaker.getSession(); sess = handshaker.getSession();
if (!writer.hasOutboundData()) { if (!writer.hasOutboundData()) {
hsStatus = HandshakeStatus.FINISHED; hsStatus = HandshakeStatus.FINISHED;
......
...@@ -907,7 +907,13 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { ...@@ -907,7 +907,13 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
handshaker.process_record(r, expectingFinished); handshaker.process_record(r, expectingFinished);
expectingFinished = false; expectingFinished = false;
if (handshaker.isDone()) { if (handshaker.invalidated) {
handshaker = null;
// if state is cs_RENEGOTIATE, revert it to cs_DATA
if (connectionState == cs_RENEGOTIATE) {
connectionState = cs_DATA;
}
} else if (handshaker.isDone()) {
sess = handshaker.getSession(); sess = handshaker.getSession();
handshaker = null; handshaker = null;
connectionState = cs_DATA; connectionState = cs_DATA;
...@@ -925,6 +931,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { ...@@ -925,6 +931,7 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
t.start(); t.start();
} }
} }
if (needAppData || connectionState != cs_DATA) { if (needAppData || connectionState != cs_DATA) {
continue; continue;
} else { } else {
...@@ -1083,11 +1090,12 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { ...@@ -1083,11 +1090,12 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
connectionState = cs_RENEGOTIATE; connectionState = cs_RENEGOTIATE;
} }
if (roleIsServer) { if (roleIsServer) {
handshaker = new ServerHandshaker handshaker = new ServerHandshaker(this, sslContext,
(this, sslContext, enabledProtocols, doClientAuth); enabledProtocols, doClientAuth,
connectionState == cs_RENEGOTIATE, protocolVersion);
} else { } else {
handshaker = new ClientHandshaker handshaker = new ClientHandshaker(this, sslContext,
(this, sslContext, enabledProtocols); enabledProtocols, protocolVersion);
} }
handshaker.enabledCipherSuites = enabledCipherSuites; handshaker.enabledCipherSuites = enabledCipherSuites;
handshaker.setEnableSessionCreation(enableSessionCreation); handshaker.setEnableSessionCreation(enableSessionCreation);
...@@ -1192,6 +1200,10 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { ...@@ -1192,6 +1200,10 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl {
break; break;
case cs_DATA: case cs_DATA:
if (!Handshaker.renegotiable) {
throw new SSLHandshakeException("renegotiation is not allowed");
}
// initialize the handshaker, move to cs_RENEGOTIATE // initialize the handshaker, move to cs_RENEGOTIATE
initHandshaker(); initHandshaker();
break; break;
......
...@@ -69,6 +69,9 @@ final class ServerHandshaker extends Handshaker { ...@@ -69,6 +69,9 @@ final class ServerHandshaker extends Handshaker {
// flag to check for clientCertificateVerify message // flag to check for clientCertificateVerify message
private boolean needClientVerify = false; private boolean needClientVerify = false;
// indicate a renegotiation handshaking
private boolean isRenegotiation = false;
/* /*
* For exportable ciphersuites using non-exportable key sizes, we use * For exportable ciphersuites using non-exportable key sizes, we use
* ephemeral RSA keys. We could also do anonymous RSA in the same way * ephemeral RSA keys. We could also do anonymous RSA in the same way
...@@ -96,20 +99,28 @@ final class ServerHandshaker extends Handshaker { ...@@ -96,20 +99,28 @@ final class ServerHandshaker extends Handshaker {
* Constructor ... use the keys found in the auth context. * Constructor ... use the keys found in the auth context.
*/ */
ServerHandshaker(SSLSocketImpl socket, SSLContextImpl context, ServerHandshaker(SSLSocketImpl socket, SSLContextImpl context,
ProtocolList enabledProtocols, byte clientAuth) { ProtocolList enabledProtocols, byte clientAuth,
boolean isRenegotiation, ProtocolVersion activeProtocolVersion) {
super(socket, context, enabledProtocols, super(socket, context, enabledProtocols,
(clientAuth != SSLEngineImpl.clauth_none), false); (clientAuth != SSLEngineImpl.clauth_none), false);
doClientAuth = clientAuth; doClientAuth = clientAuth;
this.isRenegotiation = isRenegotiation;
this.activeProtocolVersion = activeProtocolVersion;
} }
/* /*
* Constructor ... use the keys found in the auth context. * Constructor ... use the keys found in the auth context.
*/ */
ServerHandshaker(SSLEngineImpl engine, SSLContextImpl context, ServerHandshaker(SSLEngineImpl engine, SSLContextImpl context,
ProtocolList enabledProtocols, byte clientAuth) { ProtocolList enabledProtocols, byte clientAuth,
boolean isRenegotiation, ProtocolVersion activeProtocolVersion) {
super(engine, context, enabledProtocols, super(engine, context, enabledProtocols,
(clientAuth != SSLEngineImpl.clauth_none), false); (clientAuth != SSLEngineImpl.clauth_none), false);
doClientAuth = clientAuth; doClientAuth = clientAuth;
this.isRenegotiation = isRenegotiation;
this.activeProtocolVersion = activeProtocolVersion;
} }
/* /*
...@@ -257,6 +268,45 @@ final class ServerHandshaker extends Handshaker { ...@@ -257,6 +268,45 @@ final class ServerHandshaker extends Handshaker {
if (debug != null && Debug.isOn("handshake")) { if (debug != null && Debug.isOn("handshake")) {
mesg.print(System.out); mesg.print(System.out);
} }
// if it is a renegotiation request and renegotiation is not allowed
if (isRenegotiation && !renegotiable) {
if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) {
// response with a no_negotiation warning,
warningSE(Alerts.alert_no_negotiation);
// invalidate the handshake so that the caller can
// dispose this object.
invalidated = true;
// If there is still unread block in the handshake
// input stream, it would be truncated with the disposal
// and the next handshake message will become incomplete.
//
// However, according to SSL/TLS specifications, no more
// handshake message could immediately follow ClientHello
// or HelloRequest. But in case of any improper messages,
// we'd better check to ensure there is no remaining bytes
// in the handshake input stream.
if (input.available() > 0) {
fatalSE(Alerts.alert_unexpected_message,
"ClientHello followed by an unexpected " +
"handshake message");
}
return;
} else {
// For SSLv3, send the handshake_failure fatal error.
// Note that SSLv3 does not define a no_negotiation alert
// like TLSv1. However we cannot ignore the message
// simply, otherwise the other side was waiting for a
// response that would never come.
fatalSE(Alerts.alert_handshake_failure,
"renegotiation is not allowed");
}
}
/* /*
* Always make sure this entire record has been digested before we * Always make sure this entire record has been digested before we
* start emitting output, to ensure correct digesting order. * start emitting output, to ensure correct digesting order.
......
/* /*
* Copyright 2001-2003 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2001-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
* @test * @test
* @bug 4403428 * @bug 4403428
* @summary Invalidating JSSE session on server causes SSLProtocolException * @summary Invalidating JSSE session on server causes SSLProtocolException
* @ignore incompatible with disabled unsafe renegotiation (6898739), please
* reenable when safe renegotiation is implemented.
* @author Brad Wetmore * @author Brad Wetmore
*/ */
......
/* /*
* Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2001-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
* @bug 4280338 * @bug 4280338
* @summary "Unsupported SSL message version" SSLProtocolException * @summary "Unsupported SSL message version" SSLProtocolException
* w/SSL_RSA_WITH_NULL_MD5 * w/SSL_RSA_WITH_NULL_MD5
* @ignore incompatible with disabled unsafe renegotiation (6898739), please
* reenable when safe renegotiation is implemented.
* *
* @author Ram Marti * @author Ram Marti
* @author Brad Wetmore * @author Brad Wetmore
......
/* /*
* Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
* @test * @test
* @bug 4948079 * @bug 4948079
* @summary SSLEngineResult needs updating [none yet] * @summary SSLEngineResult needs updating [none yet]
* @ignore incompatible with disabled unsafe renegotiation (6898739), please
* reenable when safe renegotiation is implemented.
* *
* This is a simple hack to test a bunch of conditions and check * This is a simple hack to test a bunch of conditions and check
* their return codes. * their return codes.
......
/* /*
* Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
* @bug 4495742 * @bug 4495742
* @summary Add non-blocking SSL/TLS functionality, usable with any * @summary Add non-blocking SSL/TLS functionality, usable with any
* I/O abstraction * I/O abstraction
* @ignore incompatible with disabled unsafe renegotiation (6898739), please
* reenable when safe renegotiation is implemented.
* *
* This is a bit hacky, meant to test various conditions. The main * This is a bit hacky, meant to test various conditions. The main
* thing I wanted to do with this was to do buffer reads/writes * thing I wanted to do with this was to do buffer reads/writes
......
/* /*
* Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
* @test * @test
* @bug 4495742 * @bug 4495742
* @summary Demonstrate SSLEngine switch from no client auth to client auth. * @summary Demonstrate SSLEngine switch from no client auth to client auth.
* @ignore incompatible with disabled unsafe renegotiation (6898739), please
* reenable when safe renegotiation is implemented.
* *
* @author Brad R. Wetmore * @author Brad R. Wetmore
*/ */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册