summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtests/ssl_gtest/ssl_extension_unittest.cc28
-rw-r--r--lib/ssl/ssl3ext.c20
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;
}