mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-09 23:54:40 +02:00
first addition of verify sign stream data
This commit is contained in:
committed by
David Garske
parent
47303ed445
commit
5525f59852
19
tests/api.c
19
tests/api.c
@@ -15343,18 +15343,29 @@ static void test_wc_PKCS7_EncodeSignedData_ex(void)
|
||||
|
||||
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(NULL, hashBuf, hashSz, outputHead,
|
||||
outputHeadSz, outputFoot, outputFootSz), BAD_FUNC_ARG);
|
||||
|
||||
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, NULL, hashSz, outputHead,
|
||||
outputHeadSz, outputFoot, outputFootSz), ASN_PARSE_E);
|
||||
outputHeadSz, outputFoot, outputFootSz), BAD_FUNC_ARG);
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, 0, outputHead,
|
||||
outputHeadSz, outputFoot, outputFootSz), ASN_PARSE_E);
|
||||
outputHeadSz, outputFoot, outputFootSz), WC_PKCS7_WANT_READ_E);
|
||||
#else
|
||||
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, 0, outputHead,
|
||||
outputHeadSz, outputFoot, outputFootSz), BUFFER_E);
|
||||
#endif
|
||||
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz, NULL,
|
||||
outputHeadSz, outputFoot, outputFootSz), BAD_FUNC_ARG);
|
||||
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz,
|
||||
outputHead, 0, outputFoot, outputFootSz), BAD_FUNC_ARG);
|
||||
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz,
|
||||
outputHead, outputHeadSz, NULL, outputFootSz), ASN_PARSE_E);
|
||||
outputHead, outputHeadSz, NULL, outputFootSz), BAD_FUNC_ARG);
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz,
|
||||
outputHead, outputHeadSz, outputFoot, 0), ASN_PARSE_E);
|
||||
outputHead, outputHeadSz, outputFoot, 0), WC_PKCS7_WANT_READ_E);
|
||||
#else
|
||||
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz,
|
||||
outputHead, outputHeadSz, outputFoot, 0), BUFFER_E);
|
||||
#endif
|
||||
|
||||
printf(resultFmt, passed);
|
||||
|
||||
|
@@ -58,7 +58,6 @@ typedef enum {
|
||||
WC_PKCS7_DECODE
|
||||
} pkcs7Direction;
|
||||
|
||||
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
|
||||
#define MAX_PKCS7_STREAM_BUFFER 256
|
||||
@@ -68,6 +67,8 @@ typedef struct PKCS7State {
|
||||
byte* nonce; /* stored nonce */
|
||||
byte* aad; /* additional data for AEAD algos */
|
||||
byte* tag; /* tag data for AEAD algos */
|
||||
byte* content;
|
||||
byte multi; /* flag for if content is in multiple parts */
|
||||
|
||||
/* stack variables to store for when returning */
|
||||
word32 varOne;
|
||||
@@ -85,6 +86,7 @@ typedef struct PKCS7State {
|
||||
word32 nonceSz; /* size of nonce stored */
|
||||
word32 aadSz; /* size of additional AEAD data */
|
||||
word32 tagSz; /* size of tag for AEAD */
|
||||
word32 contentSz;
|
||||
byte tmpIv[MAX_CONTENT_IV_SIZE]; /* store IV if needed */
|
||||
#ifdef WC_PKCS7_STREAM_DEBUG
|
||||
word32 peakUsed; /* most bytes used for struct at any one time */
|
||||
@@ -159,6 +161,10 @@ static void wc_PKCS7_FreeStream(PKCS7* pkcs7)
|
||||
{
|
||||
if (pkcs7 != NULL && pkcs7->stream != NULL) {
|
||||
wc_PKCS7_ResetStream(pkcs7);
|
||||
|
||||
XFREE(pkcs7->stream->content, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||
XFREE(pkcs7->stream->tmpCert, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||
|
||||
XFREE(pkcs7->stream, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||
}
|
||||
}
|
||||
@@ -337,14 +343,18 @@ static const char* wc_PKCS7_GetStateName(int in)
|
||||
case WC_PKCS7_DECRYPT_KTRI_2: return "WC_PKCS7_DECRYPT_KTRI_2";
|
||||
case WC_PKCS7_DECRYPT_KTRI_3: return "WC_PKCS7_DECRYPT_KTRI_3";
|
||||
|
||||
|
||||
case WC_PKCS7_DECRYPT_KARI: return "WC_PKCS7_DECRYPT_KARI";
|
||||
case WC_PKCS7_DECRYPT_KEKRI: return "WC_PKCS7_DECRYPT_KEKRI";
|
||||
case WC_PKCS7_DECRYPT_PWRI: return "WC_PKCS7_DECRYPT_PWRI";
|
||||
case WC_PKCS7_DECRYPT_ORI: return "WC_PKCS7_DECRYPT_ORI";
|
||||
|
||||
case WC_PKCS7_DECRYPT_DONE: return "WC_PKCS7_DECRYPT_DONE";
|
||||
|
||||
case WC_PKCS7_VERIFY_STAGE2: return "WC_PKCS7_VERIFY_STAGE2";
|
||||
case WC_PKCS7_VERIFY_STAGE3: return "WC_PKCS7_VERIFY_STAGE3";
|
||||
case WC_PKCS7_VERIFY_STAGE4: return "WC_PKCS7_VERIFY_STAGE4";
|
||||
case WC_PKCS7_VERIFY_STAGE5: return "WC_PKCS7_VERIFY_STAGE5";
|
||||
case WC_PKCS7_VERIFY_STAGE6: return "WC_PKCS7_VERIFY_STAGE6";
|
||||
|
||||
default:
|
||||
return "Unknown state";
|
||||
}
|
||||
@@ -2583,7 +2593,6 @@ static int wc_PKCS7_RsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
|
||||
}
|
||||
|
||||
ret = wc_RsaSSL_Verify(sig, sigSz, digest, MAX_PKCS7_DIGEST_SZ, key);
|
||||
|
||||
FreeDecodedCert(dCert);
|
||||
wc_FreeRsaKey(key);
|
||||
|
||||
@@ -3130,10 +3139,10 @@ void wc_PKCS7_AllowDegenerate(PKCS7* pkcs7, word16 flag)
|
||||
* signer is required. In this case the PKCS7 flag noDegenerate could be set.
|
||||
*/
|
||||
static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
||||
word32 hashSz, byte* pkiMsg, word32 pkiMsgSz,
|
||||
word32 hashSz, byte* in, word32 inSz,
|
||||
byte* pkiMsg2, word32 pkiMsg2Sz)
|
||||
{
|
||||
word32 idx, outerContentType, hashOID, sigOID, contentTypeSz, totalSz;
|
||||
word32 idx, outerContentType, hashOID, sigOID, contentTypeSz = 0, totalSz = 0;
|
||||
int length, version, ret;
|
||||
byte* content = NULL;
|
||||
byte* contentDynamic = NULL;
|
||||
@@ -3143,18 +3152,46 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
||||
byte* contentType = NULL;
|
||||
int contentSz = 0, sigSz = 0, certSz = 0, signedAttribSz = 0;
|
||||
word32 localIdx, start;
|
||||
byte degenerate;
|
||||
byte degenerate = 0;
|
||||
#ifdef ASN_BER_TO_DER
|
||||
byte* der;
|
||||
#endif
|
||||
int multiPart = 0, keepContent;
|
||||
int contentLen;
|
||||
|
||||
byte* pkiMsg = in;
|
||||
word32 pkiMsgSz = inSz;
|
||||
word32 stateIdx = 0;
|
||||
|
||||
if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if ((hashSz > 0 && hashBuf == NULL) || (pkiMsg2Sz > 0 && pkiMsg2 == NULL)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
idx = 0;
|
||||
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
if (pkcs7->stream == NULL) {
|
||||
if ((ret = wc_PKCS7_CreateStream(pkcs7)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (pkcs7->state) {
|
||||
case WC_PKCS7_START:
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
|
||||
MAX_VERSION_SZ + MAX_SEQ_SZ + MAX_LENGTH_SZ +
|
||||
ASN_TAG_SZ + MAX_OID_SZ + MAX_SEQ_SZ,
|
||||
&pkiMsg, &idx)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
pkiMsgSz = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_SEQ_PEEK, inSz);
|
||||
#endif
|
||||
|
||||
/* determine total message size */
|
||||
totalSz = pkiMsgSz;
|
||||
if (pkiMsg2 && pkiMsg2Sz > 0) {
|
||||
@@ -3229,6 +3266,30 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
||||
return PKCS7_NO_SIGNER_E;
|
||||
}
|
||||
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
|
||||
break;
|
||||
}
|
||||
pkcs7->stream->maxLen = totalSz;
|
||||
wc_PKCS7_StreamStoreVar(pkcs7, totalSz, 0, 0);
|
||||
#endif
|
||||
|
||||
wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE2);
|
||||
FALL_THROUGH;
|
||||
|
||||
case WC_PKCS7_VERIFY_STAGE2:
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ +
|
||||
MAX_OID_SZ + ASN_TAG_SZ + MAX_LENGTH_SZ + ASN_TAG_SZ
|
||||
+ MAX_LENGTH_SZ,
|
||||
&pkiMsg, &idx)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
pkiMsgSz = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, inSz);
|
||||
wc_PKCS7_StreamGetVar(pkcs7, &totalSz, 0, 0);
|
||||
#endif
|
||||
|
||||
/* Get the inner ContentInfo sequence */
|
||||
if (GetSequence(pkiMsg, &idx, &length, totalSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
@@ -3255,6 +3316,8 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
||||
if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, totalSz) <= 0)
|
||||
ret = ASN_PARSE_E;
|
||||
|
||||
|
||||
/* get length of content in the case that there is multiple parts */
|
||||
if (ret == 0 && pkiMsg[localIdx] == (ASN_OCTET_STRING | ASN_CONSTRUCTED)) {
|
||||
multiPart = 1;
|
||||
|
||||
@@ -3278,6 +3341,78 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
||||
localIdx = start;
|
||||
}
|
||||
}
|
||||
|
||||
/* get length of content in case of single part */
|
||||
if (ret == 0 && !multiPart) {
|
||||
if (pkiMsg[localIdx++] != ASN_OCTET_STRING)
|
||||
ret = ASN_PARSE_E;
|
||||
|
||||
if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, totalSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
|
||||
/* update idx if successful */
|
||||
if (ret == 0) {
|
||||
/* support using header and footer without content */
|
||||
if (pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0) {
|
||||
localIdx = 0;
|
||||
}
|
||||
idx = localIdx;
|
||||
}
|
||||
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
/* save contentType */
|
||||
pkcs7->stream->nonce = (byte*)XMALLOC(contentTypeSz, pkcs7->heap,
|
||||
DYNAMIC_TYPE_PKCS7);
|
||||
if (pkcs7->stream->nonce == NULL) {
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
else {
|
||||
pkcs7->stream->nonceSz = contentTypeSz;
|
||||
XMEMCPY(pkcs7->stream->nonce, contentType, contentTypeSz);
|
||||
}
|
||||
|
||||
if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
|
||||
break;
|
||||
}
|
||||
wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, localIdx, length);
|
||||
|
||||
/* content expected? */
|
||||
if ((ret == 0 && length > 0) &&
|
||||
!(pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0)) {
|
||||
pkcs7->stream->expected = length;
|
||||
}
|
||||
else {
|
||||
pkcs7->stream->expected = 0;
|
||||
}
|
||||
|
||||
/* content length is in multiple parts */
|
||||
if (multiPart) {
|
||||
pkcs7->stream->expected = contentLen;
|
||||
}
|
||||
pkcs7->stream->multi = multiPart;
|
||||
|
||||
#endif
|
||||
wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE3);
|
||||
FALL_THROUGH;
|
||||
|
||||
case WC_PKCS7_VERIFY_STAGE3:
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, pkcs7->stream->expected,
|
||||
&pkiMsg, &idx)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
pkiMsgSz = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, inSz);
|
||||
wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, (int*)&localIdx, &length);
|
||||
|
||||
if (pkcs7->stream->length > 0) {
|
||||
localIdx = 0;
|
||||
}
|
||||
multiPart = pkcs7->stream->multi;
|
||||
#endif
|
||||
|
||||
/* get parts of content */
|
||||
if (ret == 0 && multiPart) {
|
||||
int i = 0;
|
||||
keepContent = !(pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0);
|
||||
@@ -3310,38 +3445,9 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
||||
localIdx += length;
|
||||
}
|
||||
}
|
||||
|
||||
localIdx = start; /* reset for sanity check, increment later */
|
||||
length = i;
|
||||
if (ret == 0 && length > 0) {
|
||||
contentSz = length;
|
||||
|
||||
/* support using header and footer without content */
|
||||
if (pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0) {
|
||||
/* Content not provided, use provided pkiMsg2 footer */
|
||||
content = NULL;
|
||||
localIdx = 0;
|
||||
if (contentSz != (int)pkcs7->contentSz) {
|
||||
WOLFSSL_MSG("Data signed does not match contentSz provided");
|
||||
return BUFFER_E;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Content pointer for calculating hashes later */
|
||||
content = pkcs7->contentDynamic;
|
||||
pkiMsg2 = pkiMsg;
|
||||
pkiMsg2Sz = pkiMsgSz;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pkiMsg2 = pkiMsg;
|
||||
}
|
||||
}
|
||||
if (ret == 0 && !multiPart) {
|
||||
if (pkiMsg[localIdx++] != ASN_OCTET_STRING)
|
||||
ret = ASN_PARSE_E;
|
||||
|
||||
if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, totalSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
|
||||
/* Save the inner data as the content. */
|
||||
if (ret == 0 && length > 0) {
|
||||
@@ -3358,9 +3464,18 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((word32)length > pkiMsgSz - localIdx) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
/* Content pointer for calculating hashes later */
|
||||
if (ret == 0 && !multiPart) {
|
||||
content = &pkiMsg[localIdx];
|
||||
localIdx += length;
|
||||
}
|
||||
if (ret == 0 && multiPart) {
|
||||
content = pkcs7->contentDynamic;
|
||||
}
|
||||
idx += length;
|
||||
|
||||
pkiMsg2 = pkiMsg;
|
||||
pkiMsg2Sz = pkiMsgSz;
|
||||
@@ -3369,15 +3484,6 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
||||
else {
|
||||
pkiMsg2 = pkiMsg;
|
||||
}
|
||||
}
|
||||
|
||||
/* update idx if successful */
|
||||
if (ret == 0)
|
||||
idx = localIdx;
|
||||
else {
|
||||
pkiMsg2 = pkiMsg;
|
||||
pkiMsg2Sz = pkiMsgSz;
|
||||
}
|
||||
|
||||
/* If getting the content info failed with non degenerate then return the
|
||||
* error case. Otherwise with a degenerate it is ok if the content
|
||||
@@ -3392,6 +3498,67 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
||||
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
/* save content */
|
||||
if (content != NULL) {
|
||||
XFREE(pkcs7->stream->content, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||
pkcs7->stream->content = (byte*)XMALLOC(contentSz, pkcs7->heap,
|
||||
DYNAMIC_TYPE_PKCS7);
|
||||
if (pkcs7->stream->content == NULL) {
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
else {
|
||||
XMEMCPY(pkcs7->stream->content, content, contentSz);
|
||||
pkcs7->stream->contentSz = contentSz;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
|
||||
break;
|
||||
}
|
||||
wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
|
||||
if (length > 0) {
|
||||
pkcs7->stream->expected = length;
|
||||
}
|
||||
else {
|
||||
pkcs7->stream->expected = MAX_SEQ_SZ;
|
||||
}
|
||||
pkcs7->stream->bufferPt = pkiMsg2;
|
||||
#endif
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE4);
|
||||
FALL_THROUGH;
|
||||
|
||||
case WC_PKCS7_VERIFY_STAGE4:
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + pkiMsg2Sz,
|
||||
pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
pkiMsgSz = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, inSz);
|
||||
wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
|
||||
pkiMsg2 = pkcs7->stream->bufferPt;
|
||||
|
||||
/* restore content */
|
||||
content = pkcs7->stream->content;
|
||||
contentSz = pkcs7->stream->contentSz;
|
||||
|
||||
/* store certificate */
|
||||
if (length > 0) {
|
||||
pkcs7->stream->tmpCert = (byte*)XMALLOC(length,
|
||||
pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||
if (pkcs7->stream->tmpCert == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMCPY(pkcs7->stream->tmpCert, pkiMsg2 + idx, length);
|
||||
pkiMsg2 = pkcs7->stream->tmpCert;
|
||||
idx = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (length > 0) {
|
||||
/* At this point, idx is at the first certificate in
|
||||
* a set of certificates. There may be more than one,
|
||||
@@ -3408,13 +3575,20 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
||||
cert = &pkiMsg2[idx];
|
||||
certSz += (certIdx - idx);
|
||||
}
|
||||
|
||||
#ifdef ASN_BER_TO_DER
|
||||
der = pkcs7->der;
|
||||
#endif
|
||||
contentDynamic = pkcs7->contentDynamic;
|
||||
/* This will reset PKCS7 structure and then set the certificate */
|
||||
wc_PKCS7_InitWithCert(pkcs7, cert, certSz);
|
||||
|
||||
{
|
||||
PKCS7State* stream = pkcs7->stream;
|
||||
/* This will reset PKCS7 structure and then set the
|
||||
* certificate */
|
||||
ret = wc_PKCS7_InitWithCert(pkcs7, cert, certSz);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
pkcs7->stream = stream;
|
||||
}
|
||||
pkcs7->contentDynamic = contentDynamic;
|
||||
#ifdef ASN_BER_TO_DER
|
||||
pkcs7->der = der;
|
||||
@@ -3450,6 +3624,36 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
||||
pkcs7->content = content;
|
||||
pkcs7->contentSz = contentSz;
|
||||
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
idx = stateIdx + idx;
|
||||
if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
|
||||
break;
|
||||
}
|
||||
wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
|
||||
#endif
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE5);
|
||||
FALL_THROUGH;
|
||||
|
||||
case WC_PKCS7_VERIFY_STAGE5:
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_OID_SZ +
|
||||
ASN_TAG_SZ + MAX_LENGTH_SZ + MAX_SET_SZ,
|
||||
&pkiMsg, &idx)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
pkiMsgSz = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, inSz);
|
||||
wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
|
||||
pkiMsg2 = pkcs7->stream->bufferPt;
|
||||
|
||||
/* restore content type */
|
||||
contentType = pkcs7->stream->nonce;
|
||||
contentTypeSz = pkcs7->stream->nonceSz;
|
||||
#endif
|
||||
|
||||
/* set contentType and size after init of PKCS7 structure */
|
||||
if (wc_PKCS7_SetContentType(pkcs7, contentType, contentTypeSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
@@ -3468,6 +3672,38 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
||||
if (GetSet(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) {
|
||||
break;
|
||||
}
|
||||
wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length);
|
||||
if (length > 0) {
|
||||
pkcs7->stream->expected = length;
|
||||
}
|
||||
else {
|
||||
pkcs7->stream->expected = 0;
|
||||
}
|
||||
pkcs7->stream->bufferPt = pkiMsg2;
|
||||
#endif
|
||||
wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE6);
|
||||
FALL_THROUGH;
|
||||
|
||||
case WC_PKCS7_VERIFY_STAGE6:
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz + pkiMsg2Sz,
|
||||
pkcs7->stream->expected, &pkiMsg, &idx)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
pkiMsgSz = wc_PKCS7_GetMaxStream(pkcs7, PKCS7_DEFAULT_PEEK, inSz);
|
||||
wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length);
|
||||
pkiMsg2 = pkcs7->stream->bufferPt;
|
||||
|
||||
/* restore content */
|
||||
content = pkcs7->stream->content;
|
||||
contentSz = pkcs7->stream->contentSz;
|
||||
#endif
|
||||
|
||||
/* require a signer if degenerate case not allowed */
|
||||
if (length == 0 && pkcs7->noDegenerate == 1)
|
||||
return PKCS7_NO_SIGNER_E;
|
||||
@@ -3488,7 +3724,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
||||
|
||||
if (version == 1) {
|
||||
/* Get the sequence of IssuerAndSerialNumber */
|
||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
if (GetSequence(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* Skip it */
|
||||
@@ -3496,19 +3732,21 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
||||
|
||||
} else if (version == 3) {
|
||||
/* Get the sequence of SubjectKeyIdentifier */
|
||||
if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
|
||||
ret = ASN_PARSE_E;
|
||||
if (pkiMsg2[idx++] != (ASN_CONSTRUCTED |
|
||||
ASN_CONTEXT_SPECIFIC | 0)) {
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) <= 0) {
|
||||
ret = ASN_PARSE_E;
|
||||
if (ret == 0 && GetLength(pkiMsg2, &idx, &length,
|
||||
pkiMsg2Sz) <= 0) {
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
if (ret == 0 && pkiMsg[idx++] != ASN_OCTET_STRING)
|
||||
ret = ASN_PARSE_E;
|
||||
if (ret == 0 && pkiMsg2[idx++] != ASN_OCTET_STRING)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
ret = ASN_PARSE_E;
|
||||
if (ret == 0 && GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* Skip it */
|
||||
idx += length;
|
||||
@@ -3575,11 +3813,26 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
||||
ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,
|
||||
signedAttrib, signedAttribSz,
|
||||
hashBuf, hashSz);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
ret = 0; /* success */
|
||||
wc_PKCS7_ResetStream(pkcs7);
|
||||
wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("PKCS7 Unknown verify state");
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret != 0 && ret != WC_PKCS7_WANT_READ_E) {
|
||||
wc_PKCS7_ResetStream(pkcs7);
|
||||
wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -9831,10 +10084,11 @@ int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* in, word32 inSz,
|
||||
wc_PKCS7_FreeDecodedAttrib(pkcs7->decodedAttrib, pkcs7->heap);
|
||||
pkcs7->decodedAttrib = NULL;
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
if (pkcs7->stream->hasAtrib) {
|
||||
if (pkcs7->stream->hasAtrib)
|
||||
#else
|
||||
if (idx < pkiMsgSz) {
|
||||
if (idx < pkiMsgSz)
|
||||
#endif
|
||||
{
|
||||
haveAttribs = 1;
|
||||
|
||||
ret = wc_PKCS7_DecodeUnprotectedAttributes(pkcs7, pkiMsg,
|
||||
@@ -9868,13 +10122,15 @@ int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* in, word32 inSz,
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("Error in unknown PKCS#7 state");
|
||||
WOLFSSL_MSG("Error in unknown PKCS#7 Decode Encrypted Data state");
|
||||
return BAD_STATE_E;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
/* restart in error case */
|
||||
wc_PKCS7_ResetStream(pkcs7);
|
||||
#endif
|
||||
wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
|
||||
}
|
||||
return ret;
|
||||
|
@@ -21411,6 +21411,20 @@ static int pkcs7signed_run_SingleShotVectors(
|
||||
wc_PKCS7_Free(pkcs7);
|
||||
return -9565;
|
||||
}
|
||||
#ifndef NO_PKCS7_STREAM
|
||||
{
|
||||
word32 z;
|
||||
for (z = 0; z < outSz && ret != 0; z++) {
|
||||
ret = wc_PKCS7_VerifySignedData(pkcs7, out + z, 1);
|
||||
if (ret < 0 && ret != WC_PKCS7_WANT_READ_E) {
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wc_PKCS7_Free(pkcs7);
|
||||
printf("unexpected error %d\n", ret);
|
||||
return -9565;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0) {
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
@@ -96,6 +96,12 @@ enum PKCS7_STATE {
|
||||
WC_PKCS7_STAGE5,
|
||||
WC_PKCS7_STAGE6,
|
||||
|
||||
WC_PKCS7_VERIFY_STAGE2,
|
||||
WC_PKCS7_VERIFY_STAGE3,
|
||||
WC_PKCS7_VERIFY_STAGE4,
|
||||
WC_PKCS7_VERIFY_STAGE5,
|
||||
WC_PKCS7_VERIFY_STAGE6,
|
||||
|
||||
/* parse info set */
|
||||
WC_PKCS7_INFOSET_START,
|
||||
WC_PKCS7_INFOSET_BER,
|
||||
|
Reference in New Issue
Block a user