if (ssl3 == NULL) {
if (!ss->ssl3.initialized) {
ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf){const ssl3BulkCipherDef *cipher_def;    ssl3State *          ssl3 			= ss->ssl3;    ssl3CipherSpec *     crSpec;    SECStatus            rv;    unsigned int         hashBytes		= MAX_MAC_LENGTH + 1;    unsigned int         padding_length;    PRBool               isTLS;    PRBool               padIsBad               = PR_FALSE;    SSL3ContentType      rType;    SSL3Opaque           hash[MAX_MAC_LENGTH];    PORT_Assert( ssl_HaveRecvBufLock(ss) );    if (ssl3 == NULL) {	ssl_GetSSL3HandshakeLock(ss);	rv = ssl3_InitState(ss);	ssl_ReleaseSSL3HandshakeLock(ss);	if (rv != SECSuccess) {	    return rv;		/* ssl3_InitState has set the error code. */    	}    }    ssl3 = ss->ssl3;    /* check for Token Presence */    if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) {	PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);	return SECFailure;    }    /* cText is NULL when we're called from ssl3_RestartHandshakeAfterXXX().     * This implies that databuf holds a previously deciphered SSL Handshake     * message.     */    if (cText == NULL) {	SSL_DBG(("%d: SSL3[%d]: HandleRecord, resuming handshake",		 SSL_GETPID(), ss->fd));	rType = content_handshake;	goto process_it;    }    databuf->len = 0; /* filled in by decode call below. */    if (databuf->space < MAX_FRAGMENT_LENGTH) {	rv = sslBuffer_Grow(databuf, MAX_FRAGMENT_LENGTH + 2048);	if (rv != SECSuccess) {	    SSL_DBG(("%d: SSL3[%d]: HandleRecord, tried to get %d bytes",		     SSL_GETPID(), ss->fd, MAX_FRAGMENT_LENGTH + 2048));	    /* sslBuffer_Grow has set a memory error code. */	    /* Perhaps we should send an alert. (but we have no memory!) */	    return SECFailure;	}    }    PRINT_BUF(80, (ss, "ciphertext:", cText->buf->buf, cText->buf->len));    ssl_GetSpecReadLock(ss); /******************************************/    crSpec = ssl3->crSpec;    cipher_def = crSpec->cipher_def;    isTLS = (PRBool)(crSpec->version > SSL_LIBRARY_VERSION_3_0);    if (isTLS && cText->buf->len > (MAX_FRAGMENT_LENGTH + 2048)) {	ssl_ReleaseSpecReadLock(ss);	SSL3_SendAlert(ss, alert_fatal, record_overflow);	PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);	return SECFailure;    }    /* decrypt from cText buf to databuf. */    rv = crSpec->decode(	crSpec->decodeContext, databuf->buf, (int *)&databuf->len,	databuf->space, cText->buf->buf, cText->buf->len);    PRINT_BUF(80, (ss, "cleartext:", databuf->buf, databuf->len));    if (rv != SECSuccess) {	int err = ssl_MapLowLevelError(SSL_ERROR_DECRYPTION_FAILURE);	ssl_ReleaseSpecReadLock(ss);	SSL3_SendAlert(ss, alert_fatal,	               isTLS ? decryption_failed : bad_record_mac);	PORT_SetError(err);	return SECFailure;    }    /* If it's a block cipher, check and strip the padding. */    if (cipher_def->type == type_block) {	padding_length = *(databuf->buf + databuf->len - 1);	/* TLS permits padding to exceed the block size, up to 255 bytes. */	if (padding_length + 1 + crSpec->mac_size > databuf->len)	    padIsBad = PR_TRUE;	/* if TLS, check value of first padding byte. */	else if (padding_length && isTLS && 	         padding_length != 	                 *(databuf->buf + databuf->len - (padding_length + 1)))	    padIsBad = PR_TRUE;	else	    databuf->len -= padding_length + 1;    }    /* Remove the MAC. */    if (databuf->len >= crSpec->mac_size)	databuf->len -= crSpec->mac_size;    else    	padIsBad = PR_TRUE;	/* really macIsBad */    /* compute the MAC */    rType = cText->type;    rv = ssl3_ComputeRecordMAC(	crSpec, (ss->sec.isServer) ? crSpec->client.write_mac_context				    : crSpec->server.write_mac_context,	rType, cText->version, crSpec->read_seq_num, 	databuf->buf, databuf->len, hash, &hashBytes);    if (rv != SECSuccess) {	int err = ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);	ssl_ReleaseSpecReadLock(ss);	SSL3_SendAlert(ss, alert_fatal, bad_record_mac);	PORT_SetError(err);	return rv;    }    /* Check the MAC */    if (hashBytes != (unsigned)crSpec->mac_size || padIsBad || 	PORT_Memcmp(databuf->buf + databuf->len, hash, crSpec->mac_size) != 0) {	/* must not hold spec lock when calling SSL3_SendAlert. */	ssl_ReleaseSpecReadLock(ss);	SSL3_SendAlert(ss, alert_fatal, bad_record_mac);	/* always log mac error, in case attacker can read server logs. */	PORT_SetError(SSL_ERROR_BAD_MAC_READ);	SSL_DBG(("%d: SSL3[%d]: mac check failed", SSL_GETPID(), ss->fd));	return SECFailure;    }    ssl3_BumpSequenceNumber(&crSpec->read_seq_num);    ssl_ReleaseSpecReadLock(ss); /*****************************************/    /*     * The decrypted data is now in databuf.     *     * the null decompression routine is right here     */    /*    ** Having completed the decompression, check the length again.     */    if (isTLS && databuf->len > (MAX_FRAGMENT_LENGTH + 1024)) {	SSL3_SendAlert(ss, alert_fatal, record_overflow);	PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);	return SECFailure;    }    /* Application data records are processed by the caller of this    ** function, not by this function.    */    if (rType == content_application_data) {    	return SECSuccess;    }    /* It's a record that must be handled by ssl itself, not the application.    */process_it:    /* XXX  Get the xmit lock here.  Odds are very high that we'll be xmiting     * data ang getting the xmit lock here prevents deadlocks.     */    ssl_GetSSL3HandshakeLock(ss);    /* All the functions called in this switch MUST set error code if    ** they return SECFailure or SECWouldBlock.    */    switch (rType) {    case content_change_cipher_spec:	rv = ssl3_HandleChangeCipherSpecs(ss, databuf);	break;    case content_alert:	rv = ssl3_HandleAlert(ss, databuf);	break;    case content_handshake:	rv = ssl3_HandleHandshake(ss, databuf);	break;    case content_application_data:	rv = SECSuccess;	break;    default:	SSL_DBG(("%d: SSL3[%d]: bogus content type=%d",		 SSL_GETPID(), ss->fd, cText->type));	/* XXX Send an alert ???  */	PORT_SetError(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE);	rv = SECFailure;	break;    }    ssl_ReleaseSSL3HandshakeLock(ss);    return rv;}