Bug 820887: Fix early return in HandshakeCallback, r=keeler

--HG--
extra : rebase_source : e60d86d2b796bda0d44fe640663261cbebede495
This commit is contained in:
Brian Smith 2013-05-15 14:32:03 -07:00
parent 92a7f0ec74
commit 92ac44f63e

View File

@ -1006,10 +1006,7 @@ CanFalseStartCallback(PRFileDesc* fd, void* client_data, PRBool *canFalseStart)
void HandshakeCallback(PRFileDesc* fd, void* client_data) {
nsNSSShutDownPreventionLock locker;
int32_t sslStatus;
char* cipherName = nullptr;
int32_t keyLength;
int32_t encryptBits;
SECStatus rv;
nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*) fd->higher->secret;
@ -1028,47 +1025,43 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
nsSSLIOLayerHelpers& ioLayerHelpers = infoObject->SharedState().IOLayerHelpers();
ioLayerHelpers.rememberTolerantSite(infoObject);
if (SECSuccess != SSL_SecurityStatus(fd, &sslStatus, &cipherName, &keyLength,
&encryptBits, nullptr, nullptr)) {
return;
PRBool siteSupportsSafeRenego;
rv = SSL_HandshakeNegotiatedExtension(fd, ssl_renegotiation_info_xtn,
&siteSupportsSafeRenego);
MOZ_ASSERT(rv == SECSuccess);
if (rv != SECSuccess) {
siteSupportsSafeRenego = false;
}
int32_t secStatus;
if (sslStatus == SSL_SECURITY_STATUS_OFF)
secStatus = nsIWebProgressListener::STATE_IS_BROKEN;
else
secStatus = nsIWebProgressListener::STATE_IS_SECURE
| nsIWebProgressListener::STATE_SECURE_HIGH;
if (siteSupportsSafeRenego ||
!ioLayerHelpers.treatUnsafeNegotiationAsBroken()) {
infoObject->SetSecurityState(nsIWebProgressListener::STATE_IS_SECURE |
nsIWebProgressListener::STATE_SECURE_HIGH);
} else {
infoObject->SetSecurityState(nsIWebProgressListener::STATE_IS_BROKEN);
}
PRBool siteSupportsSafeRenego;
if (SSL_HandshakeNegotiatedExtension(fd, ssl_renegotiation_info_xtn, &siteSupportsSafeRenego) != SECSuccess
|| !siteSupportsSafeRenego) {
// XXX Bug 883674: We shouldn't be formatting messages here in PSM; instead,
// we should set a flag on the channel that higher (UI) level code can check
// to log the warning. In particular, these warnings should go to the web
// console instead of to the error console. Also, the warning is not
// localized.
if (!siteSupportsSafeRenego &&
ioLayerHelpers.getWarnLevelMissingRFC5746() > 0) {
nsCOMPtr<nsIConsoleService> console = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (console) {
nsXPIDLCString hostName;
infoObject->GetHostName(getter_Copies(hostName));
bool wantWarning = (ioLayerHelpers.getWarnLevelMissingRFC5746() > 0);
nsCOMPtr<nsIConsoleService> console;
if (infoObject && wantWarning) {
console = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (console) {
nsXPIDLCString hostName;
infoObject->GetHostName(getter_Copies(hostName));
nsAutoString msg;
msg.Append(NS_ConvertASCIItoUTF16(hostName));
msg.Append(NS_LITERAL_STRING(" : server does not support RFC 5746, see CVE-2009-3555"));
console->LogStringMessage(msg.get());
}
}
if (ioLayerHelpers.treatUnsafeNegotiationAsBroken()) {
secStatus = nsIWebProgressListener::STATE_IS_BROKEN;
nsAutoString msg;
msg.Append(NS_ConvertASCIItoUTF16(hostName));
msg.Append(NS_LITERAL_STRING(" : server does not support RFC 5746, see CVE-2009-3555"));
console->LogStringMessage(msg.get());
}
}
ScopedCERTCertificate serverCert(SSL_PeerCertificate(fd));
infoObject->SetSecurityState(secStatus);
/* Set the SSL Status information */
RefPtr<nsSSLStatus> status(infoObject->SSLStatus());
if (!status) {
@ -1108,21 +1101,25 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
}
}
status->mHaveKeyLengthAndCipher = true;
status->mKeyLength = keyLength;
status->mSecretKeyLength = encryptBits;
status->mCipherName.Assign(cipherName);
SSLChannelInfo channelInfo;
if (SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo)) == SECSuccess) {
rv = SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo));
MOZ_ASSERT(rv == SECSuccess);
if (rv == SECSuccess) {
// Get the protocol version for telemetry
// 0=ssl3, 1=tls1, 2=tls1.1, 3=tls1.2
unsigned int versionEnum = channelInfo.protocolVersion & 0xFF;
Telemetry::Accumulate(Telemetry::SSL_HANDSHAKE_VERSION, versionEnum);
SSLCipherSuiteInfo cipherInfo;
if (SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
sizeof (cipherInfo)) == SECSuccess) {
rv = SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
sizeof cipherInfo);
MOZ_ASSERT(rv == SECSuccess);
if (rv == SECSuccess) {
status->mHaveKeyLengthAndCipher = true;
status->mKeyLength = cipherInfo.symKeyBits;
status->mSecretKeyLength = cipherInfo.effectiveKeyBits;
status->mCipherName.Assign(cipherInfo.cipherSuiteName);
// keyExchange null=0, rsa=1, dh=2, fortezza=3, ecdh=4
Telemetry::Accumulate(Telemetry::SSL_KEY_EXCHANGE_ALGORITHM,
cipherInfo.keaType);
@ -1133,8 +1130,6 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
infoObject->NoteTimeUntilReady();
infoObject->SetHandshakeCompleted(isResumedSession);
PORT_Free(cipherName);
}
struct OCSPDefaultResponders {