diff options
-rw-r--r-- | gtests/ssl_gtest/ssl_extension_unittest.cc | 28 | ||||
-rw-r--r-- | lib/ssl/ssl3ext.c | 20 |
2 files changed, 39 insertions, 9 deletions
diff --git a/gtests/ssl_gtest/ssl_extension_unittest.cc b/gtests/ssl_gtest/ssl_extension_unittest.cc index 59a6ea679..1f115ea0f 100644 --- a/gtests/ssl_gtest/ssl_extension_unittest.cc +++ b/gtests/ssl_gtest/ssl_extension_unittest.cc @@ -1365,6 +1365,34 @@ TEST_P(TlsConnectGeneric, ClientHelloExtensionPermutation) { Connect(); } +TEST_F(TlsConnectStreamTls13, ClientHelloExtensionPermutationWithPSK) { + EnsureTlsSetup(); + + ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); + const uint8_t kPskDummyVal_[16] = {0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; + SECItem psk_item; + psk_item.type = siBuffer; + psk_item.len = sizeof(kPskDummyVal_); + psk_item.data = const_cast<uint8_t*>(kPskDummyVal_); + PK11SymKey* key = + PK11_ImportSymKey(slot.get(), CKM_HKDF_KEY_GEN, PK11_OriginUnwrap, + CKA_DERIVE, &psk_item, NULL); + + ScopedPK11SymKey scoped_psk_(key); + const std::string kPskDummyLabel_ = "NSS PSK GTEST label"; + const SSLHashType kPskHash_ = ssl_hash_sha384; + AddPsk(scoped_psk_, kPskDummyLabel_, kPskHash_); + + PR_ASSERT(SSL_OptionSet(client_->ssl_fd(), + SSL_ENABLE_CH_EXTENSION_PERMUTATION, + PR_TRUE) == SECSuccess); + Connect(); + SendReceive(); + CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_psk, ssl_sig_none); +} + /* This test checks that the ClientHello extension order is actually permuted * if ss->opt.chXtnPermutation is set. It is asserted that at least one out of * 10 extension orders differs from the others. diff --git a/lib/ssl/ssl3ext.c b/lib/ssl/ssl3ext.c index c4f9c92d4..de7523566 100644 --- a/lib/ssl/ssl3ext.c +++ b/lib/ssl/ssl3ext.c @@ -1133,7 +1133,14 @@ tls_ClientHelloExtensionPermutationSetup(sslSocket *ss) /* Psk Extension and then NULL entry MUST be last. */ const size_t permutationLen = buildersLen - 2; - sslExtensionBuilder *builders = PORT_Alloc(buildersSize); + /* There shouldn't already be a stored permutation. */ + PR_ASSERT(!ss->ssl3.hs.chExtensionPermutation); + + /* This shuffle handles up to 256 extensions. */ + PR_ASSERT(buildersLen < 256); + uint8_t permutation[256] = { 0 }; + + sslExtensionBuilder *builders = PORT_ZAlloc(buildersSize); if (!builders) { return SECFailure; } @@ -1142,15 +1149,14 @@ tls_ClientHelloExtensionPermutationSetup(sslSocket *ss) PORT_Memcpy(builders, clientHelloSendersTLS, buildersSize); /* Get permutation randoms. */ - uint8_t random[permutationLen]; - if (PK11_GenerateRandom(random, permutationLen) != SECSuccess) { + if (PK11_GenerateRandom(permutation, permutationLen) != SECSuccess) { PORT_Free(builders); return SECFailure; } /* Fisher-Yates Shuffle */ for (size_t i = permutationLen - 1; i > 0; i--) { - size_t idx = random[i - 1] % (i + 1); + size_t idx = permutation[i - 1] % (i + 1); sslExtensionBuilder tmp = builders[i]; builders[i] = builders[idx]; builders[idx] = tmp; @@ -1158,13 +1164,9 @@ tls_ClientHelloExtensionPermutationSetup(sslSocket *ss) /* Make sure that Psk extension is penultimate (before NULL entry). */ PR_ASSERT(builders[buildersLen - 2].ex_type == ssl_tls13_pre_shared_key_xtn); + PR_ASSERT(builders[buildersLen - 2].ex_sender == clientHelloSendersTLS[buildersLen - 2].ex_sender); - if (ss->ssl3.hs.chExtensionPermutation) { - PORT_Free(builders); - return SECFailure; - } ss->ssl3.hs.chExtensionPermutation = builders; - return SECSuccess; } |