Bug 1539227 - land NSS 56826bedabba UPGRADE_NSS_RELEASE, r=KevinJacobs

NSS uplift, 30 April 2019.

Commit log: https://hg.mozilla.org/projects/nss/log?rev=e5e10a46b9ad..56826bedabba

Differential Revision: https://phabricator.services.mozilla.com/D29382

--HG--
extra : moz-landing-system : lando
This commit is contained in:
J.C. Jones 2019-04-30 18:22:11 +00:00
Родитель 6fbab2c8ec
Коммит 6c93b0dea7
34 изменённых файлов: 634 добавлений и 92 удалений

Просмотреть файл

@ -1 +1 @@
e5e10a46b9ad
56826bedabba

Просмотреть файл

@ -167,7 +167,7 @@ export async function initFilter() {
let comment = await getCommitComment();
// Check for try syntax in changeset comment.
let match = comment.match(/^\s*try:\s*(.*)\s*$/);
let match = comment.match(/\btry:\s*(.*)\s*$/m);
// Add try syntax filter.
if (match) {

Просмотреть файл

@ -3120,7 +3120,7 @@ certutil_main(int argc, char **argv, PRBool initialize)
PR_fprintf(PR_STDERR,
"%s -%c: specify a nickname (-n) or\n"
" a key ID (-k).\n",
commandToRun, progName);
progName, commandToRun);
return 255;
}

Просмотреть файл

@ -233,7 +233,9 @@ PrintParameterUsage()
" ecdsa_secp521r1_sha512,\n"
" rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512,\n"
" rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512,\n"
"-Z enable 0-RTT (for TLS 1.3; also use -u)\n",
"-Z enable 0-RTT (for TLS 1.3; also use -u)\n"
"-E enable post-handshake authentication\n"
" (for TLS 1.3; only has an effect with 3 or more -r options)\n",
stderr);
}
@ -804,6 +806,7 @@ PRBool failedToNegotiateName = PR_FALSE;
PRBool enableExtendedMasterSecret = PR_FALSE;
PRBool zeroRTT = PR_FALSE;
PRBool enableALPN = PR_FALSE;
PRBool enablePostHandshakeAuth = PR_FALSE;
SSLNamedGroup *enabledGroups = NULL;
unsigned int enabledGroupsCount = 0;
const SSLSignatureScheme *enabledSigSchemes = NULL;
@ -1431,15 +1434,28 @@ handle_connection(PRFileDesc *tcp_sock, PRFileDesc *model_sock)
errWarn("second SSL_OptionSet SSL_REQUIRE_CERTIFICATE");
break;
}
rv = SSL_ReHandshake(ssl_sock, PR_TRUE);
if (rv != 0) {
errWarn("SSL_ReHandshake");
break;
}
rv = SSL_ForceHandshake(ssl_sock);
if (rv < 0) {
errWarn("SSL_ForceHandshake");
break;
if (enablePostHandshakeAuth) {
rv = SSL_SendCertificateRequest(ssl_sock);
if (rv != SECSuccess) {
errWarn("SSL_SendCertificateRequest");
break;
}
rv = SSL_ForceHandshake(ssl_sock);
if (rv != SECSuccess) {
errWarn("SSL_ForceHandshake");
break;
}
} else {
rv = SSL_ReHandshake(ssl_sock, PR_TRUE);
if (rv != 0) {
errWarn("SSL_ReHandshake");
break;
}
rv = SSL_ForceHandshake(ssl_sock);
if (rv < 0) {
errWarn("SSL_ForceHandshake");
break;
}
}
}
}
@ -1948,6 +1964,16 @@ server_main(
}
}
if (enablePostHandshakeAuth) {
if (enabledVersions.max < SSL_LIBRARY_VERSION_TLS_1_3) {
errExit("You tried enabling post-handshake auth without enabling TLS 1.3!");
}
rv = SSL_OptionSet(model_sock, SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE);
if (rv != SECSuccess) {
errExit("error enabling post-handshake auth");
}
}
if (enableALPN) {
PRUint8 alpnVal[] = { 0x08,
0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 };
@ -2223,7 +2249,7 @@ main(int argc, char **argv)
** in 3.28, please leave some time before resuing those.
** 'z' was removed in 3.39. */
optstate = PL_CreateOptState(argc, argv,
"2:A:C:DGH:I:J:L:M:NP:QRS:T:U:V:W:YZa:bc:d:e:f:g:hi:jk:lmn:op:rst:uvw:y");
"2:A:C:DEGH:I:J:L:M:NP:QRS:T:U:V:W:YZa:bc:d:e:f:g:hi:jk:lmn:op:rst:uvw:y");
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
++optionsFound;
switch (optstate->option) {
@ -2243,6 +2269,11 @@ main(int argc, char **argv)
case 'D':
noDelay = PR_TRUE;
break;
case 'E':
enablePostHandshakeAuth = PR_TRUE;
break;
case 'H':
configureDHE = (PORT_Atoi(optstate->value) != 0);
break;

Просмотреть файл

@ -221,7 +221,7 @@ PrintUsageHeader()
fprintf(stderr,
"Usage: %s -h host [-a 1st_hs_name ] [-a 2nd_hs_name ] [-p port]\n"
" [-D | -d certdir] [-C] [-b | -R root-module] \n"
" [-n nickname] [-Bafosvx] [-c ciphers] [-Y] [-Z]\n"
" [-n nickname] [-Bafosvx] [-c ciphers] [-Y] [-Z] [-E]\n"
" [-V [min-version]:[max-version]] [-K] [-T] [-U]\n"
" [-r N] [-w passwd] [-W pwfile] [-q [-t seconds]]\n"
" [-I groups] [-J signatureschemes]\n"
@ -311,6 +311,9 @@ PrintParameterUsage()
fprintf(stderr, "%-20s Use DTLS\n", "-P {client, server}");
fprintf(stderr, "%-20s Exit after handshake\n", "-Q");
fprintf(stderr, "%-20s Encrypted SNI Keys\n", "-N");
fprintf(stderr, "%-20s Enable post-handshake authentication\n"
"%-20s for TLS 1.3; need to specify -n\n",
"-E", "");
}
static void
@ -989,6 +992,7 @@ PRBool requestToExit = PR_FALSE;
char *versionString = NULL;
PRBool handshakeComplete = PR_FALSE;
char *encryptedSNIKeys = NULL;
PRBool enablePostHandshakeAuth = PR_FALSE;
static int
writeBytesToServer(PRFileDesc *s, const PRUint8 *buf, int nb)
@ -1410,6 +1414,15 @@ run()
goto done;
}
if (enablePostHandshakeAuth) {
rv = SSL_OptionSet(s, SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE);
if (rv != SECSuccess) {
SECU_PrintError(progName, "error enabling post-handshake auth");
error = 1;
goto done;
}
}
if (enabledGroups) {
rv = SSL_NamedGroupConfig(s, enabledGroups, enabledGroupsCount);
if (rv < 0) {
@ -1707,7 +1720,7 @@ main(int argc, char **argv)
* Please leave some time before reusing these.
*/
optstate = PL_CreateOptState(argc, argv,
"46A:CDFGHI:J:KL:M:N:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:");
"46A:CDEFGHI:J:KL:M:N:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:");
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) {
case '?':
@ -1738,6 +1751,10 @@ main(int argc, char **argv)
openDB = PR_FALSE;
break;
case 'E':
enablePostHandshakeAuth = PR_TRUE;
break;
case 'F':
if (serverCertAuth.testFreshStatusFromSideChannel) {
/* parameter given twice or more */
@ -1988,6 +2005,11 @@ main(int argc, char **argv)
exit(1);
}
if (enablePostHandshakeAuth && !nickname) {
fprintf(stderr, "%s: -E requires the use of -n\n", progName);
exit(1);
}
PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
PK11_SetPasswordFunc(SECU_GetModulePassword);

Просмотреть файл

@ -10,3 +10,4 @@
*/
#error "Do not include this header file."

Просмотреть файл

@ -52,6 +52,7 @@ const uint8_t kTlsAlertInappropriateFallback = 86;
const uint8_t kTlsAlertMissingExtension = 109;
const uint8_t kTlsAlertUnsupportedExtension = 110;
const uint8_t kTlsAlertUnrecognizedName = 112;
const uint8_t kTlsAlertCertificateRequired = 116;
const uint8_t kTlsAlertNoApplicationProtocol = 120;
const uint8_t kTlsFakeChangeCipherSpec[] = {

Просмотреть файл

@ -8,6 +8,7 @@
#include "nss.h"
#include "pk11pub.h"
#include "sechash.h"
#include "secerr.h"
#include "cpputil.h"
#include "nss_scoped_ptrs.h"
@ -17,10 +18,17 @@
namespace nss_test {
static const CK_MECHANISM_TYPE kMech = CKM_NSS_CHACHA20_POLY1305;
static const CK_MECHANISM_TYPE kMechXor = CKM_NSS_CHACHA20_CTR;
// Some test data for simple tests.
static const uint8_t kKeyData[32] = {'k'};
static const uint8_t kCtrNonce[16] = {'c', 0, 0, 0, 'n'};
static const uint8_t kData[16] = {'d'};
class Pkcs11ChaCha20Poly1305Test
: public ::testing::TestWithParam<chacha_testvector> {
public:
void EncryptDecrypt(PK11SymKey* symKey, const bool invalid_iv,
void EncryptDecrypt(const ScopedPK11SymKey& key, const bool invalid_iv,
const bool invalid_tag, const uint8_t* data,
size_t data_len, const uint8_t* aad, size_t aad_len,
const uint8_t* iv, size_t iv_len,
@ -39,7 +47,7 @@ class Pkcs11ChaCha20Poly1305Test
// Encrypt.
unsigned int outputLen = 0;
std::vector<uint8_t> output(data_len + aead_params.ulTagLen);
SECStatus rv = PK11_Encrypt(symKey, mech, &params, output.data(),
SECStatus rv = PK11_Encrypt(key.get(), kMech, &params, output.data(),
&outputLen, output.size(), data, data_len);
// Return if encryption failure was expected due to invalid IV.
@ -60,8 +68,9 @@ class Pkcs11ChaCha20Poly1305Test
// Decrypt.
unsigned int decryptedLen = 0;
std::vector<uint8_t> decrypted(data_len);
rv = PK11_Decrypt(symKey, mech, &params, decrypted.data(), &decryptedLen,
decrypted.size(), output.data(), outputLen);
rv =
PK11_Decrypt(key.get(), kMech, &params, decrypted.data(), &decryptedLen,
decrypted.size(), output.data(), outputLen);
EXPECT_EQ(rv, SECSuccess);
// Check the plaintext.
@ -73,8 +82,9 @@ class Pkcs11ChaCha20Poly1305Test
if (outputLen != 0) {
std::vector<uint8_t> bogusCiphertext(output);
bogusCiphertext[0] ^= 0xff;
rv = PK11_Decrypt(symKey, mech, &params, decrypted.data(), &decryptedLen,
decrypted.size(), bogusCiphertext.data(), outputLen);
rv = PK11_Decrypt(key.get(), kMech, &params, decrypted.data(),
&decryptedLen, decrypted.size(), bogusCiphertext.data(),
outputLen);
EXPECT_NE(rv, SECSuccess);
}
@ -83,8 +93,9 @@ class Pkcs11ChaCha20Poly1305Test
if (outputLen != 0) {
std::vector<uint8_t> bogusTag(output);
bogusTag[outputLen - 1] ^= 0xff;
rv = PK11_Decrypt(symKey, mech, &params, decrypted.data(), &decryptedLen,
decrypted.size(), bogusTag.data(), outputLen);
rv = PK11_Decrypt(key.get(), kMech, &params, decrypted.data(),
&decryptedLen, decrypted.size(), bogusTag.data(),
outputLen);
EXPECT_NE(rv, SECSuccess);
}
@ -100,7 +111,7 @@ class Pkcs11ChaCha20Poly1305Test
bogusAeadParams.pNonce = toUcharPtr(bogusIV.data());
bogusIV[0] ^= 0xff;
rv = PK11_Decrypt(symKey, mech, &bogusParams, decrypted.data(),
rv = PK11_Decrypt(key.get(), kMech, &bogusParams, decrypted.data(),
&decryptedLen, data_len, output.data(), outputLen);
EXPECT_NE(rv, SECSuccess);
}
@ -117,7 +128,7 @@ class Pkcs11ChaCha20Poly1305Test
bogusAeadParams.pAAD = toUcharPtr(bogusAAD.data());
bogusAAD[0] ^= 0xff;
rv = PK11_Decrypt(symKey, mech, &bogusParams, decrypted.data(),
rv = PK11_Decrypt(key.get(), kMech, &bogusParams, decrypted.data(),
&decryptedLen, data_len, output.data(), outputLen);
EXPECT_NE(rv, SECSuccess);
}
@ -125,16 +136,16 @@ class Pkcs11ChaCha20Poly1305Test
void EncryptDecrypt(const chacha_testvector testvector) {
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
SECItem keyItem = {siBuffer, toUcharPtr(testvector.Key.data()),
static_cast<unsigned int>(testvector.Key.size())};
SECItem key_item = {siBuffer, toUcharPtr(testvector.Key.data()),
static_cast<unsigned int>(testvector.Key.size())};
// Import key.
ScopedPK11SymKey symKey(PK11_ImportSymKey(
slot.get(), mech, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, nullptr));
EXPECT_TRUE(!!symKey);
ScopedPK11SymKey key(PK11_ImportSymKey(slot.get(), kMech, PK11_OriginUnwrap,
CKA_ENCRYPT, &key_item, nullptr));
EXPECT_TRUE(!!key);
// Check.
EncryptDecrypt(symKey.get(), testvector.invalid_iv, testvector.invalid_tag,
EncryptDecrypt(key, testvector.invalid_iv, testvector.invalid_tag,
testvector.Data.data(), testvector.Data.size(),
testvector.AAD.data(), testvector.AAD.size(),
testvector.IV.data(), testvector.IV.size(),
@ -142,14 +153,13 @@ class Pkcs11ChaCha20Poly1305Test
}
protected:
CK_MECHANISM_TYPE mech = CKM_NSS_CHACHA20_POLY1305;
};
TEST_F(Pkcs11ChaCha20Poly1305Test, GenerateEncryptDecrypt) {
// Generate a random key.
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
ScopedPK11SymKey symKey(PK11_KeyGen(slot.get(), mech, nullptr, 32, nullptr));
EXPECT_TRUE(!!symKey);
ScopedPK11SymKey key(PK11_KeyGen(slot.get(), kMech, nullptr, 32, nullptr));
EXPECT_TRUE(!!key);
// Generate random data.
std::vector<uint8_t> data(512);
@ -168,8 +178,85 @@ TEST_F(Pkcs11ChaCha20Poly1305Test, GenerateEncryptDecrypt) {
EXPECT_EQ(rv, SECSuccess);
// Check.
EncryptDecrypt(symKey.get(), false, false, data.data(), data.size(),
aad.data(), aad.size(), iv.data(), iv.size());
EncryptDecrypt(key, false, false, data.data(), data.size(), aad.data(),
aad.size(), iv.data(), iv.size());
}
TEST_F(Pkcs11ChaCha20Poly1305Test, Xor) {
static const uint8_t kExpected[sizeof(kData)] = {
0xd8, 0x15, 0xd3, 0xb3, 0xe9, 0x34, 0x3b, 0x7a,
0x24, 0xf6, 0x5f, 0xd7, 0x95, 0x3d, 0xd3, 0x51};
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
SECItem keyItem = {siBuffer, toUcharPtr(kKeyData),
static_cast<unsigned int>(sizeof(kKeyData))};
ScopedPK11SymKey key(PK11_ImportSymKey(
slot.get(), kMechXor, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, nullptr));
EXPECT_TRUE(!!key);
SECItem ctr_nonce_item = {siBuffer, toUcharPtr(kCtrNonce),
static_cast<unsigned int>(sizeof(kCtrNonce))};
uint8_t output[sizeof(kData)];
unsigned int output_len = 88; // This should be overwritten.
SECStatus rv =
PK11_Encrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len,
sizeof(output), kData, sizeof(kData));
ASSERT_EQ(SECSuccess, rv);
ASSERT_EQ(sizeof(kExpected), static_cast<size_t>(output_len));
EXPECT_EQ(0, memcmp(kExpected, output, sizeof(kExpected)));
// Decrypting has the same effect.
rv = PK11_Decrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len,
sizeof(output), kData, sizeof(kData));
ASSERT_EQ(SECSuccess, rv);
ASSERT_EQ(sizeof(kData), static_cast<size_t>(output_len));
EXPECT_EQ(0, memcmp(kExpected, output, sizeof(kExpected)));
// Operating in reverse too.
rv = PK11_Encrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len,
sizeof(output), kExpected, sizeof(kExpected));
ASSERT_EQ(SECSuccess, rv);
ASSERT_EQ(sizeof(kExpected), static_cast<size_t>(output_len));
EXPECT_EQ(0, memcmp(kData, output, sizeof(kData)));
}
// This test just ensures that a key can be generated for use with the XOR
// function. The result is random and therefore cannot be checked.
TEST_F(Pkcs11ChaCha20Poly1305Test, GenerateXor) {
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
ScopedPK11SymKey key(PK11_KeyGen(slot.get(), kMech, nullptr, 32, nullptr));
EXPECT_TRUE(!!key);
SECItem ctr_nonce_item = {siBuffer, toUcharPtr(kCtrNonce),
static_cast<unsigned int>(sizeof(kCtrNonce))};
uint8_t output[sizeof(kData)];
unsigned int output_len = 88; // This should be overwritten.
SECStatus rv =
PK11_Encrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len,
sizeof(output), kData, sizeof(kData));
ASSERT_EQ(SECSuccess, rv);
ASSERT_EQ(sizeof(kData), static_cast<size_t>(output_len));
}
TEST_F(Pkcs11ChaCha20Poly1305Test, XorInvalidParams) {
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
ScopedPK11SymKey key(PK11_KeyGen(slot.get(), kMech, nullptr, 32, nullptr));
EXPECT_TRUE(!!key);
SECItem ctr_nonce_item = {siBuffer, toUcharPtr(kCtrNonce),
static_cast<unsigned int>(sizeof(kCtrNonce)) - 1};
uint8_t output[sizeof(kData)];
unsigned int output_len = 88;
SECStatus rv =
PK11_Encrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len,
sizeof(output), kData, sizeof(kData));
EXPECT_EQ(SECFailure, rv);
ctr_nonce_item.data = nullptr;
rv = PK11_Encrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len,
sizeof(output), kData, sizeof(kData));
EXPECT_EQ(SECFailure, rv);
EXPECT_EQ(SEC_ERROR_BAD_DATA, PORT_GetError());
}
TEST_P(Pkcs11ChaCha20Poly1305Test, TestVectors) { EncryptDecrypt(GetParam()); }

Просмотреть файл

@ -320,6 +320,46 @@ TEST_F(TlsConnectStreamTls13, PostHandshakeAuthConcurrent) {
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
}
TEST_F(TlsConnectStreamTls13, PostHandshakeAuthBeforeKeyUpdate) {
client_->SetupClientAuth();
EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE));
Connect();
// Send CertificateRequest.
EXPECT_EQ(SECSuccess, SSL_SendCertificateRequest(server_->ssl_fd()))
<< "Unexpected error: " << PORT_ErrorToName(PORT_GetError());
// Send KeyUpdate.
EXPECT_EQ(SECFailure, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
}
TEST_F(TlsConnectStreamTls13, PostHandshakeAuthDuringClientKeyUpdate) {
client_->SetupClientAuth();
EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE));
Connect();
CheckEpochs(3, 3);
// Send CertificateRequest from server.
EXPECT_EQ(SECSuccess, SSL_SendCertificateRequest(server_->ssl_fd()))
<< "Unexpected error: " << PORT_ErrorToName(PORT_GetError());
// Send KeyUpdate from client.
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_TRUE));
server_->SendData(50); // server sends CertificateRequest
client_->SendData(50); // client sends KeyUpdate
server_->ReadBytes(50); // server receives KeyUpdate and defers response
CheckEpochs(4, 3);
client_->ReadBytes(50); // client receives CertificateRequest
client_->SendData(
50); // client sends Certificate, CertificateVerify, Finished
server_->ReadBytes(
50); // server receives Certificate, CertificateVerify, Finished
client_->CheckEpochs(3, 4);
server_->CheckEpochs(4, 4);
server_->SendData(50); // server sends KeyUpdate
client_->ReadBytes(50); // client receives KeyUpdate
client_->CheckEpochs(4, 4);
}
TEST_F(TlsConnectStreamTls13, PostHandshakeAuthMissingExtension) {
client_->SetupClientAuth();
Connect();
@ -454,6 +494,9 @@ TEST_F(TlsConnectStreamTls13, PostHandshakeAuthDecline) {
client_->SetupClientAuth();
EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE));
EXPECT_EQ(SECSuccess,
SSL_OptionSet(server_->ssl_fd(), SSL_REQUIRE_CERTIFICATE,
SSL_REQUIRE_ALWAYS));
// Client to decline the certificate request.
EXPECT_EQ(SECSuccess,
SSL_GetClientAuthDataHook(
@ -472,10 +515,13 @@ TEST_F(TlsConnectStreamTls13, PostHandshakeAuthDecline) {
// Send CertificateRequest.
EXPECT_EQ(SECSuccess, SSL_SendCertificateRequest(server_->ssl_fd()))
<< "Unexpected error: " << PORT_ErrorToName(PORT_GetError());
server_->SendData(50);
client_->ReadBytes(50);
client_->SendData(50);
server_->ReadBytes(50);
server_->SendData(50); // send Certificate Request
client_->ReadBytes(50); // read Certificate Request
client_->SendData(50); // send empty Certificate+Finished
server_->ExpectSendAlert(kTlsAlertCertificateRequired);
server_->ReadBytes(50); // read empty Certificate+Finished
server_->ExpectReadWriteError();
server_->SendData(50); // send alert
// AuthCertificateCallback is not called, because the client sends
// an empty certificate_list.
EXPECT_EQ(0U, called);

Просмотреть файл

@ -1013,6 +1013,10 @@ extern SECStatus ChaCha20Poly1305_Open(
const unsigned char *nonce, unsigned int nonceLen,
const unsigned char *ad, unsigned int adLen);
extern SECStatus ChaCha20_Xor(
unsigned char *output, const unsigned char *block, unsigned int len,
const unsigned char *k, const unsigned char *nonce, PRUint32 ctr);
/******************************************/
/*
** MD5 secure hash function

Просмотреть файл

@ -170,6 +170,24 @@ ChaCha20Xor(uint8_t *output, uint8_t *block, uint32_t len, uint8_t *k,
}
#endif /* NSS_DISABLE_CHACHAPOLY */
SECStatus
ChaCha20_Xor(unsigned char *output, const unsigned char *block, unsigned int len,
const unsigned char *k, const unsigned char *nonce, PRUint32 ctr)
{
#ifdef NSS_DISABLE_CHACHAPOLY
return SECFailure;
#else
// ChaCha has a 64 octet block, with a 32-bit block counter.
if (sizeof(len) > 4 && len >= (1ULL << (6 + 32))) {
PORT_SetError(SEC_ERROR_INPUT_LEN);
return SECFailure;
}
ChaCha20Xor(output, (uint8_t *)block, len, (uint8_t *)k,
(uint8_t *)nonce, ctr);
return SECSuccess;
#endif
}
SECStatus
ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
@ -187,6 +205,11 @@ ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx, unsigned char *output,
PORT_SetError(SEC_ERROR_INPUT_LEN);
return SECFailure;
}
// ChaCha has a 64 octet block, with a 32-bit block counter.
if (sizeof(inputLen) > 4 && inputLen >= (1ULL << (6 + 32))) {
PORT_SetError(SEC_ERROR_INPUT_LEN);
return SECFailure;
}
*outputLen = inputLen + ctx->tagLen;
if (maxOutputLen < *outputLen) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN);

Просмотреть файл

@ -22,7 +22,7 @@ swap8b(PRUint64 value)
return (value);
}
#elif !defined(_MSC_VER) && !__has_builtin(__builtin_bswap64)
#elif !defined(_MSC_VER) && !__has_builtin(__builtin_bswap64) && !((defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))))
PRUint64
swap8b(PRUint64 x)

Просмотреть файл

@ -40,7 +40,8 @@
#pragma intrinsic(_byteswap_uint64)
#define FREEBL_HTONLL(x) _byteswap_uint64(x)
#elif __has_builtin(__builtin_bswap64)
/* gcc doesn't have __has_builtin, but it does have __builtin_bswap64 */
#elif __has_builtin(__builtin_bswap64) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
#define FREEBL_HTONLL(x) __builtin_bswap64(x)

Просмотреть файл

@ -313,10 +313,14 @@ static const struct FREEBLVectorStr vector =
BLAKE2B_End,
BLAKE2B_FlattenSize,
BLAKE2B_Flatten,
BLAKE2B_Resurrect
BLAKE2B_Resurrect,
/* End of Version 3.020 */
ChaCha20_Xor
/* End of version 3.021 */
};
const FREEBLVector*

Просмотреть файл

@ -2060,6 +2060,16 @@ EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
return (vector->p_EC_CopyParams)(arena, dstParams, srcParams);
}
SECStatus
ChaCha20_Xor(unsigned char *output, const unsigned char *block, unsigned int len,
const unsigned char *k, const unsigned char *nonce, PRUint32 ctr)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) {
return SECFailure;
}
return (vector->p_ChaCha20_Xor)(output, block, len, k, nonce, ctr);
}
SECStatus
ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
const unsigned char *key, unsigned int keyLen,

Просмотреть файл

@ -10,7 +10,7 @@
#include "blapi.h"
#define FREEBL_VERSION 0x0314
#define FREEBL_VERSION 0x0315
struct FREEBLVectorStr {
@ -759,6 +759,12 @@ struct FREEBLVectorStr {
/* Version 3.020 came to here */
SECStatus (*p_ChaCha20_Xor)(unsigned char *output, const unsigned char *block,
unsigned int len, const unsigned char *k,
const unsigned char *nonce, PRUint32 ctr);
/* Version 3.021 came to here */
/* Add new function pointers at the end of this struct and bump
* FREEBL_VERSION at the beginning of this file. */
};

Просмотреть файл

@ -226,6 +226,7 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type, unsigned long len)
return CKK_CAMELLIA;
case CKM_NSS_CHACHA20_POLY1305:
case CKM_NSS_CHACHA20_KEY_GEN:
case CKM_NSS_CHACHA20_CTR:
return CKK_NSS_CHACHA20;
case CKM_AES_ECB:
case CKM_AES_CBC:
@ -440,6 +441,7 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
case CKM_CAMELLIA_KEY_GEN:
return CKM_CAMELLIA_KEY_GEN;
case CKM_NSS_CHACHA20_POLY1305:
case CKM_NSS_CHACHA20_CTR:
return CKM_NSS_CHACHA20_KEY_GEN;
case CKM_AES_ECB:
case CKM_AES_CBC:
@ -730,6 +732,9 @@ PK11_GetBlockSize(CK_MECHANISM_TYPE type, SECItem *params)
case CKM_RSA_X_509:
/*actually it's the modulus length of the key!*/
return -1; /* failure */
case CKM_NSS_CHACHA20_POLY1305:
case CKM_NSS_CHACHA20_CTR:
return 64;
default:
return pk11_lookup(type)->blockSize;
}
@ -784,12 +789,16 @@ PK11_GetIVLength(CK_MECHANISM_TYPE type)
case CKM_CAST3_CBC_PAD:
case CKM_CAST5_CBC_PAD:
return 8;
case CKM_AES_GCM:
case CKM_NSS_CHACHA20_POLY1305:
return 12;
case CKM_SEED_CBC:
case CKM_SEED_CBC_PAD:
case CKM_CAMELLIA_CBC:
case CKM_CAMELLIA_CBC_PAD:
case CKM_AES_CBC:
case CKM_AES_CBC_PAD:
case CKM_NSS_CHACHA20_CTR:
return 16;
case CKM_SKIPJACK_CBC64:
case CKM_SKIPJACK_ECB64:

Просмотреть файл

@ -346,6 +346,7 @@ static const struct mechanismList mechanisms[] = {
/* ------------------------- ChaCha20 Operations ---------------------- */
{ CKM_NSS_CHACHA20_KEY_GEN, { 32, 32, CKF_GENERATE }, PR_TRUE },
{ CKM_NSS_CHACHA20_POLY1305, { 32, 32, CKF_EN_DE }, PR_TRUE },
{ CKM_NSS_CHACHA20_CTR, { 32, 32, CKF_EN_DE }, PR_TRUE },
#endif /* NSS_DISABLE_CHACHAPOLY */
/* ------------------------- Hashing Operations ----------------------- */
{ CKM_MD2, { 0, 0, CKF_DIGEST }, PR_FALSE },

Просмотреть файл

@ -760,6 +760,32 @@ sftk_ChaCha20Poly1305_Decrypt(const SFTKChaCha20Poly1305Info *ctx,
sizeof(ctx->nonce), ad, ctx->adLen);
}
static SECStatus
sftk_ChaCha20Ctr(const SFTKChaCha20CtrInfo *ctx,
unsigned char *output, unsigned int *outputLen,
unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
if (maxOutputLen < inputLen) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
return SECFailure;
}
ChaCha20_Xor(output, input, inputLen, ctx->key,
ctx->nonce, ctx->counter);
*outputLen = inputLen;
return SECSuccess;
}
static void
sftk_ChaCha20Ctr_DestroyContext(SFTKChaCha20CtrInfo *ctx,
PRBool freeit)
{
memset(ctx, 0, sizeof(*ctx));
if (freeit) {
PORT_Free(ctx);
}
}
/** NSC_CryptInit initializes an encryption/Decryption operation.
*
* Always called by NSC_EncryptInit, NSC_DecryptInit, NSC_WrapKey,NSC_UnwrapKey.
@ -1180,6 +1206,47 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
context->destroy = (SFTKDestroy)sftk_ChaCha20Poly1305_DestroyContext;
break;
case CKM_NSS_CHACHA20_CTR:
if (key_type != CKK_NSS_CHACHA20) {
crv = CKR_KEY_TYPE_INCONSISTENT;
break;
}
if (pMechanism->pParameter == NULL || pMechanism->ulParameterLen != 16) {
crv = CKR_MECHANISM_PARAM_INVALID;
break;
}
att = sftk_FindAttribute(key, CKA_VALUE);
if (att == NULL) {
crv = CKR_KEY_HANDLE_INVALID;
break;
}
SFTKChaCha20CtrInfo *ctx = PORT_ZNew(SFTKChaCha20CtrInfo);
if (!ctx) {
sftk_FreeAttribute(att);
crv = CKR_HOST_MEMORY;
break;
}
if (att->attrib.ulValueLen != sizeof(ctx->key)) {
sftk_FreeAttribute(att);
crv = CKR_KEY_HANDLE_INVALID;
break;
}
memcpy(ctx->key, att->attrib.pValue, att->attrib.ulValueLen);
sftk_FreeAttribute(att);
/* The counter is little endian. */
PRUint8 *param = pMechanism->pParameter;
int i = 0;
for (; i < 4; ++i) {
ctx->counter |= param[i] << (i * 8);
}
memcpy(ctx->nonce, param + 4, 12);
context->cipherInfo = ctx;
context->update = (SFTKCipher)sftk_ChaCha20Ctr;
context->destroy = (SFTKDestroy)sftk_ChaCha20Ctr_DestroyContext;
break;
case CKM_NSS_AES_KEY_WRAP_PAD:
context->doPad = PR_TRUE;
/* fall thru */

Просмотреть файл

@ -106,6 +106,7 @@ typedef struct SFTKOAEPEncryptInfoStr SFTKOAEPEncryptInfo;
typedef struct SFTKOAEPDecryptInfoStr SFTKOAEPDecryptInfo;
typedef struct SFTKSSLMACInfoStr SFTKSSLMACInfo;
typedef struct SFTKChaCha20Poly1305InfoStr SFTKChaCha20Poly1305Info;
typedef struct SFTKChaCha20CtrInfoStr SFTKChaCha20CtrInfo;
typedef struct SFTKItemTemplateStr SFTKItemTemplate;
/* define function pointer typdefs for pointer tables */
@ -409,6 +410,14 @@ struct SFTKChaCha20Poly1305InfoStr {
unsigned int adLen;
};
/* SFTKChaCha20BlockInfoStr the key, nonce and counter for a
* ChaCha20 block operation. */
struct SFTKChaCha20CtrInfoStr {
PRUint8 key[32];
PRUint8 nonce[12];
PRUint32 counter;
};
/*
* Template based on SECItems, suitable for passing as arrays
*/

Просмотреть файл

@ -941,9 +941,12 @@ sdb_GetAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id,
blobSize = sqlite3_column_bytes(stmt, i);
blobData = sqlite3_column_blob(stmt, i);
if (blobData == NULL) {
/* PKCS 11 requires that get attributes process all the
* attributes in the template, marking the attributes with
* issues with -1. Mark the error but continue */
template[i].ulValueLen = -1;
error = CKR_ATTRIBUTE_TYPE_INVALID;
break;
continue;
}
/* If the blob equals our explicit NULL value, then the
* attribute is a NULL. */
@ -954,9 +957,10 @@ sdb_GetAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id,
}
if (template[i].pValue) {
if (template[i].ulValueLen < blobSize) {
/* like CKR_ATTRIBUTE_TYPE_INVALID, continue processing */
template[i].ulValueLen = -1;
error = CKR_BUFFER_TOO_SMALL;
break;
continue;
}
PORT_Memcpy(template[i].pValue, blobData, blobSize);
}

Просмотреть файл

@ -564,3 +564,6 @@ ER3(SSL_ERROR_MISSING_ESNI_EXTENSION, (SSL_ERROR_BASE + 178),
ER3(SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE, (SSL_ERROR_BASE + 179),
"SSL received an unexpected record type.")
ER3(SSL_ERROR_RX_CERTIFICATE_REQUIRED_ALERT, (SSL_ERROR_BASE + 181),
"SSL received a certificate_required alert.")

Просмотреть файл

@ -2683,7 +2683,12 @@ ssl3_HandleNoCertificate(sslSocket *ss)
PRFileDesc *lower;
ssl_UncacheSessionID(ss);
SSL3_SendAlert(ss, alert_fatal, bad_certificate);
if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
SSL3_SendAlert(ss, alert_fatal, certificate_required);
} else {
SSL3_SendAlert(ss, alert_fatal, bad_certificate);
}
lower = ss->fd->lower;
#ifdef _WIN32
@ -2919,6 +2924,9 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf)
case no_certificate:
error = SSL_ERROR_NO_CERTIFICATE;
break;
case certificate_required:
error = SSL_ERROR_RX_CERTIFICATE_REQUIRED_ALERT;
break;
case bad_certificate:
error = SSL_ERROR_BAD_CERT_ALERT;
break;
@ -3719,6 +3727,10 @@ ssl3_RestartHandshakeHashes(sslSocket *ss)
PK11_DestroyContext(ss->ssl3.hs.sha, PR_TRUE);
ss->ssl3.hs.sha = NULL;
}
if (ss->ssl3.hs.shaPostHandshake) {
PK11_DestroyContext(ss->ssl3.hs.shaPostHandshake, PR_TRUE);
ss->ssl3.hs.shaPostHandshake = NULL;
}
}
/*
@ -3778,6 +3790,24 @@ ssl3_UpdateHandshakeHashes(sslSocket *ss, const unsigned char *b, unsigned int l
return rv;
}
SECStatus
ssl3_UpdatePostHandshakeHashes(sslSocket *ss, const unsigned char *b, unsigned int l)
{
SECStatus rv = SECSuccess;
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
PRINT_BUF(90, (ss, "post handshake hash input:", b, l));
PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_single);
PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
rv = PK11_DigestOp(ss->ssl3.hs.shaPostHandshake, b, l);
if (rv != SECSuccess) {
PORT_SetError(SSL_ERROR_DIGEST_FAILURE);
}
return rv;
}
SECStatus
ssl3_AppendHandshakeHeader(sslSocket *ss, SSLHandshakeType t, PRUint32 length)
{
@ -11623,7 +11653,8 @@ ssl3_FinishHandshake(sslSocket *ss)
SECStatus
ssl_HashHandshakeMessageInt(sslSocket *ss, SSLHandshakeType ct,
PRUint32 dtlsSeq,
const PRUint8 *b, PRUint32 length)
const PRUint8 *b, PRUint32 length,
sslUpdateHandshakeHashes updateHashes)
{
PRUint8 hdr[4];
PRUint8 dtlsData[8];
@ -11636,7 +11667,7 @@ ssl_HashHandshakeMessageInt(sslSocket *ss, SSLHandshakeType ct,
hdr[2] = (PRUint8)(length >> 8);
hdr[3] = (PRUint8)(length);
rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char *)hdr, 4);
rv = updateHashes(ss, (unsigned char *)hdr, 4);
if (rv != SECSuccess)
return rv; /* err code already set. */
@ -11656,14 +11687,13 @@ ssl_HashHandshakeMessageInt(sslSocket *ss, SSLHandshakeType ct,
dtlsData[6] = (PRUint8)(length >> 8);
dtlsData[7] = (PRUint8)(length);
rv = ssl3_UpdateHandshakeHashes(ss, (unsigned char *)dtlsData,
sizeof(dtlsData));
rv = updateHashes(ss, (unsigned char *)dtlsData, sizeof(dtlsData));
if (rv != SECSuccess)
return rv; /* err code already set. */
}
/* The message body */
rv = ssl3_UpdateHandshakeHashes(ss, b, length);
rv = updateHashes(ss, b, length);
if (rv != SECSuccess)
return rv; /* err code already set. */
@ -11675,7 +11705,15 @@ ssl_HashHandshakeMessage(sslSocket *ss, SSLHandshakeType ct,
const PRUint8 *b, PRUint32 length)
{
return ssl_HashHandshakeMessageInt(ss, ct, ss->ssl3.hs.recvMessageSeq,
b, length);
b, length, ssl3_UpdateHandshakeHashes);
}
SECStatus
ssl_HashPostHandshakeMessage(sslSocket *ss, SSLHandshakeType ct,
const PRUint8 *b, PRUint32 length)
{
return ssl_HashHandshakeMessageInt(ss, ct, ss->ssl3.hs.recvMessageSeq,
b, length, ssl3_UpdatePostHandshakeHashes);
}
/* Called from ssl3_HandleHandshake() when it has gathered a complete ssl3
@ -11714,9 +11752,11 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, PRUint8 *b, PRUint32 length,
break;
default:
rv = ssl_HashHandshakeMessage(ss, ss->ssl3.hs.msg_type, b, length);
if (rv != SECSuccess) {
return SECFailure;
if (!tls13_IsPostHandshake(ss)) {
rv = ssl_HashHandshakeMessage(ss, ss->ssl3.hs.msg_type, b, length);
if (rv != SECSuccess) {
return SECFailure;
}
}
}
@ -13129,6 +13169,9 @@ ssl3_DestroySSL3Info(sslSocket *ss)
if (ss->ssl3.hs.sha) {
PK11_DestroyContext(ss->ssl3.hs.sha, PR_TRUE);
}
if (ss->ssl3.hs.shaPostHandshake) {
PK11_DestroyContext(ss->ssl3.hs.shaPostHandshake, PR_TRUE);
}
if (ss->ssl3.hs.messages.buf) {
sslBuffer_Clear(&ss->ssl3.hs.messages);
}

Просмотреть файл

@ -74,6 +74,7 @@ typedef enum {
unrecognized_name = 112,
bad_certificate_status_response = 113,
bad_certificate_hash_value = 114,
certificate_required = 116,
no_application_protocol = 120,
/* invalid alert */

Просмотреть файл

@ -10,6 +10,7 @@
#include "prnetdb.h"
#include "ssl.h"
#include "sslimpl.h"
#include "sslproto.h"
/* Helper function to encode an unsigned integer into a buffer. */
static void
@ -263,9 +264,11 @@ ssl3_AppendHandshake(sslSocket *ss, const void *void_src, unsigned int bytes)
}
PRINT_BUF(60, (ss, "Append to Handshake", (unsigned char *)void_src, bytes));
rv = ssl3_UpdateHandshakeHashes(ss, src, bytes);
if (rv != SECSuccess)
return SECFailure; /* error code set by ssl3_UpdateHandshakeHashes */
if (!ss->firstHsDone || ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
rv = ssl3_UpdateHandshakeHashes(ss, src, bytes);
if (rv != SECSuccess)
return SECFailure; /* error code set by ssl3_UpdateHandshakeHashes */
}
while (bytes > room) {
if (room > 0)

Просмотреть файл

@ -269,6 +269,7 @@ typedef enum {
SSL_ERROR_MISSING_ESNI_EXTENSION = (SSL_ERROR_BASE + 178),
SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE = (SSL_ERROR_BASE + 179),
SSL_ERROR_MISSING_POST_HANDSHAKE_AUTH_EXTENSION = (SSL_ERROR_BASE + 180),
SSL_ERROR_RX_CERTIFICATE_REQUIRED_ALERT = (SSL_ERROR_BASE + 181),
SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
} SSLErrorCodes;
#endif /* NO_SECURITY_ERROR_ENUM */

Просмотреть файл

@ -144,6 +144,11 @@ typedef enum {
ticket_allow_psk_sign_auth = 16
} TLS13SessionTicketFlags;
typedef enum {
update_not_requested = 0,
update_requested = 1
} tls13KeyUpdateRequest;
struct sslNamedGroupDefStr {
/* The name is the value that is encoded on the wire in TLS. */
SSLNamedGroup name;
@ -610,6 +615,7 @@ typedef struct SSL3HandshakeStateStr {
* TLS 1.2 and later use only |sha|, for SHA-256. */
PK11Context *md5;
PK11Context *sha;
PK11Context *shaPostHandshake;
SSLSignatureScheme signatureScheme;
const ssl3KEADef *kea_def;
ssl3CipherSuite cipher_suite;
@ -743,6 +749,11 @@ struct ssl3StateStr {
* update is initiated locally. */
PRBool peerRequestedKeyUpdate;
/* This is true if we deferred sending a key update as
* post-handshake auth is in progress. */
PRBool keyUpdateDeferred;
tls13KeyUpdateRequest deferredKeyUpdateRequest;
/* This is true after the server requests client certificate;
* false after the client certificate is received. Used by the
* server. */
@ -1213,15 +1224,24 @@ extern SECStatus Null_Cipher(void *ctx, unsigned char *output, unsigned int *out
unsigned int maxOutputLen, const unsigned char *input,
unsigned int inputLen);
extern void ssl3_RestartHandshakeHashes(sslSocket *ss);
typedef SECStatus (*sslUpdateHandshakeHashes)(sslSocket *ss,
const unsigned char *b,
unsigned int l);
extern SECStatus ssl3_UpdateHandshakeHashes(sslSocket *ss,
const unsigned char *b,
unsigned int l);
extern SECStatus ssl3_UpdatePostHandshakeHashes(sslSocket *ss,
const unsigned char *b,
unsigned int l);
SECStatus
ssl_HashHandshakeMessageInt(sslSocket *ss, SSLHandshakeType type,
PRUint32 dtlsSeq,
const PRUint8 *b, PRUint32 length);
const PRUint8 *b, PRUint32 length,
sslUpdateHandshakeHashes cb);
SECStatus ssl_HashHandshakeMessage(sslSocket *ss, SSLHandshakeType type,
const PRUint8 *b, PRUint32 length);
SECStatus ssl_HashPostHandshakeMessage(sslSocket *ss, SSLHandshakeType type,
const PRUint8 *b, PRUint32 length);
/* Returns PR_TRUE if we are still waiting for the server to complete its
* response to our client second round. Once we've received the Finished from

Просмотреть файл

@ -720,7 +720,8 @@ tls13_CheckKeyUpdate(sslSocket *ss, SSLSecretDirection dir)
ssl3CipherSpec *spec;
sslSequenceNumber seqNum;
sslSequenceNumber margin;
SECStatus rv;
tls13KeyUpdateRequest keyUpdateRequest;
SECStatus rv = SECSuccess;
/* Bug 1413368: enable for DTLS */
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 || IS_DTLS(ss)) {
@ -755,9 +756,15 @@ tls13_CheckKeyUpdate(sslSocket *ss, SSLSecretDirection dir)
SSL_TRC(5, ("%d: SSL[%d]: automatic key update at %llx for %s cipher spec",
SSL_GETPID(), ss->fd, seqNum,
(dir == ssl_secret_read) ? "read" : "write"));
keyUpdateRequest = (dir == ssl_secret_read) ? update_requested : update_not_requested;
ssl_GetSSL3HandshakeLock(ss);
rv = tls13_SendKeyUpdate(ss, (dir == ssl_secret_read) ? update_requested : update_not_requested,
dir == ssl_secret_write /* buffer */);
if (ss->ssl3.clientCertRequested) {
ss->ssl3.keyUpdateDeferred = PR_TRUE;
ss->ssl3.deferredKeyUpdateRequest = keyUpdateRequest;
} else {
rv = tls13_SendKeyUpdate(ss, keyUpdateRequest,
dir == ssl_secret_write /* buffer */);
}
ssl_ReleaseSSL3HandshakeLock(ss);
return rv;
}

Просмотреть файл

@ -259,6 +259,12 @@ tls13_CheckHsState(sslSocket *ss, int err, const char *error_name,
return SECFailure;
}
PRBool
tls13_IsPostHandshake(const sslSocket *ss)
{
return ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 && ss->firstHsDone;
}
SSLHashType
tls13_GetHashForCipherSuite(ssl3CipherSuite suite)
{
@ -682,8 +688,9 @@ tls13_SendKeyUpdate(sslSocket *ss, tls13KeyUpdateRequest request, PRBool buffer)
: "not requested"));
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
PORT_Assert(!ss->sec.isServer || !ss->ssl3.clientCertRequested);
if (!ss->firstHsDone) {
if (!tls13_IsPostHandshake(ss)) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
@ -741,11 +748,16 @@ SSLExp_KeyUpdate(PRFileDesc *fd, PRBool requestUpdate)
return SECFailure;
}
if (!ss->firstHsDone) {
if (!tls13_IsPostHandshake(ss)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
if (ss->ssl3.clientCertRequested) {
PORT_SetError(PR_WOULD_BLOCK_ERROR);
return SECFailure;
}
rv = TLS13_CHECK_HS_STATE(ss, SEC_ERROR_INVALID_ARGS,
idle_handshake);
if (rv != SECSuccess) {
@ -786,7 +798,7 @@ tls13_HandleKeyUpdate(sslSocket *ss, PRUint8 *b, unsigned int length)
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
PORT_Assert(ss->firstHsDone);
if (!ss->firstHsDone) {
if (!tls13_IsPostHandshake(ss)) {
FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_KEY_UPDATE, unexpected_message);
return SECFailure;
}
@ -820,7 +832,12 @@ tls13_HandleKeyUpdate(sslSocket *ss, PRUint8 *b, unsigned int length)
if (update == update_requested) {
PRBool sendUpdate;
if (ss->ssl3.peerRequestedKeyUpdate) {
if (ss->ssl3.clientCertRequested) {
/* Post-handshake auth is in progress; defer sending a key update. */
ss->ssl3.keyUpdateDeferred = PR_TRUE;
ss->ssl3.deferredKeyUpdateRequest = update_not_requested;
sendUpdate = PR_FALSE;
} else if (ss->ssl3.peerRequestedKeyUpdate) {
/* Only send an update if we have sent with the current spec. This
* prevents us from being forced to crank forward pointlessly. */
ssl_GetSpecReadLock(ss);
@ -857,7 +874,7 @@ SSLExp_SendCertificateRequest(PRFileDesc *fd)
return SECFailure;
}
if (!ss->firstHsDone || ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
if (!tls13_IsPostHandshake(ss)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
@ -2195,10 +2212,20 @@ tls13_SendCertificateRequest(sslSocket *ss)
{
SECStatus rv;
sslBuffer extensionBuf = SSL_BUFFER_EMPTY;
unsigned int offset = 0;
SSL_TRC(3, ("%d: TLS13[%d]: begin send certificate_request",
SSL_GETPID(), ss->fd));
if (ss->firstHsDone) {
PORT_Assert(ss->ssl3.hs.shaPostHandshake == NULL);
ss->ssl3.hs.shaPostHandshake = PK11_CloneContext(ss->ssl3.hs.sha);
if (ss->ssl3.hs.shaPostHandshake == NULL) {
ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
return SECFailure;
}
}
rv = ssl_ConstructExtensions(ss, &extensionBuf, ssl_hs_certificate_request);
if (rv != SECSuccess) {
return SECFailure; /* Code already set. */
@ -2222,6 +2249,8 @@ tls13_SendCertificateRequest(sslSocket *ss)
FATAL_ERROR(ss, SEC_ERROR_NO_MEMORY, internal_error);
goto loser;
}
offset = SSL_BUFFER_LEN(&ss->sec.ci.sendBuf);
}
rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_certificate_request,
@ -2245,6 +2274,15 @@ tls13_SendCertificateRequest(sslSocket *ss)
goto loser; /* err set by AppendHandshake. */
}
if (ss->firstHsDone) {
rv = ssl3_UpdatePostHandshakeHashes(ss,
SSL_BUFFER_BASE(&ss->sec.ci.sendBuf) + offset,
SSL_BUFFER_LEN(&ss->sec.ci.sendBuf) - offset);
if (rv != SECSuccess) {
goto loser;
}
}
sslBuffer_Clear(&extensionBuf);
return SECSuccess;
@ -2410,7 +2448,19 @@ tls13_HandleCertificateRequest(sslSocket *ss, PRUint8 *b, PRUint32 length)
return SECFailure;
}
if (ss->firstHsDone) {
if (tls13_IsPostHandshake(ss)) {
PORT_Assert(ss->ssl3.hs.shaPostHandshake == NULL);
ss->ssl3.hs.shaPostHandshake = PK11_CloneContext(ss->ssl3.hs.sha);
if (ss->ssl3.hs.shaPostHandshake == NULL) {
ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
return SECFailure;
}
rv = ssl_HashPostHandshakeMessage(ss, ssl_hs_certificate_request, b, length);
if (rv != SECSuccess) {
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
return SECFailure;
}
/* clean up anything left from previous handshake. */
if (ss->ssl3.clientCertChain != NULL) {
CERT_DestroyCertificateList(ss->ssl3.clientCertChain);
@ -2441,7 +2491,7 @@ tls13_HandleCertificateRequest(sslSocket *ss, PRUint8 *b, PRUint32 length)
/* Unless it is a post-handshake client auth, the certificate
* request context must be empty. */
if (!ss->firstHsDone && context.len > 0) {
if (!tls13_IsPostHandshake(ss) && context.len > 0) {
FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERT_REQUEST, illegal_parameter);
return SECFailure;
}
@ -2501,6 +2551,9 @@ tls13_HandleCertificateRequest(sslSocket *ss, PRUint8 *b, PRUint32 length)
return SECFailure;
}
PORT_Assert(ss->ssl3.hs.ws == idle_handshake);
PORT_Assert(ss->ssl3.hs.shaPostHandshake != NULL);
PK11_DestroyContext(ss->ssl3.hs.shaPostHandshake, PR_TRUE);
ss->ssl3.hs.shaPostHandshake = NULL;
} else {
TLS13_SET_HS_STATE(ss, wait_server_cert);
}
@ -3058,6 +3111,15 @@ tls13_HandleCertificate(sslSocket *ss, PRUint8 *b, PRUint32 length)
ssl_CipherSpecReleaseByEpoch(ss, ssl_secret_read, TrafficKeyClearText);
dtls_ReceivedFirstMessageInFlight(ss);
}
if (ss->firstHsDone) {
rv = ssl_HashPostHandshakeMessage(ss, ssl_hs_certificate, b, length);
if (rv != SECSuccess) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
}
/* Process the context string */
rv = ssl3_ConsumeHandshakeVariable(ss, &context, 1, &b, &length);
if (rv != SECSuccess)
@ -3615,7 +3677,11 @@ tls13_ComputeHandshakeHashes(sslSocket *ss, SSL3Hashes *hashes)
goto loser;
}
} else {
ctx = PK11_CloneContext(ss->ssl3.hs.sha);
if (ss->firstHsDone) {
ctx = PK11_CloneContext(ss->ssl3.hs.shaPostHandshake);
} else {
ctx = PK11_CloneContext(ss->ssl3.hs.sha);
}
if (!ctx) {
ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
return SECFailure;
@ -4069,7 +4135,11 @@ tls13_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length)
return SECFailure;
}
rv = ssl_HashHandshakeMessage(ss, ssl_hs_certificate_verify, b, length);
if (ss->firstHsDone) {
rv = ssl_HashPostHandshakeMessage(ss, ssl_hs_certificate_verify, b, length);
} else {
rv = ssl_HashHandshakeMessage(ss, ssl_hs_certificate_verify, b, length);
}
if (rv != SECSuccess) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
@ -4129,10 +4199,6 @@ tls13_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length)
}
}
if (ss->ssl3.clientCertRequested) {
PORT_Assert(ss->sec.isServer);
ss->ssl3.clientCertRequested = PR_FALSE;
}
TLS13_SET_HS_STATE(ss, wait_finished);
return SECSuccess;
@ -4393,7 +4459,11 @@ tls13_CommonHandleFinished(sslSocket *ss, PK11SymKey *key,
return SECFailure;
}
rv = ssl_HashHandshakeMessage(ss, ssl_hs_finished, b, length);
if (ss->firstHsDone) {
rv = ssl_HashPostHandshakeMessage(ss, ssl_hs_finished, b, length);
} else {
rv = ssl_HashHandshakeMessage(ss, ssl_hs_finished, b, length);
}
if (rv != SECSuccess) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
@ -4443,6 +4513,22 @@ tls13_ServerHandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length)
if (ss->firstHsDone) {
TLS13_SET_HS_STATE(ss, idle_handshake);
PORT_Assert(ss->ssl3.hs.shaPostHandshake != NULL);
PK11_DestroyContext(ss->ssl3.hs.shaPostHandshake, PR_TRUE);
ss->ssl3.hs.shaPostHandshake = NULL;
ss->ssl3.clientCertRequested = PR_FALSE;
if (ss->ssl3.keyUpdateDeferred) {
rv = tls13_SendKeyUpdate(ss, ss->ssl3.deferredKeyUpdateRequest,
PR_FALSE);
if (rv != SECSuccess) {
return SECFailure; /* error is set. */
}
ss->ssl3.keyUpdateDeferred = PR_FALSE;
}
return SECSuccess;
}
@ -4525,11 +4611,16 @@ tls13_SendClientSecondFlight(sslSocket *ss, PRBool sendClientCert,
SSL3AlertDescription *sendAlert)
{
SECStatus rv;
unsigned int offset = 0;
PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
*sendAlert = internal_error;
if (ss->firstHsDone) {
offset = SSL_BUFFER_LEN(&ss->sec.ci.sendBuf);
}
if (ss->ssl3.sendEmptyCert) {
ss->ssl3.sendEmptyCert = PR_FALSE;
rv = ssl3_SendEmptyCertificate(ss);
@ -4543,6 +4634,16 @@ tls13_SendClientSecondFlight(sslSocket *ss, PRBool sendClientCert,
return SECFailure; /* error code is set. */
}
}
if (ss->firstHsDone) {
rv = ssl3_UpdatePostHandshakeHashes(ss,
SSL_BUFFER_BASE(&ss->sec.ci.sendBuf) + offset,
SSL_BUFFER_LEN(&ss->sec.ci.sendBuf) - offset);
if (rv != SECSuccess) {
return SECFailure; /* error code is set. */
}
}
if (ss->ssl3.hs.clientCertRequested) {
SECITEM_FreeItem(&ss->xtnData.certReqContext, PR_FALSE);
if (ss->xtnData.certReqAuthorities.arena) {
@ -4555,12 +4656,25 @@ tls13_SendClientSecondFlight(sslSocket *ss, PRBool sendClientCert,
}
if (sendClientCert) {
if (ss->firstHsDone) {
offset = SSL_BUFFER_LEN(&ss->sec.ci.sendBuf);
}
rv = tls13_SendCertificateVerify(ss, ss->ssl3.clientPrivateKey);
SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
ss->ssl3.clientPrivateKey = NULL;
if (rv != SECSuccess) {
return SECFailure; /* err is set. */
}
if (ss->firstHsDone) {
rv = ssl3_UpdatePostHandshakeHashes(ss,
SSL_BUFFER_BASE(&ss->sec.ci.sendBuf) + offset,
SSL_BUFFER_LEN(&ss->sec.ci.sendBuf) - offset);
if (rv != SECSuccess) {
return SECFailure; /* error is set. */
}
}
}
rv = tls13_SendFinished(ss, ss->firstHsDone ? ss->ssl3.hs.clientTrafficSecret : ss->ssl3.hs.clientHsTrafficSecret);
@ -4825,8 +4939,7 @@ SSLExp_SendSessionTicket(PRFileDesc *fd, const PRUint8 *token,
return SECFailure;
}
if (!ss->sec.isServer || !ss->firstHsDone ||
ss->version < SSL_LIBRARY_VERSION_TLS_1_3 ||
if (!ss->sec.isServer || !tls13_IsPostHandshake(ss) ||
tokenLen > 0xffff) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
@ -4862,7 +4975,7 @@ tls13_HandleNewSessionTicket(sslSocket *ss, PRUint8 *b, PRUint32 length)
if (rv != SECSuccess) {
return SECFailure;
}
if (!ss->firstHsDone || ss->sec.isServer) {
if (!tls13_IsPostHandshake(ss) || ss->sec.isServer) {
FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET,
unexpected_message);
return SECFailure;

Просмотреть файл

@ -18,11 +18,6 @@ typedef enum {
tls13_extension_unknown
} tls13ExtensionStatus;
typedef enum {
update_not_requested = 0,
update_requested = 1
} tls13KeyUpdateRequest;
#define TLS13_MAX_FINISHED_SIZE 64
SECStatus tls13_UnprotectRecord(
@ -47,6 +42,8 @@ PRBool tls13_InHsState(sslSocket *ss, ...);
#define TLS13_IN_HS_STATE(ss, ...) \
tls13_InHsState(ss, __VA_ARGS__, wait_invalid)
PRBool tls13_IsPostHandshake(const sslSocket *ss);
SSLHashType tls13_GetHashForCipherSuite(ssl3CipherSuite suite);
SSLHashType tls13_GetHash(const sslSocket *ss);
unsigned int tls13_GetHashSizeForHash(SSLHashType hash);

Просмотреть файл

@ -157,7 +157,8 @@ tls13_RecoverHashState(sslSocket *ss,
/* Now reinject the message. */
SSL_ASSERT_HASHES_EMPTY(ss);
rv = ssl_HashHandshakeMessageInt(ss, ssl_hs_message_hash, 0,
SSL_READER_CURRENT(&reader), hashLen);
SSL_READER_CURRENT(&reader), hashLen,
ssl3_UpdateHandshakeHashes);
if (rv != SECSuccess) {
return SECFailure;
}
@ -173,7 +174,8 @@ tls13_RecoverHashState(sslSocket *ss,
rv = ssl_HashHandshakeMessageInt(ss, ssl_hs_server_hello, 0,
SSL_BUFFER_BASE(&messageBuf),
SSL_BUFFER_LEN(&messageBuf));
SSL_BUFFER_LEN(&messageBuf),
ssl3_UpdateHandshakeHashes);
sslBuffer_Clear(&messageBuf);
if (rv != SECSuccess) {
return SECFailure;

Просмотреть файл

@ -230,6 +230,8 @@
#define CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN (CKM_NSS + 31)
#define CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN (CKM_NSS + 32)
#define CKM_NSS_CHACHA20_CTR (CKM_NSS + 33)
/*
* HISTORICAL:
* Do not attempt to use these. They are only used by NETSCAPE's internal

Просмотреть файл

@ -220,18 +220,20 @@ start_selfserv()
else
RSA_OPTIONS="-n ${HOSTADDR}-rsa-pss"
fi
SERVER_VMIN=${SERVER_VMIN-ssl3}
SERVER_VMAX=${SERVER_VMAX-tls1.2}
echo "selfserv starting at `date`"
echo "selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} ${RSA_OPTIONS} ${SERVER_OPTIONS} \\"
echo " ${ECC_OPTIONS} -S ${HOSTADDR}-dsa -w nss "$@" -i ${R_SERVERPID}\\"
echo " -V ssl3:tls1.2 $verbose -H 1 &"
echo " -V ${SERVER_VMIN}:${SERVER_VMAX} $verbose -H 1 &"
if [ ${fileout} -eq 1 ]; then
${PROFTOOL} ${BINDIR}/selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} ${RSA_OPTIONS} ${SERVER_OPTIONS} \
${ECC_OPTIONS} -S ${HOSTADDR}-dsa -w nss "$@" -i ${R_SERVERPID} -V ssl3:tls1.2 $verbose -H 1 \
${ECC_OPTIONS} -S ${HOSTADDR}-dsa -w nss "$@" -i ${R_SERVERPID} -V ${SERVER_VMIN}:${SERVER_VMAX} $verbose -H 1 \
> ${SERVEROUTFILE} 2>&1 &
RET=$?
else
${PROFTOOL} ${BINDIR}/selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} ${RSA_OPTIONS} ${SERVER_OPTIONS} \
${ECC_OPTIONS} -S ${HOSTADDR}-dsa -w nss "$@" -i ${R_SERVERPID} -V ssl3:tls1.2 $verbose -H 1 &
${ECC_OPTIONS} -S ${HOSTADDR}-dsa -w nss "$@" -i ${R_SERVERPID} -V ${SERVER_VMIN}:${SERVER_VMAX} $verbose -H 1 &
RET=$?
fi
@ -388,6 +390,8 @@ ssl_auth()
do
echo "${testname}" | grep "don't require client auth" > /dev/null
CAUTH=$?
echo "${testname}" | grep "TLS 1.3" > /dev/null
TLS13=$?
if [ "${CLIENT_MODE}" = "fips" -a "${CAUTH}" -eq 0 ] ; then
echo "$SCRIPTNAME: skipping $testname (non-FIPS only)"
@ -399,6 +403,13 @@ ssl_auth()
cparam=`echo $cparam | sed -e "s/Host/$HOST/g" -e "s/Dom/$DOMSUF/g" `
sparam=`echo $sparam | sed -e "s/Host/$HOST/g" -e "s/Dom/$DOMSUF/g" `
fi
# SSL3 cannot be used with TLS 1.3
unset SERVER_VMIN
unset SERVER_VMAX
if [ $TLS13 -eq 0 ] ; then
SERVER_VMIN=tls1.0
SERVER_VMAX=tls1.3
fi
start_selfserv `echo "$sparam" | sed -e 's,_, ,g'`
echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_CLIENTDIR} $verbose ${CLIENT_OPTIONS} \\"
@ -669,9 +680,18 @@ ssl_crl_ssl()
ignore_blank_lines ${SSLAUTH} | \
while read ectype value sparam cparam testname
do
echo "${testname}" | grep "TLS 1.3" > /dev/null
TLS13=$?
if [ "$ectype" = "SNI" ]; then
continue
else
# SSL3 cannot be used with TLS 1.3
unset SERVER_VMIN
unset SERVER_VMAX
if [ $TLS13 -eq 0 ] ; then
SERVER_VMIN=tls1.0
SERVER_VMAX=tls1.3
fi
servarg=`echo $sparam | awk '{r=split($0,a,"-r") - 1;print r;}'`
pwd=`echo $cparam | grep nss`
user=`echo $cparam | grep TestUser`
@ -1039,7 +1059,7 @@ ssl_crl_cache()
rm -f ${SSLAUTH_TMP}
echo ${SSLAUTH_TMP}
grep -- " $SERV_ARG " ${SSLAUTH} | grep -v "^#" | grep -v none | grep -v bogus > ${SSLAUTH_TMP}
grep -- " $SERV_ARG " ${SSLAUTH} | grep -v "^#" | grep -v none | grep -v bogus | grep -v 'post hs' > ${SSLAUTH_TMP}
echo $?
while [ $? -eq 0 -a -f ${SSLAUTH_TMP} ]
do

Просмотреть файл

@ -38,6 +38,10 @@
noECC 1 -r_-r_-r_-r -V_ssl3:ssl3_-w_nss_-n_none SSL3 Require client auth on 2nd hs (client does not provide auth)
noECC 1 -r_-r_-r_-r -V_ssl3:ssl3_-n_TestUser_-w_bogus SSL3 Require client auth on 2nd hs (bad password)
noECC 0 -r_-r_-r_-r -V_ssl3:ssl3_-n_TestUser_-w_nss SSL3 Require client auth on 2nd hs (client auth)
noECC 0 -r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_TestUser_-w_nss TLS 1.3 Request don't require client auth on post hs (client auth)
noECC 0 -r_-r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_TestUser_-w_nss TLS 1.3 Require client auth on post hs (client auth)
noECC 0 -r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 Request don't require client auth on post hs (client does not provide auth)
noECC 1 -r_-r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 Require client auth on post hs (client does not provide auth)
#
# Use EC cert for client authentication
#