TLS 1.2 updates for hash/sig id
This commit is contained in:
parent
09eda62f99
commit
4dd9f290e5
5
.gitignore
vendored
5
.gitignore
vendored
@ -13,6 +13,7 @@ Makefile
|
||||
depcomp
|
||||
missing
|
||||
libtool
|
||||
tags
|
||||
benchmark
|
||||
test
|
||||
client
|
||||
@ -22,3 +23,7 @@ server
|
||||
snifftest
|
||||
output
|
||||
testsuite
|
||||
diff
|
||||
*.gz
|
||||
*.zip
|
||||
*.bak
|
||||
|
@ -36,6 +36,9 @@
|
||||
#ifdef HAVE_ECC
|
||||
#include "ctc_ecc.h"
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
#include "sha256.h"
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_CALLBACKS
|
||||
#include "cyassl_callbacks.h"
|
||||
@ -333,6 +336,10 @@ enum Misc {
|
||||
NO_SNIFF = 0, /* not sniffing */
|
||||
SNIFF = 1, /* currently sniffing */
|
||||
|
||||
HASH_SIG_SIZE = 2, /* default SHA1 RSA */
|
||||
SHA1_ID = 2, /* hash id */
|
||||
RSA_ID = 1, /* sig id */
|
||||
|
||||
NO_COPY = 0, /* should we copy static buffer for write */
|
||||
COPY = 1 /* should we copy static buffer for write */
|
||||
};
|
||||
@ -949,6 +956,9 @@ struct SSL {
|
||||
RNG rng;
|
||||
Md5 hashMd5; /* md5 hash of handshake msgs */
|
||||
Sha hashSha; /* sha hash of handshake msgs */
|
||||
#ifndef NO_SHA256
|
||||
Sha256 hashSha256; /* sha256 hash of handshake msgs */
|
||||
#endif
|
||||
Hashes verifyHashes;
|
||||
Hashes certHashes; /* for cert verify */
|
||||
Signer* caList; /* SSL_CTX owns */
|
||||
|
@ -621,6 +621,9 @@ int InitSSL(SSL* ssl, SSL_CTX* ctx)
|
||||
|
||||
InitMd5(&ssl->hashMd5);
|
||||
InitSha(&ssl->hashSha);
|
||||
#ifndef NO_SHA256
|
||||
InitSha256(&ssl->hashSha256);
|
||||
#endif
|
||||
InitRsaKey(&ssl->peerRsaKey, ctx->heap);
|
||||
|
||||
ssl->peerRsaKeyPresent = 0;
|
||||
@ -904,6 +907,10 @@ static void HashOutput(SSL* ssl, const byte* output, int sz, int ivSz)
|
||||
|
||||
Md5Update(&ssl->hashMd5, buffer, sz);
|
||||
ShaUpdate(&ssl->hashSha, buffer, sz);
|
||||
#ifndef NO_SHA256
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
Sha256Update(&ssl->hashSha256, buffer, sz);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -922,6 +929,10 @@ static void HashInput(SSL* ssl, const byte* input, int sz)
|
||||
|
||||
Md5Update(&ssl->hashMd5, buffer, sz);
|
||||
ShaUpdate(&ssl->hashSha, buffer, sz);
|
||||
#ifndef NO_SHA256
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
Sha256Update(&ssl->hashSha256, buffer, sz);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -1322,6 +1333,11 @@ static void BuildFinished(SSL* ssl, Hashes* hashes, const byte* sender)
|
||||
/* store current states, building requires get_digest which resets state */
|
||||
Md5 md5 = ssl->hashMd5;
|
||||
Sha sha = ssl->hashSha;
|
||||
#ifndef NO_SHA256
|
||||
Sha256 sha256;
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
sha256 = ssl->hashSha256;
|
||||
#endif
|
||||
|
||||
if (ssl->options.tls)
|
||||
BuildTlsFinished(ssl, hashes, sender);
|
||||
@ -1333,6 +1349,10 @@ static void BuildFinished(SSL* ssl, Hashes* hashes, const byte* sender)
|
||||
/* restore */
|
||||
ssl->hashMd5 = md5;
|
||||
ssl->hashSha = sha;
|
||||
#ifndef NO_SHA256
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
ssl->hashSha256 = sha256;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -2311,6 +2331,11 @@ static void BuildCertHashes(SSL* ssl, Hashes* hashes)
|
||||
/* store current states, building requires get_digest which resets state */
|
||||
Md5 md5 = ssl->hashMd5;
|
||||
Sha sha = ssl->hashSha;
|
||||
#ifndef NO_SHA256 /* for possible future changes */
|
||||
Sha256 sha256;
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
sha256 = ssl->hashSha256;
|
||||
#endif
|
||||
|
||||
if (ssl->options.tls) {
|
||||
Md5Final(&ssl->hashMd5, hashes->md5);
|
||||
@ -2324,6 +2349,10 @@ static void BuildCertHashes(SSL* ssl, Hashes* hashes)
|
||||
/* restore */
|
||||
ssl->hashMd5 = md5;
|
||||
ssl->hashSha = sha;
|
||||
#ifndef NO_SHA256
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
ssl->hashSha256 = sha256;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -2528,6 +2557,9 @@ int SendCertificateRequest(SSL* ssl)
|
||||
int typeTotal = 1; /* only rsa for now */
|
||||
int reqSz = ENUM_LEN + typeTotal + REQ_HEADER_SZ; /* add auth later */
|
||||
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
reqSz += LENGTH_SZ + HASH_SIG_SIZE;
|
||||
|
||||
if (ssl->options.usingPSK_cipher) return 0; /* not needed */
|
||||
|
||||
sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + reqSz;
|
||||
@ -2551,6 +2583,15 @@ int SendCertificateRequest(SSL* ssl)
|
||||
output[i++] = typeTotal; /* # of types */
|
||||
output[i++] = rsa_sign;
|
||||
|
||||
/* supported hash/sig */
|
||||
if (IsAtLeastTLSv1_2(ssl)) {
|
||||
c16toa(HASH_SIG_SIZE, &output[i]);
|
||||
i += LENGTH_SZ;
|
||||
|
||||
output[i++] = SHA1_ID; /* hash */
|
||||
output[i++] = RSA_ID; /* sig */
|
||||
}
|
||||
|
||||
c16toa(0, &output[i]); /* auth's */
|
||||
i += REQ_HEADER_SZ;
|
||||
|
||||
@ -3573,14 +3614,15 @@ int SetCipherList(SSL_CTX* ctx, const char* list)
|
||||
if (XMEMCMP(ssl->arrays.sessionID, ssl->session.sessionID, ID_LEN)
|
||||
== 0) {
|
||||
if (SetCipherSpecs(ssl) == 0) {
|
||||
int ret;
|
||||
XMEMCPY(ssl->arrays.masterSecret, ssl->session.masterSecret,
|
||||
SECRET_LEN);
|
||||
if (ssl->options.tls)
|
||||
DeriveTlsKeys(ssl);
|
||||
ret = DeriveTlsKeys(ssl);
|
||||
else
|
||||
DeriveKeys(ssl);
|
||||
ret = DeriveKeys(ssl);
|
||||
ssl->options.serverState = SERVER_HELLODONE_COMPLETE;
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
return UNSUPPORTED_SUITE;
|
||||
@ -3612,6 +3654,13 @@ int SetCipherList(SSL_CTX* ctx, const char* list)
|
||||
ato16(&input[*inOutIdx], &len);
|
||||
*inOutIdx += LENGTH_SZ;
|
||||
|
||||
if (IsAtLeastTLSv1_2(ssl)) {
|
||||
/* hash sig format */
|
||||
*inOutIdx += len;
|
||||
ato16(&input[*inOutIdx], &len);
|
||||
*inOutIdx += LENGTH_SZ;
|
||||
}
|
||||
|
||||
/* authorities */
|
||||
while (len) {
|
||||
word16 dnSz;
|
||||
@ -3755,6 +3804,11 @@ int SetCipherList(SSL_CTX* ctx, const char* list)
|
||||
return BUFFER_ERROR;
|
||||
XMEMCPY(messageVerify, &input[*inOutIdx - verifySz], verifySz);
|
||||
|
||||
if (IsAtLeastTLSv1_2(ssl)) {
|
||||
/* just advance for now TODO: validate hash algo params */
|
||||
*inOutIdx += LENGTH_SZ;
|
||||
}
|
||||
|
||||
/* signature */
|
||||
ato16(&input[*inOutIdx], &length);
|
||||
*inOutIdx += LENGTH_SZ;
|
||||
@ -4071,14 +4125,20 @@ int SetCipherList(SSL_CTX* ctx, const char* list)
|
||||
HANDSHAKE_HEADER_SZ];
|
||||
byte* signBuffer = ssl->certHashes.md5;
|
||||
word32 signSz = sizeof(Hashes);
|
||||
byte encodedSig[MAX_ENCODED_SIG_SZ];
|
||||
byte encodedSig[MAX_ENCODED_SIG_SZ];
|
||||
word32 extraSz = 0; /* tls 1.2 hash/sig */
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls)
|
||||
verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
|
||||
#endif
|
||||
length = RsaEncryptSize(&key);
|
||||
c16toa((word16)length, verify); /* prepend verify header */
|
||||
if (IsAtLeastTLSv1_2(ssl)) {
|
||||
verify[0] = SHA1_ID;
|
||||
verify[1] = RSA_ID;
|
||||
extraSz = HASH_SIG_SIZE;
|
||||
}
|
||||
c16toa((word16)length, verify + extraSz); /* prepend verify header*/
|
||||
|
||||
if (IsAtLeastTLSv1_2(ssl)) {
|
||||
byte* digest;
|
||||
@ -4094,17 +4154,17 @@ int SetCipherList(SSL_CTX* ctx, const char* list)
|
||||
signBuffer = encodedSig;
|
||||
}
|
||||
|
||||
ret = RsaSSL_Sign(signBuffer, signSz, verify +
|
||||
ret = RsaSSL_Sign(signBuffer, signSz, verify + extraSz +
|
||||
VERIFY_HEADER, ENCRYPT_LEN, &key, &ssl->rng);
|
||||
|
||||
if (ret > 0) {
|
||||
ret = 0; /* reset */
|
||||
|
||||
AddHeaders(output, length + VERIFY_HEADER, certificate_verify,
|
||||
ssl);
|
||||
AddHeaders(output, length + extraSz + VERIFY_HEADER,
|
||||
certificate_verify, ssl);
|
||||
|
||||
sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + length +
|
||||
VERIFY_HEADER;
|
||||
extraSz + VERIFY_HEADER;
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls)
|
||||
sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
|
||||
@ -4514,6 +4574,10 @@ int SetCipherList(SSL_CTX* ctx, const char* list)
|
||||
/* manually hash input since different format */
|
||||
Md5Update(&ssl->hashMd5, input + idx, sz);
|
||||
ShaUpdate(&ssl->hashSha, input + idx, sz);
|
||||
#ifndef NO_SHA256
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
Sha256Update(&ssl->hashSha256, input + idx, sz);
|
||||
#endif
|
||||
|
||||
/* does this value mean client_hello? */
|
||||
idx++;
|
||||
@ -4589,6 +4653,7 @@ int SetCipherList(SSL_CTX* ctx, const char* list)
|
||||
|
||||
/* DoClientHello uses same resume code */
|
||||
while (ssl->options.resuming) { /* let's try */
|
||||
int ret;
|
||||
SSL_SESSION* session = GetSession(ssl, ssl->arrays.masterSecret);
|
||||
if (!session) {
|
||||
ssl->options.resuming = 0;
|
||||
@ -4599,12 +4664,12 @@ int SetCipherList(SSL_CTX* ctx, const char* list)
|
||||
|
||||
RNG_GenerateBlock(&ssl->rng, ssl->arrays.serverRandom, RAN_LEN);
|
||||
if (ssl->options.tls)
|
||||
DeriveTlsKeys(ssl);
|
||||
ret = DeriveTlsKeys(ssl);
|
||||
else
|
||||
DeriveKeys(ssl);
|
||||
ret = DeriveKeys(ssl);
|
||||
ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return MatchSuite(ssl, &clSuites);
|
||||
@ -4719,6 +4784,7 @@ int SetCipherList(SSL_CTX* ctx, const char* list)
|
||||
|
||||
/* ProcessOld uses same resume code */
|
||||
while (ssl->options.resuming) { /* let's try */
|
||||
int ret;
|
||||
SSL_SESSION* session = GetSession(ssl, ssl->arrays.masterSecret);
|
||||
if (!session) {
|
||||
ssl->options.resuming = 0;
|
||||
@ -4729,12 +4795,12 @@ int SetCipherList(SSL_CTX* ctx, const char* list)
|
||||
|
||||
RNG_GenerateBlock(&ssl->rng, ssl->arrays.serverRandom, RAN_LEN);
|
||||
if (ssl->options.tls)
|
||||
DeriveTlsKeys(ssl);
|
||||
ret = DeriveTlsKeys(ssl);
|
||||
else
|
||||
DeriveKeys(ssl);
|
||||
ret = DeriveKeys(ssl);
|
||||
ssl->options.clientState = CLIENT_KEYEXCHANGE_COMPLETE;
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
return MatchSuite(ssl, &clSuites);
|
||||
}
|
||||
@ -4759,6 +4825,8 @@ int SetCipherList(SSL_CTX* ctx, const char* list)
|
||||
if ( (i + VERIFY_HEADER) > totalSz)
|
||||
return INCOMPLETE_DATA;
|
||||
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
i += HASH_SIG_SIZE;
|
||||
ato16(&input[i], &sz);
|
||||
i += VERIFY_HEADER;
|
||||
|
||||
|
@ -431,7 +431,7 @@ int SetCipherSpecs(SSL* ssl)
|
||||
#ifndef NO_TLS
|
||||
ssl->options.tls = 1;
|
||||
ssl->hmac = TLS_hmac;
|
||||
if (ssl->version.minor == 2)
|
||||
if (ssl->version.minor >= 2)
|
||||
ssl->options.tls1_1 = 1;
|
||||
#endif
|
||||
}
|
||||
@ -678,7 +678,7 @@ int MakeMasterSecret(SSL* ssl)
|
||||
byte shaOutput[SHA_DIGEST_SIZE];
|
||||
byte md5Input[ENCRYPT_LEN + SHA_DIGEST_SIZE];
|
||||
byte shaInput[PREFIX + ENCRYPT_LEN + 2 * RAN_LEN];
|
||||
int i;
|
||||
int i, ret;
|
||||
word32 idx;
|
||||
word32 pmsSz = ssl->arrays.preMasterSz;
|
||||
|
||||
@ -740,10 +740,10 @@ int MakeMasterSecret(SSL* ssl)
|
||||
}
|
||||
#endif
|
||||
|
||||
DeriveKeys(ssl);
|
||||
ret = DeriveKeys(ssl);
|
||||
CleanPreMaster(ssl);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -999,6 +999,10 @@ int SSL_CTX_set_cipher_list(SSL_CTX* ctx, const char* list)
|
||||
/* re-init hashes, exclude first hello and verify request */
|
||||
InitMd5(&ssl->hashMd5);
|
||||
InitSha(&ssl->hashSha);
|
||||
#ifndef NO_SHA256
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
InitSha256(&ssl->hashSha256);
|
||||
#endif
|
||||
if ( (ssl->error = SendClientHello(ssl)) != 0) {
|
||||
CYASSL_ERROR(ssl->error);
|
||||
return SSL_FATAL_ERROR;
|
||||
@ -1196,6 +1200,10 @@ int SSL_CTX_set_cipher_list(SSL_CTX* ctx, const char* list)
|
||||
/* re-init hashes, exclude first hello and verify request */
|
||||
InitMd5(&ssl->hashMd5);
|
||||
InitSha(&ssl->hashSha);
|
||||
#ifndef NO_SHA256
|
||||
if (IsAtLeastTLSv1_2(ssl))
|
||||
InitSha256(&ssl->hashSha256);
|
||||
#endif
|
||||
|
||||
while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
|
||||
if ( (ssl->error = ProcessReply(ssl)) < 0) {
|
||||
|
12
src/tls.c
12
src/tls.c
@ -136,10 +136,17 @@ static void PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen,
|
||||
void BuildTlsFinished(SSL* ssl, Hashes* hashes, const byte* sender)
|
||||
{
|
||||
const byte* side;
|
||||
byte handshake_hash[FINISHED_SZ];
|
||||
byte handshake_hash[FINISHED_SZ];
|
||||
word32 hashSz = FINISHED_SZ;
|
||||
|
||||
Md5Final(&ssl->hashMd5, handshake_hash);
|
||||
ShaFinal(&ssl->hashSha, &handshake_hash[MD5_DIGEST_SIZE]);
|
||||
#ifndef NO_SHA256
|
||||
if (IsAtLeastTLSv1_2(ssl)) {
|
||||
Sha256Final(&ssl->hashSha256, handshake_hash);
|
||||
hashSz = SHA256_DIGEST_SIZE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0)
|
||||
side = tls_client;
|
||||
@ -147,8 +154,7 @@ void BuildTlsFinished(SSL* ssl, Hashes* hashes, const byte* sender)
|
||||
side = tls_server;
|
||||
|
||||
PRF(hashes->md5, TLS_FINISHED_SZ, ssl->arrays.masterSecret, SECRET_LEN,
|
||||
side, FINISHED_LABEL_SZ, handshake_hash, FINISHED_SZ,
|
||||
IsAtLeastTLSv1_2(ssl));
|
||||
side, FINISHED_LABEL_SZ, handshake_hash, hashSz, IsAtLeastTLSv1_2(ssl));
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user