Add API to get information about ciphersuites

This commit is contained in:
Juliusz Sosinowicz
2023-11-20 14:15:13 +01:00
parent fbd8996949
commit 7c2344c389
6 changed files with 205 additions and 28 deletions

View File

@ -14854,3 +14854,73 @@ available size need to be provided in bufferSz.
*/ */
int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buffer, int wolfSSL_dtls_cid_get_tx(WOLFSSL* ssl, unsigned char* buffer,
unsigned int bufferSz); 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);

View File

@ -11222,23 +11222,11 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
#endif /* WOLFSSL_NO_TLS12 */ #endif /* WOLFSSL_NO_TLS12 */
#if !defined(NO_WOLFSSL_SERVER) || !defined(NO_WOLFSSL_CLIENT) #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 /* Does this cipher suite (first, second) have the requirement
an ephemeral key exchange will still require the key for signing an ephemeral key exchange will still require the key for signing
the key exchange so ECDHE_RSA requires an rsa key thus rsa_kea */ 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; (void)requirement;

View File

@ -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 * Internal wrapper for calling certSetupCb

View File

@ -370,7 +370,7 @@
defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)) || \ defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)) || \
defined(WOLFSSL_TEST_STATIC_BUILD) || defined(WOLFSSL_DTLS) || \ defined(WOLFSSL_TEST_STATIC_BUILD) || defined(WOLFSSL_DTLS) || \
defined(HAVE_ECH) || defined(HAVE_EX_DATA) || !defined(NO_SESSION_CACHE) \ 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 testing SSL_get_peer_cert_chain, or SESSION_TICKET_HINT_DEFAULT,
* for setting authKeyIdSrc in WOLFSSL_X509, or testing DTLS sequence * for setting authKeyIdSrc in WOLFSSL_X509, or testing DTLS sequence
* number tracking */ * number tracking */
@ -44849,20 +44849,14 @@ static int test_wolfSSL_cert_cb_dyn_ciphers_certCB(WOLFSSL* ssl, void* arg)
hashSigAlgoSz == 0) hashSigAlgoSz == 0)
return 0; return 0;
if (wolfSSL_GetVersion(ssl) != TLSv1_3_MINOR) { for (idx = 0; idx < suiteSz; idx += 2) {
for (idx = 0; idx < suiteSz; idx += 2) { WOLFSSL_CIPHERSUITE_INFO info =
const char* cipherName = wolfSSL_get_cipher_name_from_suite( wolfSSL_get_ciphersuite_info(suites[idx], suites[idx+1]);
suites[idx], suites[idx+1]);
if (cipherName == NULL) if (info.rsaAuth)
return 0; haveRSA = 1;
/* TLS 1.3 suites tell us nothing about the sigalg */ else if (info.eccAuth)
if (XSTRSTR(cipherName, "TLS13-") != NULL) haveECC = 1;
continue;
if (XSTRSTR(cipherName, "-RSA-") != NULL)
haveRSA = 1;
if (XSTRSTR(cipherName, "-ECDSA-") != NULL)
haveECC = 1;
}
} }
if (hashSigAlgoSz > 0) { if (hashSigAlgoSz > 0) {
@ -44998,6 +44992,96 @@ static int test_wolfSSL_cert_cb_dyn_ciphers(void)
return EXPECT_RESULT(); 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) static int test_wolfSSL_SESSION(void)
{ {
EXPECT_DECLS; EXPECT_DECLS;
@ -69183,6 +69267,7 @@ TEST_CASE testCases[] = {
#endif #endif
TEST_DECL(test_wolfSSL_cert_cb), TEST_DECL(test_wolfSSL_cert_cb),
TEST_DECL(test_wolfSSL_cert_cb_dyn_ciphers), TEST_DECL(test_wolfSSL_cert_cb_dyn_ciphers),
TEST_DECL(test_wolfSSL_ciphersuite_auth),
/* Can't memory test as tcp_connect aborts. */ /* Can't memory test as tcp_connect aborts. */
TEST_DECL(test_wolfSSL_SESSION), TEST_DECL(test_wolfSSL_SESSION),
TEST_DECL(test_wolfSSL_SESSION_expire_downgrade), TEST_DECL(test_wolfSSL_SESSION_expire_downgrade),

View File

@ -6014,6 +6014,16 @@ enum ProvisionSide {
PROVISION_CLIENT_SERVER = 3 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 kTlsClientStr[SIZEOF_SENDER+1] = { 0x43, 0x4C, 0x4E, 0x54, 0x00 }; /* CLNT */
static const byte kTlsServerStr[SIZEOF_SENDER+1] = { 0x53, 0x52, 0x56, 0x52, 0x00 }; /* SRVR */ 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 void ShrinkOutputBuffer(WOLFSSL* ssl);
WOLFSSL_LOCAL byte* GetOutputBuffer(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, WOLFSSL_LOCAL int VerifyClientSuite(word16 havePSK, byte cipherSuite0,
byte cipherSuite); byte cipherSuite);

View File

@ -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, WOLFSSL_API void wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl,
const byte** suites, word16* suiteSz, const byte** suites, word16* suiteSz,
const byte** hashSigAlgo, word16* hashSigAlgoSz); 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_LOCAL int CertSetupCbWrapper(WOLFSSL* ssl);
WOLFSSL_API void* wolfSSL_X509_STORE_CTX_get_ex_data( WOLFSSL_API void* wolfSSL_X509_STORE_CTX_get_ex_data(