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,
|
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(NULL, hashBuf, hashSz, outputHead,
|
||||||
outputHeadSz, outputFoot, outputFootSz), BAD_FUNC_ARG);
|
outputHeadSz, outputFoot, outputFootSz), BAD_FUNC_ARG);
|
||||||
|
|
||||||
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, NULL, hashSz, outputHead,
|
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,
|
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,
|
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz, NULL,
|
||||||
outputHeadSz, outputFoot, outputFootSz), BAD_FUNC_ARG);
|
outputHeadSz, outputFoot, outputFootSz), BAD_FUNC_ARG);
|
||||||
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz,
|
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz,
|
||||||
outputHead, 0, outputFoot, outputFootSz), BAD_FUNC_ARG);
|
outputHead, 0, outputFoot, outputFootSz), BAD_FUNC_ARG);
|
||||||
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(pkcs7, hashBuf, hashSz,
|
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,
|
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);
|
printf(resultFmt, passed);
|
||||||
|
|
||||||
|
@@ -58,7 +58,6 @@ typedef enum {
|
|||||||
WC_PKCS7_DECODE
|
WC_PKCS7_DECODE
|
||||||
} pkcs7Direction;
|
} pkcs7Direction;
|
||||||
|
|
||||||
|
|
||||||
#ifndef NO_PKCS7_STREAM
|
#ifndef NO_PKCS7_STREAM
|
||||||
|
|
||||||
#define MAX_PKCS7_STREAM_BUFFER 256
|
#define MAX_PKCS7_STREAM_BUFFER 256
|
||||||
@@ -68,6 +67,8 @@ typedef struct PKCS7State {
|
|||||||
byte* nonce; /* stored nonce */
|
byte* nonce; /* stored nonce */
|
||||||
byte* aad; /* additional data for AEAD algos */
|
byte* aad; /* additional data for AEAD algos */
|
||||||
byte* tag; /* tag 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 */
|
/* stack variables to store for when returning */
|
||||||
word32 varOne;
|
word32 varOne;
|
||||||
@@ -85,6 +86,7 @@ typedef struct PKCS7State {
|
|||||||
word32 nonceSz; /* size of nonce stored */
|
word32 nonceSz; /* size of nonce stored */
|
||||||
word32 aadSz; /* size of additional AEAD data */
|
word32 aadSz; /* size of additional AEAD data */
|
||||||
word32 tagSz; /* size of tag for AEAD */
|
word32 tagSz; /* size of tag for AEAD */
|
||||||
|
word32 contentSz;
|
||||||
byte tmpIv[MAX_CONTENT_IV_SIZE]; /* store IV if needed */
|
byte tmpIv[MAX_CONTENT_IV_SIZE]; /* store IV if needed */
|
||||||
#ifdef WC_PKCS7_STREAM_DEBUG
|
#ifdef WC_PKCS7_STREAM_DEBUG
|
||||||
word32 peakUsed; /* most bytes used for struct at any one time */
|
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) {
|
if (pkcs7 != NULL && pkcs7->stream != NULL) {
|
||||||
wc_PKCS7_ResetStream(pkcs7);
|
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);
|
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_2: return "WC_PKCS7_DECRYPT_KTRI_2";
|
||||||
case WC_PKCS7_DECRYPT_KTRI_3: return "WC_PKCS7_DECRYPT_KTRI_3";
|
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_KARI: return "WC_PKCS7_DECRYPT_KARI";
|
||||||
case WC_PKCS7_DECRYPT_KEKRI: return "WC_PKCS7_DECRYPT_KEKRI";
|
case WC_PKCS7_DECRYPT_KEKRI: return "WC_PKCS7_DECRYPT_KEKRI";
|
||||||
case WC_PKCS7_DECRYPT_PWRI: return "WC_PKCS7_DECRYPT_PWRI";
|
case WC_PKCS7_DECRYPT_PWRI: return "WC_PKCS7_DECRYPT_PWRI";
|
||||||
case WC_PKCS7_DECRYPT_ORI: return "WC_PKCS7_DECRYPT_ORI";
|
case WC_PKCS7_DECRYPT_ORI: return "WC_PKCS7_DECRYPT_ORI";
|
||||||
|
|
||||||
case WC_PKCS7_DECRYPT_DONE: return "WC_PKCS7_DECRYPT_DONE";
|
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:
|
default:
|
||||||
return "Unknown state";
|
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);
|
ret = wc_RsaSSL_Verify(sig, sigSz, digest, MAX_PKCS7_DIGEST_SZ, key);
|
||||||
|
|
||||||
FreeDecodedCert(dCert);
|
FreeDecodedCert(dCert);
|
||||||
wc_FreeRsaKey(key);
|
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.
|
* signer is required. In this case the PKCS7 flag noDegenerate could be set.
|
||||||
*/
|
*/
|
||||||
static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
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)
|
byte* pkiMsg2, word32 pkiMsg2Sz)
|
||||||
{
|
{
|
||||||
word32 idx, outerContentType, hashOID, sigOID, contentTypeSz, totalSz;
|
word32 idx, outerContentType, hashOID, sigOID, contentTypeSz = 0, totalSz = 0;
|
||||||
int length, version, ret;
|
int length, version, ret;
|
||||||
byte* content = NULL;
|
byte* content = NULL;
|
||||||
byte* contentDynamic = NULL;
|
byte* contentDynamic = NULL;
|
||||||
@@ -3143,18 +3152,46 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
|||||||
byte* contentType = NULL;
|
byte* contentType = NULL;
|
||||||
int contentSz = 0, sigSz = 0, certSz = 0, signedAttribSz = 0;
|
int contentSz = 0, sigSz = 0, certSz = 0, signedAttribSz = 0;
|
||||||
word32 localIdx, start;
|
word32 localIdx, start;
|
||||||
byte degenerate;
|
byte degenerate = 0;
|
||||||
#ifdef ASN_BER_TO_DER
|
#ifdef ASN_BER_TO_DER
|
||||||
byte* der;
|
byte* der;
|
||||||
#endif
|
#endif
|
||||||
int multiPart = 0, keepContent;
|
int multiPart = 0, keepContent;
|
||||||
int contentLen;
|
int contentLen;
|
||||||
|
|
||||||
|
byte* pkiMsg = in;
|
||||||
|
word32 pkiMsgSz = inSz;
|
||||||
|
word32 stateIdx = 0;
|
||||||
|
|
||||||
if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0)
|
if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
if ((hashSz > 0 && hashBuf == NULL) || (pkiMsg2Sz > 0 && pkiMsg2 == NULL)) {
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
idx = 0;
|
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 */
|
/* determine total message size */
|
||||||
totalSz = pkiMsgSz;
|
totalSz = pkiMsgSz;
|
||||||
if (pkiMsg2 && pkiMsg2Sz > 0) {
|
if (pkiMsg2 && pkiMsg2Sz > 0) {
|
||||||
@@ -3229,6 +3266,30 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
|||||||
return PKCS7_NO_SIGNER_E;
|
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 */
|
/* Get the inner ContentInfo sequence */
|
||||||
if (GetSequence(pkiMsg, &idx, &length, totalSz) < 0)
|
if (GetSequence(pkiMsg, &idx, &length, totalSz) < 0)
|
||||||
return ASN_PARSE_E;
|
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)
|
if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, totalSz) <= 0)
|
||||||
ret = ASN_PARSE_E;
|
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)) {
|
if (ret == 0 && pkiMsg[localIdx] == (ASN_OCTET_STRING | ASN_CONSTRUCTED)) {
|
||||||
multiPart = 1;
|
multiPart = 1;
|
||||||
|
|
||||||
@@ -3278,6 +3341,78 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
|||||||
localIdx = start;
|
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) {
|
if (ret == 0 && multiPart) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
keepContent = !(pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0);
|
keepContent = !(pkiMsg2 && pkiMsg2Sz > 0 && hashBuf && hashSz > 0);
|
||||||
@@ -3310,38 +3445,9 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
|||||||
localIdx += length;
|
localIdx += length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
localIdx = start; /* reset for sanity check, increment later */
|
||||||
length = i;
|
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. */
|
/* Save the inner data as the content. */
|
||||||
if (ret == 0 && length > 0) {
|
if (ret == 0 && length > 0) {
|
||||||
@@ -3358,9 +3464,18 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if ((word32)length > pkiMsgSz - localIdx) {
|
||||||
|
return BUFFER_E;
|
||||||
|
}
|
||||||
|
|
||||||
/* Content pointer for calculating hashes later */
|
/* Content pointer for calculating hashes later */
|
||||||
|
if (ret == 0 && !multiPart) {
|
||||||
content = &pkiMsg[localIdx];
|
content = &pkiMsg[localIdx];
|
||||||
localIdx += length;
|
}
|
||||||
|
if (ret == 0 && multiPart) {
|
||||||
|
content = pkcs7->contentDynamic;
|
||||||
|
}
|
||||||
|
idx += length;
|
||||||
|
|
||||||
pkiMsg2 = pkiMsg;
|
pkiMsg2 = pkiMsg;
|
||||||
pkiMsg2Sz = pkiMsgSz;
|
pkiMsg2Sz = pkiMsgSz;
|
||||||
@@ -3369,15 +3484,6 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
|||||||
else {
|
else {
|
||||||
pkiMsg2 = pkiMsg;
|
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
|
/* If getting the content info failed with non degenerate then return the
|
||||||
* error case. Otherwise with a degenerate it is ok if the content
|
* 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)
|
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||||
return ASN_PARSE_E;
|
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) {
|
if (length > 0) {
|
||||||
/* At this point, idx is at the first certificate in
|
/* At this point, idx is at the first certificate in
|
||||||
* a set of certificates. There may be more than one,
|
* 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];
|
cert = &pkiMsg2[idx];
|
||||||
certSz += (certIdx - idx);
|
certSz += (certIdx - idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ASN_BER_TO_DER
|
#ifdef ASN_BER_TO_DER
|
||||||
der = pkcs7->der;
|
der = pkcs7->der;
|
||||||
#endif
|
#endif
|
||||||
contentDynamic = pkcs7->contentDynamic;
|
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;
|
pkcs7->contentDynamic = contentDynamic;
|
||||||
#ifdef ASN_BER_TO_DER
|
#ifdef ASN_BER_TO_DER
|
||||||
pkcs7->der = der;
|
pkcs7->der = der;
|
||||||
@@ -3450,6 +3624,36 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
|||||||
pkcs7->content = content;
|
pkcs7->content = content;
|
||||||
pkcs7->contentSz = contentSz;
|
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 */
|
/* set contentType and size after init of PKCS7 structure */
|
||||||
if (wc_PKCS7_SetContentType(pkcs7, contentType, contentTypeSz) < 0)
|
if (wc_PKCS7_SetContentType(pkcs7, contentType, contentTypeSz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
@@ -3468,6 +3672,38 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
|||||||
if (GetSet(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
if (GetSet(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||||
return ASN_PARSE_E;
|
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 */
|
/* require a signer if degenerate case not allowed */
|
||||||
if (length == 0 && pkcs7->noDegenerate == 1)
|
if (length == 0 && pkcs7->noDegenerate == 1)
|
||||||
return PKCS7_NO_SIGNER_E;
|
return PKCS7_NO_SIGNER_E;
|
||||||
@@ -3488,7 +3724,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
|||||||
|
|
||||||
if (version == 1) {
|
if (version == 1) {
|
||||||
/* Get the sequence of IssuerAndSerialNumber */
|
/* Get the sequence of IssuerAndSerialNumber */
|
||||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
if (GetSequence(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
/* Skip it */
|
/* Skip it */
|
||||||
@@ -3496,19 +3732,21 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
|||||||
|
|
||||||
} else if (version == 3) {
|
} else if (version == 3) {
|
||||||
/* Get the sequence of SubjectKeyIdentifier */
|
/* Get the sequence of SubjectKeyIdentifier */
|
||||||
if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
|
if (pkiMsg2[idx++] != (ASN_CONSTRUCTED |
|
||||||
ret = ASN_PARSE_E;
|
ASN_CONTEXT_SPECIFIC | 0)) {
|
||||||
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) <= 0) {
|
if (ret == 0 && GetLength(pkiMsg2, &idx, &length,
|
||||||
ret = ASN_PARSE_E;
|
pkiMsg2Sz) <= 0) {
|
||||||
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0 && pkiMsg[idx++] != ASN_OCTET_STRING)
|
if (ret == 0 && pkiMsg2[idx++] != ASN_OCTET_STRING)
|
||||||
ret = ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
if (ret == 0 && GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||||
ret = ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
/* Skip it */
|
/* Skip it */
|
||||||
idx += length;
|
idx += length;
|
||||||
@@ -3575,11 +3813,26 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
|||||||
ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,
|
ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,
|
||||||
signedAttrib, signedAttribSz,
|
signedAttrib, signedAttribSz,
|
||||||
hashBuf, hashSz);
|
hashBuf, hashSz);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
return ret;
|
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);
|
wc_PKCS7_FreeDecodedAttrib(pkcs7->decodedAttrib, pkcs7->heap);
|
||||||
pkcs7->decodedAttrib = NULL;
|
pkcs7->decodedAttrib = NULL;
|
||||||
#ifndef NO_PKCS7_STREAM
|
#ifndef NO_PKCS7_STREAM
|
||||||
if (pkcs7->stream->hasAtrib) {
|
if (pkcs7->stream->hasAtrib)
|
||||||
#else
|
#else
|
||||||
if (idx < pkiMsgSz) {
|
if (idx < pkiMsgSz)
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
haveAttribs = 1;
|
haveAttribs = 1;
|
||||||
|
|
||||||
ret = wc_PKCS7_DecodeUnprotectedAttributes(pkcs7, pkiMsg,
|
ret = wc_PKCS7_DecodeUnprotectedAttributes(pkcs7, pkiMsg,
|
||||||
@@ -9868,13 +10122,15 @@ int wc_PKCS7_DecodeEncryptedData(PKCS7* pkcs7, byte* in, word32 inSz,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
WOLFSSL_MSG("Error in unknown PKCS#7 state");
|
WOLFSSL_MSG("Error in unknown PKCS#7 Decode Encrypted Data state");
|
||||||
return BAD_STATE_E;
|
return BAD_STATE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
#ifndef NO_PKCS7_STREAM
|
||||||
/* restart in error case */
|
/* restart in error case */
|
||||||
wc_PKCS7_ResetStream(pkcs7);
|
wc_PKCS7_ResetStream(pkcs7);
|
||||||
|
#endif
|
||||||
wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
|
wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@@ -21411,6 +21411,20 @@ static int pkcs7signed_run_SingleShotVectors(
|
|||||||
wc_PKCS7_Free(pkcs7);
|
wc_PKCS7_Free(pkcs7);
|
||||||
return -9565;
|
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) {
|
if (pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0) {
|
||||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
@@ -96,6 +96,12 @@ enum PKCS7_STATE {
|
|||||||
WC_PKCS7_STAGE5,
|
WC_PKCS7_STAGE5,
|
||||||
WC_PKCS7_STAGE6,
|
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 */
|
/* parse info set */
|
||||||
WC_PKCS7_INFOSET_START,
|
WC_PKCS7_INFOSET_START,
|
||||||
WC_PKCS7_INFOSET_BER,
|
WC_PKCS7_INFOSET_BER,
|
||||||
|
Reference in New Issue
Block a user