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

📄 hdskkyex.c

📁 Netscape公司提供的安全套接字层
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  *********************************************************************
    File: hdskkyex.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: hdskkyex.c   Support for key exchange and server key exchange

    Encoding and decoding of key exchange and server key exchange
    messages in both the Diffie-Hellman and RSA variants; also, includes
    the necessary crypto library calls to support this negotiation.

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

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

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

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

#include <string.h>

static SSLErr SSLEncodeRSAServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx);
static SSLErr SSLEncodeRSAKeyParams(SSLBuffer *keyParams, SSLRSAPrivateKey *key, SSLContext *ctx);
static SSLErr SSLEncodeDHanonServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx);
static SSLErr SSLProcessRSAServerKeyExchange(SSLBuffer message, SSLContext *ctx);
static SSLErr SSLProcessDHanonServerKeyExchange(SSLBuffer message, SSLContext *ctx);
static SSLErr SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx);
static SSLErr SSLDecodeDHanonKeyExchange(SSLBuffer keyExchange, SSLContext *ctx);
static SSLErr SSLEncodeRSAKeyExchange(SSLRecord *keyExchange, SSLContext *ctx);
static SSLErr SSLEncodeDHanonKeyExchange(SSLRecord *keyExchange, SSLContext *ctx);

SSLErr
SSLEncodeServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
{   SSLErr      err;
    
    switch (ctx->selectedCipherSpec->keyExchangeMethod)
    {   case SSL_RSA:
        case SSL_RSA_EXPORT:
            if (ERR(err = SSLEncodeRSAServerKeyExchange(keyExch, ctx)) != 0)
                return err;
            break;
        case SSL_DH_anon:
            if (ERR(err = SSLEncodeDHanonServerKeyExchange(keyExch, ctx)) != 0)
                return err;
            break;
        default:
            return ERR(SSLUnsupportedErr);
    }
    
    return SSLNoErr;
}

static SSLErr
SSLEncodeRSAServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
{   SSLErr          err;
    uint8           *progress;
    int             length;
    unsigned int    outputLen, localKeyModulusLen;
    uint8           hashes[36];
    SSLBuffer       exportKey,clientRandom,serverRandom,hashCtx, hash;
    
    exportKey.data = 0;
    hashCtx.data = 0;
    
    if (ERR(err = SSLEncodeRSAKeyParams(&exportKey, &ctx->exportKey, ctx)) != 0)
        goto fail;
    
#if RSAREF
    localKeyModulusLen = (ctx->localKey.bits + 7)/8;
#elif BSAFE
    {   A_RSA_KEY   *keyInfo;
        int         rsaResult;
        
        if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, ctx->localKey, KI_RSAPublic)) != 0)
            return SSLUnknownErr;
        localKeyModulusLen = keyInfo->modulus.len;
    }
#endif /* RSAREF / BSAFE */
    
    length = exportKey.length + 2 + localKeyModulusLen;     /* RSA ouputs a block as long as the modulus */
    
    keyExch->protocolVersion = SSL_Version_3_0;
    keyExch->contentType = SSL_handshake;
    if (ERR(err = SSLAllocBuffer(&keyExch->contents, length+4, &ctx->sysCtx)) != 0)
        goto fail;
    
    progress = keyExch->contents.data;
    *progress++ = SSL_server_key_exchange;
    progress = SSLEncodeInt(progress, length, 3);
    
    memcpy(progress, exportKey.data, exportKey.length);
    progress += exportKey.length;
    
    clientRandom.data = ctx->clientRandom;
    clientRandom.length = 32;
    serverRandom.data = ctx->serverRandom;
    serverRandom.length = 32;
    
    hash.data = &hashes[0];
    hash.length = 16;
    if (ERR(err = ReadyHash(&SSLHashMD5, &hashCtx, ctx)) != 0)
        goto fail;
    if (ERR(err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
        goto fail;
    if (ERR(err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
        goto fail;
    if (ERR(err = SSLHashMD5.update(hashCtx, exportKey)) != 0)
        goto fail;
    if (ERR(err = SSLHashMD5.final(hashCtx, hash)) != 0)
        goto fail;
    if (ERR(err = SSLFreeBuffer(&hashCtx, &ctx->sysCtx)) != 0)
        goto fail;
    
    hash.data = &hashes[16];
    hash.length = 20;
    if (ERR(err = ReadyHash(&SSLHashSHA1, &hashCtx, ctx)) != 0)
        goto fail;
    if (ERR(err = SSLHashSHA1.update(hashCtx, clientRandom)) != 0)
        goto fail;
    if (ERR(err = SSLHashSHA1.update(hashCtx, serverRandom)) != 0)
        goto fail;
    if (ERR(err = SSLHashSHA1.update(hashCtx, exportKey)) != 0)
        goto fail;
    if (ERR(err = SSLHashSHA1.final(hashCtx, hash)) != 0)
        goto fail;
    if (ERR(err = SSLFreeBuffer(&hashCtx, &ctx->sysCtx)) != 0)
        goto fail;
    
    progress = SSLEncodeInt(progress, localKeyModulusLen, 2);
#if RSAREF
    if (RSAPrivateEncrypt(progress, &outputLen, hashes, 36, &ctx->localKey) != 0)   /* Sign the structure */
        return ERR(SSLUnknownErr);
#elif BSAFE
    {   B_ALGORITHM_OBJ     rsa;
        B_ALGORITHM_METHOD  *chooser[] = { &AM_RSA_ENCRYPT, &AM_RSA_CRT_ENCRYPT, 0 };
        int                 rsaResult;
        unsigned int        encryptedOut;
        
        if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
            return SSLUnknownErr;
        if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPrivate, 0)) != 0)
            return SSLUnknownErr;
        if ((rsaResult = B_EncryptInit(rsa, ctx->localKey, chooser, NO_SURR)) != 0)
            return SSLUnknownErr;
        if ((rsaResult = B_EncryptUpdate(rsa, progress,
                    &encryptedOut, localKeyModulusLen, hashes, 36, 0, NO_SURR)) != 0)
            return SSLUnknownErr;
        outputLen = encryptedOut;
        if ((rsaResult = B_EncryptFinal(rsa, progress+outputLen,
                    &encryptedOut, localKeyModulusLen-outputLen, 0, NO_SURR)) != 0)
            return SSLUnknownErr;
        outputLen += encryptedOut;
        B_DestroyAlgorithmObject(&rsa);
    }
#endif /* RSAREF / BSAFE */
    ASSERT(outputLen == localKeyModulusLen);
    
    err = SSLNoErr;
    
fail:
    ERR(SSLFreeBuffer(&hashCtx, &ctx->sysCtx));
    ERR(SSLFreeBuffer(&exportKey, &ctx->sysCtx));
    
    return err;
}

static SSLErr
SSLEncodeRSAKeyParams(SSLBuffer *keyParams, SSLRSAPrivateKey *key, SSLContext *ctx)
{   SSLErr      err;
    SSLBuffer   modulus, exponent;
    uint8       *progress;
    
#if RSAREF
    keyParams->data = 0;
    modulus.length = (key->bits + 7) / 8;
    modulus.data = key->modulus + MAX_RSA_MODULUS_LEN - modulus.length;
    
    exponent.length = MAX_RSA_MODULUS_LEN;
    exponent.data = key->publicExponent;            /* Point at first byte */
    
    while (*exponent.data == 0)
    {   ++exponent.data;
        --exponent.length;
    }
#elif BSAFE
    {   A_RSA_KEY   *keyInfo;
        int         rsaResult;
        
        if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, *key, KI_RSAPublic)) != 0)
            return SSLUnknownErr;
        modulus.data = keyInfo->modulus.data;
        modulus.length = keyInfo->modulus.len;
        exponent.data = keyInfo->exponent.data;
        exponent.length = keyInfo->exponent.len;
    }   
#endif /* RSAREF / BSAFE */
    
    if (ERR(err = SSLAllocBuffer(keyParams, modulus.length + exponent.length + 4, &ctx->sysCtx)) != 0)
        return err;
    progress = keyParams->data;
    progress = SSLEncodeInt(progress, modulus.length, 2);
    memcpy(progress, modulus.data, modulus.length);
    progress += modulus.length;
    progress = SSLEncodeInt(progress, exponent.length, 2);
    memcpy(progress, exponent.data, exponent.length);
    
    return SSLNoErr;
}

static SSLErr
SSLEncodeDHanonServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
{   SSLErr              err;
    unsigned int        length;
    uint8               *progress;
    SSLRandomCtx        random;
    int                 rsaErr;
    
#if RSAREF
    length = 6 + ctx->dhAnonParams.primeLen + ctx->dhAnonParams.generatorLen +
                    ctx->dhExchangePublic.length;
    
    keyExch->protocolVersion = SSL_Version_3_0;
    keyExch->contentType = SSL_handshake;
    if (ERR(err = SSLAllocBuffer(&keyExch->contents, length+4, &ctx->sysCtx)) != 0)
        return err;
    
    progress = keyExch->contents.data;
    *progress++ = SSL_server_key_exchange;
    progress = SSLEncodeInt(progress, length, 3);
    
    progress = SSLEncodeInt(progress, ctx->dhAnonParams.primeLen, 2);
    memcpy(progress, ctx->dhAnonParams.prime, ctx->dhAnonParams.primeLen);
    progress += ctx->dhAnonParams.primeLen;
    
    progress = SSLEncodeInt(progress, ctx->dhAnonParams.generatorLen, 2);
    memcpy(progress, ctx->dhAnonParams.generator, ctx->dhAnonParams.generatorLen);
    progress += ctx->dhAnonParams.generatorLen;
    
    if (ERR(err = SSLAllocBuffer(&ctx->dhExchangePublic, ctx->peerDHParams.primeLen, &ctx->sysCtx)) != 0)
        return err;
    if (ERR(err = SSLAllocBuffer(&ctx->dhPrivate, ctx->dhExchangePublic.length - 16, &ctx->sysCtx)) != 0)
        return err;

    if (ERR(err = ReadyRandom(&random, ctx)) != 0)
        return err;
    
    if ((rsaErr = R_SetupDHAgreement(ctx->dhExchangePublic.data, ctx->dhPrivate.data,
                    ctx->dhPrivate.length, &ctx->dhAnonParams, &random)) != 0)
    {   err = SSLUnknownErr;
        return err;
    }
    
    progress = SSLEncodeInt(progress, ctx->dhExchangePublic.length, 2);
    memcpy(progress, ctx->dhExchangePublic.data, ctx->dhExchangePublic.length);
    progress += ctx->dhExchangePublic.length;
    
#elif BSAFE
    {   A_DH_KEY_AGREE_PARAMS   *params;
        unsigned int            outputLen;
        
        if ((rsaErr = B_GetAlgorithmInfo((POINTER*)&params, ctx->dhAnonParams, AI_DHKeyAgree)) != 0)
            return SSLUnknownErr;
        if (ERR(err = ReadyRandom(&random, ctx)) != 0)
            return err;
        if (ERR(err = SSLAllocBuffer(&ctx->dhExchangePublic, 128, &ctx->sysCtx)) != 0)
            return err;
        if ((rsaErr = B_KeyAgreePhase1(ctx->dhAnonParams, ctx->dhExchangePublic.data,
                            &outputLen, 128, random, NO_SURR)) != 0)
        {   err = SSLUnknownErr;
            return err;
        }
        ctx->dhExchangePublic.length = outputLen;
        
        length = 6 + params->prime.len + params->base.len + ctx->dhExchangePublic.length;
        
        keyExch->protocolVersion = SSL_Version_3_0;
        keyExch->contentType = SSL_handshake;

⌨️ 快捷键说明

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