Merge pull request #440 from toddouska/output-size

Output size
This commit is contained in:
Chris Conlon 2016-06-10 11:33:31 -06:00 committed by GitHub
commit cbefaef6bc
5 changed files with 99 additions and 20 deletions

View File

@ -88,9 +88,6 @@ WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS
#error Cannot use both secure-renegotiation and renegotiation-indication
#endif
static int BuildMessage(WOLFSSL* ssl, byte* output, int outSz,
const byte* input, int inSz, int type, int hashOutput);
#ifndef NO_WOLFSSL_CLIENT
static int DoHelloVerifyRequest(WOLFSSL* ssl, const byte* input, word32*,
word32);
@ -3815,7 +3812,7 @@ int DtlsPoolSend(WOLFSSL* ssl)
output = ssl->buffers.outputBuffer.buffer +
ssl->buffers.outputBuffer.length;
sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
handshake, 0);
handshake, 0, 0);
if (sendSz < 0)
return BUILD_MSG_ERROR;
@ -9282,7 +9279,7 @@ int SendChangeCipher(WOLFSSL* ssl)
input[0] = 1; /* turn it on */
sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
change_cipher_spec, 0);
change_cipher_spec, 0, 0);
if (sendSz < 0)
return sendSz;
}
@ -9511,8 +9508,8 @@ static int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes)
#endif /* WOLFSSL_LEANPSK */
/* Build SSL Message, encrypted */
static int BuildMessage(WOLFSSL* ssl, byte* output, int outSz,
const byte* input, int inSz, int type, int hashOutput)
int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
int inSz, int type, int hashOutput, int sizeOnly)
{
#ifdef HAVE_TRUNCATED_HMAC
word32 digestSz = min(ssl->specs.hash_size,
@ -9530,10 +9527,21 @@ static int BuildMessage(WOLFSSL* ssl, byte* output, int outSz,
int ret = 0;
int atomicUser = 0;
if (ssl == NULL || output == NULL || input == NULL) {
if (ssl == NULL) {
return BAD_FUNC_ARG;
}
if (!sizeOnly && (output == NULL || input == NULL) ) {
return BAD_FUNC_ARG;
}
/* catch mistaken sizeOnly parameter */
if (sizeOnly && (output || input) ) {
WOLFSSL_MSG("BuildMessage with sizeOnly doesn't need input or output");
return BAD_FUNC_ARG;
}
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
sz += DTLS_RECORD_EXTRA;
@ -9556,9 +9564,11 @@ static int BuildMessage(WOLFSSL* ssl, byte* output, int outSz,
if (ivSz > (word32)sizeof(iv))
return BUFFER_E;
if (!sizeOnly) {
ret = wc_RNG_GenerateBlock(ssl->rng, iv, ivSz);
if (ret != 0)
return ret;
}
}
sz += 1; /* pad byte */
@ -9573,9 +9583,15 @@ static int BuildMessage(WOLFSSL* ssl, byte* output, int outSz,
ivSz = AESGCM_EXP_IV_SZ;
sz += (ivSz + ssl->specs.aead_mac_size - digestSz);
if (!sizeOnly) {
XMEMCPY(iv, ssl->keys.aead_exp_IV, AESGCM_EXP_IV_SZ);
}
}
#endif
/* done with size calculations */
if (sizeOnly) {
return sz;
}
if (sz > (word32)outSz) {
WOLFSSL_MSG("Oops, want to write past output buffer size");
return BUFFER_E;
@ -9715,7 +9731,7 @@ int SendFinished(WOLFSSL* ssl)
#endif
sendSz = BuildMessage(ssl, output, outputSz, input, headerSz + finishedSz,
handshake, 1);
handshake, 1, 0);
if (sendSz < 0)
return BUILD_MSG_ERROR;
@ -9945,7 +9961,8 @@ int SendCertificate(WOLFSSL* ssl)
XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
}
sendSz = BuildMessage(ssl, output,sendSz,input,inputSz,handshake,1);
sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
handshake, 1, 0);
XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (sendSz < 0)
@ -10137,7 +10154,7 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status,
XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
handshake, 1);
handshake, 1, 0);
XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (sendSz < 0)
@ -10582,7 +10599,7 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
}
#endif
sendSz = BuildMessage(ssl, out, outputSz, sendBuffer, buffSz,
application_data, 0);
application_data, 0, 0);
if (sendSz < 0)
return BUILD_MSG_ERROR;
@ -10733,7 +10750,8 @@ int SendAlert(WOLFSSL* ssl, int severity, int type)
/* only send encrypted alert if handshake actually complete, otherwise
other side may not be able to handle it */
if (IsEncryptionOn(ssl, 1) && ssl->options.handShakeDone)
sendSz = BuildMessage(ssl, output, outputSz, input, ALERT_SIZE,alert,0);
sendSz = BuildMessage(ssl, output, outputSz, input, ALERT_SIZE,
alert, 0, 0);
else {
AddRecordHeader(output, ALERT_SIZE, alert, ssl);
@ -11120,6 +11138,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
case DTLS_EXPORT_VER_E:
return "Version needs updated after code change or version mismatch";
case INPUT_SIZE_E:
return "Input size too large Error";
default :
return "unknown error number";
}
@ -12506,7 +12527,8 @@ static void PickHashSigAlgo(WOLFSSL* ssl,
return MEMORY_E;
XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
sendSz = BuildMessage(ssl, output,sendSz,input,inputSz,handshake,1);
sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
handshake, 1, 0);
XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (sendSz < 0)
@ -14855,7 +14877,7 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer)
XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
sendSz = BuildMessage(ssl, output, sendSz, input, inputSz,
handshake, 1);
handshake, 1, 0);
XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (sendSz < 0) {
#ifdef WOLFSSL_SMALL_STACK
@ -15233,7 +15255,7 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer)
XMEMCPY(input, output + RECORD_HEADER_SZ, inputSz);
sendSz = BuildMessage(ssl, output,
MAX_CERT_VERIFY_SZ +MAX_MSG_EXTRA,
input, inputSz, handshake, 1);
input, inputSz, handshake, 1, 0);
XFREE(input, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (sendSz < 0)

View File

@ -618,6 +618,56 @@ int wolfSSL_GetObjectSize(void)
}
#endif
/* return max record layer size plaintext input size */
int wolfSSL_GetMaxOutputSize(WOLFSSL* ssl)
{
int maxSize = OUTPUT_RECORD_SIZE;
WOLFSSL_ENTER("wolfSSL_GetMaxOutputSize");
if (ssl == NULL)
return BAD_FUNC_ARG;
if (ssl->options.handShakeState != HANDSHAKE_DONE) {
WOLFSSL_MSG("Handshake not complete yet");
return BAD_FUNC_ARG;
}
#ifdef HAVE_MAX_FRAGMENT
maxSize = min(maxSize, ssl->max_fragment);
#endif
#ifdef WOLFSSL_DTLS
if (ssl->options.dtls) {
maxSize = min(maxSize, MAX_UDP_SIZE);
}
#endif
return maxSize;
}
/* return record layer size of plaintext input size */
int wolfSSL_GetOutputSize(WOLFSSL* ssl, int inSz)
{
int maxSize;
WOLFSSL_ENTER("wolfSSL_GetOutputSize");
if (inSz < 0)
return BAD_FUNC_ARG;
maxSize = wolfSSL_GetMaxOutputSize(ssl);
if (maxSize < 0)
return maxSize; /* error */
if (inSz > maxSize)
return INPUT_SIZE_E;
return BuildMessage(ssl, NULL, 0, NULL, inSz, application_data, 0, 1);
}
#ifdef HAVE_ECC
int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz)
{

View File

@ -148,6 +148,7 @@ enum wolfSSL_ErrorCodes {
ECC_KEY_SIZE_E = -410, /* ECC key too small */
DTLS_EXPORT_VER_E = -411, /* export version error */
INPUT_SIZE_E = -412, /* input size too big error */
/* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */
/* begin negotiation parameter errors */

View File

@ -3117,6 +3117,10 @@ WOLFSSL_LOCAL int SetKeysSide(WOLFSSL*, enum encrypt_side);
WOLFSSL_LOCAL int EccMakeTempKey(WOLFSSL* ssl);
#endif
WOLFSSL_LOCAL int BuildMessage(WOLFSSL* ssl, byte* output, int outSz,
const byte* input, int inSz, int type, int hashOutput,
int sizeOnly);
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@ -1142,6 +1142,8 @@ enum {
WOLFSSL_API int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version);
WOLFSSL_API int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version);
WOLFSSL_API int wolfSSL_GetObjectSize(void); /* object size based on build */
WOLFSSL_API int wolfSSL_GetOutputSize(WOLFSSL*, int);
WOLFSSL_API int wolfSSL_GetMaxOutputSize(WOLFSSL*);
WOLFSSL_API int wolfSSL_SetVersion(WOLFSSL* ssl, int version);
WOLFSSL_API int wolfSSL_KeyPemToDer(const unsigned char*, int,
unsigned char*, int, const char*);