diff --git a/src/internal.c b/src/internal.c index a4e1829dd..e13e5536b 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2228,8 +2228,8 @@ static int GetMacDigestSize(byte macAlgo) } #endif /* USE_ECDSA_KEYSZ_HASH_ALGO */ -static WC_INLINE void AddSuiteHashSigAlgo(Suites* suites, byte macAlgo, byte sigAlgo, - int keySz, word16* inOutIdx) +static WC_INLINE void AddSuiteHashSigAlgo(Suites* suites, byte macAlgo, + byte sigAlgo, int keySz, word16* inOutIdx) { int addSigAlgo = 1; @@ -2246,6 +2246,24 @@ static WC_INLINE void AddSuiteHashSigAlgo(Suites* suites, byte macAlgo, byte sig #endif /* USE_ECDSA_KEYSZ_HASH_ALGO */ if (addSigAlgo) { + #ifdef HAVE_ED25519 + if (sigAlgo == ed25519_sa_algo) { + suites->hashSigAlgo[*inOutIdx] = ED25519_SA_MAJOR; + *inOutIdx += 1; + suites->hashSigAlgo[*inOutIdx] = ED25519_SA_MINOR; + *inOutIdx += 1; + } + else + #endif + #ifdef HAVE_ED448 + if (sigAlgo == ed448_sa_algo) { + suites->hashSigAlgo[*inOutIdx] = ED448_SA_MAJOR; + *inOutIdx += 1; + suites->hashSigAlgo[*inOutIdx] = ED448_SA_MINOR; + *inOutIdx += 1; + } + else + #endif #ifdef WC_RSA_PSS if (sigAlgo == rsa_pss_sa_algo) { /* RSA PSS is sig then mac */ @@ -2298,12 +2316,10 @@ void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, int haveRSAsig, #endif #endif #ifdef HAVE_ED25519 - AddSuiteHashSigAlgo(suites, ED25519_SA_MAJOR, ED25519_SA_MINOR, keySz, - &idx); + AddSuiteHashSigAlgo(suites, no_mac, ed25519_sa_algo, keySz, &idx); #endif #ifdef HAVE_ED448 - AddSuiteHashSigAlgo(suites, ED448_SA_MAJOR, ED448_SA_MINOR, keySz, - &idx); + AddSuiteHashSigAlgo(suites, no_mac, ed448_sa_algo, keySz, &idx); #endif } #endif /* HAVE_ECC || HAVE_ED25519 || defined(HAVE_ED448 */ @@ -3356,8 +3372,10 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suiteSz = idx; - InitSuitesHashSigAlgo(suites, haveECDSAsig | haveECC, haveRSAsig | haveRSA, - 0, tls1_2, keySz); + if (suites->hashSigAlgoSz == 0) { + InitSuitesHashSigAlgo(suites, haveECDSAsig | haveECC, + haveRSAsig | haveRSA, 0, tls1_2, keySz); + } } #if !defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS) || \ @@ -6751,7 +6769,7 @@ void FreeHandshakeResources(WOLFSSL* ssl) if (!ssl->options.tls1_3) #endif { - #ifndef OPENSSL_ALL + #ifndef OPENSSL_EXTRA /* free suites unless using compatibility layer */ FreeSuites(ssl); #endif @@ -20490,6 +20508,161 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) return ret; } +#ifdef OPENSSL_EXTRA + +struct mac_algs { + byte alg; + const char* name; +} mac_names[] = { +#ifndef NO_SHA256 + { sha256_mac, "SHA256" }, +#endif +#ifdef WOLFSSL_SHA384 + { sha384_mac, "SHA384" }, +#endif +#ifdef WOLFSSL_SHA512 + { sha512_mac, "SHA512" }, +#endif +#ifdef WOLFSSL_SHA224 + { sha224_mac, "SHA224" }, +#endif +#if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \ + defined(WOLFSSL_ALLOW_TLS_SHA1)) + { sha_mac, "SHA1" }, +#endif +}; +#define MAC_NAMES_SZ (int)(sizeof(mac_names)/sizeof(*mac_names)) + +/* Convert the hash algorithm string to a TLS MAC algorithm num. */ +static byte GetMacAlgFromName(const char* name, int len) +{ + byte alg = no_mac; + int i; + + for (i = 0; i < MAC_NAMES_SZ; i++) { + if (((int)XSTRLEN(mac_names[i].name) == len) && + (XMEMCMP(mac_names[i].name, name, len) == 0)) { + alg = mac_names[i].alg; + break; + } + } + + return alg; +} + +struct sig_algs { + byte alg; + const char* name; +} sig_names[] = { +#ifndef NO_RSA + { rsa_sa_algo, "RSA" }, +#ifdef WC_RSA_PSS + { rsa_pss_sa_algo, "RSA-PSS" }, + { rsa_pss_sa_algo, "PSS" }, +#endif +#endif +#ifdef HAVE_ECC + { ecc_dsa_sa_algo, "ECDSA" }, +#endif +#ifdef HAVE_ED25519 + { ed25519_sa_algo, "ED25519" }, +#endif +#ifdef HAVE_ED448 + { ed448_sa_algo, "ED448" }, +#endif +#ifndef NO_DSA + { dsa_sa_algo, "DSA" }, +#endif +}; +#define SIG_NAMES_SZ (int)(sizeof(sig_names)/sizeof(*sig_names)) + +/* Convert the signature algorithm string to a TLS signature algorithm num. */ +static byte GetSigAlgFromName(const char* name, int len) +{ + byte alg = anonymous_sa_algo; + int i; + + for (i = 0; i < SIG_NAMES_SZ; i++) { + if (((int)XSTRLEN(sig_names[i].name) == len) && + (XMEMCMP(sig_names[i].name, name, len) == 0)) { + alg = sig_names[i].alg; + break; + } + } + + return alg; +} + +/* Set the hash/signature algorithms that are supported for certificate signing. + * + * suites [in,out] Cipher suites and signature algorithms. + * list [in] String representing hash/signature algorithms to set. + * returns 0 on failure. + * 1 on success. + */ +int SetSuitesHashSigAlgo(Suites* suites, const char* list) +{ + int ret = 1; + word16 idx = 0; + const char* s = list; + byte sig_alg = 0; + byte mac_alg = no_mac; + + /* Setting is destructive on error. */ + suites->hashSigAlgoSz = 0; + + do { + if (*list == '+') { + if (mac_alg != 0) { + ret = 0; + break; + } + sig_alg = GetSigAlgFromName(s, (int)(list - s)); + if (sig_alg == 0) { + ret = 0; + break; + } + s = list + 1; + } + else if (*list == ':' || *list == '\0') { + if (sig_alg == 0) { + /* No signature algorithm set yet. + * Ed25519 and Ed448 have implied MAC algorithm. + */ + sig_alg = GetSigAlgFromName(s, (int)(list - s)); + if (sig_alg != ed25519_sa_algo && sig_alg != ed448_sa_algo) { + ret = 0; + break; + } + } + else { + mac_alg = GetMacAlgFromName(s, (int)(list - s)); + if (mac_alg == 0) { + ret = 0; + break; + } + } + AddSuiteHashSigAlgo(suites, mac_alg, sig_alg, 0, &idx); + sig_alg = 0; + mac_alg = no_mac; + s = list + 1; + } + + list++; + } + while (*(list-1) != '\0'); + + if (s != list && (sig_alg != 0 || mac_alg != 0)) { + ret = 0; + } + else { + suites->hashSigAlgoSz = idx; + } + + return ret; +} + +#endif /* OPENSSL_EXTRA */ #if !defined(NO_WOLFSSL_SERVER) || !defined(NO_CERTS) static int MatchSigAlgo(WOLFSSL* ssl, int sigAlgo) @@ -20681,7 +20854,7 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) case sha512_mac: #endif #ifdef WOLFSSL_STRONGEST_HASH_SIG - /* Is hash algorithm weaker than chosen/min? */ + /* Is hash algorithm weaker than chosen/min? */ if (hashAlgo < ssl->suites->hashAlgo) break; #else diff --git a/src/ssl.c b/src/ssl.c index 579e13fcc..28772bd84 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -12051,6 +12051,7 @@ int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list) WOLFSSL_MSG("Suites Memory error"); return MEMORY_E; } + *ssl->suites = *ssl->ctx->suites; ssl->options.ownSuites = 1; } #endif @@ -24427,30 +24428,11 @@ int wolfSSL_sk_CIPHER_description(WOLFSSL_CIPHER* cipher) } #endif /* OPENSSL_ALL || WOLFSSL_QT */ -char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in, - int len) +static WC_INLINE const char* wolfssl_kea_to_string(int kea) { - char *ret = in; - const char *keaStr, *authStr, *encStr, *macStr; - size_t strLen; - WOLFSSL_ENTER("wolfSSL_CIPHER_description"); + const char* keaStr; - if (cipher == NULL || in == NULL) - return NULL; - -#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) - /* if cipher is in the stack from wolfSSL_get_ciphers_compat then - * Return the description based on cipher_names[cipher->offset] - */ - if (cipher->in_stack == TRUE) { - wolfSSL_sk_CIPHER_description((WOLFSSL_CIPHER*)cipher); - XSTRNCPY(in,cipher->description,len); - return ret; - } -#endif - - /* Get the cipher description based on the SSL session cipher */ - switch (cipher->ssl->specs.kea) { + switch (kea) { case no_kea: keaStr = "None"; break; @@ -24500,7 +24482,14 @@ char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in, break; } - switch (cipher->ssl->specs.sig_algo) { + return keaStr; +} + +static WC_INLINE const char* wolfssl_sigalg_to_string(int sig_algo) +{ + const char* authStr; + + switch (sig_algo) { case anonymous_sa_algo: authStr = "None"; break; @@ -24508,6 +24497,11 @@ char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in, case rsa_sa_algo: authStr = "RSA"; break; + #ifdef WC_RSA_PSS + case rsa_pss_sa_algo: + authStr = "RSA-PSS"; + break; + #endif #endif #ifndef NO_DSA case dsa_sa_algo: @@ -24518,13 +24512,32 @@ char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in, case ecc_dsa_sa_algo: authStr = "ECDSA"; break; +#endif +#ifdef HAVE_ED25519 + case ed25519_sa_algo: + authStr = "Ed25519"; + break; +#endif +#ifdef HAVE_ED448 + case ed448_sa_algo: + authStr = "Ed448"; + break; #endif default: authStr = "unknown"; break; } - switch (cipher->ssl->specs.bulk_cipher_algorithm) { + return authStr; +} + +static WC_INLINE const char* wolfssl_cipher_to_string(int cipher, int key_size) +{ + const char* encStr; + + (void)key_size; + + switch (cipher) { case wolfssl_cipher_null: encStr = "None"; break; @@ -24545,18 +24558,18 @@ char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in, #endif #ifndef NO_AES case wolfssl_aes: - if (cipher->ssl->specs.key_size == 128) + if (key_size == 128) encStr = "AES(128)"; - else if (cipher->ssl->specs.key_size == 256) + else if (key_size == 256) encStr = "AES(256)"; else encStr = "AES(?)"; break; #ifdef HAVE_AESGCM case wolfssl_aes_gcm: - if (cipher->ssl->specs.key_size == 128) + if (key_size == 128) encStr = "AESGCM(128)"; - else if (cipher->ssl->specs.key_size == 256) + else if (key_size == 256) encStr = "AESGCM(256)"; else encStr = "AESGCM(?)"; @@ -24564,9 +24577,9 @@ char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in, #endif #ifdef HAVE_AESCCM case wolfssl_aes_ccm: - if (cipher->ssl->specs.key_size == 128) + if (key_size == 128) encStr = "AESCCM(128)"; - else if (cipher->ssl->specs.key_size == 256) + else if (key_size == 256) encStr = "AESCCM(256)"; else encStr = "AESCCM(?)"; @@ -24580,9 +24593,9 @@ char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in, #endif #ifdef HAVE_CAMELLIA case wolfssl_camellia: - if (cipher->ssl->specs.key_size == 128) + if (key_size == 128) encStr = "Camellia(128)"; - else if (cipher->ssl->specs.key_size == 256) + else if (key_size == 256) encStr = "Camellia(256)"; else encStr = "Camellia(?)"; @@ -24603,7 +24616,14 @@ char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in, break; } - switch (cipher->ssl->specs.mac_algorithm) { + return encStr; +} + +static WC_INLINE const char* wolfssl_mac_to_string(int mac) +{ + const char* macStr; + + switch (mac) { case no_mac: macStr = "None"; break; @@ -24642,6 +24662,38 @@ char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in, break; } + return macStr; +} + +char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in, + int len) +{ + char *ret = in; + const char *keaStr, *authStr, *encStr, *macStr; + size_t strLen; + WOLFSSL_ENTER("wolfSSL_CIPHER_description"); + + if (cipher == NULL || in == NULL) + return NULL; + +#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) + /* if cipher is in the stack from wolfSSL_get_ciphers_compat then + * Return the description based on cipher_names[cipher->offset] + */ + if (cipher->in_stack == TRUE) { + wolfSSL_sk_CIPHER_description((WOLFSSL_CIPHER*)cipher); + XSTRNCPY(in,cipher->description,len); + return ret; + } +#endif + + /* Get the cipher description based on the SSL session cipher */ + keaStr = wolfssl_kea_to_string(cipher->ssl->specs.kea); + authStr = wolfssl_sigalg_to_string(cipher->ssl->specs.sig_algo); + encStr = wolfssl_cipher_to_string(cipher->ssl->specs.bulk_cipher_algorithm, + cipher->ssl->specs.key_size); + macStr = wolfssl_mac_to_string(cipher->ssl->specs.mac_algorithm); + /* Build up the string by copying onto the end. */ XSTRNCPY(in, wolfSSL_CIPHER_get_name(cipher), len); in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen; @@ -35028,6 +35080,156 @@ int wolfSSL_PEM_write_RSAPrivateKey(XFILE fp, WOLFSSL_RSA *rsa, #endif /* NO_FILESYSTEM */ #endif /* WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA && WOLFSSL_PEM_TO_DER */ +/* Colon separated list of + algorithms. + * Replaces list in context. + */ +int wolfSSL_CTX_set1_sigalgs_list(WOLFSSL_CTX* ctx, const char* list) +{ + WOLFSSL_MSG("wolfSSL_CTX_set1_sigalg_list"); + + if (ctx == NULL || list == NULL) { + WOLFSSL_MSG("Bad function arguments"); + return WOLFSSL_FAILURE; + } + + /* alloc/init on demand only */ + if (ctx->suites == NULL) { + ctx->suites = (Suites*)XMALLOC(sizeof(Suites), ctx->heap, + DYNAMIC_TYPE_SUITES); + if (ctx->suites == NULL) { + WOLFSSL_MSG("Memory alloc for Suites failed"); + return WOLFSSL_FAILURE; + } + XMEMSET(ctx->suites, 0, sizeof(Suites)); + } + + return SetSuitesHashSigAlgo(ctx->suites, list); +} + +/* Colon separated list of + algorithms. + * Replaces list in SSL. + */ +int wolfSSL_set1_sigalgs_list(WOLFSSL* ssl, const char* list) +{ + WOLFSSL_MSG("wolfSSL_set1_sigalg_list"); + + if (ssl == NULL) { + WOLFSSL_MSG("Bad function arguments"); + return WOLFSSL_FAILURE; + } + +#ifdef SINGLE_THREADED + if (ssl->ctx->suites == ssl->suites) { + ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap, + DYNAMIC_TYPE_SUITES); + if (ssl->suites == NULL) { + WOLFSSL_MSG("Suites Memory error"); + return MEMORY_E; + } + *ssl->suites = *ssl->ctx->suites; + ssl->options.ownSuites = 1; + } +#endif + if (ssl == NULL || list == NULL) { + WOLFSSL_MSG("Bad function arguments"); + return WOLFSSL_FAILURE; + } + + return SetSuitesHashSigAlgo(ssl->suites, list); +} + +struct WOLFSSL_HashSigInfo { + int hashAlgo; + int sigAlgo; + int nid; +} wolfssl_hash_sig_info[] = +{ +#ifndef NO_RSA + #ifndef NO_SHA256 + { sha256_mac, rsa_sa_algo, CTC_SHA256wRSA }, + #endif + #ifdef WOLFSSL_SHA384 + { sha384_mac, rsa_sa_algo, CTC_SHA384wRSA }, + #endif + #ifdef WOLFSSL_SHA512 + { sha512_mac, rsa_sa_algo, CTC_SHA512wRSA }, + #endif + #ifdef WOLFSSL_SHA224 + { sha224_mac, rsa_sa_algo, CTC_SHA224wRSA }, + #endif + #ifndef NO_SHA + { sha_mac, rsa_sa_algo, CTC_SHAwRSA }, + #endif + #ifdef WC_RSA_PSS + #ifndef NO_SHA256 + { sha256_mac, rsa_pss_sa_algo, CTC_SHA256wRSA }, + #endif + #ifdef WOLFSSL_SHA384 + { sha384_mac, rsa_pss_sa_algo, CTC_SHA384wRSA }, + #endif + #ifdef WOLFSSL_SHA512 + { sha512_mac, rsa_pss_sa_algo, CTC_SHA512wRSA }, + #endif + #ifdef WOLFSSL_SHA224 + { sha224_mac, rsa_pss_sa_algo, CTC_SHA224wRSA }, + #endif + #endif +#endif +#ifdef HAVE_ECC + #ifndef NO_SHA256 + { sha256_mac, ecc_dsa_sa_algo, CTC_SHA256wECDSA }, + #endif + #ifdef WOLFSSL_SHA384 + { sha384_mac, ecc_dsa_sa_algo, CTC_SHA384wECDSA }, + #endif + #ifdef WOLFSSL_SHA512 + { sha512_mac, ecc_dsa_sa_algo, CTC_SHA512wECDSA }, + #endif + #ifdef WOLFSSL_SHA224 + { sha224_mac, ecc_dsa_sa_algo, CTC_SHA224wECDSA }, + #endif + #ifndef NO_SHA + { sha_mac, ecc_dsa_sa_algo, CTC_SHAwECDSA }, + #endif +#endif +#ifdef HAVE_ED25519 + { no_mac, ed25519_sa_algo, CTC_ED25519 }, +#endif +#ifdef HAVE_ED25519 + { no_mac, ed448_sa_algo, CTC_ED448 }, +#endif +#ifndef NO_DSA + #ifndef NO_SHA + { sha_mac, dsa_sa_algo, CTC_SHAwDSA }, + #endif +#endif +}; +#define WOLFSSL_HASH_SIG_INFO_SZ \ + (int)(sizeof(wolfssl_hash_sig_info)/sizeof(*wolfssl_hash_sig_info)) + +int wolfSSL_get_signature_nid(WOLFSSL *ssl, int* nid) +{ + int i; + int ret = WOLFSSL_FAILURE; + + WOLFSSL_MSG("wolfSSL_get_signature_nid"); + + if (ssl == NULL) { + WOLFSSL_MSG("Bad function arguments"); + return WOLFSSL_FAILURE; + } + + for (i = 0; i < WOLFSSL_HASH_SIG_INFO_SZ; i++) { + if (ssl->suites->hashAlgo == wolfssl_hash_sig_info[i].hashAlgo && + ssl->suites->sigAlgo == wolfssl_hash_sig_info[i].sigAlgo) { + *nid = wolfssl_hash_sig_info[i].nid; + ret = WOLFSSL_SUCCESS; + break; + } + } + + return ret; +} #ifdef HAVE_ECC diff --git a/tests/api.c b/tests/api.c index 4d3f1fb65..ef029386b 100644 --- a/tests/api.c +++ b/tests/api.c @@ -30558,6 +30558,128 @@ static void test_wolfSSL_sk_SSL_CIPHER(void) !defined(NO_FILESYSTEM) && !defined(NO_RSA) */ } +static void test_wolfSSL_set1_sigalgs_list(void) +{ + #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_RSA) + SSL* ssl; + SSL_CTX* ctx; + +#ifndef NO_WOLFSSL_SERVER + AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method())); +#else + AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method())); +#endif + AssertTrue(SSL_CTX_use_certificate_file(ctx, svrCertFile, + SSL_FILETYPE_PEM)); + AssertTrue(SSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, SSL_FILETYPE_PEM)); + AssertNotNull(ssl = SSL_new(ctx)); + + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(NULL, NULL), WOLFSSL_FAILURE); + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, NULL), WOLFSSL_FAILURE); + AssertIntEQ(wolfSSL_set1_sigalgs_list(NULL, NULL), WOLFSSL_FAILURE); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, NULL), WOLFSSL_FAILURE); + + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, ""), WOLFSSL_FAILURE); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, ""), WOLFSSL_FAILURE); + +#ifndef NO_RSA + #ifndef NO_SHA256 + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(NULL, "RSA+SHA256"), + WOLFSSL_FAILURE); + AssertIntEQ(wolfSSL_set1_sigalgs_list(NULL, "RSA+SHA256"), + WOLFSSL_FAILURE); + + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA+SHA256"), + WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA+SHA256"), + WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA-SHA256"), + WOLFSSL_FAILURE); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA-SHA256"), + WOLFSSL_FAILURE); + #ifdef WC_RSA_PSS + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA-PSS+SHA256"), + WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA-PSS+SHA256"), + WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "PSS+SHA256"), + WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, "PSS+SHA256"), + WOLFSSL_SUCCESS); + #endif + #ifdef WOLFSSL_SHA512 + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, + "RSA+SHA256:RSA+SHA512"), WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, + "RSA+SHA256:RSA+SHA512"), WOLFSSL_SUCCESS); + #elif defined(WOLFSSL_SHA384) + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, + "RSA+SHA256:RSA+SHA384"), WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, + "RSA+SHA256:RSA+SHA384"), WOLFSSL_SUCCESS); + #endif + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA"), WOLFSSL_FAILURE); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA"), WOLFSSL_FAILURE); + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA:RSA+SHA256"), + WOLFSSL_FAILURE); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA:RSA+SHA256"), + WOLFSSL_FAILURE); + + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "RSA+SHA256+SHA256"), + WOLFSSL_FAILURE); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, "RSA+SHA256+RSA"), + WOLFSSL_FAILURE); + #endif +#endif +#ifdef HAVE_ECC + #ifndef NO_SHA256 + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "ECDSA+SHA256"), + WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, "ECDSA+SHA256"), WOLFSSL_SUCCESS); + #ifdef WOLFSSL_SHA512 + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, + "ECDSA+SHA256:ECDSA+SHA512"), WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, + "ECDSA+SHA256:ECDSA+SHA512"), WOLFSSL_SUCCESS); + #elif defined(WOLFSSL_SHA384) + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, + "ECDSA+SHA256:ECDSA+SHA384"), WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, + "ECDSA+SHA256:ECDSA+SHA384"), WOLFSSL_SUCCESS); + #endif + #endif +#endif +#ifdef HAVE_ED25519 + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "ED25519"), WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, "ED25519"), WOLFSSL_SUCCESS); +#endif +#ifdef HAVE_ED448 + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "ED448"), WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, "ED448"), WOLFSSL_SUCCESS); +#endif +#ifndef NO_DSA + #ifndef NO_SHA256 + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "DSA+SHA256"), + WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, "DSA+SHA256"), + WOLFSSL_SUCCESS); + #endif + #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \ + defined(WOLFSSL_ALLOW_TLS_SHA1)) + AssertIntEQ(wolfSSL_CTX_set1_sigalgs_list(ctx, "DSA+SHA1"), + WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_set1_sigalgs_list(ssl, "DSA+SHA1"), + WOLFSSL_SUCCESS); + #endif +#endif + + SSL_free(ssl); + SSL_CTX_free(ctx); + + printf(resultFmt, passed); + #endif +} + /* Testing wolfSSL_set_tlsext_status_type function. * PRE: OPENSSL and HAVE_CERTIFICATE_STATUS_REQUEST defined. */ @@ -44312,6 +44434,7 @@ void ApiTest(void) #endif test_wolfSSL_set_options(); test_wolfSSL_sk_SSL_CIPHER(); + test_wolfSSL_set1_sigalgs_list(); test_wolfSSL_PKCS7_certs(); test_wolfSSL_X509_STORE_CTX(); test_wolfSSL_X509_STORE_CTX_trusted_stack_cleanup(); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 00bf17de9..0cdaaa54f 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1895,6 +1895,7 @@ WOLFSSL_LOCAL void InitSuites(Suites*, ProtocolVersion, int, word16, word16, word16, word16, word16, word16, word16, word16, int); WOLFSSL_LOCAL int MatchSuite(WOLFSSL* ssl, Suites* peerSuites); WOLFSSL_LOCAL int SetCipherList(WOLFSSL_CTX*, Suites*, const char* list); +WOLFSSL_LOCAL int SetSuitesHashSigAlgo(Suites*, const char* list); #ifndef PSK_TYPES_DEFINED typedef unsigned int (*wc_psk_client_callback)(WOLFSSL*, const char*, char*, diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 660155302..e8f317a42 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -313,6 +313,10 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; /* wolfSSL does not support exporting keying material */ #define SSL_export_keying_material wolfSSL_export_keying_material +#define SSL_CTX_set1_sigalgs_list wolfSSL_CTX_set1_sigalgs_list +#define SSL_set1_sigalgs_list wolfSSL_set1_sigalgs_list +#define SSL_get_signature_nid wolfSSL_get_signature_nid + #define SSL_CTX_set1_groups wolfSSL_CTX_set1_groups #define SSL_set1_groups wolfSSL_set1_groups diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index a131c6842..b4ff12a46 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -931,6 +931,10 @@ WOLFSSL_ABI WOLFSSL_API WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD*); #ifdef OPENSSL_EXTRA WOLFSSL_API int wolfSSL_CTX_up_ref(WOLFSSL_CTX*); WOLFSSL_API int wolfSSL_CTX_set_ecdh_auto(WOLFSSL_CTX* ctx, int onoff); +WOLFSSL_API int wolfSSL_get_signature_nid(WOLFSSL* ssl, int* nid); +WOLFSSL_API int wolfSSL_CTX_set1_sigalgs_list(WOLFSSL_CTX* ctx, + const char* list); +WOLFSSL_API int wolfSSL_set1_sigalgs_list(WOLFSSL* ssl, const char* list); #endif WOLFSSL_ABI WOLFSSL_API WOLFSSL* wolfSSL_new(WOLFSSL_CTX*); WOLFSSL_API WOLFSSL_CTX* wolfSSL_get_SSL_CTX(WOLFSSL* ssl); diff --git a/wolfssl/test.h b/wolfssl/test.h index 60f310a28..35c2f2dfd 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -665,11 +665,12 @@ static WC_INLINE int PasswordCallBack(char* passwd, int sz, int rw, void* userda #endif -static const char* client_showpeer_msg[][8] = { +static const char* client_showpeer_msg[][9] = { /* English */ { "SSL version is", "SSL cipher suite is", + "SSL signature algorithm is", "SSL curve name is", "SSL DH size is", "SSL reused session", @@ -682,6 +683,7 @@ static const char* client_showpeer_msg[][8] = { { "SSL バージョンは", "SSL 暗号スイートは", + "SSL signature algorithm is", "SSL 曲線名は", "SSL DH サイズは", "SSL 再利用セッション", @@ -829,6 +831,9 @@ static WC_INLINE void showPeerEx(WOLFSSL* ssl, int lng_index) #ifndef NO_DH int bits; #endif +#ifdef OPENSSL_EXTRA + int nid; +#endif #ifdef KEEP_PEER_CERT WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl); if (peer) @@ -851,20 +856,25 @@ static WC_INLINE void showPeerEx(WOLFSSL* ssl, int lng_index) #else printf("%s %s\n", words[1], wolfSSL_CIPHER_get_name(cipher)); #endif +#ifdef OPENSSL_EXTRA + if (wolfSSL_get_signature_nid(ssl, &nid) == WOLFSSL_SUCCESS) { + printf("%s %s\n", words[2], OBJ_nid2sn(nid)); + } +#endif #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \ !defined(NO_DH) if ((name = wolfSSL_get_curve_name(ssl)) != NULL) - printf("%s %s\n", words[2], name); + printf("%s %s\n", words[3], name); #endif #ifndef NO_DH else if ((bits = wolfSSL_GetDhKey_Sz(ssl)) > 0) - printf("%s %d bits\n", words[3], bits); + printf("%s %d bits\n", words[4], bits); #endif if (wolfSSL_session_reused(ssl)) - printf("%s\n", words[4]); + printf("%s\n", words[5]); #ifdef WOLFSSL_ALT_CERT_CHAINS if (wolfSSL_is_peer_alt_cert_chain(ssl)) - printf("%s\n", words[5]); + printf("%s\n", words[6]); #endif #if defined(SHOW_CERTS) && defined(SESSION_CERTS) && \