mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-29 18:27:29 +02:00
Add API to get information about ciphersuites
This commit is contained in:
@ -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);
|
||||
|
@ -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;
|
||||
|
15
src/ssl.c
15
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
|
||||
|
115
tests/api.c
115
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),
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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(
|
||||
|
Reference in New Issue
Block a user