diff --git a/src/tls.c b/src/tls.c index 4ffd6f7d0..f2f62dc69 100644 --- a/src/tls.c +++ b/src/tls.c @@ -11099,11 +11099,13 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) #ifndef WOLFSSL_PSK_ONE_ID if (ssl->options.client_psk_cs_cb != NULL) { int i; - ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0'; for (i = 0; i < ssl->suites->suiteSz; i += 2) { byte cipherSuite0 = ssl->suites->suites[i + 0]; byte cipherSuite = ssl->suites->suites[i + 1]; unsigned int keySz; + #ifdef WOLFSSL_PSK_MULTI_ID_PER_CS + int cnt = 0; + #endif #ifdef HAVE_NULL_CIPHER if (cipherSuite0 == ECC_BYTE) { @@ -11117,21 +11119,34 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) if (cipherSuite0 != TLS13_BYTE) continue; - keySz = ssl->options.client_psk_cs_cb( - ssl, ssl->arrays->server_hint, - ssl->arrays->client_identity, MAX_PSK_ID_LEN, - ssl->arrays->psk_key, MAX_PSK_KEY_LEN, - GetCipherNameInternal(cipherSuite0, cipherSuite)); - if (keySz > 0) { - ssl->arrays->psk_keySz = keySz; - ret = TLSX_PreSharedKey_Use(ssl, - (byte*)ssl->arrays->client_identity, - (word16)XSTRLEN(ssl->arrays->client_identity), 0, - SuiteMac(ssl->suites->suites + i), - cipherSuite0, cipherSuite, 0, NULL); - if (ret != 0) - return ret; + #ifdef WOLFSSL_PSK_MULTI_ID_PER_CS + do { + ssl->arrays->client_identity[0] = cnt; + #endif + + ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0'; + keySz = ssl->options.client_psk_cs_cb( + ssl, ssl->arrays->server_hint, + ssl->arrays->client_identity, MAX_PSK_ID_LEN, + ssl->arrays->psk_key, MAX_PSK_KEY_LEN, + GetCipherNameInternal(cipherSuite0, cipherSuite)); + if (keySz > 0) { + ssl->arrays->psk_keySz = keySz; + ret = TLSX_PreSharedKey_Use(ssl, + (byte*)ssl->arrays->client_identity, + (word16)XSTRLEN(ssl->arrays->client_identity), + 0, SuiteMac(ssl->suites->suites + i), + cipherSuite0, cipherSuite, 0, NULL); + if (ret != 0) + return ret; + #ifdef WOLFSSL_PSK_MULTI_ID_PER_CS + cnt++; + #endif + } + #ifdef WOLFSSL_PSK_MULTI_ID_PER_CS } + while (keySz > 0); + #endif } usingPSK = 1; diff --git a/src/tls13.c b/src/tls13.c index 16cce4c8f..de8a70794 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -73,6 +73,10 @@ * Check for alerts during the handshake in the event of an error. * WOLFSSL_NO_CLIENT_CERT_ERROR * Requires client to set a client certificate + * WOLFSSL_PSK_MULTI_ID_PER_CS + * When multiple PSK identities are available for the same cipher suite. + * Sets the first byte of the client identity to the count of identites + * that have been seen so far for the cipher suite. */ #ifdef HAVE_CONFIG_H @@ -2851,6 +2855,9 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk, int clientHello) else #endif /* OPENSSL_EXTRA */ if (ssl->options.client_psk_cs_cb != NULL) { + #ifdef WOLFSSL_PSK_MULTI_ID_PER_CS + ssl->arrays->client_identity[0] = 0; + #endif /* Lookup key again for next identity. */ ssl->arrays->psk_keySz = ssl->options.client_psk_cs_cb( ssl, ssl->arrays->server_hint, diff --git a/wolfssl/test.h b/wolfssl/test.h index 105c9fab7..a075643e6 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -2411,6 +2411,14 @@ static WC_INLINE unsigned int my_psk_client_cs_cb(WOLFSSL* ssl, (void)hint; (void)key_max_len; +#ifdef WOLFSSL_PSK_MULTI_ID_PER_CS + /* Multiple calls for each cipher suite. First identity byte indicates the + * number of identites seen so far for cipher suite. */ + if (identity[0] != 0) { + return 0; + } +#endif + /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */ XSTRNCPY(identity, kIdentityStr, id_max_len); XSTRNCAT(identity, ciphersuite + XSTRLEN(ciphersuite) - 6, id_max_len);