blob: 3f7074a0964b89822fd8d2841a456baa0c3e173e [file] [log] [blame]
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <functional>
#include <memory>
#include "secerr.h"
#include "ssl.h"
#include "sslerr.h"
#include "sslproto.h"
extern "C" {
// This is not something that should make you happy.
#include "libssl_internals.h"
}
#include "gtest_utils.h"
#include "tls_connect.h"
namespace nss_test {
// 1.3 is disabled in the next few tests because we don't
// presently support resumption in 1.3.
TEST_P(TlsConnectStreamPre13, RenegotiateClient) {
Connect();
server_->PrepareForRenegotiate();
client_->StartRenegotiate();
Handshake();
CheckConnected();
}
TEST_P(TlsConnectStreamPre13, RenegotiateServer) {
Connect();
client_->PrepareForRenegotiate();
server_->StartRenegotiate();
Handshake();
CheckConnected();
}
TEST_P(TlsConnectStreamPre13, RenegotiateRandoms) {
SSL3Random crand1, crand2, srand1, srand2;
Connect();
EXPECT_EQ(SECSuccess,
SSLInt_GetHandshakeRandoms(client_->ssl_fd(), crand1, srand1));
// Renegotiate and check that both randoms have changed.
client_->PrepareForRenegotiate();
server_->StartRenegotiate();
Handshake();
CheckConnected();
EXPECT_EQ(SECSuccess,
SSLInt_GetHandshakeRandoms(client_->ssl_fd(), crand2, srand2));
EXPECT_NE(0, memcmp(crand1, crand2, sizeof(SSL3Random)));
EXPECT_NE(0, memcmp(srand1, srand2, sizeof(SSL3Random)));
}
// The renegotiation options shouldn't cause an error if TLS 1.3 is chosen.
TEST_F(TlsConnectTest, RenegotiationConfigTls13) {
EnsureTlsSetup();
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
server_->SetOption(SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_UNRESTRICTED);
server_->SetOption(SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE);
Connect();
SendReceive();
CheckKeys();
}
TEST_P(TlsConnectStream, ConnectTls10AndServerRenegotiateHigher) {
if (version_ == SSL_LIBRARY_VERSION_TLS_1_0) {
GTEST_SKIP();
}
// Set the client so it will accept any version from 1.0
// to |version_|.
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, version_);
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
SSL_LIBRARY_VERSION_TLS_1_0);
// Reset version so that the checks succeed.
uint16_t test_version = version_;
version_ = SSL_LIBRARY_VERSION_TLS_1_0;
Connect();
// Now renegotiate, with the server being set to do
// |version_|.
client_->PrepareForRenegotiate();
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, test_version);
// Reset version and cipher suite so that the preinfo callback
// doesn't fail.
server_->ResetPreliminaryInfo();
server_->StartRenegotiate();
if (test_version >= SSL_LIBRARY_VERSION_TLS_1_3) {
ExpectAlert(server_, kTlsAlertUnexpectedMessage);
} else {
ExpectAlert(server_, kTlsAlertProtocolVersion);
}
Handshake();
if (test_version >= SSL_LIBRARY_VERSION_TLS_1_3) {
// In TLS 1.3, the server detects this problem.
client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
server_->CheckErrorCode(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED);
} else {
client_->CheckErrorCode(SSL_ERROR_PROTOCOL_VERSION_ALERT);
server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_VERSION);
}
}
TEST_P(TlsConnectStream, ConnectTls10AndClientRenegotiateHigher) {
if (version_ == SSL_LIBRARY_VERSION_TLS_1_0) {
GTEST_SKIP();
}
// Set the client so it will accept any version from 1.0
// to |version_|.
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, version_);
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
SSL_LIBRARY_VERSION_TLS_1_0);
// Reset version so that the checks succeed.
uint16_t test_version = version_;
version_ = SSL_LIBRARY_VERSION_TLS_1_0;
Connect();
// Now renegotiate, with the server being set to do
// |version_|.
server_->PrepareForRenegotiate();
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, test_version);
// Reset version and cipher suite so that the preinfo callback
// doesn't fail.
server_->ResetPreliminaryInfo();
client_->StartRenegotiate();
if (test_version >= SSL_LIBRARY_VERSION_TLS_1_3) {
ExpectAlert(server_, kTlsAlertUnexpectedMessage);
} else {
ExpectAlert(server_, kTlsAlertProtocolVersion);
}
Handshake();
if (test_version >= SSL_LIBRARY_VERSION_TLS_1_3) {
// In TLS 1.3, the server detects this problem.
client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
server_->CheckErrorCode(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED);
} else {
client_->CheckErrorCode(SSL_ERROR_PROTOCOL_VERSION_ALERT);
server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_VERSION);
}
}
TEST_P(TlsConnectStream, ConnectAndServerRenegotiateLower) {
if (version_ == SSL_LIBRARY_VERSION_TLS_1_0) {
GTEST_SKIP();
}
Connect();
// Now renegotiate with the server set to TLS 1.0.
client_->PrepareForRenegotiate();
server_->PrepareForRenegotiate();
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, version_);
// Reset version and cipher suite so that the preinfo callback
// doesn't fail.
server_->ResetPreliminaryInfo();
SECStatus rv = SSL_ReHandshake(server_->ssl_fd(), PR_TRUE);
if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
EXPECT_EQ(SECFailure, rv);
return;
}
ASSERT_EQ(SECSuccess, rv);
// Now, before handshaking, tweak the server configuration.
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
SSL_LIBRARY_VERSION_TLS_1_0);
// The server should catch the own error.
ExpectAlert(server_, kTlsAlertProtocolVersion);
Handshake();
client_->CheckErrorCode(SSL_ERROR_PROTOCOL_VERSION_ALERT);
server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_VERSION);
}
TEST_P(TlsConnectStream, ConnectAndServerWontRenegotiateLower) {
if (version_ == SSL_LIBRARY_VERSION_TLS_1_0) {
GTEST_SKIP();
}
Connect();
// Now renegotiate with the server set to TLS 1.0.
client_->PrepareForRenegotiate();
server_->PrepareForRenegotiate();
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0, version_);
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
SSL_LIBRARY_VERSION_TLS_1_0);
// Reset version and cipher suite so that the preinfo callback
// doesn't fail.
server_->ResetPreliminaryInfo();
EXPECT_EQ(SECFailure, SSL_ReHandshake(server_->ssl_fd(), PR_TRUE));
}
TEST_P(TlsConnectStream, ConnectAndClientWontRenegotiateLower) {
if (version_ == SSL_LIBRARY_VERSION_TLS_1_0) {
GTEST_SKIP();
}
Connect();
// Now renegotiate with the client set to TLS 1.0.
client_->PrepareForRenegotiate();
server_->PrepareForRenegotiate();
server_->ResetPreliminaryInfo();
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
SSL_LIBRARY_VERSION_TLS_1_0);
// The client will refuse to renegotiate down.
EXPECT_EQ(SECFailure, SSL_ReHandshake(client_->ssl_fd(), PR_TRUE));
}
TEST_F(TlsConnectTest, Tls13RejectsRehandshakeClient) {
EnsureTlsSetup();
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
Connect();
SECStatus rv = SSL_ReHandshake(client_->ssl_fd(), PR_TRUE);
EXPECT_EQ(SECFailure, rv);
EXPECT_EQ(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED, PORT_GetError());
}
TEST_F(TlsConnectTest, Tls13RejectsRehandshakeServer) {
EnsureTlsSetup();
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
Connect();
SECStatus rv = SSL_ReHandshake(server_->ssl_fd(), PR_TRUE);
EXPECT_EQ(SECFailure, rv);
EXPECT_EQ(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED, PORT_GetError());
}
} // namespace nss_test