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

📄 hdskhelo.c

📁 Netscape公司提供的安全套接字层
💻 C
字号:
/*  *********************************************************************
    File: hdskhelo.c

    SSLRef 3.0 Final -- 11/19/96

    Copyright (c)1996 by Netscape Communications Corp.

    By retrieving this software you are bound by the licensing terms
    disclosed in the file "LICENSE.txt". Please read it, and if you don't
    accept the terms, delete this software.

    SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
    View, California <http://home.netscape.com/> and Consensus Development
    Corporation of Berkeley, California <http://www.consensus.com/>.

    *********************************************************************

    File: hdskhelo.c   Support for client hello and server hello messages

    Also, encoding of Random structures and initializing the message
    hashes used for calculating finished and certificate verify messages.

    ****************************************************************** */

#ifndef _SSLCTX_H_
#include "sslctx.h"
#endif

#ifndef _SSLHDSHK_H_
#include "sslhdshk.h"
#endif

#ifndef _SSLALLOC_H_
#include "sslalloc.h"
#endif

#ifndef _SSLSESS_H_
#include "sslsess.h"
#endif

#include <string.h>

static SSLErr SSLEncodeRandom(unsigned char *p, SSLContext *ctx);

SSLErr
SSLEncodeServerHello(SSLRecord *serverHello, SSLContext *ctx)
{   SSLErr          err;
    uint8           *progress;
    int             sessionIDLen;
    
    sessionIDLen = 0;
    if (ctx->sessionID.data != 0)
        sessionIDLen = (uint8)ctx->sessionID.length;
    serverHello->protocolVersion = SSL_Version_3_0;
    serverHello->contentType = SSL_handshake;
    if ((err = SSLAllocBuffer(&serverHello->contents, 42 + sessionIDLen, &ctx->sysCtx)) != 0)
        return err;
    
    progress = serverHello->contents.data;
    *progress++ = SSL_server_hello;
    progress = SSLEncodeInt(progress, 38 + sessionIDLen, 3);
    progress = SSLEncodeInt(progress, SSL_Version_3_0, 2);
    if ((err = SSLEncodeRandom(progress, ctx)) != 0)
        return err;
    memcpy(ctx->serverRandom, progress, 32);
    progress += 32;
    *(progress++) = (uint8)sessionIDLen;
    if (sessionIDLen > 0)
        memcpy(progress, ctx->sessionID.data, sessionIDLen);
    progress += sessionIDLen;
    progress = SSLEncodeInt(progress, ctx->selectedCipher, 2);
    *(progress++) = 0;      /* Null compression */
    
    ASSERT(progress == serverHello->contents.data + serverHello->contents.length);
    
    return SSLNoErr;
}

SSLErr
SSLProcessServerHello(SSLBuffer message, SSLContext *ctx)
{   SSLErr              err;
    SSLProtocolVersion  protocolVersion;
    unsigned int        sessionIDLen;
    uint8               *p;
    
    ASSERT(ctx->protocolSide == SSL_ClientSide);
    
    if (message.length < 38 || message.length > 70)
        return SSLProtocolErr;
    p = message.data;
    
    protocolVersion = (SSLProtocolVersion)SSLDecodeInt(p, 2);
    p += 2;
    if (protocolVersion != SSL_Version_3_0)
        return SSLUnsupportedErr;
    ctx->protocolVersion = protocolVersion;
    
    memcpy(ctx->serverRandom, p, 32);
    p += 32;
    
    sessionIDLen = *p++;
    if (message.length != 38 + sessionIDLen)
        return SSLProtocolErr;
    
    if (sessionIDLen > 0 && ctx->peerID.data != 0)
    {   /* Don't die on error; just treat it as an uncached session */
        err = SSLAllocBuffer(&ctx->sessionID, sessionIDLen, &ctx->sysCtx);
        if (err == 0)
            memcpy(ctx->sessionID.data, p, sessionIDLen);
    }
    p += sessionIDLen;
    
    ctx->selectedCipher = (uint16)SSLDecodeInt(p,2);
    p += 2;
    if ((err = FindCipherSpec(ctx->selectedCipher, &ctx->selectedCipherSpec)) != 0)
        return err;
    
    if (*p++ != 0)      /* Compression */
        return SSLUnsupportedErr;
    
    ASSERT(p == message.data + message.length);
    return SSLNoErr;
}

SSLErr
SSLEncodeClientHello(SSLRecord *clientHello, SSLContext *ctx)
{   int             length, i;
    SSLErr          err;
    unsigned char   *p;
    SSLBuffer       sessionIdentifier;
    uint16          sessionIDLen;
    
    ASSERT(ctx->protocolSide == SSL_ClientSide);
    
    sessionIDLen = 0;
    if (ctx->resumableSession.data != 0)
    {   if (ERR(err = SSLRetrieveSessionIDIdentifier(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
        {   return err;
        }
        sessionIDLen = sessionIdentifier.length;
    }
    
    length = 39 + 2*CipherSpecCount + sessionIDLen;
    
    clientHello->protocolVersion = SSL_Version_3_0;
    clientHello->contentType = SSL_handshake;
    if ((err = SSLAllocBuffer(&clientHello->contents, length + 4, &ctx->sysCtx)) != 0)
        return err;
    
    p = clientHello->contents.data;
    *p++ = SSL_client_hello;
    p = SSLEncodeInt(p, length, 3);
    p = SSLEncodeInt(p, SSL_Version_3_0, 2);
    if ((err = SSLEncodeRandom(p, ctx)) != 0)
    {   SSLFreeBuffer(&clientHello->contents, &ctx->sysCtx);
        return err;
    }
    memcpy(ctx->clientRandom, p, 32);
    p += 32;
    *p++ = sessionIDLen;    /* 1 byte vector length */
    if (sessionIDLen > 0)
    {   memcpy(p, sessionIdentifier.data, sessionIDLen);
        if ((err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
            return err;
    }
    p += sessionIDLen;
    p = SSLEncodeInt(p, 2*CipherSpecCount, 2);  /* 2 byte long vector length */
    for (i = 0; i < CipherSpecCount; ++i)
        p = SSLEncodeInt(p, KnownCipherSpecs[i].cipherSpec, 2);
    *p++ = 1;                               /* 1 byte long vector */
    *p++ = 0;                               /* null compression */
    
    ASSERT(p == clientHello->contents.data + clientHello->contents.length);
    
    if ((err = SSLInitMessageHashes(ctx)) != 0)
        return err;
    
    return SSLNoErr;
}

SSLErr
SSLProcessClientHello(SSLBuffer message, SSLContext *ctx)
{   SSLErr              err;
    SSLProtocolVersion  clientVersion;
    uint16              cipherListLen, cipherCount, desiredSpec, cipherSpec;
    uint8               sessionIDLen, compressionCount;
    uint8               *progress;
    int                 i;
    
    if (message.length < 41)
        return SSLProtocolErr;
    
    progress = message.data;
    clientVersion = (SSLProtocolVersion)SSLDecodeInt(progress, 2);
    progress += 2;
    if (clientVersion < SSL_Version_3_0)
        return SSLUnsupportedErr;
    ctx->protocolVersion = SSL_Version_3_0;
    
    memcpy(ctx->clientRandom, progress, 32);
    progress += 32;
    sessionIDLen = *(progress++);
    if (message.length < 41 + sessionIDLen)
        return SSLProtocolErr;
    if (sessionIDLen > 0 && ctx->peerID.data != 0)
    {   /* Don't die on error; just treat it as an uncacheable session */
        err = SSLAllocBuffer(&ctx->sessionID, sessionIDLen, &ctx->sysCtx);
        if (err == 0)
            memcpy(ctx->sessionID.data, progress, sessionIDLen);
    }
    progress += sessionIDLen;
    
    cipherListLen = (uint16)SSLDecodeInt(progress, 2);  /* Count of cipherSpecs, must be even & >= 2 */
    progress += 2;
    if ((cipherListLen & 1) || cipherListLen < 2 || message.length < 39 + sessionIDLen + cipherListLen)
        return SSLProtocolErr;
    cipherCount = cipherListLen/2;
    cipherSpec = 0xFFFF;        /* No match marker */
    while (cipherSpec == 0xFFFF && cipherCount--)
    {   desiredSpec = (uint16)SSLDecodeInt(progress, 2);
        progress += 2;
        for (i = 0; i < CipherSpecCount; i++)
        {   if (KnownCipherSpecs[i].cipherSpec == desiredSpec)
            {   cipherSpec = desiredSpec;
                break;
            }
        }
    }
    
    if (cipherSpec == 0xFFFF)
        return SSLNegotiationErr;
    progress += 2 * cipherCount;    /* Advance past unchecked cipherCounts */
    ctx->selectedCipher = cipherSpec;
    if ((err = FindCipherSpec(ctx->selectedCipher, &ctx->selectedCipherSpec)) != 0)
        return err;
    
    compressionCount = *(progress++);
/* message.length restriction relaxed to allow too-long messages for future expansion
    following recommendation of TLS meeting 5/29/96 */
    if (compressionCount < 1 || message.length < 38 + sessionIDLen + cipherListLen + compressionCount)
        return SSLProtocolErr;
    /* Ignore list; we're doing null */
    
    if ((err = SSLInitMessageHashes(ctx)) != 0)
        return err;
    
    return SSLNoErr;
}

static SSLErr
SSLEncodeRandom(unsigned char *p, SSLContext *ctx)
{   SSLBuffer   randomData;
    SSLErr      err;
    uint32      time;
    
    if ((err = ctx->sysCtx.time(&time, ctx->sysCtx.timeRef)) != 0)
        return err;
    SSLEncodeInt(p, time, 4);
    randomData.data = p+4;
    randomData.length = 28;
    if ((err = ctx->sysCtx.random(randomData, ctx->sysCtx.randomRef)) != 0)
        return err;
    return SSLNoErr;
}

SSLErr
SSLInitMessageHashes(SSLContext *ctx)
{   SSLErr          err;
    if ((err = SSLFreeBuffer(&ctx->shaState, &ctx->sysCtx)) != 0)
        return err;
    if ((err = SSLFreeBuffer(&ctx->md5State, &ctx->sysCtx)) != 0)
        return err;
    if ((err = ReadyHash(&SSLHashSHA1, &ctx->shaState, ctx)) != 0)
        return err;
    if ((err = ReadyHash(&SSLHashMD5, &ctx->md5State, ctx)) != 0)
        return err;
    return SSLNoErr;
}

⌨️ 快捷键说明

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