mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-21 15:57:31 +09:00
nss: update nss to hg rev e5e10a46b9ad with vc2013 hackfix
This commit is contained in:
parent
ed1b356dfa
commit
dcdc5d70e0
133 changed files with 8084 additions and 2038 deletions
|
|
@ -64,6 +64,7 @@ static SECStatus ssl3_FlushHandshakeMessages(sslSocket *ss, PRInt32 flags);
|
|||
static CK_MECHANISM_TYPE ssl3_GetHashMechanismByHashType(SSLHashType hashType);
|
||||
static CK_MECHANISM_TYPE ssl3_GetMgfMechanismByHashType(SSLHashType hash);
|
||||
PRBool ssl_IsRsaPssSignatureScheme(SSLSignatureScheme scheme);
|
||||
PRBool ssl_IsDsaSignatureScheme(SSLSignatureScheme scheme);
|
||||
|
||||
const PRUint8 ssl_hello_retry_random[] = {
|
||||
0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
|
||||
|
|
@ -553,10 +554,9 @@ SSL_AtomicIncrementLong(long *x)
|
|||
}
|
||||
}
|
||||
|
||||
static PRBool
|
||||
ssl3_CipherSuiteAllowedForVersionRange(
|
||||
ssl3CipherSuite cipherSuite,
|
||||
const SSLVersionRange *vrange)
|
||||
PRBool
|
||||
ssl3_CipherSuiteAllowedForVersionRange(ssl3CipherSuite cipherSuite,
|
||||
const SSLVersionRange *vrange)
|
||||
{
|
||||
switch (cipherSuite) {
|
||||
case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
|
||||
|
|
@ -912,8 +912,8 @@ count_cipher_suites(sslSocket *ss, PRUint8 policy)
|
|||
* Null compression, mac and encryption functions
|
||||
*/
|
||||
SECStatus
|
||||
Null_Cipher(void *ctx, unsigned char *output, int *outputLen, int maxOutputLen,
|
||||
const unsigned char *input, int inputLen)
|
||||
Null_Cipher(void *ctx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen)
|
||||
{
|
||||
if (inputLen > maxOutputLen) {
|
||||
*outputLen = 0; /* Match PK11_CipherOp in setting outputLen */
|
||||
|
|
@ -1394,14 +1394,14 @@ loser:
|
|||
}
|
||||
|
||||
static SECStatus
|
||||
ssl3_SetupPendingCipherSpec(sslSocket *ss, CipherSpecDirection direction,
|
||||
ssl3_SetupPendingCipherSpec(sslSocket *ss, SSLSecretDirection direction,
|
||||
const ssl3CipherSuiteDef *suiteDef,
|
||||
ssl3CipherSpec **specp)
|
||||
{
|
||||
ssl3CipherSpec *spec;
|
||||
const ssl3CipherSpec *prev;
|
||||
|
||||
prev = (direction == CipherSpecWrite) ? ss->ssl3.cwSpec : ss->ssl3.crSpec;
|
||||
prev = (direction == ssl_secret_write) ? ss->ssl3.cwSpec : ss->ssl3.crSpec;
|
||||
if (prev->epoch == PR_UINT16_MAX) {
|
||||
PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED);
|
||||
return SECFailure;
|
||||
|
|
@ -1417,7 +1417,7 @@ ssl3_SetupPendingCipherSpec(sslSocket *ss, CipherSpecDirection direction,
|
|||
|
||||
spec->epoch = prev->epoch + 1;
|
||||
spec->nextSeqNum = 0;
|
||||
if (IS_DTLS(ss) && direction == CipherSpecRead) {
|
||||
if (IS_DTLS(ss) && direction == ssl_secret_read) {
|
||||
dtls_InitRecvdRecords(&spec->recvdRecords);
|
||||
}
|
||||
ssl_SetSpecVersions(ss, spec);
|
||||
|
|
@ -1471,12 +1471,12 @@ ssl3_SetupBothPendingCipherSpecs(sslSocket *ss)
|
|||
ss->ssl3.hs.kea_def = &kea_defs[kea];
|
||||
PORT_Assert(ss->ssl3.hs.kea_def->kea == kea);
|
||||
|
||||
rv = ssl3_SetupPendingCipherSpec(ss, CipherSpecRead, suiteDef,
|
||||
rv = ssl3_SetupPendingCipherSpec(ss, ssl_secret_read, suiteDef,
|
||||
&ss->ssl3.prSpec);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
rv = ssl3_SetupPendingCipherSpec(ss, CipherSpecWrite, suiteDef,
|
||||
rv = ssl3_SetupPendingCipherSpec(ss, ssl_secret_write, suiteDef,
|
||||
&ss->ssl3.pwSpec);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
|
|
@ -1554,15 +1554,15 @@ ssl3_BuildRecordPseudoHeader(DTLSEpoch epoch,
|
|||
}
|
||||
|
||||
static SECStatus
|
||||
ssl3_AESGCM(ssl3KeyMaterial *keys,
|
||||
ssl3_AESGCM(const ssl3KeyMaterial *keys,
|
||||
PRBool doDecrypt,
|
||||
unsigned char *out,
|
||||
int *outlen,
|
||||
int maxout,
|
||||
unsigned int *outlen,
|
||||
unsigned int maxout,
|
||||
const unsigned char *in,
|
||||
int inlen,
|
||||
unsigned int inlen,
|
||||
const unsigned char *additionalData,
|
||||
int additionalDataLen)
|
||||
unsigned int additionalDataLen)
|
||||
{
|
||||
SECItem param;
|
||||
SECStatus rv = SECFailure;
|
||||
|
|
@ -1616,11 +1616,11 @@ ssl3_AESGCM(ssl3KeyMaterial *keys,
|
|||
}
|
||||
|
||||
static SECStatus
|
||||
ssl3_ChaCha20Poly1305(ssl3KeyMaterial *keys, PRBool doDecrypt,
|
||||
unsigned char *out, int *outlen, int maxout,
|
||||
const unsigned char *in, int inlen,
|
||||
ssl3_ChaCha20Poly1305(const ssl3KeyMaterial *keys, PRBool doDecrypt,
|
||||
unsigned char *out, unsigned int *outlen, unsigned int maxout,
|
||||
const unsigned char *in, unsigned int inlen,
|
||||
const unsigned char *additionalData,
|
||||
int additionalDataLen)
|
||||
unsigned int additionalDataLen)
|
||||
{
|
||||
size_t i;
|
||||
SECItem param;
|
||||
|
|
@ -1727,7 +1727,7 @@ ssl3_InitPendingContexts(sslSocket *ss, ssl3CipherSpec *spec)
|
|||
|
||||
spec->cipher = (SSLCipher)PK11_CipherOp;
|
||||
encMechanism = ssl3_Alg2Mech(calg);
|
||||
encMode = (spec->direction == CipherSpecWrite) ? CKA_ENCRYPT : CKA_DECRYPT;
|
||||
encMode = (spec->direction == ssl_secret_write) ? CKA_ENCRYPT : CKA_DECRYPT;
|
||||
|
||||
/*
|
||||
* build the context
|
||||
|
|
@ -2012,7 +2012,7 @@ ssl3_MACEncryptRecord(ssl3CipherSpec *cwSpec,
|
|||
unsigned int ivLen = 0;
|
||||
unsigned char pseudoHeaderBuf[13];
|
||||
sslBuffer pseudoHeader = SSL_BUFFER(pseudoHeaderBuf);
|
||||
int len;
|
||||
unsigned int len;
|
||||
|
||||
if (cwSpec->cipherDef->type == type_block &&
|
||||
cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
|
||||
|
|
@ -2130,15 +2130,15 @@ ssl3_MACEncryptRecord(ssl3CipherSpec *cwSpec,
|
|||
memmove(SSL_BUFFER_NEXT(wrBuf) + p1Len, pIn + p1Len, oddLen);
|
||||
}
|
||||
if (p1Len > 0) {
|
||||
int cipherBytesPart1 = -1;
|
||||
unsigned int cipherBytesPart1 = 0;
|
||||
rv = cwSpec->cipher(cwSpec->cipherContext,
|
||||
SSL_BUFFER_NEXT(wrBuf), /* output */
|
||||
&cipherBytesPart1, /* actual outlen */
|
||||
p1Len, /* max outlen */
|
||||
pIn,
|
||||
p1Len); /* input, and inputlen */
|
||||
PORT_Assert(rv == SECSuccess && cipherBytesPart1 == (int)p1Len);
|
||||
if (rv != SECSuccess || cipherBytesPart1 != (int)p1Len) {
|
||||
PORT_Assert(rv == SECSuccess && cipherBytesPart1 == p1Len);
|
||||
if (rv != SECSuccess || cipherBytesPart1 != p1Len) {
|
||||
PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
|
@ -2146,15 +2146,15 @@ ssl3_MACEncryptRecord(ssl3CipherSpec *cwSpec,
|
|||
PORT_Assert(rv == SECSuccess);
|
||||
}
|
||||
if (p2Len > 0) {
|
||||
int cipherBytesPart2 = -1;
|
||||
unsigned int cipherBytesPart2 = 0;
|
||||
rv = cwSpec->cipher(cwSpec->cipherContext,
|
||||
SSL_BUFFER_NEXT(wrBuf),
|
||||
&cipherBytesPart2, /* output and actual outLen */
|
||||
p2Len, /* max outlen */
|
||||
SSL_BUFFER_NEXT(wrBuf),
|
||||
p2Len); /* input and inputLen*/
|
||||
PORT_Assert(rv == SECSuccess && cipherBytesPart2 == (int)p2Len);
|
||||
if (rv != SECSuccess || cipherBytesPart2 != (int)p2Len) {
|
||||
PORT_Assert(rv == SECSuccess && cipherBytesPart2 == p2Len);
|
||||
if (rv != SECSuccess || cipherBytesPart2 != p2Len) {
|
||||
PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
|
@ -2215,7 +2215,7 @@ ssl_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec, SSLContentType ct,
|
|||
unsigned int lenOffset;
|
||||
SECStatus rv;
|
||||
|
||||
PORT_Assert(cwSpec->direction == CipherSpecWrite);
|
||||
PORT_Assert(cwSpec->direction == ssl_secret_write);
|
||||
PORT_Assert(SSL_BUFFER_LEN(wrBuf) == 0);
|
||||
PORT_Assert(cwSpec->cipherDef->max_records <= RECORD_SEQ_MAX);
|
||||
|
||||
|
|
@ -2241,7 +2241,7 @@ ssl_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec, SSLContentType ct,
|
|||
|
||||
#ifdef UNSAFE_FUZZER_MODE
|
||||
{
|
||||
int len;
|
||||
unsigned int len;
|
||||
rv = Null_Cipher(NULL, SSL_BUFFER_NEXT(wrBuf), &len,
|
||||
SSL_BUFFER_SPACE(wrBuf), pIn, contentLen);
|
||||
if (rv != SECSuccess) {
|
||||
|
|
@ -2314,8 +2314,8 @@ ssl_ProtectNextRecord(sslSocket *ss, ssl3CipherSpec *spec, SSLContentType ct,
|
|||
* Returns the number of bytes of plaintext that were successfully sent
|
||||
* plus the number of bytes of plaintext that were copied into the
|
||||
* output (write) buffer.
|
||||
* Returns SECFailure on a hard IO error, memory error, or crypto error.
|
||||
* Does NOT return SECWouldBlock.
|
||||
* Returns -1 on an error. PR_WOULD_BLOCK_ERROR is set if the error is blocking
|
||||
* and not terminal.
|
||||
*
|
||||
* Notes on the use of the private ssl flags:
|
||||
* (no private SSL flags)
|
||||
|
|
@ -2360,13 +2360,26 @@ ssl3_SendRecord(sslSocket *ss,
|
|||
* error, so don't overwrite. */
|
||||
PORT_SetError(SSL_ERROR_HANDSHAKE_FAILED);
|
||||
}
|
||||
return SECFailure;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check for Token Presence */
|
||||
if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) {
|
||||
PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
|
||||
return SECFailure;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ss->recordWriteCallback) {
|
||||
PRUint16 epoch;
|
||||
ssl_GetSpecReadLock(ss);
|
||||
epoch = ss->ssl3.cwSpec->epoch;
|
||||
ssl_ReleaseSpecReadLock(ss);
|
||||
rv = ss->recordWriteCallback(ss->fd, epoch, ct, pIn, nIn,
|
||||
ss->recordWriteCallbackArg);
|
||||
if (rv != SECSuccess) {
|
||||
return -1;
|
||||
}
|
||||
return nIn;
|
||||
}
|
||||
|
||||
if (cwSpec) {
|
||||
|
|
@ -2470,7 +2483,7 @@ loser:
|
|||
#define SSL3_PENDING_HIGH_WATER 1024
|
||||
|
||||
/* Attempt to send the content of "in" in an SSL application_data record.
|
||||
* Returns "len" or SECFailure, never SECWouldBlock, nor SECSuccess.
|
||||
* Returns "len" or -1 on failure.
|
||||
*/
|
||||
int
|
||||
ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
|
||||
|
|
@ -2485,21 +2498,21 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
|
|||
PORT_Assert(!(flags & ssl_SEND_FLAG_NO_RETRANSMIT));
|
||||
if (len < 0 || !in) {
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER &&
|
||||
!ssl_SocketIsBlocking(ss)) {
|
||||
PORT_Assert(!ssl_SocketIsBlocking(ss));
|
||||
PORT_SetError(PR_WOULD_BLOCK_ERROR);
|
||||
return SECFailure;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ss->appDataBuffered && len) {
|
||||
PORT_Assert(in[0] == (unsigned char)(ss->appDataBuffered));
|
||||
if (in[0] != (unsigned char)(ss->appDataBuffered)) {
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
return -1;
|
||||
}
|
||||
in++;
|
||||
len--;
|
||||
|
|
@ -2548,7 +2561,7 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
|
|||
PORT_Assert(ss->lastWriteBlocked);
|
||||
break;
|
||||
}
|
||||
return SECFailure; /* error code set by ssl3_SendRecord */
|
||||
return -1; /* error code set by ssl3_SendRecord */
|
||||
}
|
||||
totalSent += sent;
|
||||
if (ss->pendingBuf.len) {
|
||||
|
|
@ -2577,7 +2590,6 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
|
|||
}
|
||||
|
||||
/* Attempt to send buffered handshake messages.
|
||||
* This function returns SECSuccess or SECFailure, never SECWouldBlock.
|
||||
* Always set sendBuf.len to 0, even when returning SECFailure.
|
||||
*
|
||||
* Depending on whether we are doing DTLS or not, this either calls
|
||||
|
|
@ -2600,7 +2612,6 @@ ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags)
|
|||
}
|
||||
|
||||
/* Attempt to send the content of sendBuf buffer in an SSL handshake record.
|
||||
* This function returns SECSuccess or SECFailure, never SECWouldBlock.
|
||||
* Always set sendBuf.len to 0, even when returning SECFailure.
|
||||
*
|
||||
* Called from ssl3_FlushHandshake
|
||||
|
|
@ -4309,6 +4320,22 @@ ssl_IsRsaPssSignatureScheme(SSLSignatureScheme scheme)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ssl_IsDsaSignatureScheme(SSLSignatureScheme scheme)
|
||||
{
|
||||
switch (scheme) {
|
||||
case ssl_sig_dsa_sha256:
|
||||
case ssl_sig_dsa_sha384:
|
||||
case ssl_sig_dsa_sha512:
|
||||
case ssl_sig_dsa_sha1:
|
||||
return PR_TRUE;
|
||||
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
SSLAuthType
|
||||
ssl_SignatureSchemeToAuthType(SSLSignatureScheme scheme)
|
||||
{
|
||||
|
|
@ -4956,9 +4983,8 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type)
|
|||
}
|
||||
}
|
||||
|
||||
if (ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3 &&
|
||||
type == client_hello_initial) {
|
||||
rv = tls13_SetupClientHello(ss);
|
||||
if (ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
rv = tls13_SetupClientHello(ss, type);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
|
@ -6021,6 +6047,13 @@ ssl_CanUseSignatureScheme(SSLSignatureScheme scheme,
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (ssl_IsDsaSignatureScheme(scheme) &&
|
||||
(NSS_GetAlgorithmPolicy(SEC_OID_ANSIX9_DSA_SIGNATURE, &policy) ==
|
||||
SECSuccess) &&
|
||||
!(policy & NSS_USE_ALG_IN_SSL_KX)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
hashType = ssl_SignatureSchemeToHashType(scheme);
|
||||
if (requireSha1 && (hashType != ssl_hash_sha1)) {
|
||||
return PR_FALSE;
|
||||
|
|
@ -7382,6 +7415,9 @@ ssl3_CompleteHandleCertificateRequest(sslSocket *ss,
|
|||
if (ss->getClientAuthData != NULL) {
|
||||
PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
|
||||
ssl_preinfo_all);
|
||||
PORT_Assert(ss->ssl3.clientPrivateKey == NULL);
|
||||
PORT_Assert(ss->ssl3.clientCertificate == NULL);
|
||||
PORT_Assert(ss->ssl3.clientCertChain == NULL);
|
||||
/* XXX Should pass cert_types and algorithms in this call!! */
|
||||
rv = (SECStatus)(*ss->getClientAuthData)(ss->getClientAuthDataArg,
|
||||
ss->fd, ca_list,
|
||||
|
|
@ -7603,7 +7639,8 @@ ssl3_SendClientSecondRound(sslSocket *ss)
|
|||
" certificate authentication is still pending.",
|
||||
SSL_GETPID(), ss->fd));
|
||||
ss->ssl3.hs.restartTarget = ssl3_SendClientSecondRound;
|
||||
return SECWouldBlock;
|
||||
PORT_SetError(PR_WOULD_BLOCK_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ssl_GetXmitBufLock(ss); /*******************************/
|
||||
|
|
@ -8588,6 +8625,45 @@ loser:
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
/* unwrap helper function to handle the case where the wrapKey doesn't wind
|
||||
* up in the correct token for the master secret */
|
||||
PK11SymKey *
|
||||
ssl_unwrapSymKey(PK11SymKey *wrapKey,
|
||||
CK_MECHANISM_TYPE wrapType, SECItem *param,
|
||||
SECItem *wrappedKey,
|
||||
CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
|
||||
int keySize, CK_FLAGS keyFlags, void *pinArg)
|
||||
{
|
||||
PK11SymKey *unwrappedKey;
|
||||
|
||||
/* unwrap the master secret. */
|
||||
unwrappedKey = PK11_UnwrapSymKeyWithFlags(wrapKey, wrapType, param,
|
||||
wrappedKey, target, operation, keySize,
|
||||
keyFlags);
|
||||
if (!unwrappedKey) {
|
||||
PK11SlotInfo *targetSlot = PK11_GetBestSlot(target, pinArg);
|
||||
PK11SymKey *newWrapKey;
|
||||
|
||||
/* it's possible that we failed to unwrap because the wrapKey is in
|
||||
* a slot that can't handle target. Move the wrapKey to a slot that
|
||||
* can handle this mechanism and retry the operation */
|
||||
if (targetSlot == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
newWrapKey = PK11_MoveSymKey(targetSlot, CKA_UNWRAP, 0,
|
||||
PR_FALSE, wrapKey);
|
||||
PK11_FreeSlot(targetSlot);
|
||||
if (newWrapKey == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
unwrappedKey = PK11_UnwrapSymKeyWithFlags(newWrapKey, wrapType, param,
|
||||
wrappedKey, target, operation, keySize,
|
||||
keyFlags);
|
||||
PK11_FreeSymKey(newWrapKey);
|
||||
}
|
||||
return unwrappedKey;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
ssl3_UnwrapMasterSecretServer(sslSocket *ss, sslSessionID *sid, PK11SymKey **ms)
|
||||
{
|
||||
|
|
@ -8609,12 +8685,14 @@ ssl3_UnwrapMasterSecretServer(sslSocket *ss, sslSessionID *sid, PK11SymKey **ms)
|
|||
keyFlags = CKF_SIGN | CKF_VERIFY;
|
||||
}
|
||||
|
||||
/* unwrap the master secret. */
|
||||
*ms = PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech,
|
||||
NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
|
||||
CKA_DERIVE, SSL3_MASTER_SECRET_LENGTH, keyFlags);
|
||||
*ms = ssl_unwrapSymKey(wrapKey, sid->u.ssl3.masterWrapMech, NULL,
|
||||
&wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
|
||||
CKA_DERIVE, SSL3_MASTER_SECRET_LENGTH,
|
||||
keyFlags, ss->pkcs11PinArg);
|
||||
PK11_FreeSymKey(wrapKey);
|
||||
if (!*ms) {
|
||||
SSL_TRC(10, ("%d: SSL3[%d]: server wrapping key found, but couldn't unwrap MasterSecret. wrapMech=0x%0lx",
|
||||
SSL_GETPID(), ss->fd, sid->u.ssl3.masterWrapMech));
|
||||
return SECFailure;
|
||||
}
|
||||
return SECSuccess;
|
||||
|
|
@ -9495,6 +9573,14 @@ ssl3_EncodeSigAlgs(const sslSocket *ss, sslBuffer *buf)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Skip DSA scheme if it is disabled by policy. */
|
||||
if (ssl_IsDsaSignatureScheme(ss->ssl3.signatureSchemes[i]) &&
|
||||
(NSS_GetAlgorithmPolicy(SEC_OID_ANSIX9_DSA_SIGNATURE, &policy) ==
|
||||
SECSuccess) &&
|
||||
!(policy & NSS_USE_ALG_IN_SSL_KX)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((NSS_GetAlgorithmPolicy(hashOID, &policy) != SECSuccess) ||
|
||||
(policy & NSS_USE_ALG_IN_SSL_KX)) {
|
||||
rv = sslBuffer_AppendNumber(buf, ss->ssl3.signatureSchemes[i], 2);
|
||||
|
|
@ -10737,6 +10823,9 @@ ssl3_AuthCertificate(sslSocket *ss)
|
|||
}
|
||||
}
|
||||
|
||||
if (ss->sec.ci.sid->peerCert) {
|
||||
CERT_DestroyCertificate(ss->sec.ci.sid->peerCert);
|
||||
}
|
||||
ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
|
||||
|
||||
if (!ss->sec.isServer) {
|
||||
|
|
@ -10898,13 +10987,6 @@ ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error)
|
|||
}
|
||||
|
||||
rv = target(ss);
|
||||
/* Even if we blocked here, we have accomplished enough to claim
|
||||
* success. Any remaining work will be taken care of by subsequent
|
||||
* calls to SSL_ForceHandshake/PR_Send/PR_Read/etc.
|
||||
*/
|
||||
if (rv == SECWouldBlock) {
|
||||
rv = SECSuccess;
|
||||
}
|
||||
} else {
|
||||
SSL_TRC(3, ("%d: SSL3[%p]: certificate authentication won the race with"
|
||||
" peer's finished message",
|
||||
|
|
@ -11445,7 +11527,8 @@ xmit_loser:
|
|||
}
|
||||
|
||||
ss->ssl3.hs.restartTarget = ssl3_FinishHandshake;
|
||||
return SECWouldBlock;
|
||||
PORT_SetError(PR_WOULD_BLOCK_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
rv = ssl3_FinishHandshake(ss);
|
||||
|
|
@ -11649,9 +11732,10 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, PRUint8 *b, PRUint32 length,
|
|||
* authenticate the certificate in ssl3_HandleCertificateStatus.
|
||||
*/
|
||||
rv = ssl3_AuthCertificate(ss); /* sets ss->ssl3.hs.ws */
|
||||
PORT_Assert(rv != SECWouldBlock);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
/* This can't block. */
|
||||
PORT_Assert(PORT_GetError() != PR_WOULD_BLOCK_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -11809,28 +11893,17 @@ ssl3_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b,
|
|||
static SECStatus
|
||||
ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
||||
{
|
||||
/*
|
||||
* There may be a partial handshake message already in the handshake
|
||||
* state. The incoming buffer may contain another portion, or a
|
||||
* complete message or several messages followed by another portion.
|
||||
*
|
||||
* Each message is made contiguous before being passed to the actual
|
||||
* message parser.
|
||||
*/
|
||||
sslBuffer *buf = &ss->ssl3.hs.msgState; /* do not lose the original buffer pointer */
|
||||
sslBuffer buf = *origBuf; /* Work from a copy. */
|
||||
SECStatus rv;
|
||||
|
||||
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
|
||||
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
|
||||
|
||||
if (buf->buf == NULL) {
|
||||
*buf = *origBuf;
|
||||
}
|
||||
while (buf->len > 0) {
|
||||
while (buf.len > 0) {
|
||||
if (ss->ssl3.hs.header_bytes < 4) {
|
||||
PRUint8 t;
|
||||
t = *(buf->buf++);
|
||||
buf->len--;
|
||||
t = *(buf.buf++);
|
||||
buf.len--;
|
||||
if (ss->ssl3.hs.header_bytes++ == 0)
|
||||
ss->ssl3.hs.msg_type = (SSLHandshakeType)t;
|
||||
else
|
||||
|
|
@ -11842,12 +11915,12 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
|||
if (ss->ssl3.hs.msg_len > MAX_HANDSHAKE_MSG_LEN) {
|
||||
(void)ssl3_DecodeError(ss);
|
||||
PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
|
||||
return SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
#undef MAX_HANDSHAKE_MSG_LEN
|
||||
|
||||
/* If msg_len is zero, be sure we fall through,
|
||||
** even if buf->len is zero.
|
||||
** even if buf.len is zero.
|
||||
*/
|
||||
if (ss->ssl3.hs.msg_len > 0)
|
||||
continue;
|
||||
|
|
@ -11858,43 +11931,36 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
|||
* data available for this message. If it can be done right out
|
||||
* of the original buffer, then use it from there.
|
||||
*/
|
||||
if (ss->ssl3.hs.msg_body.len == 0 && buf->len >= ss->ssl3.hs.msg_len) {
|
||||
if (ss->ssl3.hs.msg_body.len == 0 && buf.len >= ss->ssl3.hs.msg_len) {
|
||||
/* handle it from input buffer */
|
||||
rv = ssl3_HandleHandshakeMessage(ss, buf->buf, ss->ssl3.hs.msg_len,
|
||||
buf->len == ss->ssl3.hs.msg_len);
|
||||
if (rv == SECFailure) {
|
||||
/* This test wants to fall through on either
|
||||
* SECSuccess or SECWouldBlock.
|
||||
* ssl3_HandleHandshakeMessage MUST set the error code.
|
||||
*/
|
||||
return rv;
|
||||
}
|
||||
buf->buf += ss->ssl3.hs.msg_len;
|
||||
buf->len -= ss->ssl3.hs.msg_len;
|
||||
rv = ssl3_HandleHandshakeMessage(ss, buf.buf, ss->ssl3.hs.msg_len,
|
||||
buf.len == ss->ssl3.hs.msg_len);
|
||||
buf.buf += ss->ssl3.hs.msg_len;
|
||||
buf.len -= ss->ssl3.hs.msg_len;
|
||||
ss->ssl3.hs.msg_len = 0;
|
||||
ss->ssl3.hs.header_bytes = 0;
|
||||
if (rv != SECSuccess) { /* return if SECWouldBlock. */
|
||||
return rv;
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
} else {
|
||||
/* must be copied to msg_body and dealt with from there */
|
||||
unsigned int bytes;
|
||||
|
||||
PORT_Assert(ss->ssl3.hs.msg_body.len < ss->ssl3.hs.msg_len);
|
||||
bytes = PR_MIN(buf->len, ss->ssl3.hs.msg_len - ss->ssl3.hs.msg_body.len);
|
||||
bytes = PR_MIN(buf.len, ss->ssl3.hs.msg_len - ss->ssl3.hs.msg_body.len);
|
||||
|
||||
/* Grow the buffer if needed */
|
||||
rv = sslBuffer_Grow(&ss->ssl3.hs.msg_body, ss->ssl3.hs.msg_len);
|
||||
if (rv != SECSuccess) {
|
||||
/* sslBuffer_Grow has set a memory error code. */
|
||||
return SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
PORT_Memcpy(ss->ssl3.hs.msg_body.buf + ss->ssl3.hs.msg_body.len,
|
||||
buf->buf, bytes);
|
||||
buf.buf, bytes);
|
||||
ss->ssl3.hs.msg_body.len += bytes;
|
||||
buf->buf += bytes;
|
||||
buf->len -= bytes;
|
||||
buf.buf += bytes;
|
||||
buf.len -= bytes;
|
||||
|
||||
PORT_Assert(ss->ssl3.hs.msg_body.len <= ss->ssl3.hs.msg_len);
|
||||
|
||||
|
|
@ -11902,30 +11968,33 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
|||
if (ss->ssl3.hs.msg_body.len == ss->ssl3.hs.msg_len) {
|
||||
rv = ssl3_HandleHandshakeMessage(
|
||||
ss, ss->ssl3.hs.msg_body.buf, ss->ssl3.hs.msg_len,
|
||||
buf->len == 0);
|
||||
if (rv == SECFailure) {
|
||||
/* This test wants to fall through on either
|
||||
* SECSuccess or SECWouldBlock.
|
||||
* ssl3_HandleHandshakeMessage MUST set error code.
|
||||
*/
|
||||
return rv;
|
||||
}
|
||||
buf.len == 0);
|
||||
ss->ssl3.hs.msg_body.len = 0;
|
||||
ss->ssl3.hs.msg_len = 0;
|
||||
ss->ssl3.hs.header_bytes = 0;
|
||||
if (rv != SECSuccess) { /* return if SECWouldBlock. */
|
||||
return rv;
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
} else {
|
||||
PORT_Assert(buf->len == 0);
|
||||
PORT_Assert(buf.len == 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* end loop */
|
||||
|
||||
origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */
|
||||
buf->buf = NULL; /* not a leak. */
|
||||
return SECSuccess;
|
||||
|
||||
loser : {
|
||||
/* Make sure to remove any data that was consumed. */
|
||||
unsigned int consumed = origBuf->len - buf.len;
|
||||
PORT_Assert(consumed == buf.buf - origBuf->buf);
|
||||
if (consumed > 0) {
|
||||
memmove(origBuf->buf, origBuf->buf + consumed, buf.len);
|
||||
origBuf->len = buf.len;
|
||||
}
|
||||
}
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* These macros return the given value with the MSB copied to all the other
|
||||
|
|
@ -12183,7 +12252,7 @@ ssl3_UnprotectRecord(sslSocket *ss,
|
|||
unsigned int hashBytes = MAX_MAC_LENGTH + 1;
|
||||
SECStatus rv;
|
||||
|
||||
PORT_Assert(spec->direction == CipherSpecRead);
|
||||
PORT_Assert(spec->direction == ssl_secret_read);
|
||||
|
||||
good = ~0U;
|
||||
minLength = spec->macDef->mac_size;
|
||||
|
|
@ -12213,7 +12282,7 @@ ssl3_UnprotectRecord(sslSocket *ss,
|
|||
* discard it before decrypting the rest.
|
||||
*/
|
||||
PRUint8 iv[MAX_IV_LENGTH];
|
||||
int decoded;
|
||||
unsigned int decoded;
|
||||
|
||||
ivLen = cipher_def->iv_size;
|
||||
if (ivLen < 8 || ivLen > sizeof(iv)) {
|
||||
|
|
@ -12261,12 +12330,12 @@ ssl3_UnprotectRecord(sslSocket *ss,
|
|||
rType, isTLS, rVersion, IS_DTLS(ss), decryptedLen, &header);
|
||||
PORT_Assert(rv == SECSuccess);
|
||||
rv = spec->aead(&spec->keyMaterial,
|
||||
PR_TRUE, /* do decrypt */
|
||||
plaintext->buf, /* out */
|
||||
(int *)&plaintext->len, /* outlen */
|
||||
plaintext->space, /* maxout */
|
||||
cText->buf->buf, /* in */
|
||||
cText->buf->len, /* inlen */
|
||||
PR_TRUE, /* do decrypt */
|
||||
plaintext->buf, /* out */
|
||||
&plaintext->len, /* outlen */
|
||||
plaintext->space, /* maxout */
|
||||
cText->buf->buf, /* in */
|
||||
cText->buf->len, /* inlen */
|
||||
SSL_BUFFER_BASE(&header), SSL_BUFFER_LEN(&header));
|
||||
if (rv != SECSuccess) {
|
||||
good = 0;
|
||||
|
|
@ -12279,7 +12348,7 @@ ssl3_UnprotectRecord(sslSocket *ss,
|
|||
|
||||
/* decrypt from cText buf to plaintext. */
|
||||
rv = spec->cipher(
|
||||
spec->cipherContext, plaintext->buf, (int *)&plaintext->len,
|
||||
spec->cipherContext, plaintext->buf, &plaintext->len,
|
||||
plaintext->space, cText->buf->buf + ivLen, cText->buf->len - ivLen);
|
||||
if (rv != SECSuccess) {
|
||||
goto decrypt_loser;
|
||||
|
|
@ -12372,7 +12441,7 @@ ssl3_HandleNonApplicationData(sslSocket *ss, SSLContentType rType,
|
|||
ssl_GetSSL3HandshakeLock(ss);
|
||||
|
||||
/* All the functions called in this switch MUST set error code if
|
||||
** they return SECFailure or SECWouldBlock.
|
||||
** they return SECFailure.
|
||||
*/
|
||||
switch (rType) {
|
||||
case ssl_ct_change_cipher_spec:
|
||||
|
|
@ -12429,7 +12498,7 @@ ssl3_GetCipherSpec(sslSocket *ss, SSL3Ciphertext *cText)
|
|||
}
|
||||
if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
/* Try to find the cipher spec. */
|
||||
newSpec = ssl_FindCipherSpecByEpoch(ss, CipherSpecRead,
|
||||
newSpec = ssl_FindCipherSpecByEpoch(ss, ssl_secret_read,
|
||||
epoch);
|
||||
if (newSpec != NULL) {
|
||||
return newSpec;
|
||||
|
|
@ -12561,7 +12630,7 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText)
|
|||
rv = SECFailure;
|
||||
} else {
|
||||
#ifdef UNSAFE_FUZZER_MODE
|
||||
rv = Null_Cipher(NULL, plaintext->buf, (int *)&plaintext->len,
|
||||
rv = Null_Cipher(NULL, plaintext->buf, &plaintext->len,
|
||||
plaintext->space, cText->buf->buf, cText->buf->len);
|
||||
#else
|
||||
/* IMPORTANT: Unprotect functions MUST NOT send alerts
|
||||
|
|
@ -12694,8 +12763,8 @@ ssl3_InitState(sslSocket *ss)
|
|||
|
||||
ssl_GetSpecWriteLock(ss);
|
||||
PR_INIT_CLIST(&ss->ssl3.hs.cipherSpecs);
|
||||
rv = ssl_SetupNullCipherSpec(ss, CipherSpecRead);
|
||||
rv |= ssl_SetupNullCipherSpec(ss, CipherSpecWrite);
|
||||
rv = ssl_SetupNullCipherSpec(ss, ssl_secret_read);
|
||||
rv |= ssl_SetupNullCipherSpec(ss, ssl_secret_write);
|
||||
ss->ssl3.pwSpec = ss->ssl3.prSpec = NULL;
|
||||
ssl_ReleaseSpecWriteLock(ss);
|
||||
if (rv != SECSuccess) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue