mirror of https://github.com/openssl/openssl.git
189 lines
5.2 KiB
C
189 lines
5.2 KiB
C
/*
|
|
* Copyright 2025 The OpenSSL Project Authors. All Rights Reserved.
|
|
*
|
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
|
* this file except in compliance with the License. You can obtain a copy
|
|
* in the file LICENSE in the source distribution or at
|
|
* https://www.openssl.org/source/license.html
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include <openssl/crypto.h>
|
|
#include <openssl/ssl.h>
|
|
|
|
#include "helpers/ssltestlib.h"
|
|
#include "testutil.h"
|
|
|
|
/**
|
|
* @brief Global static variables for certificate and key handling.
|
|
*
|
|
* These variables store the paths and context used for managing
|
|
* certificates and private keys in the application.
|
|
*
|
|
* - certsdir: Directory containing trusted certificates.
|
|
* - cert: Path to the certificate file in use.
|
|
* - privkey: Path to the private key file.
|
|
* - mcount: Number of mallocs counted
|
|
* - rcount: Number of reallocs counted
|
|
* - fcount: Number of frees counted
|
|
* - scount: Number of mallocs counted prior to workload
|
|
*/
|
|
static char *cert = NULL;
|
|
static char *privkey = NULL;
|
|
static int mcount, rcount, fcount, scount;
|
|
|
|
/**
|
|
* @brief Performs an SSL/TLS handshake between a test client and server.
|
|
*
|
|
* This function sets up SSL/TLS contexts and objects for both client and
|
|
* server, then initiates a handshake to verify successful connection
|
|
* establishment. It is intended for use in testing scenarios to validate
|
|
* handshake behavior using specified certificates and keys.
|
|
*
|
|
* @return 1 on successful handshake, 0 on failure.
|
|
*
|
|
* @note The function uses @c TEST_true() macros to validate intermediate
|
|
* steps. All SSL objects and contexts are freed before returning.
|
|
*/
|
|
static int do_handshake(OSSL_LIB_CTX *libctx)
|
|
{
|
|
SSL_CTX *cctx = NULL, *sctx = NULL;
|
|
SSL *clientssl = NULL, *serverssl = NULL;
|
|
int testresult = 0;
|
|
|
|
if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
|
|
TLS_client_method(),
|
|
TLS1_VERSION, 0,
|
|
&sctx, &cctx, cert, privkey)))
|
|
return 0;
|
|
|
|
/* Now do a handshake */
|
|
if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl,
|
|
&clientssl, NULL, NULL))
|
|
|| !TEST_true(create_ssl_connection(serverssl, clientssl,
|
|
SSL_ERROR_NONE)))
|
|
goto end;
|
|
|
|
testresult = 1;
|
|
|
|
end:
|
|
SSL_free(serverssl);
|
|
SSL_free(clientssl);
|
|
SSL_CTX_free(sctx);
|
|
SSL_CTX_free(cctx);
|
|
|
|
return testresult;
|
|
}
|
|
|
|
/**
|
|
* @brief run our workload to count the number of allocations we make.
|
|
*
|
|
* Creates a new OpenSSL library context and performs a test SSL/TLS
|
|
* handshake. The number of malloc operations is recorded and printed for
|
|
* diagnostic purposes.
|
|
*
|
|
* @return 1 if the handshake succeeds, 0 otherwise.
|
|
*/
|
|
static int test_record_alloc_counts(void)
|
|
{
|
|
int ret;
|
|
OSSL_LIB_CTX *libctx;
|
|
|
|
libctx = OSSL_LIB_CTX_new();
|
|
if (!TEST_ptr(libctx))
|
|
return 0;
|
|
|
|
ret = do_handshake(libctx);
|
|
|
|
OSSL_LIB_CTX_free(libctx);
|
|
libctx = NULL;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief run our workload to count the number of allocations we make.
|
|
*
|
|
* Creates a new OpenSSL library context and performs a test SSL/TLS
|
|
* handshake.
|
|
*
|
|
* Note this is exactly the same as test_record_alloc_counts with 1 difference
|
|
* The test always returns 1. We do this because with allocation failures
|
|
* in effect, we can't expect things to work, so we always return success
|
|
* so that the test keeps running.
|
|
*/
|
|
static int test_alloc_failures(void)
|
|
{
|
|
OSSL_LIB_CTX *libctx;
|
|
|
|
libctx = OSSL_LIB_CTX_new();
|
|
if (!TEST_ptr(libctx))
|
|
return 1;
|
|
|
|
do_handshake(libctx);
|
|
|
|
OSSL_LIB_CTX_free(libctx);
|
|
libctx = NULL;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int test_report_alloc_counts(void)
|
|
{
|
|
CRYPTO_get_alloc_counts(&mcount, &rcount, &fcount);
|
|
/*
|
|
* Report our memory allocations from the count run
|
|
* NOTE: We report a number of allocations to skip here
|
|
* (the scount value). These are the allocations that took
|
|
* place while the test harness itself was getting setup
|
|
* (i.e. calling OPENSSL_init_crypto/etc). We can't fail
|
|
* those allocations as they will cause the test to fail before
|
|
* we have even run the workload. So report them so we can
|
|
* allow them to function before we start doing any real testing
|
|
*/
|
|
TEST_info("skip: %d count %d\n", scount, mcount - scount);
|
|
return 1;
|
|
}
|
|
|
|
int setup_tests(void)
|
|
{
|
|
char *opmode = NULL;
|
|
char *certsdir = NULL;
|
|
|
|
if (!TEST_ptr(opmode = test_get_argument(0)))
|
|
goto err;
|
|
|
|
if (!TEST_ptr(certsdir = test_get_argument(1)))
|
|
goto err;
|
|
|
|
cert = test_mk_file_path(certsdir, "servercert.pem");
|
|
if (cert == NULL)
|
|
goto err;
|
|
|
|
privkey = test_mk_file_path(certsdir, "serverkey.pem");
|
|
if (privkey == NULL)
|
|
goto err;
|
|
|
|
if (strcmp(opmode, "count") == 0) {
|
|
CRYPTO_get_alloc_counts(&scount, &rcount, &fcount);
|
|
ADD_TEST(test_record_alloc_counts);
|
|
ADD_TEST(test_report_alloc_counts);
|
|
} else {
|
|
ADD_TEST(test_alloc_failures);
|
|
}
|
|
return 1;
|
|
|
|
err:
|
|
OPENSSL_free(cert);
|
|
OPENSSL_free(privkey);
|
|
return 0;
|
|
}
|
|
|
|
void cleanup_tests(void)
|
|
{
|
|
OPENSSL_free(cert);
|
|
OPENSSL_free(privkey);
|
|
}
|