⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sslhdshk.c

📁 Netscape公司提供的安全套接字层
💻 C
📖 第 1 页 / 共 2 页
字号:
                    }
                }
                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 + -