mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-20 15:27:32 +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
|
|
@ -389,7 +389,6 @@ dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
|
|||
* application data is available.
|
||||
* Returns 0 if ssl3_GatherData hits EOF.
|
||||
* Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
|
||||
* Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
|
||||
*
|
||||
* Called from ssl_GatherRecord1stHandshake in sslcon.c,
|
||||
* and from SSL_ForceHandshake in sslsecur.c
|
||||
|
|
@ -408,7 +407,7 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
|
|||
SSL_TRC(3, ("%d: SSL3[%d] Cannot gather data; fatal alert already sent",
|
||||
SSL_GETPID(), ss->fd));
|
||||
PORT_SetError(SSL_ERROR_HANDSHAKE_FAILED);
|
||||
return SECFailure;
|
||||
return -1;
|
||||
}
|
||||
|
||||
SSL_TRC(30, ("%d: SSL3[%d]: ssl3_GatherCompleteHandshake",
|
||||
|
|
@ -422,7 +421,6 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
|
|||
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
|
||||
|
||||
do {
|
||||
PRBool handleRecordNow = PR_FALSE;
|
||||
PRBool processingEarlyData;
|
||||
|
||||
ssl_GetSSL3HandshakeLock(ss);
|
||||
|
|
@ -436,96 +434,82 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
|
|||
if (ss->ssl3.hs.restartTarget) {
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
PORT_SetError(PR_WOULD_BLOCK_ERROR);
|
||||
return (int)SECFailure;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Treat an empty msgState like a NULL msgState. (Most of the time
|
||||
* when ssl3_HandleHandshake returns SECWouldBlock, it leaves
|
||||
* behind a non-NULL but zero-length msgState).
|
||||
* Test: async_cert_restart_server_sends_hello_request_first_in_separate_record
|
||||
*/
|
||||
if (ss->ssl3.hs.msgState.buf) {
|
||||
if (ss->ssl3.hs.msgState.len == 0) {
|
||||
ss->ssl3.hs.msgState.buf = NULL;
|
||||
} else {
|
||||
handleRecordNow = PR_TRUE;
|
||||
/* If we have a detached record layer, don't ever gather. */
|
||||
if (ss->recordWriteCallback) {
|
||||
PRBool done = ss->firstHsDone;
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
if (done) {
|
||||
return 1;
|
||||
}
|
||||
PORT_SetError(PR_WOULD_BLOCK_ERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
|
||||
if (handleRecordNow) {
|
||||
/* ssl3_HandleHandshake previously returned SECWouldBlock and the
|
||||
* as-yet-unprocessed plaintext of that previous handshake record.
|
||||
* We need to process it now before we overwrite it with the next
|
||||
* handshake record.
|
||||
/* State for SSLv2 client hello support. */
|
||||
ssl2Gather ssl2gs = { PR_FALSE, 0 };
|
||||
ssl2Gather *ssl2gs_ptr = NULL;
|
||||
|
||||
/* If we're a server and waiting for a client hello, accept v2. */
|
||||
if (ss->sec.isServer && ss->opt.enableV2CompatibleHello &&
|
||||
ss->ssl3.hs.ws == wait_client_hello) {
|
||||
ssl2gs_ptr = &ssl2gs;
|
||||
}
|
||||
|
||||
/* bring in the next sslv3 record. */
|
||||
if (ss->recvdCloseNotify) {
|
||||
/* RFC 5246 Section 7.2.1:
|
||||
* Any data received after a closure alert is ignored.
|
||||
*/
|
||||
SSL_DBG(("%d: SSL3[%d]: resuming handshake",
|
||||
SSL_GETPID(), ss->fd));
|
||||
PORT_Assert(!IS_DTLS(ss));
|
||||
rv = ssl3_HandleNonApplicationData(ss, ssl_ct_handshake,
|
||||
0, 0, &ss->gs.buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!IS_DTLS(ss)) {
|
||||
/* If we're a server waiting for a ClientHello then pass
|
||||
* ssl2gs to support SSLv2 ClientHello messages. */
|
||||
rv = ssl3_GatherData(ss, &ss->gs, flags, ssl2gs_ptr);
|
||||
} else {
|
||||
/* State for SSLv2 client hello support. */
|
||||
ssl2Gather ssl2gs = { PR_FALSE, 0 };
|
||||
ssl2Gather *ssl2gs_ptr = NULL;
|
||||
rv = dtls_GatherData(ss, &ss->gs, flags);
|
||||
|
||||
if (ss->sec.isServer && ss->opt.enableV2CompatibleHello &&
|
||||
ss->ssl3.hs.ws == wait_client_hello) {
|
||||
ssl2gs_ptr = &ssl2gs;
|
||||
/* If we got a would block error, that means that no data was
|
||||
* available, so we check the timer to see if it's time to
|
||||
* retransmit */
|
||||
if (rv == SECFailure &&
|
||||
(PORT_GetError() == PR_WOULD_BLOCK_ERROR)) {
|
||||
dtls_CheckTimer(ss);
|
||||
/* Restore the error in case something succeeded */
|
||||
PORT_SetError(PR_WOULD_BLOCK_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* bring in the next sslv3 record. */
|
||||
if (ss->recvdCloseNotify) {
|
||||
/* RFC 5246 Section 7.2.1:
|
||||
* Any data received after a closure alert is ignored.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
if (rv <= 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!IS_DTLS(ss)) {
|
||||
/* Passing a non-NULL ssl2gs here enables detection of
|
||||
* SSLv2-compatible ClientHello messages. */
|
||||
rv = ssl3_GatherData(ss, &ss->gs, flags, ssl2gs_ptr);
|
||||
} else {
|
||||
rv = dtls_GatherData(ss, &ss->gs, flags);
|
||||
|
||||
/* If we got a would block error, that means that no data was
|
||||
* available, so we check the timer to see if it's time to
|
||||
* retransmit */
|
||||
if (rv == SECFailure &&
|
||||
(PORT_GetError() == PR_WOULD_BLOCK_ERROR)) {
|
||||
dtls_CheckTimer(ss);
|
||||
/* Restore the error in case something succeeded */
|
||||
PORT_SetError(PR_WOULD_BLOCK_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
if (rv <= 0) {
|
||||
if (ssl2gs.isV2) {
|
||||
rv = ssl3_HandleV2ClientHello(ss, ss->gs.inbuf.buf,
|
||||
ss->gs.inbuf.len,
|
||||
ssl2gs.padding);
|
||||
if (rv < 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (ssl2gs.isV2) {
|
||||
rv = ssl3_HandleV2ClientHello(ss, ss->gs.inbuf.buf,
|
||||
ss->gs.inbuf.len,
|
||||
ssl2gs.padding);
|
||||
if (rv < 0) {
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
/* decipher it, and handle it if it's a handshake.
|
||||
* If it's application data, ss->gs.buf will not be empty upon return.
|
||||
* If it's a change cipher spec, alert, or handshake message,
|
||||
* ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess.
|
||||
*
|
||||
* cText only needs to be valid for this next function call, so
|
||||
* it can borrow gs.hdr.
|
||||
*/
|
||||
cText.hdr = ss->gs.hdr;
|
||||
cText.hdrLen = ss->gs.hdrLen;
|
||||
cText.buf = &ss->gs.inbuf;
|
||||
rv = ssl3_HandleRecord(ss, &cText);
|
||||
}
|
||||
} else {
|
||||
/* decipher it, and handle it if it's a handshake.
|
||||
* If it's application data, ss->gs.buf will not be empty upon return.
|
||||
* If it's a change cipher spec, alert, or handshake message,
|
||||
* ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess.
|
||||
*
|
||||
* cText only needs to be valid for this next function call, so
|
||||
* it can borrow gs.hdr.
|
||||
*/
|
||||
cText.hdr = ss->gs.hdr;
|
||||
cText.hdrLen = ss->gs.hdrLen;
|
||||
cText.buf = &ss->gs.inbuf;
|
||||
rv = ssl3_HandleRecord(ss, &cText);
|
||||
}
|
||||
if (rv < 0) {
|
||||
return ss->recvdCloseNotify ? 0 : rv;
|
||||
|
|
@ -575,7 +559,7 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
|
|||
* delivered to the application before the handshake completes. */
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
PORT_SetError(PR_WOULD_BLOCK_ERROR);
|
||||
return SECWouldBlock;
|
||||
return -1;
|
||||
}
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
} while (keepGoing);
|
||||
|
|
@ -596,7 +580,6 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
|
|||
* Returns 1 when application data is available.
|
||||
* Returns 0 if ssl3_GatherData hits EOF.
|
||||
* Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
|
||||
* Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
|
||||
*
|
||||
* Called from DoRecv in sslsecur.c
|
||||
* Caller must hold the recv buf lock.
|
||||
|
|
@ -616,3 +599,109 @@ ssl3_GatherAppDataRecord(sslSocket *ss, int flags)
|
|||
|
||||
return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
SSLExp_RecordLayerData(PRFileDesc *fd, PRUint16 epoch,
|
||||
SSLContentType contentType,
|
||||
const PRUint8 *data, unsigned int len)
|
||||
{
|
||||
SECStatus rv;
|
||||
sslSocket *ss = ssl_FindSocket(fd);
|
||||
if (!ss) {
|
||||
return SECFailure;
|
||||
}
|
||||
if (IS_DTLS(ss) || data == NULL || len == 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Run any handshake function. If SSL_RecordLayerData is the only way that
|
||||
* the handshake is driven, then this is necessary to ensure that
|
||||
* ssl_BeginClientHandshake or ssl_BeginServerHandshake is called. Note that
|
||||
* the other function that might be set to ss->handshake,
|
||||
* ssl3_GatherCompleteHandshake, does nothing when this function is used. */
|
||||
ssl_Get1stHandshakeLock(ss);
|
||||
rv = ssl_Do1stHandshake(ss);
|
||||
if (rv != SECSuccess && PORT_GetError() != PR_WOULD_BLOCK_ERROR) {
|
||||
goto early_loser; /* Rely on the existing code. */
|
||||
}
|
||||
|
||||
/* Don't allow application data before handshake completion. */
|
||||
if (contentType == ssl_ct_application_data && !ss->firstHsDone) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
goto early_loser;
|
||||
}
|
||||
|
||||
/* Then we can validate the epoch. */
|
||||
PRErrorCode epochError;
|
||||
ssl_GetSpecReadLock(ss);
|
||||
if (epoch < ss->ssl3.crSpec->epoch) {
|
||||
epochError = SEC_ERROR_INVALID_ARGS; /* Too c/old. */
|
||||
} else if (epoch > ss->ssl3.crSpec->epoch) {
|
||||
epochError = PR_WOULD_BLOCK_ERROR; /* Too warm/new. */
|
||||
} else {
|
||||
epochError = 0; /* Just right. */
|
||||
}
|
||||
ssl_ReleaseSpecReadLock(ss);
|
||||
if (epochError) {
|
||||
PORT_SetError(epochError);
|
||||
goto early_loser;
|
||||
}
|
||||
|
||||
/* If the handshake is still running, we need to run that. */
|
||||
ssl_Get1stHandshakeLock(ss);
|
||||
rv = ssl_Do1stHandshake(ss);
|
||||
if (rv != SECSuccess && PORT_GetError() != PR_WOULD_BLOCK_ERROR) {
|
||||
ssl_Release1stHandshakeLock(ss);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Finally, save the data... */
|
||||
ssl_GetRecvBufLock(ss);
|
||||
rv = sslBuffer_Append(&ss->gs.buf, data, len);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* ...and process it. Just saving application data is enough for it to be
|
||||
* available to PR_Read(). */
|
||||
if (contentType != ssl_ct_application_data) {
|
||||
rv = ssl3_HandleNonApplicationData(ss, contentType, 0, 0, &ss->gs.buf);
|
||||
/* This occasionally blocks, but that's OK here. */
|
||||
if (rv != SECSuccess && PORT_GetError() != PR_WOULD_BLOCK_ERROR) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
|
||||
ssl_ReleaseRecvBufLock(ss);
|
||||
ssl_Release1stHandshakeLock(ss);
|
||||
return SECSuccess;
|
||||
|
||||
loser:
|
||||
/* Make sure that any data is not used again. */
|
||||
ss->gs.buf.len = 0;
|
||||
ssl_ReleaseRecvBufLock(ss);
|
||||
early_loser:
|
||||
ssl_Release1stHandshakeLock(ss);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
SSLExp_GetCurrentEpoch(PRFileDesc *fd, PRUint16 *readEpoch,
|
||||
PRUint16 *writeEpoch)
|
||||
{
|
||||
sslSocket *ss = ssl_FindSocket(fd);
|
||||
if (!ss) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ssl_GetSpecReadLock(ss);
|
||||
if (readEpoch) {
|
||||
*readEpoch = ss->ssl3.crSpec->epoch;
|
||||
}
|
||||
if (writeEpoch) {
|
||||
*writeEpoch = ss->ssl3.cwSpec->epoch;
|
||||
}
|
||||
ssl_ReleaseSpecReadLock(ss);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue