fix for memory leak after resetting stream state

This commit is contained in:
Jacob Barthelmeh
2018-10-24 19:16:27 -06:00
committed by David Garske
parent 5a59fdd6fd
commit 048a7f4c57

View File

@ -150,9 +150,22 @@ static void wc_PKCS7_ResetStream(PKCS7* pkcs7)
XFREE(pkcs7->stream->aad, pkcs7->heap, DYNAMIC_TYPE_PKCS7); XFREE(pkcs7->stream->aad, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
XFREE(pkcs7->stream->tag, pkcs7->heap, DYNAMIC_TYPE_PKCS7); XFREE(pkcs7->stream->tag, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
XFREE(pkcs7->stream->nonce, pkcs7->heap, DYNAMIC_TYPE_PKCS7); XFREE(pkcs7->stream->nonce, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
pkcs7->stream->aad = NULL;
pkcs7->stream->tag = NULL;
pkcs7->stream->nonce = NULL;
/* reset values */ /* reset values, note that content and tmpCert are saved */
XMEMSET(pkcs7->stream, 0, sizeof(PKCS7State)); pkcs7->stream->maxLen = 0;
pkcs7->stream->length = 0;
pkcs7->stream->idx = 0;
pkcs7->stream->expected = 0;
pkcs7->stream->totalRd = 0;
pkcs7->stream->multi = 0;
pkcs7->stream->flagOne = 0;
pkcs7->stream->varOne = 0;
pkcs7->stream->varTwo = 0;
pkcs7->stream->varThree = 0;
} }
} }
@ -164,8 +177,11 @@ static void wc_PKCS7_FreeStream(PKCS7* pkcs7)
XFREE(pkcs7->stream->content, pkcs7->heap, DYNAMIC_TYPE_PKCS7); XFREE(pkcs7->stream->content, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
XFREE(pkcs7->stream->tmpCert, pkcs7->heap, DYNAMIC_TYPE_PKCS7); XFREE(pkcs7->stream->tmpCert, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
pkcs7->stream->content = NULL;
pkcs7->stream->tmpCert = NULL;
XFREE(pkcs7->stream, pkcs7->heap, DYNAMIC_TYPE_PKCS7); XFREE(pkcs7->stream, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
pkcs7->stream = NULL;
} }
} }
@ -3235,7 +3251,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
MAX_VERSION_SZ + MAX_SEQ_SZ + MAX_LENGTH_SZ + MAX_VERSION_SZ + MAX_SEQ_SZ + MAX_LENGTH_SZ +
ASN_TAG_SZ + MAX_OID_SZ + MAX_SEQ_SZ, ASN_TAG_SZ + MAX_OID_SZ + MAX_SEQ_SZ,
&pkiMsg, &idx)) != 0) { &pkiMsg, &idx)) != 0) {
return ret; break;
} }
pkiMsgSz = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_SEQ_PEEK, in, inSz); pkiMsgSz = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_SEQ_PEEK, in, inSz);
@ -3248,10 +3264,10 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
} }
/* Get the contentInfo sequence */ /* Get the contentInfo sequence */
if (GetSequence(pkiMsg, &idx, &length, totalSz) < 0) if (ret == 0 && GetSequence(pkiMsg, &idx, &length, totalSz) < 0)
return ASN_PARSE_E; ret = ASN_PARSE_E;
if (length == 0 && pkiMsg[idx-1] == 0x80) { if (ret == 0 && length == 0 && pkiMsg[idx-1] == 0x80) {
#ifdef ASN_BER_TO_DER #ifdef ASN_BER_TO_DER
word32 len = 0; word32 len = 0;
@ -3271,50 +3287,55 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
return ASN_PARSE_E; return ASN_PARSE_E;
#else #else
return BER_INDEF_E; ret = BER_INDEF_E;
#endif #endif
} }
/* Get the contentInfo contentType */ /* Get the contentInfo contentType */
if (wc_GetContentType(pkiMsg, &idx, &outerContentType, pkiMsgSz) < 0) if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &outerContentType,
return ASN_PARSE_E; pkiMsgSz) < 0)
ret = ASN_PARSE_E;
if (outerContentType != SIGNED_DATA) { if (ret == 0 && outerContentType != SIGNED_DATA) {
WOLFSSL_MSG("PKCS#7 input not of type SignedData"); WOLFSSL_MSG("PKCS#7 input not of type SignedData");
return PKCS7_OID_E; ret = PKCS7_OID_E;
} }
/* get the ContentInfo content */ /* get the ContentInfo content */
if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) if (ret == 0 && pkiMsg[idx++] !=
return ASN_PARSE_E; (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
ret = ASN_PARSE_E;
if (GetLength(pkiMsg, &idx, &length, totalSz) < 0) if (ret == 0 && GetLength(pkiMsg, &idx, &length, totalSz) < 0)
return ASN_PARSE_E; ret = ASN_PARSE_E;
/* Get the signedData sequence */ /* Get the signedData sequence */
if (GetSequence(pkiMsg, &idx, &length, totalSz) < 0) if (ret == 0 && GetSequence(pkiMsg, &idx, &length, totalSz) < 0)
return ASN_PARSE_E; ret = ASN_PARSE_E;
/* Get the version */ /* Get the version */
if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0) if (ret == 0 && GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
return ASN_PARSE_E; ret = ASN_PARSE_E;
if (version != 1) { if (ret == 0 && version != 1) {
WOLFSSL_MSG("PKCS#7 signedData needs to be of version 1"); WOLFSSL_MSG("PKCS#7 signedData needs to be of version 1");
return ASN_VERSION_E; ret = ASN_VERSION_E;
} }
/* Get the set of DigestAlgorithmIdentifiers */ /* Get the set of DigestAlgorithmIdentifiers */
if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0) if (ret == 0 && GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
return ASN_PARSE_E; ret = ASN_PARSE_E;
/* Skip the set. */ /* Skip the set. */
idx += length; idx += length;
degenerate = (length == 0)? 1 : 0; degenerate = (length == 0)? 1 : 0;
if (pkcs7->noDegenerate == 1 && degenerate == 1) { if (pkcs7->noDegenerate == 1 && degenerate == 1) {
return PKCS7_NO_SIGNER_E; ret = PKCS7_NO_SIGNER_E;
} }
if (ret != 0)
break;
#ifndef NO_PKCS7_STREAM #ifndef NO_PKCS7_STREAM
if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) { if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
break; break;
@ -3331,7 +3352,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz, if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
MAX_SEQ_SZ + MAX_OID_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ MAX_SEQ_SZ + MAX_OID_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ
+ ASN_TAG_SZ + MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) { + ASN_TAG_SZ + MAX_LENGTH_SZ, &pkiMsg, &idx)) != 0) {
return ret; break;
} }
pkiMsgSz = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in, inSz); pkiMsgSz = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in, inSz);
@ -3340,14 +3361,14 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
/* Get the inner ContentInfo sequence */ /* Get the inner ContentInfo sequence */
if (GetSequence(pkiMsg, &idx, &length, totalSz) < 0) if (GetSequence(pkiMsg, &idx, &length, totalSz) < 0)
return ASN_PARSE_E; ret = ASN_PARSE_E;
/* Get the inner ContentInfo contentType */ /* Get the inner ContentInfo contentType */
{ if (ret == 0) {
word32 tmpIdx = idx; word32 tmpIdx = idx;
if (GetASNObjectId(pkiMsg, &idx, &length, pkiMsgSz) != 0) if (GetASNObjectId(pkiMsg, &idx, &length, pkiMsgSz) != 0)
return ASN_PARSE_E; ret = ASN_PARSE_E;
contentType = pkiMsg + tmpIdx; contentType = pkiMsg + tmpIdx;
contentTypeSz = length + (idx - tmpIdx); contentTypeSz = length + (idx - tmpIdx);
@ -3355,6 +3376,9 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
idx += length; idx += length;
} }
if (ret != 0)
break;
/* Check for content info, it could be omitted when degenerate */ /* Check for content info, it could be omitted when degenerate */
localIdx = idx; localIdx = idx;
ret = 0; ret = 0;
@ -3449,7 +3473,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
#ifndef NO_PKCS7_STREAM #ifndef NO_PKCS7_STREAM
if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz, pkcs7->stream->expected, if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz, pkcs7->stream->expected,
&pkiMsg, &idx)) != 0) { &pkiMsg, &idx)) != 0) {
return ret; break;
} }
pkiMsgSz = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in, inSz); pkiMsgSz = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, in, inSz);
@ -3461,6 +3485,11 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
multiPart = pkcs7->stream->multi; multiPart = pkcs7->stream->multi;
#endif #endif
/* Break out before content because it can be optional in degenerate
* cases. */
if (ret != 0)
break;
/* get parts of content */ /* get parts of content */
if (ret == 0 && multiPart) { if (ret == 0 && multiPart) {
int i = 0; int i = 0;
@ -3509,12 +3538,12 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
localIdx = 0; localIdx = 0;
if (contentSz != (int)pkcs7->contentSz) { if (contentSz != (int)pkcs7->contentSz) {
WOLFSSL_MSG("Data signed does not match contentSz provided"); WOLFSSL_MSG("Data signed does not match contentSz provided");
return BUFFER_E; ret = BUFFER_E;
} }
} }
else { else {
if ((word32)length > pkiMsgSz - localIdx) { if ((word32)length > pkiMsgSz - localIdx) {
return BUFFER_E; ret = BUFFER_E;
} }
/* Content pointer for calculating hashes later */ /* Content pointer for calculating hashes later */
@ -3524,13 +3553,16 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
if (ret == 0 && multiPart) { if (ret == 0 && multiPart) {
content = pkcs7->contentDynamic; content = pkcs7->contentDynamic;
} }
idx += length;
pkiMsg2 = pkiMsg; if (ret == 0) {
pkiMsg2Sz = pkiMsgSz; idx += length;
#ifndef NO_PKCS7_STREAM
pkcs7->stream->flagOne = 1; pkiMsg2 = pkiMsg;
#endif pkiMsg2Sz = pkiMsgSz;
#ifndef NO_PKCS7_STREAM
pkcs7->stream->flagOne = 1;
#endif
}
} }
} }
else { else {
@ -3544,15 +3576,21 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
* error case. Otherwise with a degenerate it is ok if the content * error case. Otherwise with a degenerate it is ok if the content
* info was omitted */ * info was omitted */
if (!degenerate && ret != 0) { if (!degenerate && ret != 0) {
return ret; break;
}
else {
ret = 0; /* reset ret state on degenerate case */
} }
/* Get the implicit[0] set of certificates */ /* Get the implicit[0] set of certificates */
if (pkiMsg2[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) { if (pkiMsg2[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
idx++; idx++;
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0) if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
return ASN_PARSE_E; ret = ASN_PARSE_E;
if (ret != 0) {
break;
}
#ifndef NO_PKCS7_STREAM #ifndef NO_PKCS7_STREAM
/* save content */ /* save content */
if (content != NULL) { if (content != NULL) {
@ -3584,9 +3622,6 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
pkcs7->stream->expected = MAX_SEQ_SZ; pkcs7->stream->expected = MAX_SEQ_SZ;
} }
#endif #endif
if (ret != 0) {
break;
}
wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE4); wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE4);
FALL_THROUGH; FALL_THROUGH;
@ -3594,7 +3629,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
#ifndef NO_PKCS7_STREAM #ifndef NO_PKCS7_STREAM
if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz, if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
return ret; break;
} }
wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length); wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
@ -3608,10 +3643,13 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
/* store certificate if needed */ /* store certificate if needed */
if (length > 0 && in2Sz == 0) { if (length > 0 && in2Sz == 0) {
/* free tmpCert if not NULL */
XFREE(pkcs7->stream->tmpCert, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
pkcs7->stream->tmpCert = (byte*)XMALLOC(length, pkcs7->stream->tmpCert = (byte*)XMALLOC(length,
pkcs7->heap, DYNAMIC_TYPE_PKCS7); pkcs7->heap, DYNAMIC_TYPE_PKCS7);
if (pkcs7->stream->tmpCert == NULL) { if (pkcs7->stream->tmpCert == NULL) {
return MEMORY_E; ret = MEMORY_E;
break;
} }
XMEMCPY(pkcs7->stream->tmpCert, pkiMsg2 + idx, length); XMEMCPY(pkcs7->stream->tmpCert, pkiMsg2 + idx, length);
pkiMsg2 = pkcs7->stream->tmpCert; pkiMsg2 = pkcs7->stream->tmpCert;
@ -3630,7 +3668,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
if (pkiMsg2[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) { if (pkiMsg2[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
if (GetLength(pkiMsg2, &certIdx, &certSz, pkiMsg2Sz) < 0) if (GetLength(pkiMsg2, &certIdx, &certSz, pkiMsg2Sz) < 0)
return ASN_PARSE_E; ret = ASN_PARSE_E;
cert = &pkiMsg2[idx]; cert = &pkiMsg2[idx];
certSz += (certIdx - idx); certSz += (certIdx - idx);
@ -3645,22 +3683,22 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
#endif #endif
contentDynamic = pkcs7->contentDynamic; contentDynamic = pkcs7->contentDynamic;
{ if (ret == 0) {
PKCS7State* stream = pkcs7->stream; PKCS7State* stream = pkcs7->stream;
/* This will reset PKCS7 structure and then set the /* This will reset PKCS7 structure and then set the
* certificate */ * certificate */
ret = wc_PKCS7_InitWithCert(pkcs7, cert, certSz); ret = wc_PKCS7_InitWithCert(pkcs7, cert, certSz);
if (ret != 0)
return ret;
pkcs7->stream = stream; pkcs7->stream = stream;
} }
pkcs7->contentDynamic = contentDynamic; pkcs7->contentDynamic = contentDynamic;
#ifdef ASN_BER_TO_DER #ifdef ASN_BER_TO_DER
pkcs7->der = der; pkcs7->der = der;
#endif #endif
if (ret != 0)
break;
/* iterate through any additional certificates */ /* iterate through any additional certificates */
if (MAX_PKCS7_CERTS > 0) { if (ret == 0 && MAX_PKCS7_CERTS > 0) {
int sz = 0; int sz = 0;
int i; int i;
@ -3668,13 +3706,18 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
pkcs7->certSz[0] = certSz; pkcs7->certSz[0] = certSz;
certIdx = idx + certSz; certIdx = idx + certSz;
for (i = 1; i < MAX_PKCS7_CERTS && certIdx + 1 < pkiMsg2Sz for (i = 1; i < MAX_PKCS7_CERTS &&
&& certIdx + 1 < (word32)length; i++) { certIdx + 1 < pkiMsg2Sz &&
certIdx + 1 < (word32)length; i++) {
localIdx = certIdx; localIdx = certIdx;
if (pkiMsg2[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) { if (pkiMsg2[certIdx++] ==
if (GetLength(pkiMsg2, &certIdx, &sz, pkiMsg2Sz) < 0) (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
return ASN_PARSE_E; if (GetLength(pkiMsg2, &certIdx, &sz,
pkiMsg2Sz) < 0) {
ret = ASN_PARSE_E;
break;
}
pkcs7->cert[i] = &pkiMsg2[localIdx]; pkcs7->cert[i] = &pkiMsg2[localIdx];
pkcs7->certSz[i] = sz + (certIdx - localIdx); pkcs7->certSz[i] = sz + (certIdx - localIdx);
@ -3690,6 +3733,9 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
pkcs7->content = content; pkcs7->content = content;
pkcs7->contentSz = contentSz; pkcs7->contentSz = contentSz;
if (ret != 0) {
break;
}
#ifndef NO_PKCS7_STREAM #ifndef NO_PKCS7_STREAM
/* factor in that recent idx was in cert buffer. If in2 buffer was /* factor in that recent idx was in cert buffer. If in2 buffer was
* used then don't advance idx. */ * used then don't advance idx. */
@ -3707,20 +3753,24 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
idx = stateIdx + idx; idx = stateIdx + idx;
} }
pkcs7->stream->expected = MAX_OID_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ +
MAX_SET_SZ;
if (pkcs7->stream->expected > (pkcs7->stream->maxLen -
pkcs7->stream->totalRd) + pkcs7->stream->length)
pkcs7->stream->expected = (pkcs7->stream->maxLen -
pkcs7->stream->totalRd) + pkcs7->stream->length;
wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length); wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
#endif #endif
if (ret != 0) {
break;
}
wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE5); wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE5);
FALL_THROUGH; FALL_THROUGH;
case WC_PKCS7_VERIFY_STAGE5: case WC_PKCS7_VERIFY_STAGE5:
#ifndef NO_PKCS7_STREAM #ifndef NO_PKCS7_STREAM
if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_OID_SZ + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz,
ASN_TAG_SZ + MAX_LENGTH_SZ + MAX_SET_SZ, pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
&pkiMsg, &idx)) != 0) { break;
return ret;
} }
wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length); wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
if (pkcs7->stream->flagOne) { if (pkcs7->stream->flagOne) {
@ -3733,33 +3783,36 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
#endif #endif
/* set contentType and size after init of PKCS7 structure */ /* set contentType and size after init of PKCS7 structure */
if (wc_PKCS7_SetContentType(pkcs7, contentType, contentTypeSz) < 0) if (ret == 0 && wc_PKCS7_SetContentType(pkcs7, contentType,
return ASN_PARSE_E; contentTypeSz) < 0)
ret = ASN_PARSE_E;
/* Get the implicit[1] set of crls */ /* Get the implicit[1] set of crls */
if (idx > pkiMsg2Sz) { if (ret == 0 && idx > pkiMsg2Sz)
return BUFFER_E; ret = BUFFER_E;
}
if (pkiMsg2[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) { if (ret == 0 && pkiMsg2[idx] ==
(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
idx++; idx++;
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0) if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
return ASN_PARSE_E; ret = ASN_PARSE_E;
/* Skip the set */ /* Skip the set */
idx += length; idx += length;
} }
/* Get the set of signerInfos */ /* Get the set of signerInfos */
if (GetSet(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0) if (ret == 0 && GetSet(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
return ASN_PARSE_E; ret = ASN_PARSE_E;
if (ret != 0)
break;
#ifndef NO_PKCS7_STREAM #ifndef NO_PKCS7_STREAM
if (!pkcs7->stream->flagOne) { if (!pkcs7->stream->flagOne) {
stateIdx = idx; /* didn't read any from internal buffer */ stateIdx = idx; /* didn't read any from internal buffer */
} }
if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) { if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
break; break;
} }
wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length); wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
@ -3777,7 +3830,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
#ifndef NO_PKCS7_STREAM #ifndef NO_PKCS7_STREAM
if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz, if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + in2Sz,
pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
return ret; break;
} }
wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length); wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
@ -3791,100 +3844,105 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
#endif #endif
/* require a signer if degenerate case not allowed */ /* require a signer if degenerate case not allowed */
if (length == 0 && pkcs7->noDegenerate == 1) if (ret == 0 && length == 0 && pkcs7->noDegenerate == 1)
return PKCS7_NO_SIGNER_E; ret = PKCS7_NO_SIGNER_E;
if (degenerate == 0 && length == 0) { if (ret == 0 && degenerate == 0 && length == 0) {
WOLFSSL_MSG("PKCS7 signers expected"); WOLFSSL_MSG("PKCS7 signers expected");
return PKCS7_NO_SIGNER_E; ret = PKCS7_NO_SIGNER_E;
} }
if (length > 0 && degenerate == 0) { if (ret == 0 && length > 0 && degenerate == 0) {
/* Get the sequence of the first signerInfo */ /* Get the sequence of the first signerInfo */
if (GetSequence(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0) if (ret == 0 && GetSequence(pkiMsg2, &idx, &length,
return ASN_PARSE_E; pkiMsg2Sz) < 0)
ret = ASN_PARSE_E;
/* Get the version */ /* Get the version */
if (GetMyVersion(pkiMsg2, &idx, &version, pkiMsg2Sz) < 0) if (ret == 0 && GetMyVersion(pkiMsg2, &idx, &version,
return ASN_PARSE_E; pkiMsg2Sz) < 0)
ret = ASN_PARSE_E;
if (version == 1) { if (ret == 0 && version == 1) {
/* Get the sequence of IssuerAndSerialNumber */ /* Get the sequence of IssuerAndSerialNumber */
if (GetSequence(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0) if (GetSequence(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
return ASN_PARSE_E; ret = ASN_PARSE_E;
/* Skip it */ /* Skip it */
idx += length; idx += length;
} else if (version == 3) { } else if (ret == 0 && version == 3) {
/* Get the sequence of SubjectKeyIdentifier */ /* Get the sequence of SubjectKeyIdentifier */
if (pkiMsg2[idx++] != (ASN_CONSTRUCTED | if (pkiMsg2[idx++] != (ASN_CONSTRUCTED |
ASN_CONTEXT_SPECIFIC | 0)) { ASN_CONTEXT_SPECIFIC | 0)) {
return ASN_PARSE_E; ret = ASN_PARSE_E;
} }
if (ret == 0 && GetLength(pkiMsg2, &idx, &length, if (ret == 0 && GetLength(pkiMsg2, &idx, &length,
pkiMsg2Sz) <= 0) { pkiMsg2Sz) <= 0) {
return ASN_PARSE_E; ret = ASN_PARSE_E;
} }
if (ret == 0 && pkiMsg2[idx++] != ASN_OCTET_STRING) if (ret == 0 && pkiMsg2[idx++] != ASN_OCTET_STRING)
return ASN_PARSE_E; ret = ASN_PARSE_E;
if (ret == 0 && GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0) if (ret == 0 && GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
return ASN_PARSE_E; ret = ASN_PARSE_E;
/* Skip it */ /* Skip it */
idx += length; idx += length;
} else { } else {
WOLFSSL_MSG("PKCS#7 signerInfo version must be 1 or 3"); WOLFSSL_MSG("PKCS#7 signerInfo version must be 1 or 3");
return ASN_VERSION_E; ret = ASN_VERSION_E;
} }
/* Get the sequence of digestAlgorithm */ /* Get the sequence of digestAlgorithm */
if (GetAlgoId(pkiMsg2, &idx, &hashOID, oidHashType, pkiMsg2Sz) < 0) { if (ret == 0 && GetAlgoId(pkiMsg2, &idx, &hashOID, oidHashType,
return ASN_PARSE_E; pkiMsg2Sz) < 0) {
ret = ASN_PARSE_E;
} }
pkcs7->hashOID = (int)hashOID; pkcs7->hashOID = (int)hashOID;
/* Get the IMPLICIT[0] SET OF signedAttributes */ /* Get the IMPLICIT[0] SET OF signedAttributes */
if (pkiMsg2[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) { if (ret == 0 && pkiMsg2[idx] ==
(ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
idx++; idx++;
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0) if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
return ASN_PARSE_E; ret = ASN_PARSE_E;
/* save pointer and length */ /* save pointer and length */
signedAttrib = &pkiMsg2[idx]; signedAttrib = &pkiMsg2[idx];
signedAttribSz = length; signedAttribSz = length;
if (wc_PKCS7_ParseAttribs(pkcs7, signedAttrib, signedAttribSz) <0) { if (ret == 0 && wc_PKCS7_ParseAttribs(pkcs7, signedAttrib,
signedAttribSz) < 0) {
WOLFSSL_MSG("Error parsing signed attributes"); WOLFSSL_MSG("Error parsing signed attributes");
return ASN_PARSE_E; ret = ASN_PARSE_E;
} }
idx += length; idx += length;
} }
/* Get digestEncryptionAlgorithm */ /* Get digestEncryptionAlgorithm */
if (GetAlgoId(pkiMsg2, &idx, &sigOID, oidSigType, pkiMsg2Sz) < 0) { if (ret == 0 && GetAlgoId(pkiMsg2, &idx, &sigOID, oidSigType,
return ASN_PARSE_E; pkiMsg2Sz) < 0) {
ret = ASN_PARSE_E;
} }
/* store public key type based on digestEncryptionAlgorithm */ /* store public key type based on digestEncryptionAlgorithm */
ret = wc_PKCS7_SetPublicKeyOID(pkcs7, sigOID); if ((ret = 0) && ((ret = wc_PKCS7_SetPublicKeyOID(pkcs7, sigOID))
if (ret <= 0) { <= 0)) {
WOLFSSL_MSG("Failed to set public key OID from signature"); WOLFSSL_MSG("Failed to set public key OID from signature");
return ret;
} }
/* Get the signature */ /* Get the signature */
if (pkiMsg2[idx] == ASN_OCTET_STRING) { if (ret == 0 && pkiMsg2[idx] == ASN_OCTET_STRING) {
idx++; idx++;
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0) if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
return ASN_PARSE_E; ret = ASN_PARSE_E;
/* save pointer and length */ /* save pointer and length */
sig = &pkiMsg2[idx]; sig = &pkiMsg2[idx];
@ -3896,11 +3954,10 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
pkcs7->content = content; pkcs7->content = content;
pkcs7->contentSz = contentSz; pkcs7->contentSz = contentSz;
ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz, if (ret == 0) {
signedAttrib, signedAttribSz, ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,
hashBuf, hashSz); signedAttrib, signedAttribSz,
if (ret < 0) { hashBuf, hashSz);
return ret;
} }
} }