mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 14:00:48 +02:00
Fix cipher property NIDs for SSL_get_current_cipher and add PSK kx mapping
The cipher property helpers (SSL_CIPHER_get_kx_nid / get_auth_nid / get_cipher_nid / get_digest_nid / is_aead) parse the cipher name looked up via cipher->offset in GetCipherSegment(). That offset is only populated when the cipher is obtained through wolfSSL_get_ciphers_compat() (SSL_get_ciphers()). When the cipher comes from SSL_get_current_cipher(), offset is left at 0, so these helpers parsed cipher_names[0] (a TLS 1.3 suite) instead of the negotiated cipher - e.g. returning NID_kx_any for a plain PSK suite while SSL_CIPHER_get_name() (which uses the suite bytes) reported the correct name. Resolve the cipher_names entry from the always-populated suite bytes in GetCipherSegment(), falling back to cipher->offset when no match is found. Also add the missing plain "PSK" -> NID_kx_psk entry to the kx lookup table so PSK suites report NID_kx_psk instead of NID_undef. Add a regression test that drives the SSL_get_current_cipher() path for TLS_PSK_WITH_AES_128_GCM_SHA256 and checks all five property helpers.
This commit is contained in:
@@ -28749,6 +28749,29 @@ const char* GetCipherSegment(const WOLFSSL_CIPHER* cipher, char n[][MAX_SEGMENT_
|
||||
|
||||
offset = cipher->offset;
|
||||
|
||||
/* The offset field is only populated when the cipher is obtained through
|
||||
* wolfSSL_get_ciphers_compat() (e.g. SSL_get_ciphers()). When the cipher
|
||||
* comes from wolfSSL_get_current_cipher() the offset is left at its default
|
||||
* value of 0, which would make the parsing below operate on
|
||||
* cipher_names[0] (a TLS 1.3 suite) rather than on the actual cipher. The
|
||||
* suite bytes are always populated, so resolve the offset from them. */
|
||||
{
|
||||
int idx;
|
||||
int namesSz = GetCipherNamesSize();
|
||||
for (idx = 0; idx < namesSz; idx++) {
|
||||
if (cipher_names[idx].cipherSuite0 == cipher->cipherSuite0 &&
|
||||
cipher_names[idx].cipherSuite == cipher->cipherSuite
|
||||
#ifndef NO_CIPHER_SUITE_ALIASES
|
||||
&& (!(cipher_names[idx].flags &
|
||||
WOLFSSL_CIPHER_SUITE_FLAG_NAMEALIAS))
|
||||
#endif
|
||||
) {
|
||||
offset = (unsigned long)idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (offset >= (unsigned long)GetCipherNamesSize())
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -11321,6 +11321,7 @@ int wolfSSL_CIPHER_get_kx_nid(const WOLFSSL_CIPHER* cipher)
|
||||
{"RSAPSK", WC_NID_kx_rsa_psk},
|
||||
{"SRP", WC_NID_kx_srp},
|
||||
{"EDH", WC_NID_kx_dhe},
|
||||
{"PSK", WC_NID_kx_psk},
|
||||
{"RSA", WC_NID_kx_rsa},
|
||||
{NULL, WC_NID_undef}
|
||||
};
|
||||
|
||||
+47
@@ -28172,6 +28172,52 @@ static int test_SSL_CIPHER_get_xxx(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* Regression test: the cipher property helpers (kx/auth/cipher/digest/aead)
|
||||
* must report the actual negotiated cipher when it is obtained through
|
||||
* SSL_get_current_cipher(). That path does not populate cipher->offset, so a
|
||||
* previous bug caused these helpers to parse cipher_names[0] (a TLS 1.3 suite)
|
||||
* instead, e.g. returning NID_kx_any for a plain PSK suite. */
|
||||
static int test_SSL_CIPHER_get_current_kx(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(OPENSSL_ALL) && !defined(NO_TLS) && \
|
||||
defined(BUILD_TLS_PSK_WITH_AES_128_GCM_SHA256)
|
||||
SSL_CTX* ctx = NULL;
|
||||
SSL* ssl = NULL;
|
||||
const SSL_CIPHER* cipher = NULL;
|
||||
|
||||
#ifndef NO_WOLFSSL_CLIENT
|
||||
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
|
||||
#else
|
||||
ExpectNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
|
||||
#endif
|
||||
ExpectNotNull(ssl = SSL_new(ctx));
|
||||
|
||||
/* Simulate a negotiated plain-PSK cipher suite without doing a full
|
||||
* handshake. SSL_get_current_cipher() reports the suite from these
|
||||
* fields, and leaves cipher->offset at its default value of 0. */
|
||||
if (ssl != NULL) {
|
||||
ssl->options.cipherSuite0 = CIPHER_BYTE; /* 0x00 */
|
||||
ssl->options.cipherSuite = TLS_PSK_WITH_AES_128_GCM_SHA256;
|
||||
}
|
||||
|
||||
ExpectNotNull(cipher = SSL_get_current_cipher(ssl));
|
||||
/* Name is resolved from the suite bytes and was already correct. */
|
||||
ExpectStrEQ(SSL_CIPHER_get_name(cipher), "TLS_PSK_WITH_AES_128_GCM_SHA256");
|
||||
/* These were wrong before the fix (read cipher_names[0]). */
|
||||
ExpectIntEQ(wolfSSL_CIPHER_get_kx_nid(cipher), NID_kx_psk);
|
||||
ExpectIntEQ(wolfSSL_CIPHER_get_auth_nid(cipher), NID_auth_psk);
|
||||
ExpectIntEQ(wolfSSL_CIPHER_get_cipher_nid(cipher), NID_aes_128_gcm);
|
||||
ExpectIntEQ(wolfSSL_CIPHER_get_digest_nid(cipher), NID_sha256);
|
||||
ExpectIntEQ(wolfSSL_CIPHER_is_aead(cipher), 1);
|
||||
|
||||
SSL_free(ssl);
|
||||
SSL_CTX_free(ctx);
|
||||
#endif
|
||||
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \
|
||||
(!defined(WOLF_CRYPTO_CB_ONLY_SHA256) && !defined(WOLF_CRYPTO_CB_ONLY_AES) && \
|
||||
!defined(WOLF_CRYPTO_CB_ONLY_ECC) && !defined(WOLF_CRYPTO_CB_ONLY_RSA))
|
||||
@@ -34955,6 +35001,7 @@ TEST_CASE testCases[] = {
|
||||
TEST_DECL(test_wolfSSL_get_peer_finished_overrun),
|
||||
#endif
|
||||
TEST_DECL(test_SSL_CIPHER_get_xxx),
|
||||
TEST_DECL(test_SSL_CIPHER_get_current_kx),
|
||||
TEST_DECL(test_wolfSSL_ERR_strings),
|
||||
TEST_DECL(test_wolfSSL_CTX_set_cipher_list_bytes),
|
||||
TEST_DECL(test_wolfSSL_set_cipher_list_tls12_keeps_tls13),
|
||||
|
||||
Reference in New Issue
Block a user