コード例 #1
0
SECStatus
tls13_ClientHandleTicketEarlyDataInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
                                         SECItem *data)
{
    PRUint32 utmp;
    SECStatus rv;

    SSL_TRC(3, ("%d: TLS13[%d]: handle early_data_info extension",
                SSL_GETPID(), ss->fd));

    /* If we are doing < TLS 1.3, then ignore this. */
    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
        PORT_SetError(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION);
        return SECFailure;
    }

    rv = ssl3_ExtConsumeHandshake(ss, &utmp, sizeof(utmp),
                                  &data->data, &data->len);
    if (rv != SECSuccess) {
        PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
        return SECFailure;
    }
    if (data->len) {
        PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
        return SECFailure;
    }

    xtnData->max_early_data_size = PR_ntohl(utmp);

    return SECSuccess;
}
コード例 #2
0
/*
 *    struct {
 *        opaque cookie<1..2^16-1>;
 *    } Cookie;
 */
SECStatus
tls13_ClientHandleHrrCookie(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data)
{
    SECStatus rv;

    SSL_TRC(3, ("%d: TLS13[%d]: handle cookie extension",
                SSL_GETPID(), ss->fd));

    PORT_Assert(ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3);

    /* IMPORTANT: this is only valid while the HelloRetryRequest is still valid. */
    rv = ssl3_ExtConsumeHandshakeVariable(
        ss, &CONST_CAST(sslSocket, ss)->ssl3.hs.cookie, 2,
        &data->data, &data->len);
    if (rv != SECSuccess) {
        PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST);
        return SECFailure;
    }
    if (!ss->ssl3.hs.cookie.len || data->len) {
        ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
        PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST);
        return SECFailure;
    }

    return SECSuccess;
}
コード例 #3
0
SECStatus
tls13_ServerHandlePskKeyExchangeModesXtn(const sslSocket *ss,
                                         TLSExtensionData *xtnData,
                                         PRUint16 ex_type, SECItem *data)
{
    SECStatus rv;

    /* If we are doing < TLS 1.3, then ignore this. */
    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
        return SECSuccess;
    }

    SSL_TRC(3, ("%d: TLS13[%d]: handle PSK key exchange modes extension",
                SSL_GETPID(), ss->fd));

    /* IMPORTANT: We aren't copying these values, just setting pointers.
     * They will only be valid as long as the ClientHello is in memory. */
    rv = ssl3_ExtConsumeHandshakeVariable(ss,
                                          &xtnData->psk_ke_modes, 1,
                                          &data->data, &data->len);
    if (rv != SECSuccess)
        return rv;
    if (!xtnData->psk_ke_modes.len || data->len) {
        PORT_SetError(SSL_ERROR_MALFORMED_PSK_KEY_EXCHANGE_MODES);
        return SECFailure;
    }

    /* Keep track of negotiated extensions. */
    xtnData->negotiated[xtnData->numNegotiated++] = ex_type;

    return SECSuccess;
}
コード例 #4
0
/* This is only registered if we are sending it. */
PRInt32
tls13_ServerSendEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData,
                             PRBool append,
                             PRUint32 maxBytes)
{
    SSL_TRC(3, ("%d: TLS13[%d]: send early_data extension",
                SSL_GETPID(), ss->fd));

    PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted);
    if (maxBytes < 4) {
        PORT_Assert(0);
        return 0;
    }

    if (append) {
        SECStatus rv;

        rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_early_data_xtn, 2);
        if (rv != SECSuccess)
            return -1;

        rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2);
        if (rv != SECSuccess)
            return -1;
    }

    return 4;
}
コード例 #5
0
/* Handle an incoming KeyShare extension at the client and copy to
 * |xtnData->remoteKeyShares| for future use. The key
 * share is processed in tls13_HandleServerKeyShare(). */
SECStatus
tls13_ClientHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data)
{
    SECStatus rv;
    PORT_Assert(PR_CLIST_IS_EMPTY(&xtnData->remoteKeyShares));

    PORT_Assert(!ss->sec.isServer);
    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
        /* This can't happen because the extension processing
         * code filters out TLS 1.3 extensions when not in
         * TLS 1.3 mode. */
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    SSL_TRC(3, ("%d: SSL3[%d]: handle key_share extension",
                SSL_GETPID(), ss->fd));

    rv = tls13_HandleKeyShareEntry(ss, xtnData, data);
    if (rv != SECSuccess) {
        PORT_SetError(SSL_ERROR_RX_MALFORMED_KEY_SHARE);
        return SECFailure;
    }

    if (data->len) {
        PORT_SetError(SSL_ERROR_RX_MALFORMED_KEY_SHARE);
        return SECFailure;
    }

    return SECSuccess;
}
コード例 #6
0
ファイル: sslsecur.c プロジェクト: Crawping/chromium_extract
int 
ssl_SecureConnect(sslSocket *ss, const PRNetAddr *sa)
{
    PRFileDesc *osfd = ss->fd->lower;
    int rv;

    if ( ss->opt.handshakeAsServer ) {
	ss->securityHandshake = ssl2_BeginServerHandshake;
	ss->handshaking = sslHandshakingAsServer;
    } else {
	ss->securityHandshake = ssl2_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;
}
コード例 #7
0
/* Returns a SECStatus: SECSuccess or SECFailure, NOT SECWouldBlock. 
 * 
 * Currently, the list of functions called through ss->handshake is:
 * 
 * In sslsocks.c:
 *  SocksGatherRecord
 *  SocksHandleReply	
 *  SocksStartGather
 *
 * In sslcon.c:
 *  ssl_GatherRecord1stHandshake
 *  ssl2_HandleClientSessionKeyMessage
 *  ssl2_HandleMessage
 *  ssl2_HandleVerifyMessage
 *  ssl2_BeginClientHandshake
 *  ssl2_BeginServerHandshake
 *  ssl2_HandleClientHelloMessage
 *  ssl2_HandleServerHelloMessage
 * 
 * The ss->handshake function returns SECWouldBlock under these conditions:
 * 1.	ssl_GatherRecord1stHandshake called ssl2_GatherData which read in 
 *	the beginning of an SSL v3 hello message and returned SECWouldBlock 
 *	to switch to SSL v3 handshake processing.
 *
 * 2.	ssl2_HandleClientHelloMessage discovered version 3.0 in the incoming
 *	v2 client hello msg, and called ssl3_HandleV2ClientHello which 
 *	returned SECWouldBlock.
 *
 * 3.   SECWouldBlock was returned by one of the callback functions, via
 *	one of these paths:
 * -	ssl2_HandleMessage() -> ssl2_HandleRequestCertificate() ->
 *	ss->getClientAuthData()
 *
 * -	ssl2_HandleServerHelloMessage() -> ss->handleBadCert()
 *
 * -	ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() -> 
 *	ssl3_HandleRecord() -> ssl3_HandleHandshake() -> 
 *	ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificate() -> 
 *	ss->handleBadCert()
 *
 * -	ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() -> 
 *	ssl3_HandleRecord() -> ssl3_HandleHandshake() -> 
 *	ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificateRequest() -> 
 *	ss->getClientAuthData()
 *
 * 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.
 */
int 
ssl_Do1stHandshake(sslSocket *ss)
{
    int rv        = SECSuccess;
    int loopCount = 0;

    do {
	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));

	if (ss->handshake == 0) {
	    /* Previous handshake finished. Switch to next one */
	    ss->handshake = ss->nextHandshake;
	    ss->nextHandshake = 0;
	}
	if (ss->handshake == 0) {
	    /* Previous handshake finished. Switch to security handshake */
	    ss->handshake = ss->securityHandshake;
	    ss->securityHandshake = 0;
	}
	if (ss->handshake == 0) {
	    ssl_GetRecvBufLock(ss);
	    ss->gs.recordLen = 0;
	    ssl_ReleaseRecvBufLock(ss);

	    SSL_TRC(3, ("%d: SSL[%d]: handshake is completed",
			SSL_GETPID(), ss->fd));
            /* call handshake callback for ssl v2 */
	    /* for v3 this is done in ssl3_HandleFinished() */
	    if ((ss->handshakeCallback != NULL) && /* has callback */
		(!ss->firstHsDone) &&              /* only first time */
		(ss->version < SSL_LIBRARY_VERSION_3_0)) {  /* not ssl3 */
		ss->firstHsDone     = PR_TRUE;
		(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
	    }
	    ss->firstHsDone         = PR_TRUE;
	    ss->gs.writeOffset = 0;
	    ss->gs.readOffset  = 0;
	    break;
	}
	rv = (*ss->handshake)(ss);
	++loopCount;
    /* This code must continue to loop on SECWouldBlock, 
     * or any positive value.	See XXX_1 comments.
     */
    } while (rv != SECFailure);  	/* was (rv >= 0); XXX_1 */

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

    if (rv == SECWouldBlock) {
	PORT_SetError(PR_WOULD_BLOCK_ERROR);
	rv = SECFailure;
    }
    return rv;
}
コード例 #8
0
PRInt32
tls13_ClientSendKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
                            PRUint32 maxBytes)
{
    PRUint32 extension_length;

    if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) {
        return 0;
    }

    /* Optimistically try to send an ECDHE key using the
     * preexisting key (in future will be keys) */
    SSL_TRC(3, ("%d: TLS13[%d]: send client key share xtn",
                SSL_GETPID(), ss->fd));

    extension_length = tls13_SizeOfClientKeyShareExtension(ss);
    if (maxBytes < extension_length) {
        PORT_Assert(0);
        return 0;
    }

    if (append) {
        SECStatus rv;
        PRCList *cursor;

        rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_key_share_xtn, 2);
        if (rv != SECSuccess)
            goto loser;

        /* The extension length */
        rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 4, 2);
        if (rv != SECSuccess)
            goto loser;

        /* The length of KeyShares */
        rv = ssl3_ExtAppendHandshakeNumber(ss, extension_length - 6, 2);
        if (rv != SECSuccess)
            goto loser;

        for (cursor = PR_NEXT_LINK(&ss->ephemeralKeyPairs);
             cursor != &ss->ephemeralKeyPairs;
             cursor = PR_NEXT_LINK(cursor)) {
            sslEphemeralKeyPair *keyPair = (sslEphemeralKeyPair *)cursor;
            rv = tls13_EncodeKeyShareEntry(ss, keyPair);
            if (rv != SECSuccess)
                goto loser;
        }

        xtnData->advertised[xtnData->numAdvertised++] =
            ssl_tls13_key_share_xtn;
    }

    return extension_length;

loser:
    return -1;
}
コード例 #9
0
ファイル: sslsecur.c プロジェクト: Metrological/chromium
/*
** 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;
}
コード例 #10
0
PRInt32
tls13_SendShortHeaderXtn(const sslSocket *ss,
                         TLSExtensionData *xtnData,
                         PRBool append, PRUint32 maxBytes)
{
    PRUint32 extension_len = 2 + 2; /* Type + length (0). */

    if (!ss->opt.enableShortHeaders) {
        return 0;
    }

    /* Presently this is incompatible with 0-RTT. We will fix if
     * it becomes more than an experiment. */
    if (ss->opt.enable0RttData) {
        return 0;
    }

    if (IS_DTLS(ss)) {
        return 0;
    }

    /* Don't send this if TLS 1.3 isn't at least possible. */
    if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) {
        /* This should only happen on the client. */
        PORT_Assert(!ss->sec.isServer);
        return 0;
    }

    SSL_TRC(3, ("%d: TLS13[%d]: send short_header extension",
                SSL_GETPID(), ss->fd));

    if (maxBytes < extension_len) {
        PORT_Assert(0);
        return 0;
    }

    if (append) {
        SECStatus rv;

        rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_short_header_xtn, 2);
        if (rv != SECSuccess)
            return -1;

        rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2);
        if (rv != SECSuccess)
            return -1;

        xtnData->advertised[xtnData->numAdvertised++] =
            ssl_tls13_short_header_xtn;
    }

    return extension_len;
}
コード例 #11
0
ファイル: sslnonce.c プロジェクト: howardroark2018/chromium
/* BEWARE: This function gets called for both client and server SIDs !!
 * If the unreferenced sid is not in the cache, Free sid and its contents.
 */
static void
ssl_DestroySID(sslSessionID *sid)
{
    int i;
    SSL_TRC(8, ("SSL: destroy sid: sid=0x%x cached=%d", sid, sid->cached));
    PORT_Assert(sid->references == 0);
    PORT_Assert(sid->cached != in_client_cache);

    if (sid->version < SSL_LIBRARY_VERSION_3_0) {
        SECITEM_ZfreeItem(&sid->u.ssl2.masterKey, PR_FALSE);
        SECITEM_ZfreeItem(&sid->u.ssl2.cipherArg, PR_FALSE);
    } else {
        if (sid->u.ssl3.locked.sessionTicket.ticket.data) {
            SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket,
                             PR_FALSE);
        }
        if (sid->u.ssl3.srvName.data) {
            SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE);
        }
        if (sid->u.ssl3.originalHandshakeHash.data) {
            SECITEM_FreeItem(&sid->u.ssl3.originalHandshakeHash, PR_FALSE);
        }
        if (sid->u.ssl3.signedCertTimestamps.data) {
            SECITEM_FreeItem(&sid->u.ssl3.signedCertTimestamps, PR_FALSE);
        }

        if (sid->u.ssl3.lock) {
            NSSRWLock_Destroy(sid->u.ssl3.lock);
        }
    }

    if (sid->peerID != NULL)
        PORT_Free((void *)sid->peerID);		/* CONST */

    if (sid->urlSvrName != NULL)
        PORT_Free((void *)sid->urlSvrName);	/* CONST */

    if ( sid->peerCert ) {
        CERT_DestroyCertificate(sid->peerCert);
    }
    for (i = 0; i < MAX_PEER_CERT_CHAIN_SIZE && sid->peerCertChain[i]; i++) {
        CERT_DestroyCertificate(sid->peerCertChain[i]);
    }
    if (sid->peerCertStatus.items) {
        SECITEM_FreeArray(&sid->peerCertStatus, PR_FALSE);
    }

    if ( sid->localCert ) {
        CERT_DestroyCertificate(sid->localCert);
    }

    PORT_ZFree(sid, sizeof(sslSessionID));
}
コード例 #12
0
ファイル: sslsecur.c プロジェクト: MichaelKohler/gecko-dev
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);
    }
    if (rv < 0) {
        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;
}
コード例 #13
0
ファイル: ssl3ext.c プロジェクト: franziskuskiefer/nss
/* Go through hello extensions in |b| and deserialize
 * them into the list in |ss->ssl3.hs.remoteExtensions|.
 * The only checking we do in this point is for duplicates.
 *
 * IMPORTANT: This list just contains pointers to the incoming
 * buffer so they can only be used during ClientHello processing.
 */
SECStatus
ssl3_ParseExtensions(sslSocket *ss, PRUint8 **b, PRUint32 *length)
{
    /* Clean out the extensions list. */
    ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions);

    while (*length) {
        SECStatus rv;
        PRUint32 extension_type;
        SECItem extension_data = { siBuffer, NULL, 0 };
        TLSExtension *extension;
        PRCList *cursor;

        /* Get the extension's type field */
        rv = ssl3_ConsumeHandshakeNumber(ss, &extension_type, 2, b, length);
        if (rv != SECSuccess) {
            return SECFailure; /* alert already sent */
        }

        /* Check whether an extension has been sent multiple times. */
        for (cursor = PR_NEXT_LINK(&ss->ssl3.hs.remoteExtensions);
             cursor != &ss->ssl3.hs.remoteExtensions;
             cursor = PR_NEXT_LINK(cursor)) {
            if (((TLSExtension *)cursor)->type == extension_type) {
                (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
                PORT_SetError(SSL_ERROR_RX_UNEXPECTED_EXTENSION);
                return SECFailure;
            }
        }

        /* Get the data for this extension, so we can pass it or skip it. */
        rv = ssl3_ConsumeHandshakeVariable(ss, &extension_data, 2, b, length);
        if (rv != SECSuccess) {
            return rv; /* alert already sent */
        }

        SSL_TRC(10, ("%d: SSL3[%d]: parsed extension %d len=%u",
                     SSL_GETPID(), ss->fd, extension_type, extension_data.len));

        extension = PORT_ZNew(TLSExtension);
        if (!extension) {
            return SECFailure;
        }

        extension->type = (PRUint16)extension_type;
        extension->data = extension_data;
        PR_APPEND_LINK(&extension->link, &ss->ssl3.hs.remoteExtensions);
    }

    return SECSuccess;
}
コード例 #14
0
/*
 *     struct {
 *          ProtocolVersion versions<2..254>;
 *     } SupportedVersions;
 */
PRInt32
tls13_ClientSendSupportedVersionsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append,
                                     PRUint32 maxBytes)
{
    PRInt32 extensions_len;
    PRUint16 version;
    SECStatus rv;

    if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) {
        return 0;
    }

    SSL_TRC(3, ("%d: TLS13[%d]: send supported_versions extension",
                SSL_GETPID(), ss->fd));

    /* Extension type, extension len fiels, vector len field,
     * length of the values. */
    extensions_len = 2 + 2 + 1 +
                     2 * (ss->vrange.max - ss->vrange.min + 1);

    if (maxBytes < (PRUint32)extensions_len) {
        PORT_Assert(0);
        return 0;
    }

    if (append) {
        rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_supported_versions_xtn, 2);
        if (rv != SECSuccess)
            return -1;

        rv = ssl3_ExtAppendHandshakeNumber(ss, extensions_len - 4, 2);
        if (rv != SECSuccess)
            return -1;

        rv = ssl3_ExtAppendHandshakeNumber(ss, extensions_len - 5, 1);
        if (rv != SECSuccess)
            return -1;

        for (version = ss->vrange.max; version >= ss->vrange.min; --version) {
            rv = ssl3_ExtAppendHandshakeNumber(
                ss, tls13_EncodeDraftVersion(version), 2);
            if (rv != SECSuccess)
                return -1;
        }

        xtnData->advertised[xtnData->numAdvertised++] =
            ssl_tls13_supported_versions_xtn;
    }

    return extensions_len;
}
コード例 #15
0
ファイル: sslspec.c プロジェクト: luke-chang/gecko-1
void
ssl_CipherSpecReleaseByEpoch(sslSocket *ss, CipherSpecDirection dir,
                             DTLSEpoch epoch)
{
    ssl3CipherSpec *spec;
    SSL_TRC(10, ("%d: SSL[%d]: releasing %s cipher spec for epoch %d",
                 SSL_GETPID(), ss->fd,
                 (dir == CipherSpecRead) ? "read" : "write", epoch));

    spec = ssl_FindCipherSpecByEpoch(ss, dir, epoch);
    if (spec) {
        ssl_CipherSpecRelease(spec);
    }
}
コード例 #16
0
int
ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
{
    sslSecurityInfo *sec;
    int              rv   = 0;

    sec = &ss->sec;

    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;
	    }
	    /* XXX short write? */
	}
	ssl_ReleaseXmitBufLock(ss);
    }
    
    rv = 0;
    /* If any of these is non-zero, the initial handshake is not done. */
    if (!ss->firstHsDone) {
	ssl_Get1stHandshakeLock(ss);
	if (ss->handshake || ss->nextHandshake || ss->securityHandshake) {
	    rv = ssl_Do1stHandshake(ss);
	}
	ssl_Release1stHandshakeLock(ss);
    }
    if (rv < 0) {
	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;
}
コード例 #17
0
SECStatus
tls13_HandleShortHeaderXtn(
    const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
    SECItem *data)
{
    SSL_TRC(3, ("%d: TLS13[%d]: handle short_header extension",
                SSL_GETPID(), ss->fd));

    /* The client might have asked for this, but we didn't negotiate TLS 1.3. */
    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
        return SECSuccess;
    }

    /* Presently this is incompatible with 0-RTT. We will fix if
     * it becomes more than an experiment. */
    if (ss->opt.enable0RttData) {
        return SECSuccess;
    }

    if (IS_DTLS(ss)) {
        PORT_SetError(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION);
        return SECFailure;
    }

    if (data->len) {
        PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
        return SECFailure;
    }

    if (!ss->opt.enableShortHeaders) {
        /* Ignore. */
        return SECSuccess;
    }

    /* Keep track of negotiated extensions. */
    xtnData->negotiated[xtnData->numNegotiated++] = ex_type;

    if (ss->sec.isServer) {
        SECStatus rv;

        rv = ssl3_RegisterExtensionSender(ss, xtnData,
                                          ssl_tls13_short_header_xtn,
                                          tls13_SendShortHeaderXtn);
        if (rv != SECSuccess) {
            return SECFailure;
        }
    }

    return SECSuccess;
}
コード例 #18
0
/* Handle an incoming KeyShare extension at the server and copy to
 * |xtnData->remoteKeyShares| for future use. The key
 * share is processed in tls13_HandleClientKeyShare(). */
SECStatus
tls13_ServerHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data)
{
    SECStatus rv;
    PRUint32 length;

    PORT_Assert(ss->sec.isServer);
    PORT_Assert(PR_CLIST_IS_EMPTY(&xtnData->remoteKeyShares));

    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
        return SECSuccess;
    }

    SSL_TRC(3, ("%d: SSL3[%d]: handle key_share extension",
                SSL_GETPID(), ss->fd));

    /* Redundant length because of TLS encoding (this vector consumes
     * the entire extension.) */
    rv = ssl3_ExtConsumeHandshakeNumber(ss, &length, 2, &data->data,
                                        &data->len);
    if (rv != SECSuccess)
        goto loser;
    if (length != data->len) {
        /* Check for consistency */
        PORT_SetError(SSL_ERROR_RX_MALFORMED_KEY_SHARE);
        goto loser;
    }

    while (data->len) {
        rv = tls13_HandleKeyShareEntry(ss, xtnData, data);
        if (rv != SECSuccess)
            goto loser;
    }

    /* Check that the client only offered one share if this is
     * after HRR. */
    if (ss->ssl3.hs.helloRetry) {
        if (PR_PREV_LINK(&xtnData->remoteKeyShares) !=
            PR_NEXT_LINK(&xtnData->remoteKeyShares)) {
            PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
            goto loser;
        }
    }

    return SECSuccess;

loser:
    tls13_DestroyKeyShares(&xtnData->remoteKeyShares);
    return SECFailure;
}
コード例 #19
0
ファイル: sslspec.c プロジェクト: luke-chang/gecko-1
ssl3CipherSpec *
ssl_CreateCipherSpec(sslSocket *ss, CipherSpecDirection direction)
{
    ssl3CipherSpec *spec = PORT_ZNew(ssl3CipherSpec);
    if (!spec) {
        return NULL;
    }
    spec->refCt = 1;
    spec->version = ss->version;
    spec->direction = direction;
    SSL_TRC(10, ("%d: SSL[%d]: new %s spec %d ct=%d",
                 SSL_GETPID(), ss->fd, SPEC_DIR(spec), spec,
                 spec->refCt));
    return spec;
}
コード例 #20
0
ファイル: sslspec.c プロジェクト: luke-chang/gecko-1
/* This function is never called on a spec which is on the
 * cipherSpecs list. */
void
ssl_CipherSpecRelease(ssl3CipherSpec *spec)
{
    if (!spec) {
        return;
    }

    PORT_Assert(spec->refCt > 0);
    --spec->refCt;
    SSL_TRC(10, ("%d: SSL[-]: decrement refct for %s spec %d. epoch=%d new ct = %d",
                 SSL_GETPID(), SPEC_DIR(spec), spec, spec->epoch, spec->refCt));
    if (!spec->refCt) {
        ssl_FreeCipherSpec(spec);
    }
}
コード例 #21
0
ファイル: sslsecur.c プロジェクト: Metrological/chromium
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) {
	(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
    }
}
コード例 #22
0
SECStatus
tls13_ClientHandleKeyShareXtnHrr(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data)
{
    SECStatus rv;
    PRUint32 tmp;
    const sslNamedGroupDef *group;

    PORT_Assert(!ss->sec.isServer);
    PORT_Assert(ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3);

    SSL_TRC(3, ("%d: SSL3[%d]: handle key_share extension in HRR",
                SSL_GETPID(), ss->fd));

    rv = ssl3_ExtConsumeHandshakeNumber(ss, &tmp, 2, &data->data, &data->len);
    if (rv != SECSuccess) {
        return SECFailure; /* error code already set */
    }
    if (data->len) {
        ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
        PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST);
        return SECFailure;
    }

    group = ssl_LookupNamedGroup((SSLNamedGroup)tmp);
    /* If the group is not enabled, or we already have a share for the
     * requested group, abort. */
    if (!ssl_NamedGroupEnabled(ss, group) ||
        ssl_HaveEphemeralKeyPair(ss, group)) {
        ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter);
        PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST);
        return SECFailure;
    }

    /* Now delete all the key shares per [draft-ietf-tls-tls13 S 4.1.2] */
    ssl_FreeEphemeralKeyPairs(CONST_CAST(sslSocket, ss));

    /* And replace with our new share. */
    rv = tls13_CreateKeyShare(CONST_CAST(sslSocket, ss), group);
    if (rv != SECSuccess) {
        ssl3_ExtSendAlert(ss, alert_fatal, internal_error);
        PORT_SetError(SEC_ERROR_KEYGEN_FAIL);
        return SECFailure;
    }

    return SECSuccess;
}
コード例 #23
0
ファイル: sslspec.c プロジェクト: luke-chang/gecko-1
static void
ssl_FreeCipherSpec(ssl3CipherSpec *spec)
{
    SSL_TRC(10, ("%d: SSL[-]: Freeing %s spec %d. epoch=%d",
                 SSL_GETPID(), SPEC_DIR(spec), spec, spec->epoch));

    PR_REMOVE_LINK(&spec->link);

    /*  PORT_Assert( ss->opt.noLocks || ssl_HaveSpecWriteLock(ss)); Don't have ss! */
    if (spec->cipherContext) {
        PK11_DestroyContext(spec->cipherContext, PR_TRUE);
    }
    PK11_FreeSymKey(spec->masterSecret);
    ssl_DestroyKeyMaterial(&spec->keyMaterial);

    PORT_ZFree(spec, sizeof(*spec));
}
コード例 #24
0
/*
 *     enum { psk_ke(0), psk_dhe_ke(1), (255) } PskKeyExchangeMode;
 *
 *     struct {
 *         PskKeyExchangeMode ke_modes<1..255>;
 *     } PskKeyExchangeModes;
 */
PRInt32
tls13_ClientSendPskKeyExchangeModesXtn(const sslSocket *ss,
                                       TLSExtensionData *xtnData,
                                       PRBool append, PRUint32 maxBytes)
{
    static const PRUint8 ke_modes[] = { tls13_psk_dh_ke };
    static const unsigned long ke_modes_len = sizeof(ke_modes);
    PRInt32 extension_len;

    if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3 ||
        ss->opt.noCache) {
        return 0;
    }

    extension_len =
        2 + 2 +           /* Type + length */
        1 + ke_modes_len; /* key exchange modes vector */

    SSL_TRC(3, ("%d: TLS13[%d]: send psk key exchange modes extension",
                SSL_GETPID(), ss->fd));

    if (maxBytes < (PRUint32)extension_len) {
        PORT_Assert(0);
        return 0;
    }

    if (append) {
        SECStatus rv = ssl3_ExtAppendHandshakeNumber(
            ss, ssl_tls13_psk_key_exchange_modes_xtn, 2);
        if (rv != SECSuccess)
            return -1;

        rv = ssl3_ExtAppendHandshakeNumber(ss, extension_len - 4, 2);
        if (rv != SECSuccess)
            return -1;

        rv = ssl3_ExtAppendHandshakeVariable(
            ss, ke_modes, ke_modes_len, 1);
        if (rv != SECSuccess)
            return -1;
    }
    return extension_len;
}
コード例 #25
0
ファイル: sslsecur.c プロジェクト: Crawping/chromium_extract
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->version < SSL_LIBRARY_VERSION_3_0 ||
                  (ss->ssl3.hs.preliminaryInfo & ssl_preinfo_all) ==
                  ssl_preinfo_all);
	(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
    }
}
コード例 #26
0
ファイル: sslsecur.c プロジェクト: Metrological/chromium
/*
** Grow a buffer to hold newLen bytes of data.
** Called for both recv buffers and xmit buffers.
** Caller must hold xmitBufLock or recvBufLock, as appropriate.
*/
SECStatus
sslBuffer_Grow(sslBuffer *b, unsigned int newLen)
{
    newLen = PR_MAX(newLen, MAX_FRAGMENT_LENGTH + 2048);
    if (newLen > b->space) {
	unsigned char *newBuf;
	if (b->buf) {
	    newBuf = (unsigned char *) PORT_Realloc(b->buf, newLen);
	} else {
	    newBuf = (unsigned char *) PORT_Alloc(newLen);
	}
	if (!newBuf) {
	    return SECFailure;
	}
	SSL_TRC(10, ("%d: SSL: grow buffer from %d to %d",
		     SSL_GETPID(), b->space, newLen));
	b->buf = newBuf;
	b->space = newLen;
    }
    return SECSuccess;
}
コード例 #27
0
SECStatus
tls13_ServerHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
                               SECItem *data)
{
    SSL_TRC(3, ("%d: TLS13[%d]: handle early_data extension",
                SSL_GETPID(), ss->fd));

    /* If we are doing < TLS 1.3, then ignore this. */
    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
        return SECSuccess;
    }

    if (data->len) {
        PORT_SetError(SSL_ERROR_MALFORMED_EARLY_DATA);
        return SECFailure;
    }

    xtnData->negotiated[xtnData->numNegotiated++] = ex_type;

    return SECSuccess;
}
コード例 #28
0
ファイル: sslnonce.c プロジェクト: binoc-software/mozilla-cvs
/* 
 * If sid "zap" is in the cache,
 *    removes sid from cache, and decrements reference count.
 * Caller must hold cache lock.
 */
static void
UncacheSID(sslSessionID *zap)
{
    sslSessionID **sidp = &cache;
    sslSessionID *sid;

    if (zap->cached != in_client_cache) {
	return;
    }

    SSL_TRC(8,("SSL: Uncache: zap=0x%x cached=%d addr=0x%08x%08x%08x%08x port=0x%04x "
	       "time=%x cipher=%d",
	       zap, zap->cached, zap->addr.pr_s6_addr32[0],
	       zap->addr.pr_s6_addr32[1], zap->addr.pr_s6_addr32[2],
	       zap->addr.pr_s6_addr32[3], zap->port, zap->creationTime,
	       zap->u.ssl2.cipherType));
    if (zap->version < SSL_LIBRARY_VERSION_3_0) {
	PRINT_BUF(8, (0, "sessionID:",
		      zap->u.ssl2.sessionID, sizeof(zap->u.ssl2.sessionID)));
	PRINT_BUF(8, (0, "masterKey:",
		      zap->u.ssl2.masterKey.data, zap->u.ssl2.masterKey.len));
	PRINT_BUF(8, (0, "cipherArg:",
		      zap->u.ssl2.cipherArg.data, zap->u.ssl2.cipherArg.len));
    }

    /* See if it's in the cache, if so nuke it */
    while ((sid = *sidp) != 0) {
	if (sid == zap) {
	    /*
	    ** Bingo. Reduce reference count by one so that when
	    ** everyone is done with the sid we can free it up.
	    */
	    *sidp = zap->next;
	    zap->cached = invalid_cache;
	    ssl_FreeLockedSID(zap);
	    return;
	}
	sidp = &sid->next;
    }
}
コード例 #29
0
ファイル: sslsecur.c プロジェクト: Metrological/chromium
/*
** 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;
}
コード例 #30
0
/* BEWARE: This function gets called for both client and server SIDs !!
 * If the unreferenced sid is not in the cache, Free sid and its contents.
 */
static void
ssl_DestroySID(sslSessionID *sid)
{
    int i;
    SSL_TRC(8, ("SSL: destroy sid: sid=0x%x cached=%d", sid, sid->cached));
    PORT_Assert((sid->references == 0));

    if (sid->cached == in_client_cache)
    	return;	/* it will get taken care of next time cache is traversed. */

    if (sid->version < SSL_LIBRARY_VERSION_3_0) {
	SECITEM_ZfreeItem(&sid->u.ssl2.masterKey, PR_FALSE);
	SECITEM_ZfreeItem(&sid->u.ssl2.cipherArg, PR_FALSE);
    }
    if (sid->peerID != NULL)
	PORT_Free((void *)sid->peerID);		/* CONST */

    if (sid->urlSvrName != NULL)
	PORT_Free((void *)sid->urlSvrName);	/* CONST */

    if ( sid->peerCert ) {
	CERT_DestroyCertificate(sid->peerCert);
    }
    for (i = 0; i < MAX_PEER_CERT_CHAIN_SIZE && sid->peerCertChain[i]; i++) {
	CERT_DestroyCertificate(sid->peerCertChain[i]);
    }
    if ( sid->localCert ) {
	CERT_DestroyCertificate(sid->localCert);
    }
    if (sid->u.ssl3.sessionTicket.ticket.data) {
	SECITEM_FreeItem(&sid->u.ssl3.sessionTicket.ticket, PR_FALSE);
    }
    if (sid->u.ssl3.srvName.data) {
	SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE);
    }
    
    PORT_ZFree(sid, sizeof(sslSessionID));
}