Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/boringssl.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'ssl/ssl_test.cc')
-rw-r--r--ssl/ssl_test.cc265
1 files changed, 243 insertions, 22 deletions
diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc
index ed1d3c7d..3e9cd1ed 100644
--- a/ssl/ssl_test.cc
+++ b/ssl/ssl_test.cc
@@ -254,6 +254,31 @@ static const char *kMustNotIncludeNull[] = {
"TLSv1.2",
};
+static const char *kMustNotIncludeCECPQ1[] = {
+ "ALL",
+ "DEFAULT",
+ "MEDIUM",
+ "HIGH",
+ "FIPS",
+ "SHA",
+ "SHA1",
+ "SHA256",
+ "SHA384",
+ "RSA",
+ "SSLv3",
+ "TLSv1",
+ "TLSv1.2",
+ "aRSA",
+ "RSA",
+ "aECDSA",
+ "ECDSA",
+ "AES",
+ "AES128",
+ "AES256",
+ "AESGCM",
+ "CHACHA20",
+};
+
static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
bool in_group = false;
for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
@@ -324,6 +349,24 @@ static bool TestRuleDoesNotIncludeNull(const char *rule) {
return true;
}
+static bool TestRuleDoesNotIncludeCECPQ1(const char *rule) {
+ ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ if (!ctx) {
+ return false;
+ }
+ if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
+ fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
+ return false;
+ }
+ for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
+ if (SSL_CIPHER_is_CECPQ1(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
+ fprintf(stderr, "Error: cipher rule '%s' includes CECPQ1\n",rule);
+ return false;
+ }
+ }
+ return true;
+}
+
static bool TestCipherRules() {
for (const CipherTest &test : kCipherTests) {
if (!TestCipherRule(test)) {
@@ -349,6 +392,12 @@ static bool TestCipherRules() {
}
}
+ for (const char *rule : kMustNotIncludeCECPQ1) {
+ if (!TestRuleDoesNotIncludeCECPQ1(rule)) {
+ return false;
+ }
+ }
+
return true;
}
@@ -646,7 +695,10 @@ static bool TestDefaultVersion(uint16_t version,
if (!ctx) {
return false;
}
- return ctx->min_version == version && ctx->max_version == version;
+ // TODO(svaldez): Remove TLS1_2_VERSION fallback upon implementing TLS 1.3.
+ return ctx->min_version == version &&
+ (ctx->max_version == version ||
+ (version == 0 && ctx->max_version == TLS1_2_VERSION));
}
static bool CipherGetRFCName(std::string *out, uint16_t value) {
@@ -1001,8 +1053,7 @@ static ScopedX509 GetTestCertificate() {
"T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
"j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
"-----END CERTIFICATE-----\n";
- ScopedBIO bio(
- BIO_new_mem_buf(const_cast<char *>(kCertPEM), strlen(kCertPEM)));
+ ScopedBIO bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
}
@@ -1023,28 +1074,14 @@ static ScopedEVP_PKEY GetTestKey() {
"tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
"moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
"-----END RSA PRIVATE KEY-----\n";
- ScopedBIO bio(BIO_new_mem_buf(const_cast<char *>(kKeyPEM), strlen(kKeyPEM)));
+ ScopedBIO bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
return ScopedEVP_PKEY(
PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
}
-static bool TestSequenceNumber(bool dtls) {
- ScopedSSL_CTX client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
- ScopedSSL_CTX server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
- if (!client_ctx || !server_ctx) {
- return false;
- }
-
- ScopedX509 cert = GetTestCertificate();
- ScopedEVP_PKEY key = GetTestKey();
- if (!cert || !key ||
- !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
- !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
- return false;
- }
-
- // Create a client and server connected to each other.
- ScopedSSL client(SSL_new(client_ctx.get())), server(SSL_new(server_ctx.get()));
+static bool ConnectClientAndServer(ScopedSSL *out_client, ScopedSSL *out_server,
+ SSL_CTX *client_ctx, SSL_CTX *server_ctx) {
+ ScopedSSL client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
if (!client || !server) {
return false;
}
@@ -1084,6 +1121,32 @@ static bool TestSequenceNumber(bool dtls) {
}
}
+ *out_client = std::move(client);
+ *out_server = std::move(server);
+ return true;
+}
+
+static bool TestSequenceNumber(bool dtls) {
+ ScopedSSL_CTX client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
+ ScopedSSL_CTX server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
+ if (!client_ctx || !server_ctx) {
+ return false;
+ }
+
+ ScopedX509 cert = GetTestCertificate();
+ ScopedEVP_PKEY key = GetTestKey();
+ if (!cert || !key ||
+ !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
+ !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
+ return false;
+ }
+
+ ScopedSSL client, server;
+ if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
+ server_ctx.get())) {
+ return false;
+ }
+
uint64_t client_read_seq = SSL_get_read_sequence(client.get());
uint64_t client_write_seq = SSL_get_write_sequence(client.get());
uint64_t server_read_seq = SSL_get_read_sequence(server.get());
@@ -1132,6 +1195,162 @@ static bool TestSequenceNumber(bool dtls) {
return true;
}
+static bool TestOneSidedShutdown() {
+ ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
+ ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
+ if (!client_ctx || !server_ctx) {
+ return false;
+ }
+
+ ScopedX509 cert = GetTestCertificate();
+ ScopedEVP_PKEY key = GetTestKey();
+ if (!cert || !key ||
+ !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
+ !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
+ return false;
+ }
+
+ ScopedSSL client, server;
+ if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
+ server_ctx.get())) {
+ return false;
+ }
+
+ // Shut down half the connection. SSL_shutdown will return 0 to signal only
+ // one side has shut down.
+ if (SSL_shutdown(client.get()) != 0) {
+ fprintf(stderr, "Could not shutdown.\n");
+ return false;
+ }
+
+ // Reading from the server should consume the EOF.
+ uint8_t byte;
+ if (SSL_read(server.get(), &byte, 1) != 0 ||
+ SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
+ fprintf(stderr, "Connection was not shut down cleanly.\n");
+ return false;
+ }
+
+ // However, the server may continue to write data and then shut down the
+ // connection.
+ byte = 42;
+ if (SSL_write(server.get(), &byte, 1) != 1 ||
+ SSL_read(client.get(), &byte, 1) != 1 ||
+ byte != 42) {
+ fprintf(stderr, "Could not send byte.\n");
+ return false;
+ }
+
+ // The server may then shutdown the connection.
+ if (SSL_shutdown(server.get()) != 1 ||
+ SSL_shutdown(client.get()) != 1) {
+ fprintf(stderr, "Could not complete shutdown.\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
+ if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
+ fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
+ SSL_get_wfd(ssl), rfd, wfd);
+ return false;
+ }
+
+ // The wrapper BIOs are always equal when fds are equal, even if set
+ // individually.
+ if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
+ fprintf(stderr, "rbio and wbio did not match.\n");
+ return false;
+ }
+
+ return true;
+}
+
+static bool TestSetFD() {
+ ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ if (!ctx) {
+ return false;
+ }
+
+ // Test setting different read and write FDs.
+ ScopedSSL ssl(SSL_new(ctx.get()));
+ if (!ssl ||
+ !SSL_set_rfd(ssl.get(), 1) ||
+ !SSL_set_wfd(ssl.get(), 2) ||
+ !ExpectFDs(ssl.get(), 1, 2)) {
+ return false;
+ }
+
+ // Test setting the same FD.
+ ssl.reset(SSL_new(ctx.get()));
+ if (!ssl ||
+ !SSL_set_fd(ssl.get(), 1) ||
+ !ExpectFDs(ssl.get(), 1, 1)) {
+ return false;
+ }
+
+ // Test setting the same FD one side at a time.
+ ssl.reset(SSL_new(ctx.get()));
+ if (!ssl ||
+ !SSL_set_rfd(ssl.get(), 1) ||
+ !SSL_set_wfd(ssl.get(), 1) ||
+ !ExpectFDs(ssl.get(), 1, 1)) {
+ return false;
+ }
+
+ // Test setting the same FD in the other order.
+ ssl.reset(SSL_new(ctx.get()));
+ if (!ssl ||
+ !SSL_set_wfd(ssl.get(), 1) ||
+ !SSL_set_rfd(ssl.get(), 1) ||
+ !ExpectFDs(ssl.get(), 1, 1)) {
+ return false;
+ }
+
+ // Test changing the read FD partway through.
+ ssl.reset(SSL_new(ctx.get()));
+ if (!ssl ||
+ !SSL_set_fd(ssl.get(), 1) ||
+ !SSL_set_rfd(ssl.get(), 2) ||
+ !ExpectFDs(ssl.get(), 2, 1)) {
+ return false;
+ }
+
+ // Test changing the write FD partway through.
+ ssl.reset(SSL_new(ctx.get()));
+ if (!ssl ||
+ !SSL_set_fd(ssl.get(), 1) ||
+ !SSL_set_wfd(ssl.get(), 2) ||
+ !ExpectFDs(ssl.get(), 1, 2)) {
+ return false;
+ }
+
+ // Test a no-op change to the read FD partway through.
+ ssl.reset(SSL_new(ctx.get()));
+ if (!ssl ||
+ !SSL_set_fd(ssl.get(), 1) ||
+ !SSL_set_rfd(ssl.get(), 1) ||
+ !ExpectFDs(ssl.get(), 1, 1)) {
+ return false;
+ }
+
+ // Test a no-op change to the write FD partway through.
+ ssl.reset(SSL_new(ctx.get()));
+ if (!ssl ||
+ !SSL_set_fd(ssl.get(), 1) ||
+ !SSL_set_wfd(ssl.get(), 1) ||
+ !ExpectFDs(ssl.get(), 1, 1)) {
+ return false;
+ }
+
+ // ASan builds will implicitly test that the internal |BIO| reference-counting
+ // is correct.
+
+ return true;
+}
+
int main() {
CRYPTO_library_init();
@@ -1155,7 +1374,9 @@ int main() {
!TestClientCAList() ||
!TestInternalSessionCache() ||
!TestSequenceNumber(false /* TLS */) ||
- !TestSequenceNumber(true /* DTLS */)) {
+ !TestSequenceNumber(true /* DTLS */) ||
+ !TestOneSidedShutdown() ||
+ !TestSetFD()) {
ERR_print_errors_fp(stderr);
return 1;
}