📄 ssl2mesg.c
字号:
memcpy(ctx->masterSecret + clearLength, secretData.data, secretLength);
if (ERR(err = SSLFreeBuffer(&secretData, &ctx->sysCtx)) != 0)
return err;
if (keyArgLength != ctx->selectedCipherSpec->cipher->ivSize)
return ERR(SSLProtocolErr);
/* Stash the IV after the master key in master secret storage */
memcpy(ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize, progress, keyArgLength);
progress += keyArgLength;
ASSERT(progress = msg.data + msg.length);
return SSLNoErr;
}
SSLErr
SSL2EncodeClientMasterKey(SSLBuffer *msg, SSLContext *ctx)
{ SSLErr err;
int length, i, clearLen, rsaResult;
unsigned int outputLen, peerKeyModulusLen;
SSLBuffer keyData;
uint8 *progress;
SSLRandomCtx rsaRandom;
#if RSAREF
peerKeyModulusLen = (ctx->peerKey.bits + 7)/8;
#elif BSAFE
{ A_RSA_KEY *keyInfo;
int rsaResult;
if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, ctx->peerKey, KI_RSAPublic)) != 0)
return SSLUnknownErr;
peerKeyModulusLen = keyInfo->modulus.len;
}
#endif /* RSAREF / BSAFE */
/* Length is 10 + clear key size + encrypted output size + iv size */
length = 10;
clearLen = ctx->selectedCipherSpec->cipher->keySize - ctx->selectedCipherSpec->cipher->secretKeySize;
length += clearLen;
length += peerKeyModulusLen;
length += ctx->selectedCipherSpec->cipher->ivSize;
if (ERR(err = SSLAllocBuffer(msg, length, &ctx->sysCtx)) != 0)
return err;
progress = msg->data;
*progress++ = ssl2_mt_client_master_key;
for (i = 0; i < SSL2CipherMapCount; i++)
if (ctx->selectedCipher == SSL2CipherMap[i].cipherSuite)
break;
ASSERT(i < SSL2CipherMapCount);
progress = SSLEncodeInt(progress, SSL2CipherMap[i].cipherKind, 3);
progress = SSLEncodeInt(progress, clearLen, 2);
progress = SSLEncodeInt(progress, peerKeyModulusLen, 2);
progress = SSLEncodeInt(progress, ctx->selectedCipherSpec->cipher->ivSize, 2);
/* Generate the keying material; we need enough data for the key and IV */
keyData.data = ctx->masterSecret;
keyData.length = ctx->selectedCipherSpec->cipher->keySize + ctx->selectedCipherSpec->cipher->ivSize;
ASSERT(keyData.length <= 48); /* Must be able to store it in the masterSecret array */
if (ERR(err = ctx->sysCtx.random(keyData, ctx->sysCtx.randomRef)) != 0)
return err;
memcpy(progress, ctx->masterSecret, clearLen);
progress += clearLen;
if (ERR(err = ReadyRandom(&rsaRandom, ctx)) != 0)
return err;
/* Replace this with code to do encryption at lower level & set PKCS1 padding
for rollback attack */
#if RSAREF
if ((rsaResult = RSAPublicEncrypt(progress, &outputLen,
ctx->masterSecret + clearLen,
ctx->selectedCipherSpec->cipher->keySize - clearLen,
&ctx->peerKey,&rsaRandom)) != 0)
{ R_RandomFinal(&rsaRandom);
return ERR(SSLUnknownErr);
}
#elif BSAFE
{ B_ALGORITHM_OBJ rsa;
B_ALGORITHM_METHOD *chooser[] = { &AM_RSA_ENCRYPT, 0 };
unsigned int encryptedOut;
if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
return SSLUnknownErr;
if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPublic, 0)) != 0)
return SSLUnknownErr;
if ((rsaResult = B_EncryptInit(rsa, ctx->peerKey, chooser, NO_SURR)) != 0)
return SSLUnknownErr;
if ((rsaResult = B_EncryptUpdate(rsa, progress,
&encryptedOut, peerKeyModulusLen, ctx->masterSecret + clearLen,
ctx->selectedCipherSpec->cipher->keySize - clearLen,
rsaRandom, NO_SURR)) != 0)
return SSLUnknownErr;
outputLen = encryptedOut;
if ((rsaResult = B_EncryptFinal(rsa, progress+outputLen,
&encryptedOut, peerKeyModulusLen-outputLen, rsaRandom, NO_SURR)) != 0)
return SSLUnknownErr;
outputLen += encryptedOut;
B_DestroyAlgorithmObject(&rsa);
}
#endif
progress += outputLen;
#if RSAREF
R_RandomFinal(&rsaRandom);
#elif BSAFE
B_DestroyAlgorithmObject(&rsaRandom);
#endif
memcpy(progress, ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize,
ctx->selectedCipherSpec->cipher->ivSize);
progress += ctx->selectedCipherSpec->cipher->ivSize;
ASSERT(progress == msg->data + msg->length);
return SSLNoErr;
}
SSLErr
SSL2ProcessClientFinished(SSLBuffer msg, SSLContext *ctx)
{ if (msg.length != ctx->sessionID.length)
return ERR(SSLProtocolErr);
if (memcmp(msg.data, ctx->serverRandom, ctx->ssl2ConnectionIDLength) != 0)
return ERR(SSLProtocolErr);
return SSLNoErr;
}
SSLErr
SSL2EncodeClientFinished(SSLBuffer *msg, SSLContext *ctx)
{ SSLErr err;
if (ERR(err = SSLAllocBuffer(msg, ctx->ssl2ConnectionIDLength+1, &ctx->sysCtx)) != 0)
return err;
msg->data[0] = ssl2_mt_client_finished;
memcpy(msg->data+1, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
return SSLNoErr;
}
SSLErr
SSL2ProcessServerHello(SSLBuffer msg, SSLContext *ctx)
{ SSLErr err;
SSL2CertTypeCode certType;
int sessionIDMatch, certLen, cipherSpecsLen, connectionIDLen;
int i, j;
SSL2CipherKind cipherKind;
SSLBuffer certBuf;
SSLCertificate *cert;
CipherSuite matchingCipher, selectedCipher;
uint8 *progress;
SSLProtocolVersion version;
if (msg.length < 10)
return ERR(SSLProtocolErr);
progress = msg.data;
sessionIDMatch = *progress++;
certType = (SSL2CertTypeCode)*progress++;
version = (SSLProtocolVersion)SSLDecodeInt(progress, 2);
progress += 2;
if (version != SSL_Version_2_0)
return ERR(SSLProtocolErr);
ctx->protocolVersion = version;
certLen = SSLDecodeInt(progress, 2);
progress += 2;
cipherSpecsLen = SSLDecodeInt(progress, 2);
progress += 2;
connectionIDLen = SSLDecodeInt(progress, 2);
progress += 2;
if (connectionIDLen < 16 || connectionIDLen > 32 || cipherSpecsLen % 3 != 0 ||
(msg.length != 10 + certLen + cipherSpecsLen + connectionIDLen) )
return ERR(SSLProtocolErr);
if (sessionIDMatch != 0)
{ if (certLen != 0 || cipherSpecsLen != 0 /* || certType != 0 */ )
return ERR(SSLProtocolErr);
ctx->ssl2SessionMatch = 1;
ctx->ssl2ConnectionIDLength = connectionIDLen;
memcpy(ctx->serverRandom, progress, connectionIDLen);
progress += connectionIDLen;
}
else
{ if (certType != ssl2_ct_x509_certificate)
return ERR(SSLNegotiationErr);
cipherSpecsLen /= 3;
if (ERR(err = SSLAllocBuffer(&certBuf, sizeof(SSLCertificate), &ctx->sysCtx)) != 0)
return err;
cert = (SSLCertificate*)certBuf.data;
cert->next = 0;
if (ERR(err = SSLAllocBuffer(&cert->derCert, certLen, &ctx->sysCtx)) != 0)
{ ERR(SSLFreeBuffer(&certBuf, &ctx->sysCtx));
return err;
}
memcpy(cert->derCert.data, progress, certLen);
progress += certLen;
if (ERR(err = ASNParseX509Certificate(cert->derCert, &cert->cert, ctx)) != 0)
{ ERR(SSLFreeBuffer(&cert->derCert, &ctx->sysCtx));
ERR(SSLFreeBuffer(&certBuf, &ctx->sysCtx));
return err;
}
ctx->peerCert = cert;
if (ERR(err = X509ExtractPublicKey(&cert->cert.pubKey, &ctx->peerKey)) != 0)
return err;
selectedCipher = SSL_NO_SUCH_CIPHERSUITE;
for (i = 0; i < cipherSpecsLen; i++)
{ cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
progress += 3;
if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE) /* After we find one, just keep advancing progress past the unused ones */
{ for (j = 0; j < SSL2CipherMapCount; j++)
if (cipherKind == SSL2CipherMap[j].cipherKind)
{ matchingCipher = SSL2CipherMap[j].cipherSuite;
break;
}
for (j = 0; j < CipherSpecCount; j++)
if (KnownCipherSpecs[j].cipherSpec == matchingCipher)
{ selectedCipher = matchingCipher;
break;
}
}
}
if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE)
return ERR(SSLNegotiationErr);
ctx->selectedCipher = selectedCipher;
if (ERR(err = FindCipherSpec(ctx->selectedCipher, &ctx->selectedCipherSpec)) != 0)
return err;
ctx->ssl2ConnectionIDLength = connectionIDLen;
memcpy(ctx->serverRandom, progress, connectionIDLen);
progress += connectionIDLen;
}
ASSERT(progress == msg.data + msg.length);
return SSLNoErr;
}
SSLErr
SSL2EncodeServerHello(SSLBuffer *msg, SSLContext *ctx)
{ SSLErr err;
SSLCertificate *cert;
SSLBuffer randomData;
uint8 *progress;
int i;
/* Create the connection ID */
ctx->ssl2ConnectionIDLength = SSL2_CONNECTION_ID_LENGTH;
randomData.data = ctx->serverRandom;
randomData.length = ctx->ssl2ConnectionIDLength;
if (ERR(err = ctx->sysCtx.random(randomData, ctx->sysCtx.randomRef)) != 0)
return err;
if (ctx->ssl2SessionMatch != 0)
{ if (ERR(err = SSLAllocBuffer(msg, 11 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
return err;
progress = msg->data;
*progress++ = ssl2_mt_server_hello;
*progress++ = ctx->ssl2SessionMatch;
*progress++ = 0; /* cert type */
progress = SSLEncodeInt(progress, ctx->protocolVersion, 2);
progress = SSLEncodeInt(progress, 0, 2); /* cert len */
progress = SSLEncodeInt(progress, 0, 2); /* cipherspecs len */
progress = SSLEncodeInt(progress, ctx->ssl2ConnectionIDLength, 2);
memcpy(progress, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
progress += ctx->ssl2ConnectionIDLength;
}
else
{ /* First, find the last cert in the chain; it's the one we'll send */
ASSERT(ctx->localCert != 0);
cert = ctx->localCert;
while (cert->next != 0)
cert = cert->next;
if (ERR(err = SSLAllocBuffer(msg, 11 + cert->derCert.length + 3 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
return err;
progress = msg->data;
*progress++ = ssl2_mt_server_hello;
*progress++ = ctx->ssl2SessionMatch;
*progress++ = ssl2_ct_x509_certificate; /* cert type */
progress = SSLEncodeInt(progress, ctx->protocolVersion, 2);
progress = SSLEncodeInt(progress, cert->derCert.length, 2);
progress = SSLEncodeInt(progress, 3, 2); /* cipherspecs len */
progress = SSLEncodeInt(progress, ctx->ssl2ConnectionIDLength, 2);
memcpy(progress, cert->derCert.data, cert->derCert.length);
progress += cert->derCert.length;
for (i = 0; i < SSL2CipherMapCount; i++)
if (ctx->selectedCipher == SSL2CipherMap[i].cipherSuite)
break;
ASSERT(i < SSL2CipherMapCount);
progress = SSLEncodeInt(progress, SSL2CipherMap[i].cipherKind, 3);
memcpy(progress, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
progress += ctx->ssl2ConnectionIDLength;
}
ASSERT(progress == msg->data + msg->length);
return SSLNoErr;
}
SSLErr
SSL2ProcessServerVerify(SSLBuffer msg, SSLContext *ctx)
{ if (msg.length != ctx->ssl2ChallengeLength)
return ERR(SSLProtocolErr);
if (memcmp(msg.data, ctx->clientRandom + 32 - ctx->ssl2ChallengeLength,
ctx->ssl2ChallengeLength) != 0)
return ERR(SSLProtocolErr);
return SSLNoErr;
}
SSLErr
SSL2EncodeServerVerify(SSLBuffer *msg, SSLContext *ctx)
{ SSLErr err;
if (ERR(err = SSLAllocBuffer(msg, 1 + ctx->ssl2ChallengeLength, &ctx->sysCtx)) != 0)
return err;
msg->data[0] = ssl2_mt_server_verify;
memcpy(msg->data+1, ctx->clientRandom + 32 - ctx->ssl2ChallengeLength,
ctx->ssl2ChallengeLength);
return SSLNoErr;
}
SSLErr
SSL2ProcessServerFinished(SSLBuffer msg, SSLContext *ctx)
{ SSLErr err;
if (ERR(err = SSLAllocBuffer(&ctx->sessionID, msg.length, &ctx->sysCtx)) != 0)
return err;
memcpy(ctx->sessionID.data, msg.data, msg.length);
return SSLNoErr;
}
SSLErr
SSL2EncodeServerFinished(SSLBuffer *msg, SSLContext *ctx)
{ SSLErr err;
if (ERR(err = SSLAllocBuffer(msg, 1 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
return err;
msg->data[0] = ssl2_mt_server_finished;
memcpy(msg->data+1, ctx->sessionID.data, ctx->sessionID.length);
return SSLNoErr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -