Fixes to ASN GetLength changes. Additional GetLength checks in PKCS7 and PKCS12.

This commit is contained in:
David Garske
2017-02-07 10:59:34 -08:00
parent 0286d157a7
commit 3a1921e107
4 changed files with 54 additions and 48 deletions

View File

@@ -595,10 +595,8 @@ WOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx,
WOLFSSL_ENTER("GetMyVersion");
if (idx + MIN_VERSION_SZ > maxIdx) {
WOLFSSL_MSG("GetMyVersion bad index on input");
return ASN_PARSE_E;
}
if ((idx + MIN_VERSION_SZ) > maxIdx)
return ASN_PARSE_E;
if (input[idx++] != ASN_INTEGER)
return ASN_PARSE_E;
@@ -623,10 +621,8 @@ int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx)
*number = 0;
/* check for type and length bytes */
if ((idx + 2) > maxIdx) {
WOLFSSL_MSG("GetShortInt bad index on input");
if ((idx + 2) > maxIdx)
return ASN_PARSE_E;
}
if (input[idx++] != ASN_INTEGER)
return ASN_PARSE_E;
@@ -656,10 +652,8 @@ static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version,
WOLFSSL_ENTER("GetExplicitVersion");
if ((idx + 1) > maxIdx) {
WOLFSSL_MSG("GetExplicitVersion bad index on input");
if ((idx + 1) > maxIdx)
return ASN_PARSE_E;
}
if (input[idx++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
*inOutIdx = ++idx; /* skip header byte */
@@ -1439,11 +1433,11 @@ static int SkipObjectId(const byte* input, word32* inOutIdx, word32 maxIdx)
if (input[idx++] != ASN_OBJECT_ID)
return ASN_OBJECT_ID_E;
if (GetLength(input, inOutIdx, &length, maxIdx) < 0)
if (GetLength(input, &idx, &length, maxIdx) < 0)
return ASN_PARSE_E;
idx += length;
*inOutIdx += idx;
*inOutIdx = idx;
return 0;
}
@@ -2195,7 +2189,6 @@ int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
if (b != ASN_BIT_STRING)
return ASN_BITSTR_E;
/* length should not be 0 */
if (GetLength(input, inOutIdx, &length, inSz) <= 0)
return ASN_PARSE_E;

View File

@@ -200,7 +200,7 @@ static int GetSafeContent(WC_PKCS12* pkcs12, const byte* input,
freeSafe(safe, pkcs12->heap);
return ASN_PARSE_E;
}
if ((ret = GetLength(input, &localIdx, &size, maxIdx)) < 0) {
if ((ret = GetLength(input, &localIdx, &size, maxIdx)) <= 0) {
freeSafe(safe, pkcs12->heap);
return ret;
}
@@ -218,7 +218,7 @@ static int GetSafeContent(WC_PKCS12* pkcs12, const byte* input,
freeSafe(safe, pkcs12->heap);
return ASN_PARSE_E;
}
if ((ret = GetLength(input, &localIdx, &size, maxIdx)) < 0) {
if ((ret = GetLength(input, &localIdx, &size, maxIdx)) <= 0) {
freeSafe(safe, pkcs12->heap);
return ret;
}
@@ -367,7 +367,7 @@ static int GetSignData(WC_PKCS12* pkcs12, const byte* mem, word32* idx,
return ASN_PARSE_E;
}
if ((ret = GetLength(mem, &curIdx, &size, totalSz)) < 0) {
if ((ret = GetLength(mem, &curIdx, &size, totalSz)) <= 0) {
XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
return ret;
}
@@ -398,7 +398,7 @@ static int GetSignData(WC_PKCS12* pkcs12, const byte* mem, word32* idx,
return ASN_PARSE_E;
}
if ((ret = GetLength(mem, &curIdx, &size, totalSz)) < 0) {
if ((ret = GetLength(mem, &curIdx, &size, totalSz)) <= 0) {
XFREE(mac->digest, pkcs12->heap, DYNAMIC_TYPE_PKCS);
XFREE(mac, pkcs12->heap, DYNAMIC_TYPE_PKCS);
return ret;
@@ -800,7 +800,7 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
freeCertList(certList, pkcs12->heap);
return ASN_PARSE_E;
}
if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
if ((ret = GetLength(data, &idx, &size, ci->dataSz)) <= 0) {
freeBuffers(*pkey, buf, pkcs12->heap);
freeCertList(certList, pkcs12->heap);
return ret;
@@ -851,7 +851,7 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
freeCertList(certList, pkcs12->heap);
return ASN_PARSE_E;
}
if ((ret = GetLength(data, &idx, &size, ci->dataSz)) < 0) {
if ((ret = GetLength(data, &idx, &size, ci->dataSz)) <= 0) {
freeBuffers(*pkey, buf, pkcs12->heap);
freeCertList(certList, pkcs12->heap);
return ASN_PARSE_E;
@@ -987,7 +987,7 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
return ASN_PARSE_E;
}
if ((ret = GetLength(data, &idx, &size, ci->dataSz))
< 0) {
<= 0) {
freeBuffers(*pkey, buf, pkcs12->heap);
freeCertList(certList, pkcs12->heap);
return ret;

View File

@@ -86,7 +86,7 @@ static int wc_SetContentType(int pkcs7TypeOID, byte* output)
typeSz = sizeof(signedData);
typeName = signedData;
break;
case ENVELOPED_DATA:
typeSz = sizeof(envelopedData);
typeName = envelopedData;
@@ -853,7 +853,7 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
return ASN_PARSE_E;
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) <= 0)
return ASN_PARSE_E;
if (pkiMsg[idx++] != ASN_OCTET_STRING)
@@ -2735,14 +2735,18 @@ static int wc_PKCS7_KariGetUserKeyingMaterial(WC_PKCS7_KARI* kari,
return 0;
}
kari->ukm = (byte*)XMALLOC(length, kari->heap, DYNAMIC_TYPE_PKCS7);
if (kari->ukm == NULL)
return MEMORY_E;
kari->ukm = NULL;
if (length > 0) {
kari->ukm = (byte*)XMALLOC(length, kari->heap, DYNAMIC_TYPE_PKCS7);
if (kari->ukm == NULL)
return MEMORY_E;
XMEMCPY(kari->ukm, pkiMsg + (*idx), length);
kari->ukmOwner = 1;
}
XMEMCPY(kari->ukm, pkiMsg + (*idx), length);
(*idx) += length;
kari->ukmSz = length;
kari->ukmOwner = 1;
return 0;
}
@@ -3129,7 +3133,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
/* walk through RecipientInfo set, find correct recipient */
if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
return ASN_PARSE_E;
#ifdef WOLFSSL_SMALL_STACK
decryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, NULL,
DYNAMIC_TYPE_PKCS7);
@@ -3163,7 +3167,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
#endif
return ASN_PARSE_E;
}
if (wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(decryptedKey, NULL, DYNAMIC_TYPE_PKCS7);
@@ -3201,14 +3205,14 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
#endif
return ASN_PARSE_E;
}
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(decryptedKey, NULL, DYNAMIC_TYPE_PKCS7);
#endif
return ASN_PARSE_E;
}
if (length != expBlockSz) {
WOLFSSL_MSG("Incorrect IV length, must be of content alg block size");
#ifdef WOLFSSL_SMALL_STACK
@@ -3228,7 +3232,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
return ASN_PARSE_E;
}
if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) < 0) {
if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) <= 0) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(decryptedKey, NULL, DYNAMIC_TYPE_PKCS7);
#endif
@@ -3682,7 +3686,7 @@ int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz,
if (pkiMsg[idx++] != (ASN_CONTEXT_SPECIFIC | 0))
return ASN_PARSE_E;
if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) < 0)
if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) <= 0)
return ASN_PARSE_E;
encryptedContent = (byte*)XMALLOC(encryptedContentSz, pkcs7->heap,

View File

@@ -797,7 +797,7 @@ static int GetLength(const byte* input, word32* inOutIdx, int* len,
*len = 0; /* default length */
if ( (idx+1) > maxIdx) { /* for first read */
if ((idx + 1) > maxIdx) { /* for first read */
USER_DEBUG(("GetLength bad index on input\n"));
return USER_CRYPTO_ERROR;
}
@@ -806,7 +806,7 @@ static int GetLength(const byte* input, word32* inOutIdx, int* len,
if (b >= 0x80) {
word32 bytes = b & 0x7F;
if ( (idx+bytes) > maxIdx) { /* for reading bytes */
if ((idx + bytes) > maxIdx) { /* for reading bytes */
USER_DEBUG(("GetLength bad long length\n"));
return USER_CRYPTO_ERROR;
}
@@ -819,7 +819,7 @@ static int GetLength(const byte* input, word32* inOutIdx, int* len,
else
length = b;
if ( (idx+length) > maxIdx) { /* for user of length */
if ((idx + length) > maxIdx) { /* for user of length */
USER_DEBUG(("GetLength value exceeds buffer length\n"));
return USER_CRYPTO_ERROR;
}
@@ -905,8 +905,8 @@ static int GetMyVersion(const byte* input, word32* inOutIdx,
{
word32 idx = *inOutIdx;
if (idx + MIN_VERSION_SZ > maxIdx)
return USER_CRYPTO_ERROR;
if ((idx + MIN_VERSION_SZ) > maxIdx)
return USER_CRYPTO_ERROR;
if (input[idx++] != 0x02)
return USER_CRYPTO_ERROR;
@@ -1059,9 +1059,12 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
word32 inSz)
{
int length;
int length;
int ctxSz;
IppStatus ret;
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
byte b;
#endif
USER_DEBUG(("Entering wc_RsaPublicKeyDecode\n"));
@@ -1071,8 +1074,12 @@ int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
key->type = RSA_PUBLIC;
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
{
byte b = input[*inOutIdx];
if ((*inOutIdx + 1) > inSz) {
printf("wc_RsaPublicKeyDecode error\n");
return ASN_PARSE_E;
}
b = input[*inOutIdx];
if (b != ASN_INTEGER) {
/* not from decoded cert, will have algo id, skip past */
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
@@ -1095,16 +1102,17 @@ int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
if (b != 0)
return USER_CRYPTO_ERROR;
}
else
/* go back, didn't have it */
else {
/* go back, didn't have it */
(*inOutIdx)--;
}
/* should have bit tag length and seq next */
b = input[(*inOutIdx)++];
if (b != ASN_BIT_STRING)
return USER_CRYPTO_ERROR;
if (GetLength(input, inOutIdx, &length, inSz) < 0)
if (GetLength(input, inOutIdx, &length, inSz) <= 0)
return USER_CRYPTO_ERROR;
/* could have 0 */
@@ -1114,12 +1122,13 @@ int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return USER_CRYPTO_ERROR;
} /* end if */
} /* openssl var block */
#endif /* OPENSSL_EXTRA */
}
#endif /* OPENSSL_EXTRA || RSA_DECODE_EXTRA */
if (GetInt(&key->n, input, inOutIdx, inSz) < 0 ||
GetInt(&key->e, input, inOutIdx, inSz) < 0 ) return USER_CRYPTO_ERROR;
GetInt(&key->e, input, inOutIdx, inSz) < 0) {
return USER_CRYPTO_ERROR;
}
/* get sizes set for IPP BN states */
ret = ippsGetSize_BN(key->n, &key->nSz);