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 + -
显示快捷键?