📄 hdskkyex.c
字号:
/* *********************************************************************
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*)¶ms, 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 + -