From 556a42edfb9b3fcd744f2e032e59498bc8af4841 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 17 Dec 2021 23:40:11 +0100 Subject: [PATCH] nss:set_cipher don't clobber the cipher list The string is set by the user and needs to remain intact for proper connection reuse etc. Reported-by: Eric Musser Fixes #8160 Closes #8161 --- lib/vtls/nss.c | 78 ++++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c index 1897b9ab1d..260ff0b046 100644 --- a/lib/vtls/nss.c +++ b/lib/vtls/nss.c @@ -304,13 +304,14 @@ static char *nss_sslver_to_name(PRUint16 nssver) } } -static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model, - char *cipher_list) +/* the longest cipher name this supports */ +#define MAX_CIPHER_LENGTH 128 + +static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc *model, + const char *cipher_list) { unsigned int i; - PRBool cipher_state[NUM_OF_CIPHERS]; - PRBool found; - char *cipher; + const char *cipher; /* use accessors to avoid dynamic linking issues after an update of NSS */ const PRUint16 num_implemented_ciphers = SSL_GetNumImplementedCiphers(); @@ -326,51 +327,52 @@ static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model, SSL_CipherPrefSet(model, implemented_ciphers[i], PR_FALSE); } - /* Set every entry in our list to false */ - for(i = 0; i < NUM_OF_CIPHERS; i++) { - cipher_state[i] = PR_FALSE; - } - cipher = cipher_list; - while(cipher_list && (cipher_list[0])) { + while(cipher && cipher[0]) { + const char *end; + char name[MAX_CIPHER_LENGTH + 1]; + size_t len; + bool found = FALSE; while((*cipher) && (ISSPACE(*cipher))) ++cipher; - cipher_list = strpbrk(cipher, ":, "); - if(cipher_list) { - *cipher_list++ = '\0'; - } - - found = PR_FALSE; - - for(i = 0; i MAX_CIPHER_LENGTH) { + failf(data, "Bad cipher list"); return SECFailure; } - - if(cipher_list) { - cipher = cipher_list; + else if(len) { + memcpy(name, cipher, len); + name[len] = 0; + + for(i = 0; i