コード例 #1
0
ファイル: sslcon.c プロジェクト: MichaelKohler/gecko-dev
/***********************************************************************
 * Gathers in and handles records/messages until either the handshake is
 * complete or application data is available.
 *
 * Called from ssl_Do1stHandshake() via function pointer ss->handshake.
 * Caller must hold handshake lock.
 * This function acquires and releases the RecvBufLock.
 *
 * returns SECSuccess for success.
 * returns SECWouldBlock when that value is returned by
 *  ssl3_GatherCompleteHandshake().
 * returns SECFailure on all other errors.
 *
 * The gather functions called by ssl_GatherRecord1stHandshake are expected
 *  to return values interpreted as follows:
 *  1 : the function completed without error.
 *  0 : the function read EOF.
 * -1 : read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
 * -2 : the function wants ssl_GatherRecord1stHandshake to be called again
 *  immediately, by ssl_Do1stHandshake.
 *
 * This code is similar to, and easily confused with, DoRecv() in sslsecur.c
 *
 * This function is called from ssl_Do1stHandshake().
 * The following functions put ssl_GatherRecord1stHandshake into ss->handshake:
 *  ssl_BeginClientHandshake
 *  ssl3_RestartHandshakeAfterCertReq
 *  ssl3_RestartHandshakeAfterServerCert
 *  ssl_BeginServerHandshake
 */
SECStatus
ssl_GatherRecord1stHandshake(sslSocket *ss)
{
    int rv;

    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));

    ssl_GetRecvBufLock(ss);

    /* Wait for handshake to complete, or application data to arrive.  */
    rv = ssl3_GatherCompleteHandshake(ss, 0);
    SSL_TRC(10, ("%d: SSL[%d]: handshake gathering, rv=%d",
                 SSL_GETPID(), ss->fd, rv));

    ssl_ReleaseRecvBufLock(ss);

    if (rv <= 0) {
        if (rv == SECWouldBlock) {
            /* Progress is blocked waiting for callback completion.  */
            SSL_TRC(10, ("%d: SSL[%d]: handshake blocked (need %d)",
                         SSL_GETPID(), ss->fd, ss->gs.remainder));
            return SECWouldBlock;
        }
        if (rv == 0) {
            /* EOF. Loser  */
            PORT_SetError(PR_END_OF_FILE_ERROR);
        }
        return SECFailure; /* rv is < 0 here. */
    }

    ss->handshake = NULL;
    return SECSuccess;
}
コード例 #2
0
ファイル: sslsecur.c プロジェクト: Metrological/chromium
/* 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.
** For SSLv2, returns when handshake is complete or fatal error occurs.
** For SSLv3, 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);
	} else if (gatherResult == SECWouldBlock) {
	    PORT_SetError(PR_WOULD_BLOCK_ERROR);
	}
    } else if (!ss->firstHsDone) {
	rv = ssl_Do1stHandshake(ss);
    } else {
	/* tried to force handshake on an SSL 2 socket that has 
	** already completed the handshake. */
    	rv = SECSuccess;	/* just pretend we did it. */
    }

    ssl_Release1stHandshakeLock(ss);

    return rv;
}
コード例 #3
0
ファイル: ssl3gthr.c プロジェクト: LittoCats/OT_4010D
/* Repeatedly gather in a record and when complete, Handle that record.
 * Repeat this until some application data is received.
 *
 * 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.
 */
int
ssl3_GatherAppDataRecord(sslSocket *ss, int flags)
{
    int            rv;

    PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
    do {
	rv = ssl3_GatherCompleteHandshake(ss, flags);
    } while (rv > 0 && ss->gs.buf.len == 0);

    return rv;
}