/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * Various SSL functions.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "cert.h"
#include "secitem.h"
#include "keyhi.h"
#include "ssl.h"
#include "sslimpl.h"
#include "sslproto.h"
#include "secoid.h"   /* for SECOID_GetALgorithmTag */
#include "pk11func.h" /* for PK11_GenerateRandom */
#include "nss.h"      /* for NSS_RegisterShutdown */
#include "prinit.h"   /* for PR_CallOnceWithArg */
#include "tls13psk.h"

/* Step through the handshake functions.
 *
 * Called from: SSL_ForceHandshake  (below),
 *              ssl_SecureRecv      (below) and
 *              ssl_SecureSend      (below)
 *    from: WaitForResponse     in sslsocks.c
 *          ssl_SocksRecv       in sslsocks.c
 *              ssl_SocksSend       in sslsocks.c
 *
 * Caller must hold the (write) handshakeLock.
 */
SECStatus
ssl_Do1stHandshake(sslSocket *ss)
{
    SECStatus rv = SECSuccess;

    while (ss->handshake && rv == SECSuccess) {
        PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
        PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss));
        PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss));
        PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss));

        rv = (*ss->handshake)(ss);
    };

    PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss));
    PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss));
    PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss));

    return rv;
}

void
ssl_FinishHandshake(sslSocket *ss)
{
    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));

    SSL_TRC(3, ("%d: SSL[%d]: handshake is completed", SSL_GETPID(), ss->fd));

    ss->firstHsDone = PR_TRUE;
    ss->enoughFirstHsDone = PR_TRUE;
    ss->gs.writeOffset = 0;
    ss->gs.readOffset = 0;

    if (ss->handshakeCallback) {
        PORT_Assert((ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
                    ssl_preinfo_all);
        (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
    }

    ssl_FreeEphemeralKeyPairs(ss);
}

/*
 * Handshake function that blocks.  Used to force a
 * retry on a connection on the next read/write.
 */
static SECStatus
ssl3_AlwaysBlock(sslSocket *ss)
{
    PORT_SetError(PR_WOULD_BLOCK_ERROR);
    return SECFailure;
}

/*
 * set the initial handshake state machine to block
 */
void
ssl3_SetAlwaysBlock(sslSocket *ss)
{
    if (!ss->firstHsDone) {
        ss->handshake = ssl3_AlwaysBlock;
    }
}

static SECStatus
ssl_SetTimeout(PRFileDesc *fd, PRIntervalTime timeout)
{
    sslSocket *ss;

    ss = ssl_FindSocket(fd);
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: bad socket in SetTimeout", SSL_GETPID(), fd));
        return SECFailure;
    }
    SSL_LOCK_READER(ss);
    ss->rTimeout = timeout;
    if (ss->opt.fdx) {
        SSL_LOCK_WRITER(ss);
    }
    ss->wTimeout = timeout;
    if (ss->opt.fdx) {
        SSL_UNLOCK_WRITER(ss);
    }
    SSL_UNLOCK_READER(ss);
    return SECSuccess;
}

/* Acquires and releases HandshakeLock.
*/
SECStatus
SSL_ResetHandshake(PRFileDesc *s, PRBool asServer)
{
    sslSocket *ss;
    SECStatus status;
    PRNetAddr addr;

    ss = ssl_FindSocket(s);
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: bad socket in ResetHandshake", SSL_GETPID(), s));
        return SECFailure;
    }

    /* Don't waste my time */
    if (!ss->opt.useSecurity)
        return SECSuccess;

    SSL_LOCK_READER(ss);
    SSL_LOCK_WRITER(ss);

    /* Reset handshake state */
    ssl_Get1stHandshakeLock(ss);

    ss->firstHsDone = PR_FALSE;
    ss->enoughFirstHsDone = PR_FALSE;
    if (asServer) {
        ss->handshake = ssl_BeginServerHandshake;
        ss->handshaking = sslHandshakingAsServer;
    } else {
        ss->handshake = ssl_BeginClientHandshake;
        ss->handshaking = sslHandshakingAsClient;
    }

    ssl_GetRecvBufLock(ss);
    status = ssl3_InitGather(&ss->gs);
    ssl_ReleaseRecvBufLock(ss);
    if (status != SECSuccess)
        goto loser;

    ssl_GetSSL3HandshakeLock(ss);
    ss->ssl3.hs.canFalseStart = PR_FALSE;
    ss->ssl3.hs.restartTarget = NULL;

    /*
    ** Blow away old security state and get a fresh setup.
    */
    ssl_GetXmitBufLock(ss);
    ssl_ResetSecurityInfo(&ss->sec, PR_TRUE);
    status = ssl_CreateSecurityInfo(ss);
    ssl_ReleaseXmitBufLock(ss);

    ssl_ReleaseSSL3HandshakeLock(ss);
    ssl_Release1stHandshakeLock(ss);

    ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions);
    ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.echOuterExtensions);
    ssl3_ResetExtensionData(&ss->xtnData, ss);
    tls13_ResetHandshakePsks(ss, &ss->ssl3.hs.psks);

    if (ss->ssl3.hs.echHpkeCtx) {
        PK11_HPKE_DestroyContext(ss->ssl3.hs.echHpkeCtx, PR_TRUE);
        ss->ssl3.hs.echHpkeCtx = NULL;
        PORT_Assert(ss->ssl3.hs.echPublicName);
        PORT_Free((void *)ss->ssl3.hs.echPublicName); /* CONST */
        ss->ssl3.hs.echPublicName = NULL;
        sslBuffer_Clear(&ss->ssl3.hs.greaseEchBuf);
    }

    if (!ss->TCPconnected)
        ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr));

loser:
    SSL_UNLOCK_WRITER(ss);
    SSL_UNLOCK_READER(ss);

    return status;
}

/* For SSLv2, does nothing but return an error.
** For SSLv3, flushes SID cache entry (if requested),
** and then starts new client hello or hello request.
** Acquires and releases HandshakeLock.
*/
SECStatus
SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache)
{
    sslSocket *ss;
    SECStatus rv;

    ss = ssl_FindSocket(fd);
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: bad socket in RedoHandshake", SSL_GETPID(), fd));
        return SECFailure;
    }

    if (!ss->opt.useSecurity)
        return SECSuccess;

    ssl_Get1stHandshakeLock(ss);

    ssl_GetSSL3HandshakeLock(ss);
    rv = ssl3_RedoHandshake(ss, flushCache); /* force full handshake. */
    ssl_ReleaseSSL3HandshakeLock(ss);

    ssl_Release1stHandshakeLock(ss);

    return rv;
}

/*
** Same as above, but with an I/O timeout.
 */
SSL_IMPORT SECStatus
SSL_ReHandshakeWithTimeout(PRFileDesc *fd,
                           PRBool flushCache,
                           PRIntervalTime timeout)
{
    if (SECSuccess != ssl_SetTimeout(fd, timeout)) {
        return SECFailure;
    }
    return SSL_ReHandshake(fd, flushCache);
}

SECStatus
SSL_RedoHandshake(PRFileDesc *fd)
{
    return SSL_ReHandshake(fd, PR_TRUE);
}

/* Register an application callback to be called when SSL handshake completes.
** Acquires and releases HandshakeLock.
*/
SECStatus
SSL_HandshakeCallback(PRFileDesc *fd, SSLHandshakeCallback cb,
                      void *client_data)
{
    sslSocket *ss;

    ss = ssl_FindSocket(fd);
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: bad socket in HandshakeCallback",
                 SSL_GETPID(), fd));
        return SECFailure;
    }

    if (!ss->opt.useSecurity) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    ssl_Get1stHandshakeLock(ss);
    ssl_GetSSL3HandshakeLock(ss);

    ss->handshakeCallback = cb;
    ss->handshakeCallbackData = client_data;

    ssl_ReleaseSSL3HandshakeLock(ss);
    ssl_Release1stHandshakeLock(ss);

    return SECSuccess;
}

/* Register an application callback to be called when false start may happen.
** Acquires and releases HandshakeLock.
*/
SECStatus
SSL_SetCanFalseStartCallback(PRFileDesc *fd, SSLCanFalseStartCallback cb,
                             void *arg)
{
    sslSocket *ss;

    ss = ssl_FindSocket(fd);
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCanFalseStartCallback",
                 SSL_GETPID(), fd));
        return SECFailure;
    }

    if (!ss->opt.useSecurity) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    ssl_Get1stHandshakeLock(ss);
    ssl_GetSSL3HandshakeLock(ss);

    ss->canFalseStartCallback = cb;
    ss->canFalseStartCallbackData = arg;

    ssl_ReleaseSSL3HandshakeLock(ss);
    ssl_Release1stHandshakeLock(ss);

    return SECSuccess;
}

SECStatus
SSL_RecommendedCanFalseStart(PRFileDesc *fd, PRBool *canFalseStart)
{
    sslSocket *ss;

    *canFalseStart = PR_FALSE;
    ss = ssl_FindSocket(fd);
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RecommendedCanFalseStart",
                 SSL_GETPID(), fd));
        return SECFailure;
    }

    /* Require a forward-secret key exchange. */
    *canFalseStart = ss->ssl3.hs.kea_def->kea == kea_dhe_dss ||
                     ss->ssl3.hs.kea_def->kea == kea_dhe_rsa ||
                     ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
                     ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa;

    return SECSuccess;
}

/* Try to make progress on an SSL handshake by attempting to read the
** next handshake from the peer, and sending any responses.
** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK  if it cannot
** read the next handshake from the underlying socket.
** Returns when handshake is complete, or application data has
** arrived that must be taken by application before handshake can continue,
** or a fatal error occurs.
** Application should use handshake completion callback to tell which.
*/
SECStatus
SSL_ForceHandshake(PRFileDesc *fd)
{
    sslSocket *ss;
    SECStatus rv = SECFailure;

    ss = ssl_FindSocket(fd);
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: bad socket in ForceHandshake",
                 SSL_GETPID(), fd));
        return rv;
    }

    /* Don't waste my time */
    if (!ss->opt.useSecurity)
        return SECSuccess;

    if (!ssl_SocketIsBlocking(ss)) {
        ssl_GetXmitBufLock(ss);
        if (ss->pendingBuf.len != 0) {
            int sent = ssl_SendSavedWriteData(ss);
            if ((sent < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) {
                ssl_ReleaseXmitBufLock(ss);
                return SECFailure;
            }
        }
        ssl_ReleaseXmitBufLock(ss);
    }

    ssl_Get1stHandshakeLock(ss);

    if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
        int gatherResult;

        ssl_GetRecvBufLock(ss);
        gatherResult = ssl3_GatherCompleteHandshake(ss, 0);
        ssl_ReleaseRecvBufLock(ss);
        if (gatherResult > 0) {
            rv = SECSuccess;
        } else {
            if (gatherResult == 0) {
                PORT_SetError(PR_END_OF_FILE_ERROR);
            }
            /* We can rely on ssl3_GatherCompleteHandshake to set
             * PR_WOULD_BLOCK_ERROR as needed here. */
            rv = SECFailure;
        }
    } else {
        PORT_Assert(!ss->firstHsDone);
        rv = ssl_Do1stHandshake(ss);
    }

    ssl_Release1stHandshakeLock(ss);

    return rv;
}

/*
 ** Same as above, but with an I/O timeout.
 */
SSL_IMPORT SECStatus
SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
                              PRIntervalTime timeout)
{
    if (SECSuccess != ssl_SetTimeout(fd, timeout)) {
        return SECFailure;
    }
    return SSL_ForceHandshake(fd);
}

/************************************************************************/

/*
** Save away write data that is trying to be written before the security
** handshake has been completed. When the handshake is completed, we will
** flush this data out.
** Caller must hold xmitBufLock
*/
SECStatus
ssl_SaveWriteData(sslSocket *ss, const void *data, unsigned int len)
{
    SECStatus rv;

    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
    rv = sslBuffer_Append(&ss->pendingBuf, data, len);
    SSL_TRC(5, ("%d: SSL[%d]: saving %u bytes of data (%u total saved so far)",
                SSL_GETPID(), ss->fd, len, ss->pendingBuf.len));
    return rv;
}

/*
** Send saved write data. This will flush out data sent prior to a
** complete security handshake. Hopefully there won't be too much of it.
** Returns count of the bytes sent, NOT a SECStatus.
** Caller must hold xmitBufLock
*/
int
ssl_SendSavedWriteData(sslSocket *ss)
{
    int rv = 0;

    PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
    if (ss->pendingBuf.len != 0) {
        SSL_TRC(5, ("%d: SSL[%d]: sending %d bytes of saved data",
                    SSL_GETPID(), ss->fd, ss->pendingBuf.len));
        rv = ssl_DefSend(ss, ss->pendingBuf.buf, ss->pendingBuf.len, 0);
        if (rv < 0) {
            return rv;
        }
        ss->pendingBuf.len -= rv;
        if (ss->pendingBuf.len > 0 && rv > 0) {
            /* UGH !! This shifts the whole buffer down by copying it */
            PORT_Memmove(ss->pendingBuf.buf, ss->pendingBuf.buf + rv,
                         ss->pendingBuf.len);
        }
    }
    return rv;
}

/************************************************************************/

/*
** Receive some application data on a socket.  Reads SSL records from the input
** stream, decrypts them and then copies them to the output buffer.
** Called from ssl_SecureRecv() below.
**
** Caller does NOT hold 1stHandshakeLock because that handshake is over.
** Caller doesn't call this until initial handshake is complete.
** The call to ssl3_GatherAppDataRecord may encounter handshake
** messages from a subsequent handshake.
**
** This code is similar to, and easily confused with,
**   ssl_GatherRecord1stHandshake() in sslcon.c
*/
static int
DoRecv(sslSocket *ss, unsigned char *out, int len, int flags)
{
    int rv;
    int amount;
    int available;

    /* ssl3_GatherAppDataRecord may call ssl_FinishHandshake, which needs the
     * 1stHandshakeLock. */
    ssl_Get1stHandshakeLock(ss);
    ssl_GetRecvBufLock(ss);

    available = ss->gs.writeOffset - ss->gs.readOffset;
    if (available == 0) {
        /* Wait for application data to arrive.  */
        rv = ssl3_GatherAppDataRecord(ss, 0);
        if (rv <= 0) {
            if (rv == 0) {
                /* EOF */
                SSL_TRC(10, ("%d: SSL[%d]: ssl_recv EOF",
                             SSL_GETPID(), ss->fd));
                goto done;
            }
            if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {
                /* Some random error */
                goto done;
            }

            /*
            ** Gather record is blocked waiting for more record data to
            ** arrive. Try to process what we have already received
            */
        } else {
            /* Gather record has finished getting a complete record */
        }

        /* See if any clear data is now available */
        available = ss->gs.writeOffset - ss->gs.readOffset;
        if (available == 0) {
            /*
            ** No partial data is available. Force error code to
            ** EWOULDBLOCK so that caller will try again later. Note
            ** that the error code is probably EWOULDBLOCK already,
            ** but if it isn't (for example, if we received a zero
            ** length record) then this will force it to be correct.
            */
            PORT_SetError(PR_WOULD_BLOCK_ERROR);
            rv = SECFailure;
            goto done;
        }
        SSL_TRC(30, ("%d: SSL[%d]: partial data ready, available=%d",
                     SSL_GETPID(), ss->fd, available));
    }

    if (IS_DTLS(ss) && (len < available)) {
        /* DTLS does not allow you to do partial reads */
        SSL_TRC(30, ("%d: SSL[%d]: DTLS short read. len=%d available=%d",
                     SSL_GETPID(), ss->fd, len, available));
        ss->gs.readOffset += available;
        PORT_SetError(SSL_ERROR_RX_SHORT_DTLS_READ);
        rv = SECFailure;
        goto done;
    }

    /* Dole out clear data to reader */
    amount = PR_MIN(len, available);
    PORT_Memcpy(out, ss->gs.buf.buf + ss->gs.readOffset, amount);
    if (!(flags & PR_MSG_PEEK)) {
        ss->gs.readOffset += amount;
    }
    PORT_Assert(ss->gs.readOffset <= ss->gs.writeOffset);
    rv = amount;

    SSL_TRC(30, ("%d: SSL[%d]: amount=%d available=%d",
                 SSL_GETPID(), ss->fd, amount, available));
    PRINT_BUF(4, (ss, "DoRecv receiving plaintext:", out, amount));

done:
    ssl_ReleaseRecvBufLock(ss);
    ssl_Release1stHandshakeLock(ss);
    return rv;
}

/************************************************************************/

SECStatus
ssl_CreateSecurityInfo(sslSocket *ss)
{
    SECStatus status;

    ssl_GetXmitBufLock(ss);
    status = sslBuffer_Grow(&ss->sec.writeBuf, 4096);
    ssl_ReleaseXmitBufLock(ss);

    return status;
}

SECStatus
ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os)
{
    ss->sec.isServer = os->sec.isServer;

    ss->sec.peerCert = CERT_DupCertificate(os->sec.peerCert);
    if (os->sec.peerCert && !ss->sec.peerCert)
        goto loser;

    return SECSuccess;

loser:
    return SECFailure;
}

/* Reset sec back to its initial state.
** Caller holds any relevant locks.
*/
void
ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset)
{
    if (sec->localCert) {
        CERT_DestroyCertificate(sec->localCert);
        sec->localCert = NULL;
    }
    if (sec->peerCert) {
        CERT_DestroyCertificate(sec->peerCert);
        sec->peerCert = NULL;
    }
    if (sec->peerKey) {
        SECKEY_DestroyPublicKey(sec->peerKey);
        sec->peerKey = NULL;
    }

    /* cleanup the ci */
    if (sec->ci.sid != NULL) {
        ssl_FreeSID(sec->ci.sid);
    }
    PORT_ZFree(sec->ci.sendBuf.buf, sec->ci.sendBuf.space);
    if (doMemset) {
        memset(&sec->ci, 0, sizeof sec->ci);
    }
}

/*
** Called from SSL_ResetHandshake (above), and
**        from ssl_FreeSocket     in sslsock.c
** Caller should hold relevant locks (e.g. XmitBufLock)
*/
void
ssl_DestroySecurityInfo(sslSecurityInfo *sec)
{
    ssl_ResetSecurityInfo(sec, PR_FALSE);

    PORT_ZFree(sec->writeBuf.buf, sec->writeBuf.space);
    sec->writeBuf.buf = 0;

    memset(sec, 0, sizeof *sec);
}

/************************************************************************/

int
ssl_SecureConnect(sslSocket *ss, const PRNetAddr *sa)
{
    PRFileDesc *osfd = ss->fd->lower;
    int rv;

    if (ss->opt.handshakeAsServer) {
        ss->handshake = ssl_BeginServerHandshake;
        ss->handshaking = sslHandshakingAsServer;
    } else {
        ss->handshake = ssl_BeginClientHandshake;
        ss->handshaking = sslHandshakingAsClient;
    }

    /* connect to server */
    rv = osfd->methods->connect(osfd, sa, ss->cTimeout);
    if (rv == PR_SUCCESS) {
        ss->TCPconnected = 1;
    } else {
        int err = PR_GetError();
        SSL_DBG(("%d: SSL[%d]: connect failed, errno=%d",
                 SSL_GETPID(), ss->fd, err));
        if (err == PR_IS_CONNECTED_ERROR) {
            ss->TCPconnected = 1;
        }
    }

    SSL_TRC(5, ("%d: SSL[%d]: secure connect completed, rv == %d",
                SSL_GETPID(), ss->fd, rv));
    return rv;
}

/*
 * Also, in the unlikely event that the TCP pipe is full and the peer stops
 * reading, the SSL3_SendAlert call in ssl_SecureClose and ssl_SecureShutdown
 * may block indefinitely in blocking mode, and may fail (without retrying)
 * in non-blocking mode.
 */

int
ssl_SecureClose(sslSocket *ss)
{
    int rv;

    if (!(ss->shutdownHow & ssl_SHUTDOWN_SEND) &&
        ss->firstHsDone) {

        /* We don't want the final alert to be Nagle delayed. */
        if (!ss->delayDisabled) {
            ssl_EnableNagleDelay(ss, PR_FALSE);
            ss->delayDisabled = 1;
        }

        (void)SSL3_SendAlert(ss, alert_warning, close_notify);
    }
    rv = ssl_DefClose(ss);
    return rv;
}

/* Caller handles all locking */
int
ssl_SecureShutdown(sslSocket *ss, int nsprHow)
{
    PRFileDesc *osfd = ss->fd->lower;
    int rv;
    PRIntn sslHow = nsprHow + 1;

    if ((unsigned)nsprHow > PR_SHUTDOWN_BOTH) {
        PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
        return PR_FAILURE;
    }

    if ((sslHow & ssl_SHUTDOWN_SEND) != 0 &&
        !(ss->shutdownHow & ssl_SHUTDOWN_SEND) &&
        ss->firstHsDone) {

        (void)SSL3_SendAlert(ss, alert_warning, close_notify);
    }

    rv = osfd->methods->shutdown(osfd, nsprHow);

    ss->shutdownHow |= sslHow;

    return rv;
}

/************************************************************************/

static SECStatus
tls13_CheckKeyUpdate(sslSocket *ss, SSLSecretDirection dir)
{
    PRBool keyUpdate;
    ssl3CipherSpec *spec;
    sslSequenceNumber seqNum;
    sslSequenceNumber margin;
    tls13KeyUpdateRequest keyUpdateRequest;
    SECStatus rv = SECSuccess;

    /* Bug 1413368: enable for DTLS */
    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 || IS_DTLS(ss)) {
        return SECSuccess;
    }

    /* If both sides update at the same number, then this will cause two updates
     * to happen at once. The problem is that the KeyUpdate itself consumes a
     * sequence number, and that will trigger the reading side to request an
     * update.
     *
     * If we have the writing side update first, the writer will be the one that
     * drives the update.  An update by the writer doesn't need a response, so
     * it is more efficient overall.  The margins here are pretty arbitrary, but
     * having the write margin larger reduces the number of times that a
     * KeyUpdate is sent by a reader. */
    ssl_GetSpecReadLock(ss);
    if (dir == ssl_secret_read) {
        spec = ss->ssl3.crSpec;
        margin = spec->cipherDef->max_records / 8;
    } else {
        spec = ss->ssl3.cwSpec;
        margin = spec->cipherDef->max_records / 4;
    }
    seqNum = spec->nextSeqNum;
    keyUpdate = seqNum > spec->cipherDef->max_records - margin;
    ssl_ReleaseSpecReadLock(ss);
    if (!keyUpdate) {
        return SECSuccess;
    }

    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);
    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;
}

int
ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
{
    int rv = 0;

    if (ss->shutdownHow & ssl_SHUTDOWN_RCV) {
        PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
        return PR_FAILURE;
    }
    if (flags & ~PR_MSG_PEEK) {
        PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
        return PR_FAILURE;
    }

    if (!ssl_SocketIsBlocking(ss) && !ss->opt.fdx) {
        ssl_GetXmitBufLock(ss);
        if (ss->pendingBuf.len != 0) {
            rv = ssl_SendSavedWriteData(ss);
            if ((rv < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) {
                ssl_ReleaseXmitBufLock(ss);
                return SECFailure;
            }
        }
        ssl_ReleaseXmitBufLock(ss);
    }

    rv = 0;
    if (!PR_CLIST_IS_EMPTY(&ss->ssl3.hs.bufferedEarlyData)) {
        PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
        return tls13_Read0RttData(ss, buf, len);
    }

    /* If any of these is non-zero, the initial handshake is not done. */
    if (!ss->firstHsDone) {
        ssl_Get1stHandshakeLock(ss);
        if (ss->handshake) {
            rv = ssl_Do1stHandshake(ss);
        }
        ssl_Release1stHandshakeLock(ss);
    } else {
        if (tls13_CheckKeyUpdate(ss, ssl_secret_read) != SECSuccess) {
            rv = PR_FAILURE;
        }
    }
    if (rv < 0) {
        if (PORT_GetError() == PR_WOULD_BLOCK_ERROR &&
            !PR_CLIST_IS_EMPTY(&ss->ssl3.hs.bufferedEarlyData)) {
            PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
            return tls13_Read0RttData(ss, buf, len);
        }
        return rv;
    }

    if (len == 0)
        return 0;

    rv = DoRecv(ss, (unsigned char *)buf, len, flags);
    SSL_TRC(2, ("%d: SSL[%d]: recving %d bytes securely (errno=%d)",
                SSL_GETPID(), ss->fd, rv, PORT_GetError()));
    return rv;
}

int
ssl_SecureRead(sslSocket *ss, unsigned char *buf, int len)
{
    return ssl_SecureRecv(ss, buf, len, 0);
}

/* Caller holds the SSL Socket's write lock. SSL_LOCK_WRITER(ss) */
int
ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
{
    int rv = 0;
    PRBool zeroRtt = PR_FALSE;

    SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes",
                SSL_GETPID(), ss->fd, len));

    if (ss->shutdownHow & ssl_SHUTDOWN_SEND) {
        PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
        rv = PR_FAILURE;
        goto done;
    }
    if (flags) {
        PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
        rv = PR_FAILURE;
        goto done;
    }

    ssl_GetXmitBufLock(ss);
    if (ss->pendingBuf.len != 0) {
        PORT_Assert(ss->pendingBuf.len > 0);
        rv = ssl_SendSavedWriteData(ss);
        if (rv >= 0 && ss->pendingBuf.len != 0) {
            PORT_Assert(ss->pendingBuf.len > 0);
            PORT_SetError(PR_WOULD_BLOCK_ERROR);
            rv = SECFailure;
        }
    }
    ssl_ReleaseXmitBufLock(ss);
    if (rv < 0) {
        goto done;
    }

    if (len > 0)
        ss->writerThread = PR_GetCurrentThread();

    /* Check to see if we can write even though we're not finished.
     *
     * Case 1: False start
     * Case 2: TLS 1.3 0-RTT
     */
    if (!ss->firstHsDone) {
        PRBool allowEarlySend = PR_FALSE;
        PRBool firstClientWrite = PR_FALSE;

        ssl_Get1stHandshakeLock(ss);
        /* The client can sometimes send before the handshake is fully
         * complete. In TLS 1.2: false start; in TLS 1.3: 0-RTT. */
        if (!ss->sec.isServer &&
            (ss->opt.enableFalseStart || ss->opt.enable0RttData)) {
            ssl_GetSSL3HandshakeLock(ss);
            zeroRtt = ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
                      ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted;
            allowEarlySend = ss->ssl3.hs.canFalseStart || zeroRtt;
            firstClientWrite = ss->ssl3.hs.ws == idle_handshake;
            ssl_ReleaseSSL3HandshakeLock(ss);
        }
        /* Allow the server to send 0.5 RTT data in TLS 1.3. Requesting a
         * certificate implies that the server might condition its sending on
         * client authentication, so force servers that do that to wait.
         *
         * What might not be obvious here is that this allows 0.5 RTT when doing
         * PSK-based resumption.  As a result, 0.5 RTT is always enabled when
         * early data is accepted.
         *
         * This check might be more conservative than absolutely necessary.
         * It's possible that allowing 0.5 RTT data when the server requests,
         * but does not require client authentication is safe because we can
         * expect the server to check for a client certificate properly. */
        if (ss->sec.isServer &&
            ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
            !tls13_ShouldRequestClientAuth(ss)) {
            ssl_GetSSL3HandshakeLock(ss);
            allowEarlySend = TLS13_IN_HS_STATE(ss, wait_finished);
            ssl_ReleaseSSL3HandshakeLock(ss);
        }
        if (!allowEarlySend && ss->handshake) {
            rv = ssl_Do1stHandshake(ss);
        }
        if (firstClientWrite) {
            /* Wait until after sending ClientHello and double-check 0-RTT. */
            ssl_GetSSL3HandshakeLock(ss);
            zeroRtt = ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
                      ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted;
            ssl_ReleaseSSL3HandshakeLock(ss);
        }
        ssl_Release1stHandshakeLock(ss);
    }

    if (rv < 0) {
        ss->writerThread = NULL;
        goto done;
    }

    if (ss->firstHsDone) {
        if (tls13_CheckKeyUpdate(ss, ssl_secret_write) != SECSuccess) {
            rv = PR_FAILURE;
            goto done;
        }
    }

    if (zeroRtt) {
        /* There's a limit to the number of early data octets we can send.
         *
         * Note that taking this lock doesn't prevent the cipher specs from
         * being changed out between here and when records are ultimately
         * encrypted.  The only effect of that is to occasionally do an
         * unnecessary short write when data is identified as 0-RTT here but
         * 1-RTT later.
         */
        ssl_GetSpecReadLock(ss);
        len = tls13_LimitEarlyData(ss, ssl_ct_application_data, len);
        ssl_ReleaseSpecReadLock(ss);
    }

    /* Check for zero length writes after we do housekeeping so we make forward
     * progress.
     */
    if (len == 0) {
        rv = 0;
        goto done;
    }
    PORT_Assert(buf != NULL);
    if (!buf) {
        PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
        rv = PR_FAILURE;
        goto done;
    }

    ssl_GetXmitBufLock(ss);
    rv = ssl3_SendApplicationData(ss, buf, len, flags);
    ssl_ReleaseXmitBufLock(ss);
    ss->writerThread = NULL;
done:
    if (rv < 0) {
        SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count, error %d",
                    SSL_GETPID(), ss->fd, rv, PORT_GetError()));
    } else {
        SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count",
                    SSL_GETPID(), ss->fd, rv));
    }
    return rv;
}

int
ssl_SecureWrite(sslSocket *ss, const unsigned char *buf, int len)
{
    return ssl_SecureSend(ss, buf, len, 0);
}

SECStatus
SSLExp_RecordLayerWriteCallback(PRFileDesc *fd, SSLRecordWriteCallback cb,
                                void *arg)
{
    sslSocket *ss = ssl_FindSocket(fd);
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: invalid socket for SSL_RecordLayerWriteCallback",
                 SSL_GETPID(), fd));
        return SECFailure;
    }
    if (IS_DTLS(ss)) {
        SSL_DBG(("%d: SSL[%d]: DTLS socket for SSL_RecordLayerWriteCallback",
                 SSL_GETPID(), fd));
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* This needs both HS and Xmit locks because this value is checked under
     * both locks. HS to disable reading from the underlying IO layer; Xmit to
     * prevent writing. */
    ssl_GetSSL3HandshakeLock(ss);
    ssl_GetXmitBufLock(ss);
    ss->recordWriteCallback = cb;
    ss->recordWriteCallbackArg = arg;
    ssl_ReleaseXmitBufLock(ss);
    ssl_ReleaseSSL3HandshakeLock(ss);
    return SECSuccess;
}

SECStatus
SSL_AlertReceivedCallback(PRFileDesc *fd, SSLAlertCallback cb, void *arg)
{
    sslSocket *ss;

    ss = ssl_FindSocket(fd);
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: unable to find socket in SSL_AlertReceivedCallback",
                 SSL_GETPID(), fd));
        return SECFailure;
    }

    ss->alertReceivedCallback = cb;
    ss->alertReceivedCallbackArg = arg;

    return SECSuccess;
}

SECStatus
SSL_AlertSentCallback(PRFileDesc *fd, SSLAlertCallback cb, void *arg)
{
    sslSocket *ss;

    ss = ssl_FindSocket(fd);
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: unable to find socket in SSL_AlertSentCallback",
                 SSL_GETPID(), fd));
        return SECFailure;
    }

    ss->alertSentCallback = cb;
    ss->alertSentCallbackArg = arg;

    return SECSuccess;
}

SECStatus
SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg)
{
    sslSocket *ss;

    ss = ssl_FindSocket(fd);
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: bad socket in SSLBadCertHook",
                 SSL_GETPID(), fd));
        return SECFailure;
    }

    ss->handleBadCert = f;
    ss->badCertArg = arg;

    return SECSuccess;
}

/*
 * Allow the application to pass the url or hostname into the SSL library
 * so that we can do some checking on it. It will be used for the value in
 * SNI extension of client hello message.
 */
SECStatus
SSL_SetURL(PRFileDesc *fd, const char *url)
{
    sslSocket *ss = ssl_FindSocket(fd);
    SECStatus rv = SECSuccess;

    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: bad socket in SSLSetURL",
                 SSL_GETPID(), fd));
        return SECFailure;
    }
    ssl_Get1stHandshakeLock(ss);
    ssl_GetSSL3HandshakeLock(ss);

    if (ss->url) {
        PORT_Free((void *)ss->url); /* CONST */
    }

    ss->url = (const char *)PORT_Strdup(url);
    if (ss->url == NULL) {
        rv = SECFailure;
    }

    ssl_ReleaseSSL3HandshakeLock(ss);
    ssl_Release1stHandshakeLock(ss);

    return rv;
}

/*
 * Allow the application to pass the set of trust anchors
 */
SECStatus
SSL_SetTrustAnchors(PRFileDesc *fd, CERTCertList *certList)
{
    sslSocket *ss = ssl_FindSocket(fd);
    CERTDistNames *names = NULL;

    if (!certList) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetTrustAnchors",
                 SSL_GETPID(), fd));
        return SECFailure;
    }

    names = CERT_DistNamesFromCertList(certList);
    if (names == NULL) {
        return SECFailure;
    }
    ssl_Get1stHandshakeLock(ss);
    ssl_GetSSL3HandshakeLock(ss);
    if (ss->ssl3.ca_list) {
        CERT_FreeDistNames(ss->ssl3.ca_list);
    }
    ss->ssl3.ca_list = names;
    ssl_ReleaseSSL3HandshakeLock(ss);
    ssl_Release1stHandshakeLock(ss);

    return SECSuccess;
}

/*
** Returns Negative number on error, zero or greater on success.
** Returns the amount of data immediately available to be read.
*/
int
SSL_DataPending(PRFileDesc *fd)
{
    sslSocket *ss;
    int rv = 0;

    ss = ssl_FindSocket(fd);

    if (ss && ss->opt.useSecurity) {
        ssl_GetRecvBufLock(ss);
        rv = ss->gs.writeOffset - ss->gs.readOffset;
        ssl_ReleaseRecvBufLock(ss);
    }

    return rv;
}

SECStatus
SSL_InvalidateSession(PRFileDesc *fd)
{
    sslSocket *ss = ssl_FindSocket(fd);
    SECStatus rv = SECFailure;

    if (ss) {
        ssl_Get1stHandshakeLock(ss);
        ssl_GetSSL3HandshakeLock(ss);

        if (ss->sec.ci.sid) {
            ssl_UncacheSessionID(ss);
            rv = SECSuccess;
        }

        ssl_ReleaseSSL3HandshakeLock(ss);
        ssl_Release1stHandshakeLock(ss);
    }
    return rv;
}

SECItem *
SSL_GetSessionID(PRFileDesc *fd)
{
    sslSocket *ss;
    SECItem *item = NULL;

    ss = ssl_FindSocket(fd);
    if (ss) {
        ssl_Get1stHandshakeLock(ss);
        ssl_GetSSL3HandshakeLock(ss);

        if (ss->opt.useSecurity && ss->firstHsDone && ss->sec.ci.sid) {
            item = (SECItem *)PORT_Alloc(sizeof(SECItem));
            if (item) {
                sslSessionID *sid = ss->sec.ci.sid;
                item->len = sid->u.ssl3.sessionIDLength;
                item->data = (unsigned char *)PORT_Alloc(item->len);
                PORT_Memcpy(item->data, sid->u.ssl3.sessionID, item->len);
            }
        }

        ssl_ReleaseSSL3HandshakeLock(ss);
        ssl_Release1stHandshakeLock(ss);
    }
    return item;
}

SECStatus
SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle)
{
    sslSocket *ss;

    ss = ssl_FindSocket(fd);
    if (!ss)
        return SECFailure;
    if (!dbHandle) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    ss->dbHandle = dbHandle;
    return SECSuccess;
}

/* DO NOT USE. This function was exported in ssl.def with the wrong signature;
 * this implementation exists to maintain link-time compatibility.
 */
int
SSL_RestartHandshakeAfterCertReq(sslSocket *ss,
                                 CERTCertificate *cert,
                                 SECKEYPrivateKey *key,
                                 CERTCertificateList *certChain)
{
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return -1;
}

/* DO NOT USE. This function was exported in ssl.def with the wrong signature;
 * this implementation exists to maintain link-time compatibility.
 */
int
SSL_RestartHandshakeAfterServerCert(sslSocket *ss)
{
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return -1;
}

/* See documentation in ssl.h */
SECStatus
SSL_AuthCertificateComplete(PRFileDesc *fd, PRErrorCode error)
{
    SECStatus rv;
    sslSocket *ss = ssl_FindSocket(fd);

    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: bad socket in SSL_AuthCertificateComplete",
                 SSL_GETPID(), fd));
        return SECFailure;
    }

    ssl_Get1stHandshakeLock(ss);
    rv = ssl3_AuthCertificateComplete(ss, error);
    ssl_Release1stHandshakeLock(ss);

    return rv;
}

/* For more info see ssl.h */
SECStatus
SSL_SNISocketConfigHook(PRFileDesc *fd, SSLSNISocketConfig func,
                        void *arg)
{
    sslSocket *ss;

    ss = ssl_FindSocket(fd);
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: bad socket in SNISocketConfigHook",
                 SSL_GETPID(), fd));
        return SECFailure;
    }

    ss->sniSocketConfig = func;
    ss->sniSocketConfigArg = arg;
    return SECSuccess;
}
