Fix for handling of static RSA PKCS formatting failures so they are indistinguishable from from correctly formatted RSA blocks (per RFC5246 section 7.4.7.1). Adjusted the static RSA preMasterSecret RNG creation for consistency in client case. Removed obsolete PMS_VERSION_ERROR.

This commit is contained in:
David Garske 2017-11-14 14:05:50 -08:00
parent cc65429946
commit fd455d5a5e
2 changed files with 62 additions and 12 deletions

View File

@ -14200,9 +14200,6 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
case NOT_READY_ERROR :
return "handshake layer not ready yet, complete first";
case PMS_VERSION_ERROR :
return "premaster secret version mismatch error";
case VERSION_ERROR :
return "record layer version error";
@ -18770,8 +18767,10 @@ int SendClientKeyExchange(WOLFSSL* ssl)
#ifndef NO_RSA
case rsa_kea:
{
/* build PreMasterSecret with RNG data */
ret = wc_RNG_GenerateBlock(ssl->rng,
ssl->arrays->preMasterSecret, SECRET_LEN);
&ssl->arrays->preMasterSecret[VERSION_SZ],
SECRET_LEN - VERSION_SZ);
if (ret != 0) {
goto exit_scke;
}
@ -23569,6 +23568,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
word32 idx;
word32 begin;
word32 sigSz;
#ifndef NO_RSA
int lastErr;
#endif
} DckeArgs;
static void FreeDckeArgs(WOLFSSL* ssl, void* pArgs)
@ -23794,6 +23796,14 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ERROR_OUT(BUFFER_ERROR, exit_dcke);
}
/* pre-load PreMasterSecret with RNG data */
ret = wc_RNG_GenerateBlock(ssl->rng,
&ssl->arrays->preMasterSecret[VERSION_SZ],
SECRET_LEN - VERSION_SZ);
if (ret != 0) {
goto exit_dcke;
}
args->output = NULL;
break;
} /* rsa_kea */
@ -24258,6 +24268,20 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
NULL, 0, NULL
#endif
);
/* Errors that can occur here that should be
* indistinguishable:
* RSA_BUFFER_E, RSA_PAD_E and RSA_PRIVATE_ERROR
*/
if (ret < 0 && ret != BAD_FUNC_ARG) {
#ifdef WOLFSSL_ASYNC_CRYPT
if (ret == WC_PENDING_E)
goto exit_dcke;
#endif
/* store error code for handling below */
args->lastErr = ret;
ret = 0;
}
break;
} /* rsa_kea */
#endif /* !NO_RSA */
@ -24404,16 +24428,42 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* Add the signature length to idx */
args->idx += args->length;
if (args->sigSz == SECRET_LEN && args->output != NULL) {
XMEMCPY(ssl->arrays->preMasterSecret, args->output, SECRET_LEN);
if (ssl->arrays->preMasterSecret[0] != ssl->chVersion.major ||
ssl->arrays->preMasterSecret[1] != ssl->chVersion.minor) {
ERROR_OUT(PMS_VERSION_ERROR, exit_dcke);
#ifdef DEBUG_WOLFSSL
/* check version (debug warning message only) */
if (args->output != NULL) {
if (args->output[0] != ssl->chVersion.major ||
args->output[1] != ssl->chVersion.minor) {
WOLFSSL_MSG("preMasterSecret version mismatch");
}
}
else {
ERROR_OUT(RSA_PRIVATE_ERROR, exit_dcke);
#endif
/* RFC5246 7.4.7.1:
* Treat incorrectly formatted message blocks and/or
* mismatched version numbers in a manner
* indistinguishable from correctly formatted RSA blocks
*/
ret = args->lastErr;
args->lastErr = 0; /* reset */
/* build PreMasterSecret */
ssl->arrays->preMasterSecret[0] = ssl->chVersion.major;
ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor;
if (ret == 0 && args->sigSz == SECRET_LEN &&
args->output != NULL) {
XMEMCPY(&ssl->arrays->preMasterSecret[VERSION_SZ],
&args->output[VERSION_SZ],
SECRET_LEN - VERSION_SZ);
}
else {
/* preMasterSecret has RNG and version set */
/* return proper length and ignore error */
/* error will be caught as decryption error */
args->sigSz = SECRET_LEN;
ret = 0;
}
break;
} /* rsa_kea */
#endif /* !NO_RSA */

View File

@ -57,7 +57,7 @@ enum wolfSSL_ErrorCodes {
DOMAIN_NAME_MISMATCH = -322, /* peer subject name mismatch */
WANT_READ = -323, /* want read, call again */
NOT_READY_ERROR = -324, /* handshake layer not ready */
PMS_VERSION_ERROR = -325, /* pre m secret version error */
VERSION_ERROR = -326, /* record layer version error */
WANT_WRITE = -327, /* want write, call again */
BUFFER_ERROR = -328, /* malformed buffer input */