sslcon.c

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

C
2,213
字号
void      ssl2_InitSocketPolicy(sslSocket *ss){    ss->allowedByPolicy		= allowedByPolicy;    ss->maybeAllowedByPolicy	= maybeAllowedByPolicy;    ss->chosenPreference 	= chosenPreference;}/************************************************************************//* Called from ssl2_CreateSessionCypher(), which already holds handshake lock. */static SECStatusssl2_CreateMAC(sslSecurityInfo *sec, SECItem *readKey, SECItem *writeKey,           int cipherChoice){    switch (cipherChoice) {      case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:      case SSL_CK_RC2_128_CBC_WITH_MD5:      case SSL_CK_RC4_128_EXPORT40_WITH_MD5:      case SSL_CK_RC4_128_WITH_MD5:      case SSL_CK_DES_64_CBC_WITH_MD5:      case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:	sec->hash = &SECHashObjects[HASH_AlgMD5];	SECITEM_CopyItem(0, &sec->sendSecret, writeKey);	SECITEM_CopyItem(0, &sec->rcvSecret, readKey);	break;      default:	PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);	return SECFailure;    }    sec->hashcx = (*sec->hash->create)();    if (sec->hashcx == NULL)	return SECFailure;    return SECSuccess;}/************************************************************************ * All the Send functions below must acquire and release the socket's  * xmitBufLock. *//* Called from all the Send* functions below. */static SECStatusssl2_GetSendBuffer(sslSocket *ss, unsigned int len){    sslConnectInfo *ci;    SECStatus rv = SECSuccess;    PORT_Assert((ss->sec != 0));    PORT_Assert(ssl_HaveXmitBufLock(ss));    ci = &ss->sec->ci;    if (len < 128) {	len = 128;    }    if (len > ci->sendBuf.space) {	rv = sslBuffer_Grow(&ci->sendBuf, len);	if (rv != SECSuccess) {	    SSL_DBG(("%d: SSL[%d]: ssl2_GetSendBuffer failed, tried to get %d bytes",		     SSL_GETPID(), ss->fd, len));	    rv = SECFailure;	}    }    return rv;}/* Called from: * ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage() * ssl2_HandleRequestCertificate()     <- ssl2_HandleMessage() <-  					ssl_Do1stHandshake() * ssl2_HandleMessage()                <- ssl_Do1stHandshake() * ssl2_HandleServerHelloMessage() <- ssl_Do1stHandshake()                                     after ssl2_BeginClientHandshake() * ssl2_RestartHandshakeAfterCertReq() <- Called from certdlgs.c in nav. * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake()                                      after ssl2_BeginServerHandshake() *  * Acquires and releases the socket's xmitBufLock. */	intssl2_SendErrorMessage(sslSocket *ss, int error){    sslSecurityInfo *sec;    int rv;    PRUint8 msg[SSL_HL_ERROR_HBYTES];    PORT_Assert( ssl_Have1stHandshakeLock(ss) );    PORT_Assert((ss->sec != 0));    msg[0] = SSL_MT_ERROR;    msg[1] = MSB(error);    msg[2] = LSB(error);    ssl_GetXmitBufLock(ss);    /***************************************/    sec = ss->sec;    SSL_TRC(3, ("%d: SSL[%d]: sending error %d", SSL_GETPID(), ss->fd, error));    rv = (*sec->send)(ss, msg, sizeof(msg), 0);    if (rv >= 0) {	rv = SECSuccess;    }    ssl_ReleaseXmitBufLock(ss);    /***************************************/    return rv;}/* Called from ssl2_TryToFinish().   * Acquires and releases the socket's xmitBufLock. */static SECStatusssl2_SendClientFinishedMessage(sslSocket *ss){    sslSecurityInfo *sec;    sslConnectInfo * ci;    SECStatus        rv    = SECSuccess;    int              sent;    PRUint8    msg[1 + SSL_CONNECTIONID_BYTES];    PORT_Assert( ssl_Have1stHandshakeLock(ss) );    PORT_Assert((ss->sec != 0));    ssl_GetXmitBufLock(ss);    /***************************************/    sec = ss->sec;    ci = &sec->ci;    if (ci->sentFinished == 0) {	ci->sentFinished = 1;	SSL_TRC(3, ("%d: SSL[%d]: sending client-finished",		    SSL_GETPID(), ss->fd));	msg[0] = SSL_MT_CLIENT_FINISHED;	PORT_Memcpy(msg+1, ci->connectionID, sizeof(ci->connectionID));	DUMP_MSG(29, (ss, msg, 1 + sizeof(ci->connectionID)));	sent = (*sec->send)(ss, msg, 1 + sizeof(ci->connectionID), 0);	rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;    }    ssl_ReleaseXmitBufLock(ss);    /***************************************/    return rv;}/* Called from  * ssl2_HandleClientSessionKeyMessage() <- ssl2_HandleClientHelloMessage() * ssl2_HandleClientHelloMessage()  <- ssl_Do1stHandshake()                                       after ssl2_BeginServerHandshake() * Acquires and releases the socket's xmitBufLock. */static SECStatusssl2_SendServerVerifyMessage(sslSocket *ss){    sslSecurityInfo *sec;    sslConnectInfo * ci;    PRUint8 *        msg;    int              sendLen;    int              sent;    SECStatus        rv;    PORT_Assert( ssl_Have1stHandshakeLock(ss) );    PORT_Assert((ss->sec != 0));    ssl_GetXmitBufLock(ss);    /***************************************/    sec = ss->sec;    ci = &sec->ci;    sendLen = 1 + SSL_CHALLENGE_BYTES;    rv = ssl2_GetSendBuffer(ss, sendLen);    if (rv != SECSuccess) {	goto done;    }    msg = ci->sendBuf.buf;    msg[0] = SSL_MT_SERVER_VERIFY;    PORT_Memcpy(msg+1, ci->clientChallenge, SSL_CHALLENGE_BYTES);    DUMP_MSG(29, (ss, msg, sendLen));    sent = (*sec->send)(ss, msg, sendLen, 0);    rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;done:    ssl_ReleaseXmitBufLock(ss);    /***************************************/    return rv;}/* Called from ssl2_TryToFinish().  * Acquires and releases the socket's xmitBufLock. */static SECStatusssl2_SendServerFinishedMessage(sslSocket *ss){    sslSecurityInfo *sec;    sslConnectInfo * ci;    sslSessionID *   sid;    PRUint8 *        msg;    int              sendLen, sent;    SECStatus        rv    = SECSuccess;    PORT_Assert( ssl_Have1stHandshakeLock(ss) );    PORT_Assert((ss->sec != 0));    ssl_GetXmitBufLock(ss);    /***************************************/    sec = ss->sec;    ci = &sec->ci;    if (ci->sentFinished == 0) {	ci->sentFinished = 1;	PORT_Assert(ci->sid != 0);	sid = ci->sid;	SSL_TRC(3, ("%d: SSL[%d]: sending server-finished",		    SSL_GETPID(), ss->fd));	sendLen = 1 + sizeof(sid->u.ssl2.sessionID);	rv = ssl2_GetSendBuffer(ss, sendLen);	if (rv != SECSuccess) {	    goto done;	}	msg = ci->sendBuf.buf;	msg[0] = SSL_MT_SERVER_FINISHED;	PORT_Memcpy(msg+1, sid->u.ssl2.sessionID,		    sizeof(sid->u.ssl2.sessionID));	DUMP_MSG(29, (ss, msg, sendLen));	sent = (*sec->send)(ss, msg, sendLen, 0);	if (sent < 0) {	    /* If send failed, it is now a bogus  session-id */	    (*sec->uncache)(sid);	    rv = (SECStatus)sent;	} else if (!ss->noCache) {	    /* Put the sid in session-id cache, (may already be there) */	    (*sec->cache)(sid);	    rv = SECSuccess;	}	ssl_FreeSID(sid);	ci->sid = 0;    }done:    ssl_ReleaseXmitBufLock(ss);    /***************************************/    return rv;}/* Called from ssl2_ClientSetupSessionCypher() <-  *						ssl2_HandleServerHelloMessage()  *                                           after ssl2_BeginClientHandshake() * Acquires and releases the socket's xmitBufLock. */static SECStatusssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize,		      PRUint8 *ca, int caLen,		      PRUint8 *ck, int ckLen,		      PRUint8 *ek, int ekLen){    sslSecurityInfo *sec;    PRUint8 *        msg;    int              sendLen;    int              sent;    SECStatus        rv;    PORT_Assert( ssl_Have1stHandshakeLock(ss) );    PORT_Assert((ss->sec != 0));    ssl_GetXmitBufLock(ss);    /***************************************/    sec = ss->sec;    sendLen = SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen;    rv = ssl2_GetSendBuffer(ss, sendLen);    if (rv != SECSuccess) 	goto done;    SSL_TRC(3, ("%d: SSL[%d]: sending client-session-key",		SSL_GETPID(), ss->fd));    msg = sec->ci.sendBuf.buf;    msg[0] = SSL_MT_CLIENT_MASTER_KEY;    msg[1] = cipher;    msg[2] = MSB(keySize);    msg[3] = LSB(keySize);    msg[4] = MSB(ckLen);    msg[5] = LSB(ckLen);    msg[6] = MSB(ekLen);    msg[7] = LSB(ekLen);    msg[8] = MSB(caLen);    msg[9] = LSB(caLen);    PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES, ck, ckLen);    PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen, ek, ekLen);    PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen+ekLen, ca, caLen);    DUMP_MSG(29, (ss, msg, sendLen));    sent = (*sec->send)(ss, msg, sendLen, 0);    rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;done:    ssl_ReleaseXmitBufLock(ss);    /***************************************/    return rv;}/* Called from ssl2_TriggerNextMessage() <- ssl2_HandleMessage()  * Acquires and releases the socket's xmitBufLock. */static SECStatusssl2_SendCertificateRequestMessage(sslSocket *ss){    sslSecurityInfo *sec;    sslConnectInfo * ci;    PRUint8 *        msg;    int              sent;    int              sendLen;    SECStatus        rv;    PORT_Assert( ssl_Have1stHandshakeLock(ss) );    PORT_Assert((ss->sec != 0));    ssl_GetXmitBufLock(ss);    /***************************************/    sec = ss->sec;    ci = &sec->ci;    sendLen = SSL_HL_REQUEST_CERTIFICATE_HBYTES + SSL_CHALLENGE_BYTES;    rv = ssl2_GetSendBuffer(ss, sendLen);    if (rv != SECSuccess) 	goto done;    SSL_TRC(3, ("%d: SSL[%d]: sending certificate request",		SSL_GETPID(), ss->fd));    /* Generate random challenge for client to encrypt */    PK11_GenerateRandom(ci->serverChallenge, SSL_CHALLENGE_BYTES);    msg = ci->sendBuf.buf;    msg[0] = SSL_MT_REQUEST_CERTIFICATE;    msg[1] = SSL_AT_MD5_WITH_RSA_ENCRYPTION;    PORT_Memcpy(msg + SSL_HL_REQUEST_CERTIFICATE_HBYTES, ci->serverChallenge,	      SSL_CHALLENGE_BYTES);    DUMP_MSG(29, (ss, msg, sendLen));    sent = (*sec->send)(ss, msg, sendLen, 0);    rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;done:    ssl_ReleaseXmitBufLock(ss);    /***************************************/    return rv;}/* Called from ssl2_HandleRequestCertificate() <- ssl2_HandleMessage() *             ssl2_RestartHandshakeAfterCertReq() <- (application) * Acquires and releases the socket's xmitBufLock. */static intssl2_SendCertificateResponseMessage(sslSocket *ss, SECItem *cert,                                     SECItem *encCode){    sslSecurityInfo *sec;    PRUint8 *msg;    int rv, sendLen;    PORT_Assert( ssl_Have1stHandshakeLock(ss) );    PORT_Assert((ss->sec != 0));    ssl_GetXmitBufLock(ss);    /***************************************/    sec = ss->sec;    sendLen = SSL_HL_CLIENT_CERTIFICATE_HBYTES + encCode->len + cert->len;    rv = ssl2_GetSendBuffer(ss, sendLen);    if (rv)     	goto done;    SSL_TRC(3, ("%d: SSL[%d]: sending certificate response",		SSL_GETPID(), ss->fd));    msg = sec->ci.sendBuf.buf;    msg[0] = SSL_MT_CLIENT_CERTIFICATE;    msg[1] = SSL_CT_X509_CERTIFICATE;    msg[2] = MSB(cert->len);    msg[3] = LSB(cert->len);    msg[4] = MSB(encCode->len);    msg[5] = LSB(encCode->len);    PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES, cert->data, cert->len);    PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES + cert->len,	      encCode->data, encCode->len);    DUMP_MSG(29, (ss, msg, sendLen));    rv = (*sec->send)(ss, msg, sendLen, 0);    if (rv >= 0) {	rv = SECSuccess;    }done:    ssl_ReleaseXmitBufLock(ss);    /***************************************/    return rv;}/**********************************************************************  Send functions above this line must aquire & release the socket's   **	xmitBufLock.  ** All the ssl2_Send functions below this line are called vis ss->sec->send**	and require that the caller hold the xmitBufLock.*//*** Called from ssl2_SendStream, ssl2_SendBlock, but not from ssl2_SendClear.*/static SECStatusssl2_CalcMAC(PRUint8             * result, 	     sslSecurityInfo     * sec,	     const PRUint8       * data, 	     unsigned int          dataLen,	     unsigned int          paddingLen){    const PRUint8 *      secret		= sec->sendSecret.data;    unsigned int         secretLen	= sec->sendSecret.len;    unsigned long        sequenceNumber = sec->sendSequence;    unsigned int         nout;    PRUint8              seq[4];    PRUint8              padding[32];/* XXX max blocksize? */    if (!sec->hash || !sec->hash->length)    	return SECSuccess;    if (!sec->hashcx)    	return SECFailure;    /* Reset hash function */    (*sec->hash->begin)(sec->hashcx);    /* Feed hash the data */    (*sec->hash->update)(sec->hashcx, secret, secretLen);    (*sec->hash->update)(sec->hashcx, data, dataLen);    PORT_Memset(padding, paddingLen, paddingLen);    (*sec->hash->update)(sec->hashcx, padding, paddingLen);    seq[0] = (PRUint8) (sequenceNumber >> 24);    seq[1] = (PRUint8) (sequenceNumber >> 16);    seq[2] = (PRUint8) (sequenceNumber >> 8);    seq[3] = (PRUint8) (sequenceNumber);    PRINT_BUF(60, (0, "calc-mac secret:", secret, secretLen));    PRINT_BUF(60, (0, "calc-mac data:", data, dataLen));    PRINT_BUF(60, (0, "calc-mac padding:", padding, paddingLen));    PRINT_BUF(60, (0, "calc-mac seq:", seq, 4));

⌨️ 快捷键说明

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