diff --git a/source/handshake.c b/source/handshake.c index 464d59e..43c6567 100644 --- a/source/handshake.c +++ b/source/handshake.c @@ -37,6 +37,7 @@ struct ctxs { OSSL_LIB_CTX *libctx; SSL_CTX *sctx; SSL_CTX *cctx; + PERFLIB_CREDS creds; }; static struct ctxs **ctx_pool = NULL; @@ -46,6 +47,7 @@ static SSL_CTX *sctx = NULL, *cctx = NULL; static int share_ctx = 1; static char *cert = NULL; static char *privkey = NULL; +static PERFLIB_CREDS creds; size_t *counts; @@ -84,8 +86,7 @@ static void do_handshake(size_t num) if (share_ctx == 0) { if (!perflib_create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), - 0, 0, &lsctx, &lcctx, cert, - privkey)) { + 0, 0, &lsctx, &lcctx, &creds)) { ERR_print_errors_fp(stderr); fprintf(stderr, "%s:%d: Failed to create SSL_CTX pair\n", __FILE__, __LINE__); break; @@ -124,6 +125,7 @@ static void do_handshake_ossl_lib_ctx_per_thread(size_t num) OSSL_LIB_CTX *libctx = NULL; SSL_CTX *lsctx = NULL; SSL_CTX *lcctx = NULL; + PERFLIB_CREDS tcreds; libctx = OSSL_LIB_CTX_new(); if (libctx == NULL) { @@ -132,6 +134,14 @@ static void do_handshake_ossl_lib_ctx_per_thread(size_t num) return; } + if (!perflib_load_creds_ex(libctx, cert, privkey, &tcreds)) { + ERR_print_errors_fp(stderr); + fprintf(stderr, "%s:%d: Failed to load cert/privkey\n", __FILE__, __LINE__); + err = 1; + OSSL_LIB_CTX_free(libctx); + return; + } + counts[num] = 0; do { @@ -139,11 +149,13 @@ static void do_handshake_ossl_lib_ctx_per_thread(size_t num) if (!perflib_create_ossl_lib_ctx_pair(libctx, TLS_server_method(), TLS_client_method(), - 0, 0, &lsctx, &lcctx, cert, - privkey)) { + 0, 0, &lsctx, &lcctx, + &tcreds)) { ERR_print_errors_fp(stderr); fprintf(stderr, "%s:%d: Failed to create SSL_CTX pair\n", __FILE__, __LINE__); err = 1; + perflib_free_creds(&tcreds); + OSSL_LIB_CTX_free(libctx); return; } } @@ -172,6 +184,7 @@ static void do_handshake_ossl_lib_ctx_per_thread(size_t num) if (!ret) err = 1; + perflib_free_creds(&tcreds); OSSL_LIB_CTX_free(libctx); } @@ -197,8 +210,8 @@ static void do_handshake_ctx_pool(size_t num) if (!perflib_create_ossl_lib_ctx_pair(ctx->libctx, TLS_server_method(), TLS_client_method(), - 0, 0, &lsctx, &lcctx, cert, - privkey)) { + 0, 0, &lsctx, &lcctx, + &ctx->creds)) { ERR_print_errors_fp(stderr); fprintf(stderr, "%s:%d: Failed to create SSL_CTX pair\n", __FILE__, __LINE__); err = 1; @@ -213,8 +226,8 @@ static void do_handshake_ctx_pool(size_t num) if (!perflib_create_ossl_lib_ctx_pair(ctx->libctx, TLS_server_method(), TLS_client_method(), - 0, 0, &lsctx, &lcctx, cert, - privkey)) { + 0, 0, &lsctx, &lcctx, + &ctx->creds)) { ERR_print_errors_fp(stderr); fprintf(stderr, "%s:%d: Failed to create SSL_CTX pair\n", __FILE__, __LINE__); err = 1; @@ -257,6 +270,7 @@ static void free_ctx_pool() if (ctx_pool[i]) { SSL_CTX_free(ctx_pool[i]->sctx); SSL_CTX_free(ctx_pool[i]->cctx); + perflib_free_creds(&ctx_pool[i]->creds); OSSL_LIB_CTX_free(ctx_pool[i]->libctx); OPENSSL_free(ctx_pool[i]); } @@ -276,6 +290,7 @@ static int init_ctx_pool(init_ctx init_ctx) for (int i = 0; i < pool_size; ++i) { SSL_CTX *lsctx = NULL, *lcctx = NULL; struct ctxs *ctx = NULL; + PERFLIB_CREDS lcreds; OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new(); if (libctx == NULL) { @@ -283,13 +298,20 @@ static int init_ctx_pool(init_ctx init_ctx) return 0; } + if (!perflib_load_creds_ex(libctx, cert, privkey, &lcreds)) { + fprintf(stderr, "%s:%d: Failed to load cert/privkey\n", __FILE__, __LINE__); + OSSL_LIB_CTX_free(libctx); + return 0; + } + if (init_ctx == INIT_LIB_AND_SSL_CTX) { if (!perflib_create_ossl_lib_ctx_pair(libctx, TLS_server_method(), TLS_client_method(), - 0, 0, &lsctx, &lcctx, cert, - privkey)) { + 0, 0, &lsctx, &lcctx, + &lcreds)) { fprintf(stderr, "%s:%d: Failed to create SSL_CTX pair\n", __FILE__, __LINE__); + perflib_free_creds(&lcreds); OSSL_LIB_CTX_free(libctx); return 0; } @@ -297,15 +319,17 @@ static int init_ctx_pool(init_ctx init_ctx) ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx == NULL) { - OSSL_LIB_CTX_free(libctx); SSL_CTX_free(lsctx); SSL_CTX_free(lcctx); + perflib_free_creds(&lcreds); + OSSL_LIB_CTX_free(libctx); return 0; } ctx->libctx = libctx; ctx->sctx = lsctx; ctx->cctx = lcctx; + ctx->creds = lcreds; ctx_pool[i] = ctx; } @@ -483,9 +507,15 @@ int main(int argc, char * const argv[]) switch (test_case) { case TC_SSL_CTX: { + if (!perflib_load_creds(cert, privkey, &creds)) { + ERR_print_errors_fp(stderr); + fprintf(stderr, "%s:%d: Failed to load cert/privkey\n", __FILE__, __LINE__); + goto err; + } + if (share_ctx == 1) { if (!perflib_create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), - 0, 0, &sctx, &cctx, cert, privkey)) { + 0, 0, &sctx, &cctx, &creds)) { ERR_print_errors_fp(stderr); fprintf(stderr, "%s:%d: Failed to create SSL_CTX pair\n", __FILE__, __LINE__); goto err; @@ -544,6 +574,7 @@ int main(int argc, char * const argv[]) OPENSSL_free(cert); OPENSSL_free(privkey); OPENSSL_free(counts); + perflib_free_creds(&creds); if (share_ctx == 1) { SSL_CTX_free(sctx); SSL_CTX_free(cctx); diff --git a/source/perflib/perflib.h b/source/perflib/perflib.h index 64dfeff..63b31f5 100644 --- a/source/perflib/perflib.h +++ b/source/perflib/perflib.h @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include "perflib/time.h" # if defined(_WIN32) @@ -43,15 +45,28 @@ int perflib_run_multi_thread_test(void (*f)(size_t), size_t threadcount, OSSL_TIME *duration); char *perflib_mk_file_path(const char *dir, const char *file); +typedef struct perflib_creds_st { + X509 *cert; + EVP_PKEY *privkey; +} PERFLIB_CREDS; + +int perflib_load_creds(const char *certfile, const char *privkeyfile, + PERFLIB_CREDS *creds); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +int perflib_load_creds_ex(OSSL_LIB_CTX *libctx, const char *certfile, + const char *privkeyfile, PERFLIB_CREDS *creds); +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ +void perflib_free_creds(PERFLIB_CREDS *creds); + int perflib_create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm, int min_proto_version, int max_proto_version, - SSL_CTX **sctx, SSL_CTX **cctx, char *certfile, - char *privkeyfile); + SSL_CTX **sctx, SSL_CTX **cctx, + PERFLIB_CREDS *creds); #if OPENSSL_VERSION_NUMBER >= 0x30000000L int perflib_create_ossl_lib_ctx_pair(OSSL_LIB_CTX *libctx, const SSL_METHOD *sm, const SSL_METHOD *cm, int min_proto_version, int max_proto_version, SSL_CTX **sctx, SSL_CTX **cctx, - char *certfile, char *privkeyfile); + PERFLIB_CREDS *creds); #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ int perflib_create_ssl_objects(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl, SSL **cssl, BIO *s_to_c_fbio, diff --git a/source/perflib/perfsslhelper.c b/source/perflib/perfsslhelper.c index 25131df..5d58a15 100644 --- a/source/perflib/perfsslhelper.c +++ b/source/perflib/perfsslhelper.c @@ -11,14 +11,92 @@ #include #include #include +#include +#include #include +#include #include "perflib/perflib.h" +static int perflib_read_creds(void *libctx, const char *certfile, + const char *privkeyfile, PERFLIB_CREDS *creds) +{ + BIO *bio = NULL; + +#if OPENSSL_VERSION_NUMBER < 0x30000000L + (void)libctx; +#endif + + creds->cert = NULL; + creds->privkey = NULL; + + if (certfile == NULL || privkeyfile == NULL) + return 0; + + if ((bio = BIO_new_file(certfile, "r")) == NULL) + goto err; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if ((creds->cert = X509_new_ex((OSSL_LIB_CTX *)libctx, NULL)) == NULL) + goto err; + if (PEM_read_bio_X509(bio, &creds->cert, NULL, NULL) == NULL) + goto err; +#else + if ((creds->cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) + goto err; +#endif + BIO_free(bio); + + if ((bio = BIO_new_file(privkeyfile, "r")) == NULL) + goto err; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + creds->privkey = PEM_read_bio_PrivateKey_ex(bio, NULL, NULL, NULL, + (OSSL_LIB_CTX *)libctx, NULL); +#else + creds->privkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); +#endif + if (creds->privkey == NULL) + goto err; + BIO_free(bio); + bio = NULL; + + if (X509_check_private_key(creds->cert, creds->privkey) != 1) + goto err; + + return 1; + + err: + BIO_free(bio); + perflib_free_creds(creds); + return 0; +} + +int perflib_load_creds(const char *certfile, const char *privkeyfile, + PERFLIB_CREDS *creds) +{ + return perflib_read_creds(NULL, certfile, privkeyfile, creds); +} + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +int perflib_load_creds_ex(OSSL_LIB_CTX *libctx, const char *certfile, + const char *privkeyfile, PERFLIB_CREDS *creds) +{ + return perflib_read_creds(libctx, certfile, privkeyfile, creds); +} +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ + +void perflib_free_creds(PERFLIB_CREDS *creds) +{ + if (creds == NULL) + return; + X509_free(creds->cert); + EVP_PKEY_free(creds->privkey); + creds->cert = NULL; + creds->privkey = NULL; +} static int perflib_use_certificate(SSL_CTX *serverctx, SSL_CTX *clientctx, int min_proto_version, int max_proto_version, SSL_CTX **sctx, SSL_CTX **cctx, - char *certfile, char *privkeyfile) + PERFLIB_CREDS *creds) { if (serverctx != NULL && ((min_proto_version > 0 @@ -38,12 +116,9 @@ static int perflib_use_certificate(SSL_CTX *serverctx, SSL_CTX *clientctx, max_proto_version)))) goto err; - if (serverctx != NULL && certfile != NULL && privkeyfile != NULL) { - if (SSL_CTX_use_certificate_file(serverctx, certfile, - SSL_FILETYPE_PEM) != 1 - || SSL_CTX_use_PrivateKey_file(serverctx, privkeyfile, - SSL_FILETYPE_PEM) != 1 - || SSL_CTX_check_private_key(serverctx) != 1) + if (serverctx != NULL && creds != NULL) { + if (SSL_CTX_use_certificate(serverctx, creds->cert) != 1 + || SSL_CTX_use_PrivateKey(serverctx, creds->privkey) != 1) goto err; } @@ -65,7 +140,7 @@ static int perflib_use_certificate(SSL_CTX *serverctx, SSL_CTX *clientctx, int perflib_create_ossl_lib_ctx_pair(OSSL_LIB_CTX *libctx, const SSL_METHOD *sm, const SSL_METHOD *cm, int min_proto_version, int max_proto_version, SSL_CTX **sctx, SSL_CTX **cctx, - char *certfile, char *privkeyfile) + PERFLIB_CREDS *creds) { SSL_CTX *serverctx = NULL; SSL_CTX *clientctx = NULL; @@ -86,8 +161,7 @@ int perflib_create_ossl_lib_ctx_pair(OSSL_LIB_CTX *libctx, const SSL_METHOD *sm, } return perflib_use_certificate(serverctx, clientctx, min_proto_version, - max_proto_version, sctx, cctx, certfile, - privkeyfile); + max_proto_version, sctx, cctx, creds); err: return 0; } @@ -96,8 +170,7 @@ int perflib_create_ossl_lib_ctx_pair(OSSL_LIB_CTX *libctx, const SSL_METHOD *sm, int perflib_create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm, int min_proto_version, int max_proto_version, SSL_CTX **sctx, - SSL_CTX **cctx, char *certfile, - char *privkeyfile) + SSL_CTX **cctx, PERFLIB_CREDS *creds) { SSL_CTX *serverctx = NULL; SSL_CTX *clientctx = NULL; @@ -117,8 +190,7 @@ int perflib_create_ssl_ctx_pair(const SSL_METHOD *sm, } return perflib_use_certificate(serverctx, clientctx, min_proto_version, - max_proto_version, sctx, cctx, certfile, - privkeyfile); + max_proto_version, sctx, cctx, creds); err: return 0; } diff --git a/source/writeread.c b/source/writeread.c index 2c166d2..99295c5 100644 --- a/source/writeread.c +++ b/source/writeread.c @@ -29,6 +29,7 @@ static SSL_CTX *sctx = NULL, *cctx = NULL; static int share_ctx = 1; static char *cert = NULL; static char *privkey = NULL; +static PERFLIB_CREDS creds; static const SSL_METHOD *smethod, *cmethod; static int use_dtls = 0; /* Protocol version to pin both min and max to, 0 = library default. */ @@ -60,7 +61,7 @@ static void do_writeread(size_t num) } else { if (!perflib_create_ssl_ctx_pair(smethod, cmethod, proto_version, proto_version, - &lsctx, &lcctx, cert, privkey)) { + &lsctx, &lcctx, &creds)) { fprintf(stderr, "Failed to create SSL_CTX pair\n"); err = 1; return; @@ -222,10 +223,15 @@ int main(int argc, char * const argv[]) max_time = ossl_time_add(ossl_time_now(), ossl_seconds2time(RUN_TIME)); + if (!perflib_load_creds(cert, privkey, &creds)) { + fprintf(stderr, "Failed to load cert/privkey\n"); + goto err; + } + if (share_ctx == 1) { if (!perflib_create_ssl_ctx_pair(smethod, cmethod, proto_version, proto_version, - &sctx, &cctx, cert, privkey)) { + &sctx, &cctx, &creds)) { fprintf(stderr, "Failed to create SSL_CTX pair\n"); goto err; } @@ -257,6 +263,7 @@ int main(int argc, char * const argv[]) free(cert); free(privkey); free(counts); + perflib_free_creds(&creds); if (share_ctx == 1) { SSL_CTX_free(sctx); SSL_CTX_free(cctx);