From fbd8996949a63e4960294df3a023471a2fdeea0b Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 10 Nov 2023 12:31:55 +0100 Subject: [PATCH 1/5] Add API to choose dynamic certs based on client ciphers/sigalgs --- src/internal.c | 5 +- src/ssl.c | 27 +++++ src/tls13.c | 18 ++- tests/api.c | 270 ++++++++++++++++++++++++++++++++++++--------- wolfssl/internal.h | 3 + wolfssl/ssl.h | 3 + 6 files changed, 270 insertions(+), 56 deletions(-) diff --git a/src/internal.c b/src/internal.c index 98dafc2ff..fadeb10a3 100644 --- a/src/internal.c +++ b/src/internal.c @@ -35403,6 +35403,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif #ifdef OPENSSL_EXTRA + ssl->clSuites = clSuites; /* Give user last chance to provide a cert for cipher selection */ if (ret == 0 && ssl->ctx->certSetupCb != NULL) ret = CertSetupCbWrapper(ssl); @@ -35426,7 +35427,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif out: - +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) + ssl->clSuites = NULL; +#endif #ifdef WOLFSSL_SMALL_STACK if (clSuites != NULL) XFREE(clSuites, ssl->heap, DYNAMIC_TYPE_SUITES); diff --git a/src/ssl.c b/src/ssl.c index 275fa5f71..cd1104fa0 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16296,6 +16296,33 @@ int wolfSSL_set_compression(WOLFSSL* ssl) ctx->certSetupCbArg = arg; } + void wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl, + const byte** suites, word16* suiteSz, + const byte** hashSigAlgo, word16* hashSigAlgoSz) + { + WOLFSSL_ENTER("wolfSSL_get_client_suites_sigalgs"); + + if (suites != NULL) + *suites = NULL; + if (suiteSz != NULL) + *suiteSz = 0; + if (hashSigAlgo != NULL) + *hashSigAlgo = NULL; + if (hashSigAlgoSz != NULL) + *hashSigAlgoSz = 0; + + if (ssl != NULL && ssl->clSuites != NULL) { + if (suites != NULL && suiteSz != NULL) { + *suites = ssl->clSuites->suites; + *suiteSz = ssl->clSuites->suiteSz; + } + if (hashSigAlgo != NULL && hashSigAlgoSz != NULL) { + *hashSigAlgo = ssl->clSuites->hashSigAlgo; + *hashSigAlgoSz = ssl->clSuites->hashSigAlgoSz; + } + } + } + /** * Internal wrapper for calling certSetupCb * @param ssl The SSL/TLS Object diff --git a/src/tls13.c b/src/tls13.c index ddbc2324d..c0e3a9cdc 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -5617,6 +5617,11 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input, if (ssl->toInfoOn) AddLateName("CertificateRequest", &ssl->timeoutInfo); #endif +#ifdef OPENSSL_EXTRA + if ((ret = CertSetupCbWrapper(ssl)) != 0) + return ret; +#endif + if (OPAQUE8_LEN > size) return BUFFER_ERROR; @@ -6594,6 +6599,9 @@ static void FreeDch13Args(WOLFSSL* ssl, void* pArgs) XFREE(args->clSuites, ssl->heap, DYNAMIC_TYPE_SUITES); args->clSuites = NULL; } +#ifdef OPENSSL_EXTRA + ssl->clSuites = NULL; +#endif } int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, @@ -6978,6 +6986,11 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, case TLS_ASYNC_DO: { +#ifdef OPENSSL_EXTRA + ssl->clSuites = args->clSuites; + if ((ret = CertSetupCbWrapper(ssl)) != 0) + goto exit_dch; +#endif #ifndef NO_CERTS if (!args->usingPSK) { if ((ret = MatchSuite(ssl, args->clSuites)) < 0) { @@ -8244,11 +8257,6 @@ static int SendTls13Certificate(WOLFSSL* ssl) listSz = 0; } else { -#ifdef OPENSSL_EXTRA - if ((ret = CertSetupCbWrapper(ssl)) != 0) - return ret; -#endif - if (!ssl->buffers.certificate) { WOLFSSL_MSG("Send Cert missing certificate buffer"); return BUFFER_ERROR; diff --git a/tests/api.c b/tests/api.c index fffd51249..e89c2fb04 100644 --- a/tests/api.c +++ b/tests/api.c @@ -5824,8 +5824,12 @@ static WC_INLINE int test_ssl_memio_setup(test_ssl_memio_ctx *ctx) #ifdef WOLFSSL_ENCRYPTED_KEYS wolfSSL_CTX_set_default_passwd_cb(ctx->c_ctx, PasswordCallBack); #endif - ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->c_ctx, caCertFile, 0), - WOLFSSL_SUCCESS); + if (ctx->c_cb.caPemFile != NULL) + ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->c_ctx, + ctx->c_cb.caPemFile, 0), WOLFSSL_SUCCESS); + else + ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->c_ctx, + caCertFile, 0), WOLFSSL_SUCCESS); #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE) if (!c_sharedCtx) #endif @@ -5889,8 +5893,12 @@ static WC_INLINE int test_ssl_memio_setup(test_ssl_memio_ctx *ctx) wolfSSL_SetIOSend(ctx->s_ctx, test_ssl_memio_write_cb); wolfSSL_CTX_set_verify(ctx->s_ctx, WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0); - ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->s_ctx, cliCertFile, 0), - WOLFSSL_SUCCESS); + if (ctx->s_cb.caPemFile != NULL) + ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->s_ctx, + ctx->s_cb.caPemFile, 0), WOLFSSL_SUCCESS); + else + ExpectIntEQ(wolfSSL_CTX_load_verify_locations(ctx->s_ctx, + cliCertFile, 0), WOLFSSL_SUCCESS); #ifdef WOLFSSL_ENCRYPTED_KEYS wolfSSL_CTX_set_default_passwd_cb(ctx->s_ctx, PasswordCallBack); #endif @@ -44746,60 +44754,40 @@ static int test_wolfSSL_BIO_reset(void) /* test that the callback arg is correct */ static int certCbArg = 0; -static int clientCertCb(WOLFSSL* ssl, void* arg) +static int certCb(WOLFSSL* ssl, void* arg) { if (ssl == NULL || arg != &certCbArg) return 0; - if (wolfSSL_use_certificate_file(ssl, cliCertFile, - WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) - return 0; - if (wolfSSL_use_PrivateKey_file(ssl, cliKeyFile, - WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) - return 0; + if (wolfSSL_is_server(ssl)) { + if (wolfSSL_use_certificate_file(ssl, svrCertFile, + WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) + return 0; + if (wolfSSL_use_PrivateKey_file(ssl, svrKeyFile, + WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) + return 0; + } + else { + if (wolfSSL_use_certificate_file(ssl, cliCertFile, + WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) + return 0; + if (wolfSSL_use_PrivateKey_file(ssl, cliKeyFile, + WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) + return 0; + } return 1; } -static int clientCertSetupCb(WOLFSSL_CTX* ctx) +static int certSetupCb(WOLFSSL_CTX* ctx) { - SSL_CTX_set_cert_cb(ctx, clientCertCb, &certCbArg); + SSL_CTX_set_cert_cb(ctx, certCb, &certCbArg); return TEST_SUCCESS; } /** - * This is only done because test_client_nofail has no way to stop - * certificate and key loading + * This is only done because test_wolfSSL_client_server_nofail_memio has no way + * to stop certificate and key loading */ -static int clientCertClearCb(WOLFSSL* ssl) -{ - /* Clear the loaded certs to force the callbacks to set them up */ - SSL_certs_clear(ssl); - return TEST_SUCCESS; -} - -static int serverCertCb(WOLFSSL* ssl, void* arg) -{ - if (ssl == NULL || arg != &certCbArg) - return 0; - if (wolfSSL_use_certificate_file(ssl, svrCertFile, - WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) - return 0; - if (wolfSSL_use_PrivateKey_file(ssl, svrKeyFile, - WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) - return 0; - return 1; -} - -static int serverCertSetupCb(WOLFSSL_CTX* ctx) -{ - SSL_CTX_set_cert_cb(ctx, serverCertCb, &certCbArg); - return TEST_SUCCESS; -} - -/** - * This is only done because test_server_nofail has no way to stop - * certificate and key loading - */ -static int serverCertClearCb(WOLFSSL* ssl) +static int certClearCb(WOLFSSL* ssl) { /* Clear the loaded certs to force the callbacks to set them up */ SSL_certs_clear(ssl); @@ -44818,10 +44806,10 @@ static int test_wolfSSL_cert_cb(void) XMEMSET(&func_cb_client, 0, sizeof(func_cb_client)); XMEMSET(&func_cb_server, 0, sizeof(func_cb_server)); - func_cb_client.ctx_ready = clientCertSetupCb; - func_cb_client.ssl_ready = clientCertClearCb; - func_cb_server.ctx_ready = serverCertSetupCb; - func_cb_server.ssl_ready = serverCertClearCb; + func_cb_client.ctx_ready = certSetupCb; + func_cb_client.ssl_ready = certClearCb; + func_cb_server.ctx_ready = certSetupCb; + func_cb_server.ssl_ready = certClearCb; ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client, &func_cb_server, NULL), TEST_SUCCESS); @@ -44829,6 +44817,187 @@ static int test_wolfSSL_cert_cb(void) return EXPECT_RESULT(); } +#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) + +static const char* test_wolfSSL_cert_cb_dyn_ciphers_client_cipher = NULL; +static const char* test_wolfSSL_cert_cb_dyn_ciphers_client_sigalgs = NULL; +static int test_wolfSSL_cert_cb_dyn_ciphers_client_ctx_ready(WOLFSSL_CTX* ctx) +{ + EXPECT_DECLS; + ExpectIntEQ(wolfSSL_CTX_set_cipher_list(ctx, + test_wolfSSL_cert_cb_dyn_ciphers_client_cipher), WOLFSSL_SUCCESS); + ExpectIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, + test_wolfSSL_cert_cb_dyn_ciphers_client_sigalgs), WOLFSSL_SUCCESS); + return EXPECT_RESULT(); +} + +static int test_wolfSSL_cert_cb_dyn_ciphers_certCB(WOLFSSL* ssl, void* arg) +{ + const byte* suites = NULL; + word16 suiteSz = 0; + const byte* hashSigAlgo = NULL; + word16 hashSigAlgoSz = 0; + word16 idx = 0; + int haveRSA = 0; + int haveECC = 0; + + (void)arg; + + wolfSSL_get_client_suites_sigalgs(ssl, &suites, &suiteSz, &hashSigAlgo, + &hashSigAlgoSz); + if (suites == NULL || suiteSz == 0 || hashSigAlgo == NULL || + hashSigAlgoSz == 0) + return 0; + + if (wolfSSL_GetVersion(ssl) != TLSv1_3_MINOR) { + for (idx = 0; idx < suiteSz; idx += 2) { + const char* cipherName = wolfSSL_get_cipher_name_from_suite( + suites[idx], suites[idx+1]); + if (cipherName == NULL) + return 0; + /* TLS 1.3 suites tell us nothing about the sigalg */ + if (XSTRSTR(cipherName, "TLS13-") != NULL) + continue; + if (XSTRSTR(cipherName, "-RSA-") != NULL) + haveRSA = 1; + if (XSTRSTR(cipherName, "-ECDSA-") != NULL) + haveECC = 1; + } + } + + if (hashSigAlgoSz > 0) { + /* sigalgs extension takes precedence over ciphersuites */ + haveRSA = 0; + haveECC = 0; + } + for (idx = 0; idx < hashSigAlgoSz; idx += 2) { + /* Based on DecodeSigAlg. Enums are not exposed so need to use magic + * numbers. */ + switch (hashSigAlgo[idx+0]) { + case 8: + switch (hashSigAlgo[idx+1]) { + case 7: /* ED25519 */ + case 8: /* ED448 */ + haveECC = 1; + break; + default: + /* RSA-PSS */ + haveRSA = 1; + break; + } + break; + default: + switch (hashSigAlgo[idx+1]) { + case 1: /* RSA */ + haveRSA = 1; + break; + case 3: /* ECC */ + haveECC = 1; + break; + } + } + } + + if (haveRSA) { + if (wolfSSL_use_certificate_file(ssl, svrCertFile, WOLFSSL_FILETYPE_PEM) + != WOLFSSL_SUCCESS) + return 0; + if (wolfSSL_use_PrivateKey_file(ssl, svrKeyFile, WOLFSSL_FILETYPE_PEM) + != WOLFSSL_SUCCESS) + return 0; + } + else if (haveECC) { + if (wolfSSL_use_certificate_file(ssl, eccCertFile, WOLFSSL_FILETYPE_PEM) + != WOLFSSL_SUCCESS) + return 0; + if (wolfSSL_use_PrivateKey_file(ssl, eccKeyFile, WOLFSSL_FILETYPE_PEM) + != WOLFSSL_SUCCESS) + return 0; + } + + return 1; +} + +static int test_wolfSSL_cert_cb_dyn_ciphers_server_ctx_ready(WOLFSSL_CTX* ctx) +{ + SSL_CTX_set_cert_cb(ctx, test_wolfSSL_cert_cb_dyn_ciphers_certCB, NULL); + wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, NULL); + return TEST_SUCCESS; +} + +#endif + +/* Testing dynamic ciphers offered by client */ +static int test_wolfSSL_cert_cb_dyn_ciphers(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) + test_ssl_cbf func_cb_client; + test_ssl_cbf func_cb_server; + struct { + method_provider client_meth; + const char* client_ciphers; + const char* client_sigalgs; + const char* client_ca; + method_provider server_meth; + } test_params[] = { +#if !defined(NO_SHA256) && defined(HAVE_AESGCM) +#ifdef WOLFSSL_TLS13 +#if !defined(NO_RSA) && defined(WC_RSA_PSS) + {wolfTLSv1_3_client_method, + "TLS13-AES256-GCM-SHA384:TLS13-AES128-GCM-SHA256", + "RSA-PSS+SHA256", caCertFile, wolfTLSv1_3_server_method}, +#endif +#ifdef HAVE_ECC + {wolfTLSv1_3_client_method, + "TLS13-AES256-GCM-SHA384:TLS13-AES128-GCM-SHA256", + "ECDSA+SHA256", caEccCertFile, wolfTLSv1_3_server_method}, +#endif +#endif +#ifndef WOLFSSL_NO_TLS12 +#if !defined(NO_RSA) && defined(WC_RSA_PSS) && !defined(NO_DH) + {wolfTLSv1_2_client_method, + "DHE-RSA-AES128-GCM-SHA256", + "RSA-PSS+SHA256", caCertFile, wolfTLSv1_2_server_method}, +#endif +#ifdef HAVE_ECC + {wolfTLSv1_2_client_method, + "ECDHE-ECDSA-AES128-GCM-SHA256", + "ECDSA+SHA256", caEccCertFile, wolfTLSv1_2_server_method}, +#endif +#endif +#endif + }; + size_t i; + + for (i = 0; i < sizeof(test_params)/sizeof(*test_params); i++) { + printf("\tTesting %s ciphers with %s sigalgs\n", + test_params[i].client_ciphers, test_params[i].client_sigalgs); + + XMEMSET(&func_cb_client, 0, sizeof(func_cb_client)); + XMEMSET(&func_cb_server, 0, sizeof(func_cb_server)); + + test_wolfSSL_cert_cb_dyn_ciphers_client_cipher = + test_params[i].client_ciphers; + test_wolfSSL_cert_cb_dyn_ciphers_client_sigalgs = + test_params[i].client_sigalgs; + func_cb_client.method = test_params[i].client_meth; + func_cb_client.caPemFile = test_params[i].client_ca; + func_cb_client.ctx_ready = + test_wolfSSL_cert_cb_dyn_ciphers_client_ctx_ready; + + func_cb_server.ctx_ready = + test_wolfSSL_cert_cb_dyn_ciphers_server_ctx_ready; + func_cb_server.ssl_ready = certClearCb; /* Reuse from previous test */ + func_cb_server.method = test_params[i].server_meth; + + ExpectIntEQ(test_wolfSSL_client_server_nofail_memio(&func_cb_client, + &func_cb_server, NULL), TEST_SUCCESS); + } +#endif + return EXPECT_RESULT(); +} + static int test_wolfSSL_SESSION(void) { EXPECT_DECLS; @@ -69013,6 +69182,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_check_domain), #endif TEST_DECL(test_wolfSSL_cert_cb), + TEST_DECL(test_wolfSSL_cert_cb_dyn_ciphers), /* Can't memory test as tcp_connect aborts. */ TEST_DECL(test_wolfSSL_SESSION), TEST_DECL(test_wolfSSL_SESSION_expire_downgrade), diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 27b1486f6..2f9b912cb 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -5389,6 +5389,9 @@ struct WOLFSSL { * re-using the context's object. When WOLFSSL * object needs separate instance of suites use * AllocateSuites(). */ +#ifdef OPENSSL_EXTRA + const Suites* clSuites; +#endif #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) WOLF_STACK_OF(WOLFSSL_CIPHER)* suitesStack; /* stack of available cipher * suites */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index d70983658..2b18d2b30 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2121,6 +2121,9 @@ WOLFSSL_API void wolfSSL_CTX_set_client_cert_cb(WOLFSSL_CTX *ctx, client_cert_cb typedef int (*CertSetupCallback)(WOLFSSL* ssl, void*); WOLFSSL_API void wolfSSL_CTX_set_cert_cb(WOLFSSL_CTX* ctx, CertSetupCallback cb, void *arg); +WOLFSSL_API void wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl, + const byte** suites, word16* suiteSz, + const byte** hashSigAlgo, word16* hashSigAlgoSz); WOLFSSL_LOCAL int CertSetupCbWrapper(WOLFSSL* ssl); WOLFSSL_API void* wolfSSL_X509_STORE_CTX_get_ex_data( From 7c2344c3893f5a48efb8580e5839e7da3796d1f7 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 20 Nov 2023 14:15:13 +0100 Subject: [PATCH 2/5] Add API to get information about ciphersuites --- doc/dox_comments/header_files/ssl.h | 70 +++++++++++++++++ src/internal.c | 14 +--- src/ssl.c | 15 ++++ tests/api.c | 115 ++++++++++++++++++++++++---- wolfssl/internal.h | 11 +++ wolfssl/ssl.h | 8 ++ 6 files changed, 205 insertions(+), 28 deletions(-) diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index 6fe45a084..4c207fda6 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -14854,3 +14854,73 @@ available size need to be provided in bufferSz. */ int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buffer, unsigned int bufferSz); + +/*! + \ingroup TLS + + \brief This function returns the raw list of ciphersuites and signature + algorithms offered by the client. The lists are only stored and returned + inside a callback setup with wolfSSL_CTX_set_cert_cb(). This is useful to + be able to dynamically load certificates and keys based on the available + ciphersuites and signature algorithms. + + \param [in] ssl The WOLFSSL object to extract the lists from. + \param [out] suites Raw and unfiltered list of client ciphersuites + \param [out] suiteSz Size of suites in bytes + \param [out] hashSigAlgo Raw and unfiltered list of client signature algorithms + \param [out] hashSigAlgoSz Size of hashSigAlgo in bytes + + _Example_ + \code + int certCB(WOLFSSL* ssl, void* arg) + { + const byte* suites = NULL; + word16 suiteSz = 0; + const byte* hashSigAlgo = NULL; + word16 hashSigAlgoSz = 0; + + wolfSSL_get_client_suites_sigalgs(ssl, &suites, &suiteSz, &hashSigAlgo, + &hashSigAlgoSz); + + // Choose certificate to load based on ciphersuites + } + + WOLFSSL* ctx; + ctx = wolfSSL_CTX_new(wolfTLSv1_3_method_ex(NULL)); + wolfSSL_CTX_set_cert_cb(ctx, certCB, NULL); + \endcode + + \sa wolfSSL_new + \sa wolfSSL_free +*/ +void wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl, + const byte** suites, word16* suiteSz, + const byte** hashSigAlgo, word16* hashSigAlgoSz); + +/*! + \ingroup TLS + + \brief This returns information about the ciphersuite directly from the + raw ciphersuite bytes. + + \param [in] first First byte of the ciphersuite + \param [in] second Second byte of the ciphersuite + + \return WOLFSSL_CIPHERSUITE_INFO A struct containing information about the + type of authentication used in the ciphersuite. + + _Example_ + \code + WOLFSSL_CIPHERSUITE_INFO info = + wolfSSL_get_ciphersuite_info(suites[0], suites[1]); + if (info.rsaAuth) + haveRSA = 1; + else if (info.eccAuth) + haveECC = 1; + \endcode + + \sa wolfSSL_new + \sa wolfSSL_free +*/ +WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first, + byte second); diff --git a/src/internal.c b/src/internal.c index fadeb10a3..8db5e7b8b 100644 --- a/src/internal.c +++ b/src/internal.c @@ -11222,23 +11222,11 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) #endif /* WOLFSSL_NO_TLS12 */ #if !defined(NO_WOLFSSL_SERVER) || !defined(NO_WOLFSSL_CLIENT) -/* cipher requirements */ -enum { - REQUIRES_RSA, - REQUIRES_DHE, - REQUIRES_ECC, - REQUIRES_ECC_STATIC, - REQUIRES_PSK, - REQUIRES_RSA_SIG, - REQUIRES_AEAD -}; - - /* Does this cipher suite (first, second) have the requirement an ephemeral key exchange will still require the key for signing the key exchange so ECDHE_RSA requires an rsa key thus rsa_kea */ -static int CipherRequires(byte first, byte second, int requirement) +int CipherRequires(byte first, byte second, int requirement) { (void)requirement; diff --git a/src/ssl.c b/src/ssl.c index cd1104fa0..22782e9f4 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16322,6 +16322,21 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } } } + WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first, + byte second) + { + WOLFSSL_CIPHERSUITE_INFO info; + info.rsaAuth = (byte)(CipherRequires(first, second, REQUIRES_RSA) || + CipherRequires(first, second, REQUIRES_RSA_SIG)); + info.eccAuth = (byte)(CipherRequires(first, second, REQUIRES_ECC) || + /* Static ECC ciphers may require RSA for authentication */ + (CipherRequires(first, second, REQUIRES_ECC_STATIC) && + !CipherRequires(first, second, REQUIRES_RSA_SIG))); + info.eccStatic = + (byte)CipherRequires(first, second, REQUIRES_ECC_STATIC); + info.psk = (byte)CipherRequires(first, second, REQUIRES_PSK); + return info; + } /** * Internal wrapper for calling certSetupCb diff --git a/tests/api.c b/tests/api.c index e89c2fb04..18781eb94 100644 --- a/tests/api.c +++ b/tests/api.c @@ -370,7 +370,7 @@ defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)) || \ defined(WOLFSSL_TEST_STATIC_BUILD) || defined(WOLFSSL_DTLS) || \ defined(HAVE_ECH) || defined(HAVE_EX_DATA) || !defined(NO_SESSION_CACHE) \ - || !defined(WOLFSSL_NO_TLS12) + || !defined(WOLFSSL_NO_TLS12) || defined(WOLFSSL_TLS13) /* for testing SSL_get_peer_cert_chain, or SESSION_TICKET_HINT_DEFAULT, * for setting authKeyIdSrc in WOLFSSL_X509, or testing DTLS sequence * number tracking */ @@ -44849,20 +44849,14 @@ static int test_wolfSSL_cert_cb_dyn_ciphers_certCB(WOLFSSL* ssl, void* arg) hashSigAlgoSz == 0) return 0; - if (wolfSSL_GetVersion(ssl) != TLSv1_3_MINOR) { - for (idx = 0; idx < suiteSz; idx += 2) { - const char* cipherName = wolfSSL_get_cipher_name_from_suite( - suites[idx], suites[idx+1]); - if (cipherName == NULL) - return 0; - /* TLS 1.3 suites tell us nothing about the sigalg */ - if (XSTRSTR(cipherName, "TLS13-") != NULL) - continue; - if (XSTRSTR(cipherName, "-RSA-") != NULL) - haveRSA = 1; - if (XSTRSTR(cipherName, "-ECDSA-") != NULL) - haveECC = 1; - } + for (idx = 0; idx < suiteSz; idx += 2) { + WOLFSSL_CIPHERSUITE_INFO info = + wolfSSL_get_ciphersuite_info(suites[idx], suites[idx+1]); + + if (info.rsaAuth) + haveRSA = 1; + else if (info.eccAuth) + haveECC = 1; } if (hashSigAlgoSz > 0) { @@ -44998,6 +44992,96 @@ static int test_wolfSSL_cert_cb_dyn_ciphers(void) return EXPECT_RESULT(); } +static int test_wolfSSL_ciphersuite_auth(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) + WOLFSSL_CIPHERSUITE_INFO info; + + (void)info; + +#ifndef WOLFSSL_NO_TLS12 +#ifdef HAVE_CHACHA + info = wolfSSL_get_ciphersuite_info(CHACHA_BYTE, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256); + ExpectIntEQ(info.rsaAuth, 1); + ExpectIntEQ(info.eccAuth, 0); + ExpectIntEQ(info.eccStatic, 0); + ExpectIntEQ(info.psk, 0); + + info = wolfSSL_get_ciphersuite_info(CHACHA_BYTE, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256); + ExpectIntEQ(info.rsaAuth, 0); + ExpectIntEQ(info.eccAuth, 1); + ExpectIntEQ(info.eccStatic, 0); + ExpectIntEQ(info.psk, 0); + + info = wolfSSL_get_ciphersuite_info(CHACHA_BYTE, + TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256); + ExpectIntEQ(info.rsaAuth, 0); + ExpectIntEQ(info.eccAuth, 0); + ExpectIntEQ(info.eccStatic, 0); + ExpectIntEQ(info.psk, 1); +#endif +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) +#ifndef NO_RSA + info = wolfSSL_get_ciphersuite_info(ECC_BYTE, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA); + ExpectIntEQ(info.rsaAuth, 1); + ExpectIntEQ(info.eccAuth, 0); + ExpectIntEQ(info.eccStatic, 0); + ExpectIntEQ(info.psk, 0); + + info = wolfSSL_get_ciphersuite_info(ECC_BYTE, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA); + ExpectIntEQ(info.rsaAuth, 1); + ExpectIntEQ(info.eccAuth, 0); + ExpectIntEQ(info.eccStatic, 1); + ExpectIntEQ(info.psk, 0); + + info = wolfSSL_get_ciphersuite_info(ECC_BYTE, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA); + ExpectIntEQ(info.rsaAuth, 1); + ExpectIntEQ(info.eccAuth, 0); + ExpectIntEQ(info.eccStatic, 1); + ExpectIntEQ(info.psk, 0); +#endif + info = wolfSSL_get_ciphersuite_info(ECC_BYTE, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA); + ExpectIntEQ(info.rsaAuth, 0); + ExpectIntEQ(info.eccAuth, 1); + ExpectIntEQ(info.eccStatic, 0); + ExpectIntEQ(info.psk, 0); + + info = wolfSSL_get_ciphersuite_info(ECC_BYTE, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA); + ExpectIntEQ(info.rsaAuth, 0); + ExpectIntEQ(info.eccAuth, 1); + ExpectIntEQ(info.eccStatic, 1); + ExpectIntEQ(info.psk, 0); + + info = wolfSSL_get_ciphersuite_info(ECDHE_PSK_BYTE, + TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256); + ExpectIntEQ(info.rsaAuth, 0); + ExpectIntEQ(info.eccAuth, 0); + ExpectIntEQ(info.eccStatic, 0); + ExpectIntEQ(info.psk, 1); +#endif +#endif + +#ifdef WOLFSSL_TLS13 + info = wolfSSL_get_ciphersuite_info(TLS13_BYTE, + TLS_AES_128_GCM_SHA256); + ExpectIntEQ(info.rsaAuth, 0); + ExpectIntEQ(info.eccAuth, 0); + ExpectIntEQ(info.eccStatic, 0); + ExpectIntEQ(info.psk, 0); +#endif + +#endif + return EXPECT_RESULT(); +} + static int test_wolfSSL_SESSION(void) { EXPECT_DECLS; @@ -69183,6 +69267,7 @@ TEST_CASE testCases[] = { #endif TEST_DECL(test_wolfSSL_cert_cb), TEST_DECL(test_wolfSSL_cert_cb_dyn_ciphers), + TEST_DECL(test_wolfSSL_ciphersuite_auth), /* Can't memory test as tcp_connect aborts. */ TEST_DECL(test_wolfSSL_SESSION), TEST_DECL(test_wolfSSL_SESSION_expire_downgrade), diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 2f9b912cb..071261cb7 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -6014,6 +6014,16 @@ enum ProvisionSide { PROVISION_CLIENT_SERVER = 3 }; +/* cipher requirements */ +enum { + REQUIRES_RSA, + REQUIRES_DHE, + REQUIRES_ECC, + REQUIRES_ECC_STATIC, + REQUIRES_PSK, + REQUIRES_RSA_SIG, + REQUIRES_AEAD +}; static const byte kTlsClientStr[SIZEOF_SENDER+1] = { 0x43, 0x4C, 0x4E, 0x54, 0x00 }; /* CLNT */ static const byte kTlsServerStr[SIZEOF_SENDER+1] = { 0x53, 0x52, 0x56, 0x52, 0x00 }; /* SRVR */ @@ -6105,6 +6115,7 @@ WOLFSSL_LOCAL void ShrinkInputBuffer(WOLFSSL* ssl, int forcedFree); WOLFSSL_LOCAL void ShrinkOutputBuffer(WOLFSSL* ssl); WOLFSSL_LOCAL byte* GetOutputBuffer(WOLFSSL* ssl); +WOLFSSL_LOCAL int CipherRequires(byte first, byte second, int requirement); WOLFSSL_LOCAL int VerifyClientSuite(word16 havePSK, byte cipherSuite0, byte cipherSuite); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 2b18d2b30..5bc473063 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2124,6 +2124,14 @@ WOLFSSL_API void wolfSSL_CTX_set_cert_cb(WOLFSSL_CTX* ctx, WOLFSSL_API void wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl, const byte** suites, word16* suiteSz, const byte** hashSigAlgo, word16* hashSigAlgoSz); +typedef struct WOLFSSL_CIPHERSUITE_INFO { + byte rsaAuth:1; + byte eccAuth:1; + byte eccStatic:1; + byte psk:1; +} WOLFSSL_CIPHERSUITE_INFO; +WOLFSSL_API WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first, + byte second); WOLFSSL_LOCAL int CertSetupCbWrapper(WOLFSSL* ssl); WOLFSSL_API void* wolfSSL_X509_STORE_CTX_get_ex_data( From 9337cfbb16328b5dccf5ad96855fe24e18c0da84 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 21 Nov 2023 16:30:18 +0100 Subject: [PATCH 3/5] Add wolfSSL_get_sigalg_info --- doc/dox_comments/header_files/ssl.h | 41 +++++++++-- src/internal.c | 4 +- src/ssl.c | 106 ++++++++++++++++++++++++++++ tests/api.c | 73 ++++++++++++------- wolfssl/internal.h | 7 +- wolfssl/ssl.h | 4 +- 6 files changed, 200 insertions(+), 35 deletions(-) diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index 4c207fda6..67427d9f6 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -14882,7 +14882,7 @@ int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buffer, wolfSSL_get_client_suites_sigalgs(ssl, &suites, &suiteSz, &hashSigAlgo, &hashSigAlgoSz); - // Choose certificate to load based on ciphersuites + // Choose certificate to load based on ciphersuites and sigalgs } WOLFSSL* ctx; @@ -14890,8 +14890,8 @@ int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buffer, wolfSSL_CTX_set_cert_cb(ctx, certCB, NULL); \endcode - \sa wolfSSL_new - \sa wolfSSL_free + \sa wolfSSL_get_ciphersuite_info + \sa wolfSSL_get_sigalg_info */ void wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl, const byte** suites, word16* suiteSz, @@ -14919,8 +14919,39 @@ void wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl, haveECC = 1; \endcode - \sa wolfSSL_new - \sa wolfSSL_free + \sa wolfSSL_get_client_suites_sigalgs + \sa wolfSSL_get_sigalg_info */ WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first, byte second); + +/*! + \ingroup TLS + + \brief This returns information about the hash and signature algorithm + directly from the raw ciphersuite bytes. + + \param [in] first First byte of the hash and signature algorith + \param [in] second Second byte of the hash and signature algorith + \param [out] hashAlgo The enum wc_HashType of the MAC algorithm + \param [out] sigAlgo The enum Key_Sum of the authentication algorithm + + _Example_ + \code + enum wc_HashType hashAlgo; + enum Key_Sum sigAlgo; + + wolfSSL_get_sigalg_info(hashSigAlgo[idx+0], hashSigAlgo[idx+1], + &hashAlgo, &sigAlgo); + + if (sigAlgo == RSAk || sigAlgo == RSAPSSk) + haveRSA = 1; + else if (sigAlgo == ECDSAk) + haveECC = 1; + \endcode + + \sa wolfSSL_get_client_suites_sigalgs + \sa wolfSSL_get_ciphersuite_info +*/ +void wolfSSL_get_sigalg_info(byte first, byte second, + enum wc_HashType* hashAlgo, enum Key_Sum* sigAlgo); diff --git a/src/internal.c b/src/internal.c index 8db5e7b8b..786d12261 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4236,7 +4236,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, * hashalgo The hash algorithm. * hsType The signature type. */ -static WC_INLINE void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType) +WC_INLINE void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType) { *hsType = invalid_sa_algo; switch (input[0]) { @@ -4324,7 +4324,7 @@ static WC_INLINE void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsTy #if !defined(NO_DH) || defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ defined(HAVE_CURVE448) || (!defined(NO_RSA) && defined(WC_RSA_PSS)) -static enum wc_HashType HashAlgoToType(int hashAlgo) +enum wc_HashType HashAlgoToType(int hashAlgo) { switch (hashAlgo) { #ifdef WOLFSSL_SHA512 diff --git a/src/ssl.c b/src/ssl.c index 22782e9f4..8f08b7375 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16338,6 +16338,112 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return info; } + void wolfSSL_get_sigalg_info(byte first, byte second, + enum wc_HashType* hashAlgo, enum Key_Sum* sigAlgo) + { + byte input[2]; + byte hashType; + byte sigType; + + if (hashAlgo == NULL || sigAlgo == NULL) + return; + + input[0] = first; + input[1] = second; + DecodeSigAlg(input, &hashType, &sigType); + + /* cast so that compiler reminds us of unimplemented values */ + switch ((enum SignatureAlgorithm)sigType) { + case anonymous_sa_algo: + *sigAlgo = (enum Key_Sum)0; + break; + case rsa_sa_algo: + *sigAlgo = RSAk; + break; + case dsa_sa_algo: + *sigAlgo = DSAk; + break; + case ecc_dsa_sa_algo: + *sigAlgo = ECDSAk; + break; + case rsa_pss_sa_algo: + *sigAlgo = RSAPSSk; + break; + case ed25519_sa_algo: + *sigAlgo = ED25519k; + break; + case rsa_pss_pss_algo: + *sigAlgo = RSAPSSk; + break; + case ed448_sa_algo: + *sigAlgo = ED448k; + break; + case falcon_level1_sa_algo: + *sigAlgo = FALCON_LEVEL1k; + break; + case falcon_level5_sa_algo: + *sigAlgo = FALCON_LEVEL5k; + break; + case dilithium_level2_sa_algo: + *sigAlgo = DILITHIUM_LEVEL2k; + break; + case dilithium_level3_sa_algo: + *sigAlgo = DILITHIUM_LEVEL3k; + break; + case dilithium_level5_sa_algo: + *sigAlgo = DILITHIUM_LEVEL5k; + break; + case sm2_sa_algo: + *sigAlgo = SM2k; + break; + case invalid_sa_algo: + default: + *hashAlgo = WC_HASH_TYPE_NONE; + *sigAlgo = (enum Key_Sum)0; + return; + } + + /* cast so that compiler reminds us of unimplemented values */ + switch((enum wc_MACAlgorithm)hashType) { + case no_mac: + case rmd_mac: /* Don't have a RIPEMD type in wc_HashType */ + *hashAlgo = WC_HASH_TYPE_NONE; + break; + case md5_mac: + *hashAlgo = WC_HASH_TYPE_MD5; + break; + case sha_mac: + *hashAlgo = WC_HASH_TYPE_SHA; + break; + case sha224_mac: + *hashAlgo = WC_HASH_TYPE_SHA224; + break; + case sha256_mac: + *hashAlgo = WC_HASH_TYPE_SHA256; + break; + case sha384_mac: + *hashAlgo = WC_HASH_TYPE_SHA384; + break; + case sha512_mac: + *hashAlgo = WC_HASH_TYPE_SHA512; + break; + case blake2b_mac: + *hashAlgo = WC_HASH_TYPE_BLAKE2B; + break; + case sm3_mac: +#ifdef WOLFSSL_SM3 + *hashAlgo = WC_HASH_TYPE_SM3; +#else + *hashAlgo = WC_HASH_TYPE_NONE; +#endif + break; + default: + *hashAlgo = WC_HASH_TYPE_NONE; + *sigAlgo = (enum Key_Sum)0; + return; + } + } + /** * Internal wrapper for calling certSetupCb * @param ssl The SSL/TLS Object diff --git a/tests/api.c b/tests/api.c index 18781eb94..d9710a98f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -44865,31 +44865,16 @@ static int test_wolfSSL_cert_cb_dyn_ciphers_certCB(WOLFSSL* ssl, void* arg) haveECC = 0; } for (idx = 0; idx < hashSigAlgoSz; idx += 2) { - /* Based on DecodeSigAlg. Enums are not exposed so need to use magic - * numbers. */ - switch (hashSigAlgo[idx+0]) { - case 8: - switch (hashSigAlgo[idx+1]) { - case 7: /* ED25519 */ - case 8: /* ED448 */ - haveECC = 1; - break; - default: - /* RSA-PSS */ - haveRSA = 1; - break; - } - break; - default: - switch (hashSigAlgo[idx+1]) { - case 1: /* RSA */ - haveRSA = 1; - break; - case 3: /* ECC */ - haveECC = 1; - break; - } - } + enum wc_HashType hashAlgo; + enum Key_Sum sigAlgo; + + wolfSSL_get_sigalg_info(hashSigAlgo[idx+0], hashSigAlgo[idx+1], + &hashAlgo, &sigAlgo); + + if (sigAlgo == RSAk || sigAlgo == RSAPSSk) + haveRSA = 1; + else if (sigAlgo == ECDSAk) + haveECC = 1; } if (haveRSA) { @@ -45082,6 +45067,43 @@ static int test_wolfSSL_ciphersuite_auth(void) return EXPECT_RESULT(); } +static int test_wolfSSL_sigalg_info(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) + byte hashSigAlgo[WOLFSSL_MAX_SIGALGO]; + word16 len = 0; + word16 idx = 0; + int allSigAlgs = SIG_ECDSA | SIG_RSA | SIG_SM2 | SIG_FALCON | SIG_DILITHIUM; + + InitSuitesHashSigAlgo_ex2(hashSigAlgo, allSigAlgs, 1, 0xFFFFFFFF, &len); + for (idx = 0; idx < len; idx += 2) { + enum wc_HashType hashAlgo; + enum Key_Sum sigAlgo; + + wolfSSL_get_sigalg_info(hashSigAlgo[idx+0], hashSigAlgo[idx+1], + &hashAlgo, &sigAlgo); + + ExpectIntNE(hashAlgo, 0); + ExpectIntNE(sigAlgo, 0); + } + + InitSuitesHashSigAlgo_ex2(hashSigAlgo, allSigAlgs | SIG_ANON, 1, + 0xFFFFFFFF, &len); + for (idx = 0; idx < len; idx += 2) { + enum wc_HashType hashAlgo; + enum Key_Sum sigAlgo; + + wolfSSL_get_sigalg_info(hashSigAlgo[idx+0], hashSigAlgo[idx+1], + &hashAlgo, &sigAlgo); + + ExpectIntNE(hashAlgo, 0); + } + +#endif + return EXPECT_RESULT(); +} + static int test_wolfSSL_SESSION(void) { EXPECT_DECLS; @@ -69268,6 +69290,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_cert_cb), TEST_DECL(test_wolfSSL_cert_cb_dyn_ciphers), TEST_DECL(test_wolfSSL_ciphersuite_auth), + TEST_DECL(test_wolfSSL_sigalg_info), /* Can't memory test as tcp_connect aborts. */ TEST_DECL(test_wolfSSL_SESSION), TEST_DECL(test_wolfSSL_SESSION_expire_downgrade), diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 071261cb7..8480fbed1 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2352,7 +2352,8 @@ WOLFSSL_LOCAL void InitSuitesHashSigAlgo_ex(byte* hashSigAlgo, int haveECDSAsig, int haveRSAsig, int haveFalconSig, int haveDilithiumSig, int haveAnon, int tls1_2, int keySz, word16* len); -WOLFSSL_LOCAL void InitSuitesHashSigAlgo_ex2(byte* hashSigAlgo, int have, +/* use wolfSSL_API visibility to be able to test in tests/api.c */ +WOLFSSL_API void InitSuitesHashSigAlgo_ex2(byte* hashSigAlgo, int have, int tls1_2, int keySz, word16* len); WOLFSSL_LOCAL int AllocateCtxSuites(WOLFSSL_CTX* ctx); @@ -6325,6 +6326,10 @@ WOLFSSL_LOCAL word32 LowResTimer(void); WOLFSSL_LOCAL int FindSuiteSSL(const WOLFSSL* ssl, byte* suite); +WOLFSSL_LOCAL void DecodeSigAlg(const byte* input, byte* hashAlgo, + byte* hsType); +WOLFSSL_LOCAL enum wc_HashType HashAlgoToType(int hashAlgo); + #ifndef NO_CERTS WOLFSSL_LOCAL void InitX509Name(WOLFSSL_X509_NAME* name, int dynamicFlag, void* heap); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 5bc473063..0c4690131 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1531,9 +1531,7 @@ WOLFSSL_API int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in); WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx); WOLFSSL_API int wolfSSL_sk_push(WOLFSSL_STACK *st, const void *data); -#if defined(HAVE_OCSP) || defined(HAVE_CRL) #include "wolfssl/wolfcrypt/asn.h" -#endif #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(WOLFSSL_QT) WOLFSSL_API int wolfSSL_sk_ACCESS_DESCRIPTION_push( @@ -2132,6 +2130,8 @@ typedef struct WOLFSSL_CIPHERSUITE_INFO { } WOLFSSL_CIPHERSUITE_INFO; WOLFSSL_API WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first, byte second); +WOLFSSL_API void wolfSSL_get_sigalg_info(byte first, + byte second, enum wc_HashType* hashAlgo, enum Key_Sum* sigAlgo); WOLFSSL_LOCAL int CertSetupCbWrapper(WOLFSSL* ssl); WOLFSSL_API void* wolfSSL_X509_STORE_CTX_get_ex_data( From 3edfcfe162c2836faa012d37ab68442e978a98ce Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 29 Nov 2023 18:02:36 +0100 Subject: [PATCH 4/5] Jenkins fixes --- doc/dox_comments/header_files/ssl.h | 6 +++--- src/internal.c | 2 +- src/ssl.c | 12 +++++++++--- tests/api.c | 12 ++++++------ wolfssl/ssl.h | 4 +++- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index 67427d9f6..0c7302142 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -14931,8 +14931,8 @@ WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first, \brief This returns information about the hash and signature algorithm directly from the raw ciphersuite bytes. - \param [in] first First byte of the hash and signature algorith - \param [in] second Second byte of the hash and signature algorith + \param [in] first First byte of the hash and signature algorithm + \param [in] second Second byte of the hash and signature algorithm \param [out] hashAlgo The enum wc_HashType of the MAC algorithm \param [out] sigAlgo The enum Key_Sum of the authentication algorithm @@ -14954,4 +14954,4 @@ WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first, \sa wolfSSL_get_ciphersuite_info */ void wolfSSL_get_sigalg_info(byte first, byte second, - enum wc_HashType* hashAlgo, enum Key_Sum* sigAlgo); + int* hashAlgo, int* sigAlgo); diff --git a/src/internal.c b/src/internal.c index 786d12261..db44fe38b 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4236,7 +4236,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, * hashalgo The hash algorithm. * hsType The signature type. */ -WC_INLINE void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType) +void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType) { *hsType = invalid_sa_algo; switch (input[0]) { diff --git a/src/ssl.c b/src/ssl.c index 8f08b7375..1b89cd65d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16338,8 +16338,14 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return info; } + /** + * @param first First byte of the hash and signature algorithm + * @param second Second byte of the hash and signature algorithm + * @param hashAlgo The enum wc_HashType of the MAC algorithm + * @param sigAlgo The enum Key_Sum of the authentication algorithm + */ void wolfSSL_get_sigalg_info(byte first, byte second, - enum wc_HashType* hashAlgo, enum Key_Sum* sigAlgo) + int* hashAlgo, int* sigAlgo) { byte input[2]; byte hashType; @@ -16399,7 +16405,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) case invalid_sa_algo: default: *hashAlgo = WC_HASH_TYPE_NONE; - *sigAlgo = (enum Key_Sum)0; + *sigAlgo = 0; return; } @@ -16439,7 +16445,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) break; default: *hashAlgo = WC_HASH_TYPE_NONE; - *sigAlgo = (enum Key_Sum)0; + *sigAlgo = 0; return; } } diff --git a/tests/api.c b/tests/api.c index d9710a98f..2acd9bc0f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -44865,8 +44865,8 @@ static int test_wolfSSL_cert_cb_dyn_ciphers_certCB(WOLFSSL* ssl, void* arg) haveECC = 0; } for (idx = 0; idx < hashSigAlgoSz; idx += 2) { - enum wc_HashType hashAlgo; - enum Key_Sum sigAlgo; + int hashAlgo; + int sigAlgo; wolfSSL_get_sigalg_info(hashSigAlgo[idx+0], hashSigAlgo[idx+1], &hashAlgo, &sigAlgo); @@ -45078,8 +45078,8 @@ static int test_wolfSSL_sigalg_info(void) InitSuitesHashSigAlgo_ex2(hashSigAlgo, allSigAlgs, 1, 0xFFFFFFFF, &len); for (idx = 0; idx < len; idx += 2) { - enum wc_HashType hashAlgo; - enum Key_Sum sigAlgo; + int hashAlgo; + int sigAlgo; wolfSSL_get_sigalg_info(hashSigAlgo[idx+0], hashSigAlgo[idx+1], &hashAlgo, &sigAlgo); @@ -45091,8 +45091,8 @@ static int test_wolfSSL_sigalg_info(void) InitSuitesHashSigAlgo_ex2(hashSigAlgo, allSigAlgs | SIG_ANON, 1, 0xFFFFFFFF, &len); for (idx = 0; idx < len; idx += 2) { - enum wc_HashType hashAlgo; - enum Key_Sum sigAlgo; + int hashAlgo; + int sigAlgo; wolfSSL_get_sigalg_info(hashSigAlgo[idx+0], hashSigAlgo[idx+1], &hashAlgo, &sigAlgo); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 0c4690131..a0263f28a 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1531,7 +1531,9 @@ WOLFSSL_API int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in); WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx); WOLFSSL_API int wolfSSL_sk_push(WOLFSSL_STACK *st, const void *data); +#if defined(HAVE_OCSP) || defined(HAVE_CRL) #include "wolfssl/wolfcrypt/asn.h" +#endif #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(WOLFSSL_QT) WOLFSSL_API int wolfSSL_sk_ACCESS_DESCRIPTION_push( @@ -2131,7 +2133,7 @@ typedef struct WOLFSSL_CIPHERSUITE_INFO { WOLFSSL_API WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first, byte second); WOLFSSL_API void wolfSSL_get_sigalg_info(byte first, - byte second, enum wc_HashType* hashAlgo, enum Key_Sum* sigAlgo); + byte second, int* hashAlgo, int* sigAlgo); WOLFSSL_LOCAL int CertSetupCbWrapper(WOLFSSL* ssl); WOLFSSL_API void* wolfSSL_X509_STORE_CTX_get_ex_data( From fbe79d73178e37f80b05d9fbf193f8574b98fe8a Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 7 Dec 2023 11:13:16 +0100 Subject: [PATCH 5/5] Code review --- doc/dox_comments/header_files/ssl.h | 19 +++++++++++++------ src/ssl.c | 13 ++++++++----- tests/api.c | 18 ++++++++++-------- wolfssl/ssl.h | 4 ++-- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index 0c7302142..5965f11d3 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -14865,10 +14865,13 @@ int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buffer, ciphersuites and signature algorithms. \param [in] ssl The WOLFSSL object to extract the lists from. - \param [out] suites Raw and unfiltered list of client ciphersuites - \param [out] suiteSz Size of suites in bytes - \param [out] hashSigAlgo Raw and unfiltered list of client signature algorithms - \param [out] hashSigAlgoSz Size of hashSigAlgo in bytes + \param [out] optional suites Raw and unfiltered list of client ciphersuites + \param [out] optional suiteSz Size of suites in bytes + \param [out] optional hashSigAlgo Raw and unfiltered list of client + signature algorithms + \param [out] optional hashSigAlgoSz Size of hashSigAlgo in bytes + \return WOLFSSL_SUCCESS when suites available + \return WOLFSSL_FAILURE when suites not available _Example_ \code @@ -14893,7 +14896,7 @@ int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buffer, \sa wolfSSL_get_ciphersuite_info \sa wolfSSL_get_sigalg_info */ -void wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl, +int wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl, const byte** suites, word16* suiteSz, const byte** hashSigAlgo, word16* hashSigAlgoSz); @@ -14936,6 +14939,10 @@ WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first, \param [out] hashAlgo The enum wc_HashType of the MAC algorithm \param [out] sigAlgo The enum Key_Sum of the authentication algorithm + \return 0 when info was correctly set + \return BAD_FUNC_ARG when either input paramters are NULL or the bytes + are not a recognized sigalg suite + _Example_ \code enum wc_HashType hashAlgo; @@ -14953,5 +14960,5 @@ WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first, \sa wolfSSL_get_client_suites_sigalgs \sa wolfSSL_get_ciphersuite_info */ -void wolfSSL_get_sigalg_info(byte first, byte second, +int wolfSSL_get_sigalg_info(byte first, byte second, int* hashAlgo, int* sigAlgo); diff --git a/src/ssl.c b/src/ssl.c index 1b89cd65d..8a271c9d0 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16296,7 +16296,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) ctx->certSetupCbArg = arg; } - void wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl, + int wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl, const byte** suites, word16* suiteSz, const byte** hashSigAlgo, word16* hashSigAlgoSz) { @@ -16320,7 +16320,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl) *hashSigAlgo = ssl->clSuites->hashSigAlgo; *hashSigAlgoSz = ssl->clSuites->hashSigAlgoSz; } + return WOLFSSL_SUCCESS; } + return WOLFSSL_FAILURE; } WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first, byte second) @@ -16344,7 +16346,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) * @param hashAlgo The enum wc_HashType of the MAC algorithm * @param sigAlgo The enum Key_Sum of the authentication algorithm */ - void wolfSSL_get_sigalg_info(byte first, byte second, + int wolfSSL_get_sigalg_info(byte first, byte second, int* hashAlgo, int* sigAlgo) { byte input[2]; @@ -16352,7 +16354,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) byte sigType; if (hashAlgo == NULL || sigAlgo == NULL) - return; + return BAD_FUNC_ARG; input[0] = first; input[1] = second; @@ -16406,7 +16408,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) default: *hashAlgo = WC_HASH_TYPE_NONE; *sigAlgo = 0; - return; + return BAD_FUNC_ARG; } /* cast so that compiler reminds us of unimplemented values */ @@ -16446,8 +16448,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl) default: *hashAlgo = WC_HASH_TYPE_NONE; *sigAlgo = 0; - return; + return BAD_FUNC_ARG; } + return 0; } /** diff --git a/tests/api.c b/tests/api.c index 2acd9bc0f..0cc6e59dd 100644 --- a/tests/api.c +++ b/tests/api.c @@ -44843,8 +44843,9 @@ static int test_wolfSSL_cert_cb_dyn_ciphers_certCB(WOLFSSL* ssl, void* arg) (void)arg; - wolfSSL_get_client_suites_sigalgs(ssl, &suites, &suiteSz, &hashSigAlgo, - &hashSigAlgoSz); + if (wolfSSL_get_client_suites_sigalgs(ssl, &suites, &suiteSz, &hashSigAlgo, + &hashSigAlgoSz) != WOLFSSL_SUCCESS) + return 0; if (suites == NULL || suiteSz == 0 || hashSigAlgo == NULL || hashSigAlgoSz == 0) return 0; @@ -44868,8 +44869,9 @@ static int test_wolfSSL_cert_cb_dyn_ciphers_certCB(WOLFSSL* ssl, void* arg) int hashAlgo; int sigAlgo; - wolfSSL_get_sigalg_info(hashSigAlgo[idx+0], hashSigAlgo[idx+1], - &hashAlgo, &sigAlgo); + if (wolfSSL_get_sigalg_info(hashSigAlgo[idx+0], hashSigAlgo[idx+1], + &hashAlgo, &sigAlgo) != 0) + return 0; if (sigAlgo == RSAk || sigAlgo == RSAPSSk) haveRSA = 1; @@ -45081,8 +45083,8 @@ static int test_wolfSSL_sigalg_info(void) int hashAlgo; int sigAlgo; - wolfSSL_get_sigalg_info(hashSigAlgo[idx+0], hashSigAlgo[idx+1], - &hashAlgo, &sigAlgo); + ExpectIntEQ(wolfSSL_get_sigalg_info(hashSigAlgo[idx+0], + hashSigAlgo[idx+1], &hashAlgo, &sigAlgo), 0); ExpectIntNE(hashAlgo, 0); ExpectIntNE(sigAlgo, 0); @@ -45094,8 +45096,8 @@ static int test_wolfSSL_sigalg_info(void) int hashAlgo; int sigAlgo; - wolfSSL_get_sigalg_info(hashSigAlgo[idx+0], hashSigAlgo[idx+1], - &hashAlgo, &sigAlgo); + ExpectIntEQ(wolfSSL_get_sigalg_info(hashSigAlgo[idx+0], + hashSigAlgo[idx+1], &hashAlgo, &sigAlgo), 0); ExpectIntNE(hashAlgo, 0); } diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index a0263f28a..c78d6b6f7 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2121,7 +2121,7 @@ WOLFSSL_API void wolfSSL_CTX_set_client_cert_cb(WOLFSSL_CTX *ctx, client_cert_cb typedef int (*CertSetupCallback)(WOLFSSL* ssl, void*); WOLFSSL_API void wolfSSL_CTX_set_cert_cb(WOLFSSL_CTX* ctx, CertSetupCallback cb, void *arg); -WOLFSSL_API void wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl, +WOLFSSL_API int wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl, const byte** suites, word16* suiteSz, const byte** hashSigAlgo, word16* hashSigAlgoSz); typedef struct WOLFSSL_CIPHERSUITE_INFO { @@ -2132,7 +2132,7 @@ typedef struct WOLFSSL_CIPHERSUITE_INFO { } WOLFSSL_CIPHERSUITE_INFO; WOLFSSL_API WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first, byte second); -WOLFSSL_API void wolfSSL_get_sigalg_info(byte first, +WOLFSSL_API int wolfSSL_get_sigalg_info(byte first, byte second, int* hashAlgo, int* sigAlgo); WOLFSSL_LOCAL int CertSetupCbWrapper(WOLFSSL* ssl);