From 9337cfbb16328b5dccf5ad96855fe24e18c0da84 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 21 Nov 2023 16:30:18 +0100 Subject: [PATCH] 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(