ssl3con.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,928 行 · 第 1/5 页

C
1,928
字号
/*  ssl_ReleaseSpecReadLock(ss); */    PRINT_BUF(95, (NULL, "frag hash2: result", outbuf, *outLength));    if (rv != SECSuccess) {    	rv = SECFailure;	ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);    }    return rv;}/* Process the plain text before sending it. * Returns the number of bytes of plaintext that were succesfully sent * 	plus the number of bytes of plaintext that were copied into the *	output (write) buffer. * Returns SECFailure on a hard IO error, memory error, or crypto error. * Does NOT return SECWouldBlock. */static PRInt32ssl3_SendRecord(   sslSocket *        ss,                   SSL3ContentType    type,		   const SSL3Opaque * buf,		   PRInt32            bytes,		   PRInt32            flags){    ssl3CipherSpec *          cwSpec;    sslBuffer      *          write 	  = &ss->sec->writeBuf;    const ssl3BulkCipherDef * cipher_def;    SECStatus                 rv;    PRUint32                  bufSize     =  0;    PRInt32                   sent        =  0;    PRInt32                   cipherBytes = -1;    PRBool                    isBlocking  = ssl_SocketIsBlocking(ss);    PRBool                    ssl3WasNull = PR_FALSE;    SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s bytes=%d",		SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),		bytes));    PRINT_BUF(3, (ss, "Send record (plain text)", buf, bytes));    PORT_Assert( ssl_HaveXmitBufLock(ss) );    if (ss->ssl3 == NULL) {	/* This can happen on a server if the very first incoming record	** looks like a defective ssl3 record (e.g. too long), and we're	** trying to send an alert.	*/	ssl3WasNull = PR_TRUE;	PR_ASSERT(type == content_alert);	rv = ssl3_InitState(ss);	if (rv != SECSuccess) {	    return SECFailure;	/* ssl3_InitState has set the error code. */    	}    }    while (bytes > 0) {    	PRInt32   count;	PRUint32  contentLen;	PRUint32  fragLen;	PRUint32  macLen;	contentLen = PR_MIN(bytes, MAX_FRAGMENT_LENGTH);	if (write->space < contentLen + SSL3_BUFFER_FUDGE) {	    rv = sslBuffer_Grow(write, contentLen + SSL3_BUFFER_FUDGE);	    if (rv != SECSuccess) {		SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes",			 SSL_GETPID(), ss->fd, contentLen + SSL3_BUFFER_FUDGE));		return SECFailure; /* sslBuffer_Grow set a memory error code. */	    }	}	/* This variable records 	 * the actual size of the buffer we allocated above. Some	 * algorithms (FORTEZZA) will expand the number of bytes it needs to	 * send data. If we only supply the output buffer with the same number	 * of bytes as the input buffer, we will fail.	 */	bufSize = contentLen + SSL3_BUFFER_FUDGE;	/*	 * null compression is easy to do	 */	PORT_Memcpy(write->buf + SSL3_RECORD_HEADER_LENGTH, buf, contentLen);	buf   += contentLen;	bytes -= contentLen;	PORT_Assert( bytes >= 0 );	ssl_GetSpecReadLock(ss);	/********************************/	cwSpec = ss->ssl3->cwSpec;	cipher_def = cwSpec->cipher_def;	/*	 * Add the MAC	 */	rv = ssl3_ComputeRecordMAC(	    cwSpec, (ss->sec->isServer) ? cwSpec->server.write_mac_context	                                : cwSpec->client.write_mac_context,	    type, cwSpec->version, cwSpec->write_seq_num,	    write->buf + SSL3_RECORD_HEADER_LENGTH, contentLen,	    write->buf + contentLen + SSL3_RECORD_HEADER_LENGTH, &macLen);	if (rv != SECSuccess) {	    ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);	    goto spec_locked_loser;	}	fragLen = contentLen + macLen;	/* needs to be encrypted */	PORT_Assert(fragLen <= MAX_FRAGMENT_LENGTH + 1024);	/*	 * Pad the text (if we're doing a block cipher)	 * then Encrypt it	 */	if (cipher_def->type == type_block) {	    int             padding_length;	    int             i;	    unsigned char * pBuf;	    /* Assume blockSize is a power of two */	    padding_length = cipher_def->block_size - 1 -		((fragLen) & (cipher_def->block_size - 1));	    fragLen += padding_length + 1;	    PORT_Assert((fragLen % cipher_def->block_size) == 0);	    /* Pad according to TLS rules (also acceptable to SSL3). */	    pBuf = &write->buf[fragLen + SSL3_RECORD_HEADER_LENGTH - 1];	    for (i = padding_length + 1; i > 0; --i) {	    	*pBuf-- = padding_length;	    }	}	rv = cwSpec->encode(	    cwSpec->encodeContext, write->buf + SSL3_RECORD_HEADER_LENGTH,	    &cipherBytes, bufSize, write->buf + SSL3_RECORD_HEADER_LENGTH,	    fragLen);	if (rv != SECSuccess) {	    ssl_MapLowLevelError(SSL_ERROR_ENCRYPTION_FAILURE);spec_locked_loser:	    ssl_ReleaseSpecReadLock(ss);	    return SECFailure;	}	PORT_Assert(cipherBytes <= MAX_FRAGMENT_LENGTH + 1024);	/*	 * XXX should we zero out our copy of the buffer after compressing	 * and encryption ??	 */	ssl3_BumpSequenceNumber(&cwSpec->write_seq_num);	ssl_ReleaseSpecReadLock(ss); /************************************/	/* PORT_Assert(fragLen == cipherBytes); */	write->len    = cipherBytes + SSL3_RECORD_HEADER_LENGTH;	write->buf[0] = type;	write->buf[1] = MSB(cwSpec->version);	write->buf[2] = LSB(cwSpec->version);	write->buf[3] = MSB(cipherBytes);	write->buf[4] = LSB(cipherBytes);	PRINT_BUF(50, (ss, "send (encrypted) record data:", write->buf, write->len));	/* If there's still some previously saved ciphertext,	 * or the caller doesn't want us to send the data yet,	 * then add all our new ciphertext to the amount previously saved.	 */	if ((ss->pendingBuf.len > 0) ||	    (flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {	    rv = ssl_SaveWriteData(ss, &ss->pendingBuf,				   write->buf, write->len);	    if (rv != SECSuccess) {		/* presumably a memory error, SEC_ERROR_NO_MEMORY */		return SECFailure;	    }	    write->len = 0;	/* All cipher text is saved away. */	    if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {		count = ssl_SendSavedWriteData(ss, &ss->pendingBuf,		                               &ssl_DefSend);		if (count < 0 && PR_GetError() != PR_WOULD_BLOCK_ERROR) {		    ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);		    return SECFailure;		}	    }	} else if (write->len > 0) {	    count = ssl_DefSend(ss, write->buf, write->len,				flags & ~ssl_SEND_FLAG_MASK);	    if (count < 0) {		if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {		    ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE);		    return (sent > 0) ? sent : SECFailure;		}		/* we got PR_WOULD_BLOCK_ERROR, which means none was sent. */		count = 0;	    }	    /* now take all the remaining unsent newly-generated ciphertext and	     * append it to the buffer of previously unsent ciphertext.	     */	    if ((unsigned)count < write->len) {		rv = ssl_SaveWriteData(ss, &ss->pendingBuf,				       write->buf + (unsigned)count,				       write->len - (unsigned)count);		if (rv != SECSuccess) {		    /* presumably a memory error, SEC_ERROR_NO_MEMORY */		    return SECFailure;		}	    }	    write->len = 0;	}	sent += contentLen;	if ((flags & ssl_SEND_FLAG_NO_BUFFER) &&	    (isBlocking || (ss->pendingBuf.len > 0))) {	    break;	}    }    return sent;}/* Attempt to send the content of "in" in an SSL application_data record. * Returns "len" or SECFailure,   never SECWouldBlock, nor SECSuccess. */intssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,			 PRInt32 len, PRInt32 flags){    PRInt32   sent	= 0;    PORT_Assert( ssl_HaveXmitBufLock(ss) );    while (len > 0) {	PRInt32   count;	if (sent > 0) {	    ssl_ReleaseXmitBufLock(ss);	    PR_Sleep(PR_INTERVAL_NO_WAIT);	/* PR_Yield(); */	    ssl_GetXmitBufLock(ss);	}	count = ssl3_SendRecord(ss, content_application_data, in, len,	                           flags | ssl_SEND_FLAG_NO_BUFFER);	if (count < 0) {	    return (sent > 0) ? sent : count;				    /* error code set by ssl3_SendRecord */	}	sent += count;	len  -= count;	in   += count;    }    return sent;}/* Attempt to send the content of sendBuf buffer in an SSL handshake record. * This function returns SECSuccess or SECFailure, never SECWouldBlock. * It used to always set sendBuf.len to 0, even when returning SECFailure. * Now it does not. * * Called from SSL3_SendAlert(), ssl3_SendChangeCipherSpecs(), *             ssl3_AppendHandshake(), ssl3_SendClientHello(), *             ssl3_SendHelloRequest(), ssl3_SendServerHelloDone(), *             ssl3_SendFinished(), */static SECStatusssl3_FlushHandshake(sslSocket *ss, PRInt32 flags){    PRInt32 rv;    sslConnectInfo *ci;    PORT_Assert(ss->sec != NULL);    PORT_Assert( ssl_HaveSSL3HandshakeLock(ss));    PORT_Assert( ssl_HaveXmitBufLock(ss) );    ci = &ss->sec->ci;    if (!ci->sendBuf.buf || !ci->sendBuf.len)	return SECSuccess;    rv = ssl3_SendRecord(ss, content_handshake, ci->sendBuf.buf,			    ci->sendBuf.len, flags);    if (rv < 0) {	return (SECStatus)rv;	/* error code set by ssl3_SendRecord */    }    ci->sendBuf.len = 0;    return SECSuccess;}/* * Called from ssl3_HandleAlert and from ssl3_HandleCertificates when * the remote client sends a negative response to our certificate request. * Returns SECFailure if the application has required client auth. *         SECSuccess otherwise. */static SECStatusssl3_HandleNoCertificate(sslSocket *ss){    if (ss->sec->peerCert != NULL) {	if (ss->sec->peerKey != NULL) {	    SECKEY_DestroyPublicKey(ss->sec->peerKey);	    ss->sec->peerKey = NULL;	}	CERT_DestroyCertificate(ss->sec->peerCert);	ss->sec->peerCert = NULL;    }    /* If the server has required client-auth blindly but doesn't     * actually look at the certificate it won't know that no     * certificate was presented so we shutdown the socket to ensure     * an error.  We only do this if we aren't connected because     * if we're redoing the handshake we know the server is paying     * attention to the certificate.     */    if ((ss->requireCertificate == 1) ||	(!ss->connected && (ss->requireCertificate > 1))) {	PRFileDesc * lower;	ss->sec->uncache(ss->sec->ci.sid);	SSL3_SendAlert(ss, alert_fatal, bad_certificate);	lower = ss->fd->lower;	lower->methods->shutdown(lower, PR_SHUTDOWN_BOTH);	PORT_SetError(SSL_ERROR_NO_CERTIFICATE);	return SECFailure;    }    return SECSuccess;}/************************************************************************ * Alerts *//*** Acquires both handshake and XmitBuf locks.** Called from: ssl3_IllegalParameter	<-**              ssl3_HandshakeFailure	<-**              ssl3_HandleAlert	<- ssl3_HandleRecord.**              ssl3_HandleChangeCipherSpecs <- ssl3_HandleRecord**              ssl3_ConsumeHandshakeVariable <-**              ssl3_HandleHelloRequest	<-**              ssl3_HandleServerHello	<-**              ssl3_HandleServerKeyExchange <-**              ssl3_HandleCertificateRequest <-**              ssl3_HandleServerHelloDone <-**              ssl3_HandleClientHello	<-**              ssl3_HandleV2ClientHello <-**              ssl3_HandleCertificateVerify <-**              ssl3_HandleFortezzaClientKeyExchange <-**              ssl3_HandleClientKeyExchange <-**              ssl3_HandleCertificate	<-**              ssl3_HandleFinished	<-**              ssl3_HandleHandshakeMessage <-**              ssl3_HandleRecord	<-***/SECStatusSSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc){    uint8 	bytes[2];    SECStatus	rv;    SSL_TRC(3, ("%d: SSL3[%d]: send alert record, level=%d desc=%d",		SSL_GETPID(), ss->fd, level, desc));    bytes[0] = level;    bytes[1] = desc;    ssl_GetSSL3HandshakeLock(ss);    if (level == alert_fatal) {	if (ss->sec->ci.sid) {	    ss->sec->uncache(ss->sec->ci.sid);	}    }    ssl_GetXmitBufLock(ss);    rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER);    if (rv == SECSuccess) {	PRInt32 sent;	sent = ssl3_SendRecord(ss, content_alert, bytes, 2, 0);	rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;    }    ssl_ReleaseXmitBufLock(ss);    ssl_ReleaseSSL3HandshakeLock(ss);    return rv;	/* error set by ssl3_FlushHandshake or ssl3_SendRecord */}/* * Send illegal_parameter alert.  Set generic error number. */static SECStatusssl3_IllegalParameter(sslSocket *ss)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?