📄 sslhdshk.c
字号:
}
}
if (ERR(err = SSLFreeBuffer(&ctx->sessionID, &ctx->sysCtx)) != 0)
{ ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
return err;
}
}
/* If we get here, we're not resuming; generate a new session ID if we know our peer */
if (ctx->peerID.data != 0)
{ /* Ignore errors; just treat as uncached session */
ASSERT(ctx->sessionID.data == 0);
ERR(err = SSLAllocBuffer(&ctx->sessionID, SSL_SESSION_ID_LEN, &ctx->sysCtx));
if (err == 0)
{ if (ERR(err = ctx->sysCtx.random(ctx->sessionID, ctx->sysCtx.randomRef)) != 0)
{ ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
return err;
}
}
}
if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerHello, ctx)) != 0)
return err;
switch (ctx->selectedCipherSpec->keyExchangeMethod)
{ case SSL_NULL_auth:
case SSL_DH_anon:
case SSL_DH_anon_EXPORT:
ctx->requestClientCert = 0;
break;
default: /* everything else */
if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificate, ctx)) != 0)
return err;
break;
}
if (ctx->selectedCipherSpec->keyExchangeMethod != SSL_RSA)
if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange, ctx)) != 0)
return err;
if (ctx->requestClientCert != 0)
{ if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificateRequest, ctx)) != 0)
return err;
ctx->certRequested = 1;
}
if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerHelloDone, ctx)) != 0)
return err;
if (ctx->certRequested)
ctx->state = HandshakeClientCertificate;
else
ctx->state = HandshakeClientKeyExchange;
break;
case SSL_server_hello:
if (ctx->resumableSession.data != 0 && ctx->sessionID.data != 0)
{ if (ERR(err = SSLRetrieveSessionIDIdentifier(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
{ ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
return err;
}
if (sessionIdentifier.length == ctx->sessionID.length &&
memcmp(sessionIdentifier.data, ctx->sessionID.data, ctx->sessionID.length) == 0)
{ /* Everything matches; resume the session */
if (ERR(err = SSLInstallSessionID(ctx->resumableSession, ctx)) != 0 ||
ERR(err = SSLInitPendingCiphers(ctx)) != 0 ||
ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
{ ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
return err;
}
ctx->state = HandshakeChangeCipherSpec;
break;
}
if (ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
{ ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
return err;
}
}
switch (ctx->selectedCipherSpec->keyExchangeMethod)
{ case SSL_NULL_auth:
case SSL_DH_anon:
case SSL_DH_anon_EXPORT:
ctx->state = HandshakeKeyExchange;
break;
case SSL_RSA:
case SSL_DH_DSS:
case SSL_DH_DSS_EXPORT:
case SSL_DH_RSA:
case SSL_DH_RSA_EXPORT:
case SSL_RSA_EXPORT:
case SSL_DHE_DSS:
case SSL_DHE_DSS_EXPORT:
case SSL_DHE_RSA:
case SSL_DHE_RSA_EXPORT:
case SSL_Fortezza:
ctx->state = HandshakeCertificate;
break;
default:
ASSERTMSG("Unknown key exchange method");
break;
}
break;
case SSL_certificate:
if (ctx->state == HandshakeCertificate)
switch (ctx->selectedCipherSpec->keyExchangeMethod)
{ case SSL_RSA:
case SSL_DH_DSS:
case SSL_DH_DSS_EXPORT:
case SSL_DH_RSA:
case SSL_DH_RSA_EXPORT:
ctx->state = HandshakeHelloDone;
break;
case SSL_RSA_EXPORT:
case SSL_DHE_DSS:
case SSL_DHE_DSS_EXPORT:
case SSL_DHE_RSA:
case SSL_DHE_RSA_EXPORT:
case SSL_Fortezza:
ctx->state = HandshakeKeyExchange;
break;
default:
ASSERTMSG("Unknown or unexpected key exchange method");
break;
}
else if (ctx->state == HandshakeClientCertificate)
{ ctx->state = HandshakeClientKeyExchange;
if (ctx->peerCert != 0)
ctx->certReceived = 1;
}
break;
case SSL_certificate_request: /* state stays in HandshakeHelloDone; distinction is in ctx->certRequested */
if (ctx->peerCert == 0)
{ ERR(SSLFatalSessionAlert(alert_handshake_failure, ctx));
return ERR(SSLProtocolErr);
}
ctx->certRequested = 1;
break;
case SSL_server_key_exchange:
ctx->state = HandshakeHelloDone;
break;
case SSL_server_hello_done:
if (ctx->certRequested)
{ if (ctx->localCert != 0 && ctx->x509Requested)
{ if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificate, ctx)) != 0)
return err;
}
else
{ if (ERR(err = SSLSendAlert(alert_warning, alert_no_certificate, ctx)) != 0)
return err;
}
}
if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeKeyExchange, ctx)) != 0)
return err;
if (ERR(err = SSLCalculateMasterSecret(ctx)) != 0 ||
ERR(err = SSLInitPendingCiphers(ctx)) != 0)
{ ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
return err;
}
if (ERR(err = SSLFreeBuffer(&ctx->preMasterSecret, &ctx->sysCtx)) != 0)
return err;
if (ctx->certSent)
if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificateVerify, ctx)) != 0)
return err;
if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec, ctx)) != 0)
return err;
/* Install new cipher spec on write side */
if (ERR(err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
{ ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
return err;
}
ctx->writeCipher = ctx->writePending;
ctx->writeCipher.ready = 0; /* Can't send data until Finished is sent */
memset(&ctx->writePending, 0, sizeof(CipherContext)); /* Zero out old data */
if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage, ctx)) != 0)
return err;
/* Finished has been sent; enable data dransfer on write channel */
ctx->writeCipher.ready = 1;
ctx->state = HandshakeChangeCipherSpec;
break;
case SSL_certificate_verify:
ctx->state = HandshakeChangeCipherSpec;
break;
case SSL_client_key_exchange:
if (ERR(err = SSLCalculateMasterSecret(ctx)) != 0 ||
ERR(err = SSLInitPendingCiphers(ctx)) != 0)
{ ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
return err;
}
if (ERR(err = SSLFreeBuffer(&ctx->preMasterSecret, &ctx->sysCtx)) != 0)
return err;
if (ctx->certReceived)
ctx->state = HandshakeClientCertVerify;
else
ctx->state = HandshakeChangeCipherSpec;
break;
case SSL_finished:
/* Handshake is over; enable data transfer on read channel */
ctx->readCipher.ready = 1;
/* If writePending is set, we haven't yet sent a finished message; send it */
if (ctx->writePending.ready != 0)
{ if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec, ctx)) != 0)
return err;
/* Install new cipher spec on write side */
if (ERR(err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
{ SSLFatalSessionAlert(alert_close_notify, ctx);
return err;
}
ctx->writeCipher = ctx->writePending;
ctx->writeCipher.ready = 0; /* Can't send data until Finished is sent */
memset(&ctx->writePending, 0, sizeof(CipherContext)); /* Zero out old data */
if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage, ctx)) != 0)
return err;
ctx->writeCipher.ready = 1;
}
if (ctx->protocolSide == SSL_ServerSide)
ctx->state = HandshakeServerIdle;
else
ctx->state = HandshakeClientIdle;
if (ctx->peerID.data != 0)
ERR(SSLAddSessionID(ctx));
break;
default:
ASSERTMSG("Unknown State");
break;
}
return SSLNoErr;
}
SSLErr
SSLPrepareAndQueueMessage(EncodeMessageFunc msgFunc, SSLContext *ctx)
{ SSLErr err;
SSLRecord rec;
if (ERR(err = msgFunc(&rec, ctx)) != 0)
{ ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
goto fail;
}
if (rec.contentType == SSL_handshake)
{ if (ERR(err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
ERR(err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
{ ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
goto fail;
}
}
if (ERR(err = SSLWriteRecord(rec, ctx)) != 0)
goto fail;
err = SSLNoErr;
fail:
SSLFreeBuffer(&rec.contents, &ctx->sysCtx);
return err;
}
SSLErr
SSL3ReceiveSSL2ClientHello(SSLRecord rec, SSLContext *ctx)
{ SSLErr err;
if (ERR(err = SSLInitMessageHashes(ctx)) != 0)
return err;
if (ERR(err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
ERR(err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
{ ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
return err;
}
if (ERR(err = SSLAdvanceHandshake(SSL_client_hello, ctx)) != 0)
return err;
return SSLNoErr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -