mirror of https://github.com/wolfSSL/wolfssl.git
Merge pull request #1780 from dgarske/pkcs7_ex
Added new PKCS7 ex API's to support signing and validation of large datapull/1782/head
commit
cc39f3211a
|
@ -174,6 +174,7 @@ WOLFSSL_API int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output,
|
|||
PKCS7 pkcs7;
|
||||
int ret;
|
||||
|
||||
byte data[] = {}; // initialize with data to sign
|
||||
byte derBuff[] = { }; // initialize with DER-encoded certificate
|
||||
byte pkcs7Buff[FOURK_BUF];
|
||||
|
||||
|
@ -183,12 +184,16 @@ WOLFSSL_API int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output,
|
|||
pkcs7.privateKeySz = keySz;
|
||||
pkcs7.content = data;
|
||||
pkcs7.contentSz = dataSz;
|
||||
pkcs7.hashOID = SHAh;
|
||||
pkcs7.rng = &rng;
|
||||
... etc.
|
||||
|
||||
ret = wc_PKCS7_EncodeSignedData(&pkcs7, pkcs7Buff, sizeof(pkcs7Buff));
|
||||
if ( ret != 0 ) {
|
||||
// error encoding into output buffer
|
||||
}
|
||||
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
\endcode
|
||||
|
||||
\sa wc_PKCS7_InitWithCert
|
||||
|
@ -197,6 +202,107 @@ WOLFSSL_API int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output,
|
|||
WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7,
|
||||
byte* output, word32 outputSz);
|
||||
|
||||
/*!
|
||||
\ingroup PKCS7
|
||||
|
||||
\brief This function builds the PKCS7 signed data content type, encoding
|
||||
the PKCS7 structure into a header and footer buffer containing a parsable PKCS7
|
||||
signed data packet. This does not include the content.
|
||||
A hash must be computed and provided for the data
|
||||
|
||||
\return 0=Success
|
||||
\return BAD_FUNC_ARG Returned if the PKCS7 structure is missing one or
|
||||
more required elements to generate a signed data packet
|
||||
\return MEMORY_E Returned if there is an error allocating memory
|
||||
\return PUBLIC_KEY_E Returned if there is an error parsing the public key
|
||||
\return RSA_BUFFER_E Returned if buffer error, output too small or input
|
||||
too large
|
||||
\return BUFFER_E Returned if the given buffer is not large enough to hold
|
||||
the encoded certificate
|
||||
\return MP_INIT_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_READ_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_CMP_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_INVMOD_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_EXPTMOD_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_MOD_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_MUL_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_ADD_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_MULMOD_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_TO_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_MEM may be returned if there is an error generating the signature
|
||||
|
||||
\param pkcs7 pointer to the PKCS7 structure to encode
|
||||
\param hashBuf pointer to computed hash for the content data
|
||||
\param hashSz size of the digest
|
||||
\param outputHead pointer to the buffer in which to store the
|
||||
encoded certificate header
|
||||
\param outputHeadSz pointer populated with size of output header buffer
|
||||
and returns actual size
|
||||
\param outputFoot pointer to the buffer in which to store the
|
||||
encoded certificate footer
|
||||
\param outputFootSz pointer populated with size of output footer buffer
|
||||
and returns actual size
|
||||
|
||||
_Example_
|
||||
\code
|
||||
PKCS7 pkcs7;
|
||||
int ret;
|
||||
byte derBuff[] = { }; // initialize with DER-encoded certificate
|
||||
byte data[] = {}; // initialize with data to sign
|
||||
byte pkcs7HeadBuff[FOURK_BUF/2];
|
||||
byte pkcs7FootBuff[FOURK_BUF/2];
|
||||
word32 pkcs7HeadSz = (word32)sizeof(pkcs7HeadBuff);
|
||||
word32 pkcs7FootSz = (word32)sizeof(pkcs7HeadBuff);
|
||||
enum wc_HashType hashType = WC_HASH_TYPE_SHA;
|
||||
byte hashBuf[WC_MAX_DIGEST_SIZE];
|
||||
word32 hashSz = wc_HashGetDigestSize(hashType);
|
||||
|
||||
wc_PKCS7_InitWithCert(&pkcs7, derBuff, sizeof(derBuff));
|
||||
// update message and data to encode
|
||||
pkcs7.privateKey = key;
|
||||
pkcs7.privateKeySz = keySz;
|
||||
pkcs7.content = NULL;
|
||||
pkcs7.contentSz = dataSz;
|
||||
pkcs7.hashOID = SHAh;
|
||||
pkcs7.rng = &rng;
|
||||
... etc.
|
||||
|
||||
// calculate hash for content
|
||||
ret = wc_HashInit(&hash, hashType);
|
||||
if (ret == 0) {
|
||||
ret = wc_HashUpdate(&hash, hashType, data, sizeof(data));
|
||||
if (ret == 0) {
|
||||
ret = wc_HashFinal(&hash, hashType, hashBuf);
|
||||
}
|
||||
wc_HashFree(&hash, hashType);
|
||||
}
|
||||
|
||||
ret = wc_PKCS7_EncodeSignedData_ex(&pkcs7, hashBuf, hashSz, pkcs7HeadBuff,
|
||||
&pkcs7HeadSz, pkcs7FootBuff, &pkcs7FootSz);
|
||||
if ( ret != 0 ) {
|
||||
// error encoding into output buffer
|
||||
}
|
||||
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
\endcode
|
||||
|
||||
\sa wc_PKCS7_InitWithCert
|
||||
\sa wc_PKCS7_VerifySignedData_ex
|
||||
*/
|
||||
WOLFSSL_API int wc_PKCS7_EncodeSignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
|
||||
word32 hashSz, byte* outputHead, word32* outputHeadSz, byte* outputFoot,
|
||||
word32* outputFootSz);
|
||||
|
||||
/*!
|
||||
\ingroup PKCS7
|
||||
|
||||
|
@ -250,11 +356,9 @@ WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7,
|
|||
\code
|
||||
PKCS7 pkcs7;
|
||||
int ret;
|
||||
byte pkcs7Buff[] = {}; // the PKCS7 signature
|
||||
|
||||
byte derBuff[] = { }; // initialize with DER-encoded certificate
|
||||
byte pkcs7Buff[FOURK_BUF];
|
||||
|
||||
wc_PKCS7_InitWithCert(&pkcs7, derBuff, sizeof(derBuff));
|
||||
wc_PKCS7_InitWithCert(&pkcs7, NULL, 0);
|
||||
// update message and data to encode
|
||||
pkcs7.privateKey = key;
|
||||
pkcs7.privateKeySz = keySz;
|
||||
|
@ -262,10 +366,12 @@ WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7,
|
|||
pkcs7.contentSz = dataSz;
|
||||
... etc.
|
||||
|
||||
ret = wc_PKCS7_EncodeSignedData(&pkcs7, pkcs7Buff, sizeof(pkcs7Buff));
|
||||
ret = wc_PKCS7_VerifySignedData(&pkcs7, pkcs7Buff, sizeof(pkcs7Buff));
|
||||
if ( ret != 0 ) {
|
||||
// error encoding into output buffer
|
||||
}
|
||||
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
\endcode
|
||||
|
||||
\sa wc_PKCS7_InitWithCert
|
||||
|
@ -274,6 +380,107 @@ WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7,
|
|||
WOLFSSL_API int wc_PKCS7_VerifySignedData(PKCS7* pkcs7,
|
||||
byte* pkiMsg, word32 pkiMsgSz);
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup PKCS7
|
||||
|
||||
\brief This function takes in a transmitted PKCS7 signed data message as
|
||||
hash/header/footer, then extracts the certificate list and certificate
|
||||
revocation list, and then verifies the signature. It stores the extracted
|
||||
content in the given PKCS7 structure.
|
||||
|
||||
\return 0 Returned on successfully extracting the information
|
||||
from the message
|
||||
\return BAD_FUNC_ARG Returned if one of the input parameters is invalid
|
||||
\return ASN_PARSE_E Returned if there is an error parsing from the
|
||||
given pkiMsg
|
||||
\return PKCS7_OID_E Returned if the given pkiMsg is not a signed data type
|
||||
\return ASN_VERSION_E Returned if the PKCS7 signer info is not version 1
|
||||
\return MEMORY_E Returned if there is an error allocating memory
|
||||
\return PUBLIC_KEY_E Returned if there is an error parsing the public key
|
||||
\return RSA_BUFFER_E Returned if buffer error, output too small or
|
||||
input too large
|
||||
\return BUFFER_E Returned if the given buffer is not large enough to
|
||||
hold the encoded certificate
|
||||
\return MP_INIT_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_READ_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_CMP_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_INVMOD_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_EXPTMOD_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_MOD_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_MUL_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_ADD_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_MULMOD_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_TO_E may be returned if there is an error generating
|
||||
the signature
|
||||
\return MP_MEM may be returned if there is an error generating the signature
|
||||
|
||||
\param pkcs7 pointer to the PKCS7 structure in which to store the parsed
|
||||
certificates
|
||||
\param hashBuf pointer to computed hash for the content data
|
||||
\param hashSz size of the digest
|
||||
\param pkiMsgHead pointer to the buffer containing the signed message header
|
||||
to verify and decode
|
||||
\param pkiMsgHeadSz size of the signed message header
|
||||
\param pkiMsgFoot pointer to the buffer containing the signed message footer
|
||||
to verify and decode
|
||||
\param pkiMsgFootSz size of the signed message footer
|
||||
|
||||
_Example_
|
||||
\code
|
||||
PKCS7 pkcs7;
|
||||
int ret;
|
||||
byte data[] = {}; // initialize with data to sign
|
||||
byte pkcs7HeadBuff[] = {}; // initialize with PKCS7 header
|
||||
byte pkcs7FootBuff[] = {}; // initialize with PKCS7 footer
|
||||
enum wc_HashType hashType = WC_HASH_TYPE_SHA;
|
||||
byte hashBuf[WC_MAX_DIGEST_SIZE];
|
||||
word32 hashSz = wc_HashGetDigestSize(hashType);
|
||||
|
||||
wc_PKCS7_InitWithCert(&pkcs7, NULL, 0);
|
||||
// update message and data to encode
|
||||
pkcs7.privateKey = key;
|
||||
pkcs7.privateKeySz = keySz;
|
||||
pkcs7.content = NULL;
|
||||
pkcs7.contentSz = dataSz;
|
||||
pkcs7.rng = &rng;
|
||||
... etc.
|
||||
|
||||
// calculate hash for content
|
||||
ret = wc_HashInit(&hash, hashType);
|
||||
if (ret == 0) {
|
||||
ret = wc_HashUpdate(&hash, hashType, data, sizeof(data));
|
||||
if (ret == 0) {
|
||||
ret = wc_HashFinal(&hash, hashType, hashBuf);
|
||||
}
|
||||
wc_HashFree(&hash, hashType);
|
||||
}
|
||||
|
||||
ret = wc_PKCS7_VerifySignedData_ex(&pkcs7, hashBuf, hashSz, pkcs7HeadBuff,
|
||||
sizeof(pkcs7HeadBuff), pkcs7FootBuff, sizeof(pkcs7FootBuff));
|
||||
if ( ret != 0 ) {
|
||||
// error encoding into output buffer
|
||||
}
|
||||
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
\endcode
|
||||
|
||||
\sa wc_PKCS7_InitWithCert
|
||||
\sa wc_PKCS7_EncodeSignedData_ex
|
||||
*/
|
||||
WOLFSSL_API int wc_PKCS7_VerifySignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
|
||||
word32 hashSz, byte* pkiMsgHead, word32 pkiMsgHeadSz, byte* pkiMsgFoot,
|
||||
word32 pkiMsgFootSz);
|
||||
|
||||
/*!
|
||||
\ingroup PKCS7
|
||||
|
||||
|
|
196
tests/api.c
196
tests/api.c
|
@ -14525,7 +14525,7 @@ static void test_wc_PKCS7_EncodeData (void)
|
|||
/*
|
||||
* Testing wc_PKCS7_EncodeSignedData()
|
||||
*/
|
||||
static void test_wc_PKCS7_EncodeSignedData (void)
|
||||
static void test_wc_PKCS7_EncodeSignedData(void)
|
||||
{
|
||||
#if defined(HAVE_PKCS7)
|
||||
PKCS7 pkcs7;
|
||||
|
@ -14628,6 +14628,8 @@ static void test_wc_PKCS7_EncodeSignedData (void)
|
|||
AssertIntEQ(wc_PKCS7_EncodeSignedData(&pkcs7, NULL, outputSz), BAD_FUNC_ARG);
|
||||
AssertIntEQ(wc_PKCS7_EncodeSignedData(&pkcs7, badOut,
|
||||
badOutSz), BAD_FUNC_ARG);
|
||||
pkcs7.hashOID = 0; /* bad hashOID */
|
||||
AssertIntEQ(wc_PKCS7_EncodeSignedData(&pkcs7, output, outputSz), BAD_FUNC_ARG);
|
||||
|
||||
printf(resultFmt, passed);
|
||||
|
||||
|
@ -14637,6 +14639,197 @@ static void test_wc_PKCS7_EncodeSignedData (void)
|
|||
#endif
|
||||
} /* END test_wc_PKCS7_EncodeSignedData */
|
||||
|
||||
/*
|
||||
* Testing wc_PKCS7_EncodeSignedData_ex() and wc_PKCS7_VerifySignedData_ex()
|
||||
*/
|
||||
static void test_wc_PKCS7_EncodeSignedData_ex(void)
|
||||
{
|
||||
#if defined(HAVE_PKCS7)
|
||||
int ret, i;
|
||||
PKCS7 pkcs7;
|
||||
WC_RNG rng;
|
||||
byte outputHead[FOURK_BUF/2];
|
||||
byte outputFoot[FOURK_BUF/2];
|
||||
word32 outputHeadSz = (word32)sizeof(outputHead);
|
||||
word32 outputFootSz = (word32)sizeof(outputFoot);
|
||||
byte data[FOURK_BUF];
|
||||
wc_HashAlg hash;
|
||||
enum wc_HashType hashType = WC_HASH_TYPE_SHA;
|
||||
byte hashBuf[WC_MAX_DIGEST_SIZE];
|
||||
word32 hashSz = wc_HashGetDigestSize(hashType);
|
||||
|
||||
#ifndef NO_RSA
|
||||
#if defined(USE_CERT_BUFFERS_2048)
|
||||
byte key[sizeof_client_key_der_2048];
|
||||
byte cert[sizeof_client_cert_der_2048];
|
||||
word32 keySz = (word32)sizeof(key);
|
||||
word32 certSz = (word32)sizeof(cert);
|
||||
XMEMSET(key, 0, keySz);
|
||||
XMEMSET(cert, 0, certSz);
|
||||
XMEMCPY(key, client_key_der_2048, keySz);
|
||||
XMEMCPY(cert, client_cert_der_2048, certSz);
|
||||
#elif defined(USE_CERT_BUFFERS_1024)
|
||||
byte key[sizeof_client_key_der_1024];
|
||||
byte cert[sizeof_client_cert_der_1024];
|
||||
word32 keySz = (word32)sizeof(key);
|
||||
word32 certSz = (word32)sizeof(cert);
|
||||
XMEMSET(key, 0, keySz);
|
||||
XMEMSET(cert, 0, certSz);
|
||||
XMEMCPY(key, client_key_der_1024, keySz);
|
||||
XMEMCPY(cert, client_cert_der_1024, certSz);
|
||||
#else
|
||||
unsigned char cert[ONEK_BUF];
|
||||
unsigned char key[ONEK_BUF];
|
||||
FILE* fp;
|
||||
int certSz;
|
||||
int keySz;
|
||||
|
||||
fp = fopen("./certs/1024/client-cert.der", "rb");
|
||||
AssertNotNull(fp);
|
||||
certSz = fread(cert, 1, sizeof_client_cert_der_1024, fp);
|
||||
fclose(fp);
|
||||
|
||||
fp = fopen("./certs/1024/client-key.der", "rb");
|
||||
AssertNotNull(fp);
|
||||
keySz = fread(key, 1, sizeof_client_key_der_1024, fp);
|
||||
fclose(fp);
|
||||
#endif
|
||||
#elif defined(HAVE_ECC)
|
||||
#if defined(USE_CERT_BUFFERS_256)
|
||||
unsigned char cert[sizeof_cliecc_cert_der_256];
|
||||
unsigned char key[sizeof_ecc_clikey_der_256];
|
||||
int certSz = (int)sizeof(cert);
|
||||
int keySz = (int)sizeof(key);
|
||||
XMEMSET(cert, 0, certSz);
|
||||
XMEMSET(key, 0, keySz);
|
||||
XMEMCPY(cert, cliecc_cert_der_256, sizeof_cliecc_cert_der_256);
|
||||
XMEMCPY(key, ecc_clikey_der_256, sizeof_ecc_clikey_der_256);
|
||||
#else
|
||||
unsigned char cert[ONEK_BUF];
|
||||
unsigned char key[ONEK_BUF];
|
||||
FILE* fp;
|
||||
int certSz, keySz;
|
||||
|
||||
fp = fopen("./certs/client-ecc-cert.der", "rb");
|
||||
AssertNotNull(fp);
|
||||
certSz = fread(cert, 1, sizeof_cliecc_cert_der_256, fp);
|
||||
fclose(fp);
|
||||
|
||||
fp = fopen("./certs/client-ecc-key.der", "rb");
|
||||
AssertNotNull(fp);
|
||||
keySz = fread(key, 1, sizeof_ecc_clikey_der_256, fp);
|
||||
fclose(fp);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* initialize large data with sequence */
|
||||
for (i=0; i<(int)sizeof(data); i++)
|
||||
data[i] = i & 0xff;
|
||||
|
||||
XMEMSET(outputHead, 0, outputHeadSz);
|
||||
XMEMSET(outputFoot, 0, outputFootSz);
|
||||
AssertIntEQ(wc_InitRng(&rng), 0);
|
||||
|
||||
AssertIntEQ(wc_PKCS7_Init(&pkcs7, HEAP_HINT, INVALID_DEVID), 0);
|
||||
|
||||
AssertIntEQ(wc_PKCS7_InitWithCert(&pkcs7, cert, certSz), 0);
|
||||
|
||||
printf(testingFmt, "wc_PKCS7_EncodeSignedData()");
|
||||
|
||||
pkcs7.content = NULL; /* not used for ex */
|
||||
pkcs7.contentSz = (word32)sizeof(data);
|
||||
pkcs7.privateKey = key;
|
||||
pkcs7.privateKeySz = (word32)sizeof(key);
|
||||
pkcs7.encryptOID = RSAk;
|
||||
pkcs7.hashOID = SHAh;
|
||||
pkcs7.rng = &rng;
|
||||
|
||||
/* calculate hash for content */
|
||||
ret = wc_HashInit(&hash, hashType);
|
||||
if (ret == 0) {
|
||||
ret = wc_HashUpdate(&hash, hashType, data, sizeof(data));
|
||||
if (ret == 0) {
|
||||
ret = wc_HashFinal(&hash, hashType, hashBuf);
|
||||
}
|
||||
wc_HashFree(&hash, hashType);
|
||||
}
|
||||
AssertIntEQ(ret, 0);
|
||||
|
||||
/* Perform PKCS7 sign using hash directly */
|
||||
AssertIntEQ(wc_PKCS7_EncodeSignedData_ex(&pkcs7, hashBuf, hashSz,
|
||||
outputHead, &outputHeadSz, outputFoot, &outputFootSz), 0);
|
||||
AssertIntGT(outputHeadSz, 0);
|
||||
AssertIntGT(outputFootSz, 0);
|
||||
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
AssertIntEQ(wc_PKCS7_InitWithCert(&pkcs7, NULL, 0), 0);
|
||||
|
||||
/* required parameter even on verify when using _ex */
|
||||
pkcs7.contentSz = (word32)sizeof(data);
|
||||
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(&pkcs7, hashBuf, hashSz,
|
||||
outputHead, outputHeadSz, outputFoot, outputFootSz), 0);
|
||||
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
|
||||
/* assembly complete PKCS7 sign and use normal verify */
|
||||
{
|
||||
byte* output = (byte*)XMALLOC(outputHeadSz + sizeof(data) + outputFootSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
word32 outputSz = 0;
|
||||
AssertNotNull(output);
|
||||
XMEMCPY(&output[outputSz], outputHead, outputHeadSz);
|
||||
outputSz += outputHeadSz;
|
||||
XMEMCPY(&output[outputSz], data, sizeof(data));
|
||||
outputSz += sizeof(data);
|
||||
XMEMCPY(&output[outputSz], outputFoot, outputFootSz);
|
||||
outputSz += outputFootSz;
|
||||
|
||||
AssertIntEQ(wc_PKCS7_InitWithCert(&pkcs7, NULL, 0), 0);
|
||||
AssertIntEQ(wc_PKCS7_VerifySignedData(&pkcs7, output, outputSz), 0);
|
||||
XFREE(output, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
|
||||
/* Pass in bad args. */
|
||||
AssertIntEQ(wc_PKCS7_EncodeSignedData_ex(NULL, hashBuf, hashSz, outputHead,
|
||||
&outputHeadSz, outputFoot, &outputFootSz), BAD_FUNC_ARG);
|
||||
AssertIntEQ(wc_PKCS7_EncodeSignedData_ex(&pkcs7, NULL, hashSz, outputHead,
|
||||
&outputHeadSz, outputFoot, &outputFootSz), BAD_FUNC_ARG);
|
||||
AssertIntEQ(wc_PKCS7_EncodeSignedData_ex(&pkcs7, hashBuf, 0, outputHead,
|
||||
&outputHeadSz, outputFoot, &outputFootSz), BAD_FUNC_ARG);
|
||||
AssertIntEQ(wc_PKCS7_EncodeSignedData_ex(&pkcs7, hashBuf, hashSz, NULL,
|
||||
&outputHeadSz, outputFoot, &outputFootSz), BAD_FUNC_ARG);
|
||||
AssertIntEQ(wc_PKCS7_EncodeSignedData_ex(&pkcs7, hashBuf, hashSz,
|
||||
outputHead, NULL, outputFoot, &outputFootSz), BAD_FUNC_ARG);
|
||||
AssertIntEQ(wc_PKCS7_EncodeSignedData_ex(&pkcs7, hashBuf, hashSz,
|
||||
outputHead, &outputHeadSz, NULL, &outputFootSz), BAD_FUNC_ARG);
|
||||
AssertIntEQ(wc_PKCS7_EncodeSignedData_ex(&pkcs7, hashBuf, hashSz,
|
||||
outputHead, &outputHeadSz, outputFoot, NULL), BAD_FUNC_ARG);
|
||||
pkcs7.hashOID = 0; /* bad hashOID */
|
||||
AssertIntEQ(wc_PKCS7_EncodeSignedData_ex(&pkcs7, hashBuf, hashSz,
|
||||
outputHead, &outputHeadSz, outputFoot, &outputFootSz), BAD_FUNC_ARG);
|
||||
|
||||
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);
|
||||
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(&pkcs7, hashBuf, 0, outputHead,
|
||||
outputHeadSz, outputFoot, outputFootSz), ASN_PARSE_E);
|
||||
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);
|
||||
AssertIntEQ(wc_PKCS7_VerifySignedData_ex(&pkcs7, hashBuf, hashSz,
|
||||
outputHead, outputHeadSz, outputFoot, 0), ASN_PARSE_E);
|
||||
|
||||
printf(resultFmt, passed);
|
||||
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
wc_FreeRng(&rng);
|
||||
|
||||
#endif
|
||||
} /* END test_wc_PKCS7_EncodeSignedData_ex */
|
||||
|
||||
|
||||
/*
|
||||
* Testing wc_PKCS_VerifySignedData()
|
||||
|
@ -20656,6 +20849,7 @@ void ApiTest(void)
|
|||
test_wc_PKCS7_InitWithCert();
|
||||
test_wc_PKCS7_EncodeData();
|
||||
test_wc_PKCS7_EncodeSignedData();
|
||||
test_wc_PKCS7_EncodeSignedData_ex();
|
||||
test_wc_PKCS7_VerifySignedData();
|
||||
test_wc_PKCS7_EncodeDecodeEnvelopedData();
|
||||
test_wc_PKCS7_EncodeEncryptedData();
|
||||
|
|
|
@ -303,8 +303,7 @@ int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz)
|
|||
if (dCert == NULL)
|
||||
return MEMORY_E;
|
||||
#else
|
||||
DecodedCert stack_dCert;
|
||||
DecodedCert* dCert = &stack_dCert;
|
||||
DecodedCert dCert[1];
|
||||
#endif
|
||||
|
||||
pkcs7->singleCert = cert;
|
||||
|
@ -611,8 +610,7 @@ static int wc_PKCS7_RsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
|
|||
#ifdef WOLFSSL_SMALL_STACK
|
||||
RsaKey* privKey;
|
||||
#else
|
||||
RsaKey stack_privKey;
|
||||
RsaKey* privKey = &stack_privKey;
|
||||
RsaKey privKey[1];
|
||||
#endif
|
||||
|
||||
if (pkcs7 == NULL || pkcs7->rng == NULL || in == NULL || esd == NULL) {
|
||||
|
@ -664,8 +662,7 @@ static int wc_PKCS7_EcdsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
|
|||
#ifdef WOLFSSL_SMALL_STACK
|
||||
ecc_key* privKey;
|
||||
#else
|
||||
ecc_key stack_privKey;
|
||||
ecc_key* privKey = &stack_privKey;
|
||||
ecc_key privKey[1];
|
||||
#endif
|
||||
|
||||
if (pkcs7 == NULL || pkcs7->rng == NULL || in == NULL || esd == NULL) {
|
||||
|
@ -716,9 +713,9 @@ static int wc_PKCS7_EcdsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
|
|||
*
|
||||
* return 0 on success, negative on error */
|
||||
static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd,
|
||||
byte* contentTypeOid, word32 contentTypeOidSz,
|
||||
byte* contentType, word32 contentTypeSz,
|
||||
byte* messageDigestOid, word32 messageDigestOidSz)
|
||||
const byte* contentTypeOid, word32 contentTypeOidSz,
|
||||
const byte* contentType, word32 contentTypeSz,
|
||||
const byte* messageDigestOid, word32 messageDigestOidSz)
|
||||
{
|
||||
int hashSz;
|
||||
|
||||
|
@ -941,7 +938,7 @@ static int wc_PKCS7_BuildDigestInfo(PKCS7* pkcs7, byte* flatSignedAttribs,
|
|||
|
||||
/* build SignedData signature over DigestInfo or content digest
|
||||
*
|
||||
* pkcs7 - pointer to initizlied PKCS7 struct
|
||||
* pkcs7 - pointer to initialized PKCS7 struct
|
||||
* flatSignedAttribs - flattened, signed attributes
|
||||
* flatSignedAttribsSz - size of flatSignedAttribs, octets
|
||||
* esd - pointer to initialized ESD struct
|
||||
|
@ -960,7 +957,7 @@ static int wc_PKCS7_SignedDataBuildSignature(PKCS7* pkcs7,
|
|||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte* digestInfo;
|
||||
#else
|
||||
byte digestInfo[MAX_PKCS7_DIGEST_SZ];
|
||||
byte digestInfo[MAX_PKCS7_DIGEST_SZ];
|
||||
#endif
|
||||
|
||||
if (pkcs7 == NULL || esd == NULL)
|
||||
|
@ -1027,88 +1024,55 @@ static int wc_PKCS7_SignedDataBuildSignature(PKCS7* pkcs7,
|
|||
}
|
||||
|
||||
/* build PKCS#7 signedData content type */
|
||||
int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
||||
static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd,
|
||||
const byte* hashBuf, word32 hashSz, byte* output, word32* outputSz,
|
||||
byte* output2, word32* output2Sz)
|
||||
{
|
||||
static const byte outerOid[] =
|
||||
{ ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
|
||||
0x07, 0x02 };
|
||||
static const byte innerOid[] =
|
||||
{ ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
|
||||
0x07, 0x01 };
|
||||
const byte outerOid[] =
|
||||
{ ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
|
||||
0x07, 0x02 };
|
||||
const byte innerOid[] =
|
||||
{ ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
|
||||
0x07, 0x01 };
|
||||
|
||||
byte contentTypeOid[] =
|
||||
const byte contentTypeOid[] =
|
||||
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
|
||||
0x09, 0x03 };
|
||||
byte contentType[] =
|
||||
const byte contentType[] =
|
||||
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
|
||||
0x07, 0x01 };
|
||||
byte messageDigestOid[] =
|
||||
const byte messageDigestOid[] =
|
||||
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
|
||||
0x09, 0x04 };
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
ESD* esd = NULL;
|
||||
#else
|
||||
ESD stack_esd;
|
||||
ESD* esd = &stack_esd;
|
||||
#endif
|
||||
|
||||
word32 signerInfoSz = 0;
|
||||
word32 totalSz = 0;
|
||||
word32 totalSz, total2Sz;
|
||||
int idx = 0, ret = 0;
|
||||
int digEncAlgoId, digEncAlgoType, hashSz;
|
||||
int digEncAlgoId, digEncAlgoType;
|
||||
byte* flatSignedAttribs = NULL;
|
||||
word32 flatSignedAttribsSz = 0;
|
||||
word32 innerOidSz = sizeof(innerOid);
|
||||
word32 outerOidSz = sizeof(outerOid);
|
||||
|
||||
if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
|
||||
if (pkcs7 == NULL || pkcs7->contentSz == 0 ||
|
||||
pkcs7->encryptOID == 0 || pkcs7->hashOID == 0 || pkcs7->rng == 0 ||
|
||||
pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0 ||
|
||||
output == NULL || outputSz == 0) {
|
||||
output == NULL || outputSz == NULL || *outputSz == 0 || hashSz == 0 ||
|
||||
hashBuf == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (esd == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
XMEMSET(esd, 0, sizeof(ESD));
|
||||
|
||||
/* verify the hash size matches */
|
||||
esd->hashType = wc_OidGetHash(pkcs7->hashOID);
|
||||
ret = wc_HashGetDigestSize(esd->hashType);
|
||||
if (ret < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
if (wc_HashGetDigestSize(esd->hashType) != (int)hashSz) {
|
||||
WOLFSSL_MSG("hashSz did not match hashOID");
|
||||
return BUFFER_E;
|
||||
}
|
||||
hashSz = ret;
|
||||
|
||||
if (pkcs7->contentSz != 0)
|
||||
{
|
||||
ret = wc_HashInit(&esd->hash, esd->hashType);
|
||||
if (ret == 0) {
|
||||
ret = wc_HashUpdate(&esd->hash, esd->hashType,
|
||||
pkcs7->content, pkcs7->contentSz);
|
||||
if (ret == 0) {
|
||||
esd->contentDigest[0] = ASN_OCTET_STRING;
|
||||
esd->contentDigest[1] = (byte)hashSz;
|
||||
ret = wc_HashFinal(&esd->hash, esd->hashType,
|
||||
&esd->contentDigest[2]);
|
||||
}
|
||||
wc_HashFree(&esd->hash, esd->hashType);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
/* include hash */
|
||||
esd->contentDigest[0] = ASN_OCTET_STRING;
|
||||
esd->contentDigest[1] = (byte)hashSz;
|
||||
XMEMCPY(&esd->contentDigest[2], hashBuf, hashSz);
|
||||
|
||||
esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets);
|
||||
esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz + pkcs7->contentSz,
|
||||
|
@ -1134,9 +1098,6 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||
ret = wc_PKCS7_SignedDataGetEncAlgoId(pkcs7, &digEncAlgoId,
|
||||
&digEncAlgoType);
|
||||
if (ret < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
esd->digEncAlgoIdSz = SetAlgoID(digEncAlgoId, esd->digEncAlgoId,
|
||||
|
@ -1151,9 +1112,6 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||
contentType, sizeof(contentType),
|
||||
messageDigestOid, sizeof(messageDigestOid));
|
||||
if (ret < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
|
@ -1161,9 +1119,6 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||
DYNAMIC_TYPE_PKCS7);
|
||||
flatSignedAttribsSz = esd->signedAttribsSz;
|
||||
if (flatSignedAttribs == NULL) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
|
@ -1179,9 +1134,6 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||
if (ret < 0) {
|
||||
if (pkcs7->signedAttribsSz != 0)
|
||||
XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1207,23 +1159,30 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||
esd->versionSz = SetMyVersion(1, esd->version, 0);
|
||||
|
||||
totalSz = esd->versionSz + esd->singleDigAlgoIdSz + esd->digAlgoIdSetSz +
|
||||
esd->contentInfoSeqSz + esd->certsSetSz + pkcs7->singleCertSz +
|
||||
esd->innerOctetsSz + esd->innerContSeqSz +
|
||||
innerOidSz + pkcs7->contentSz +
|
||||
signerInfoSz;
|
||||
esd->innerSeqSz = SetSequence(totalSz, esd->innerSeq);
|
||||
esd->contentInfoSeqSz + innerOidSz + esd->innerContSeqSz +
|
||||
esd->innerOctetsSz + pkcs7->contentSz;
|
||||
total2Sz = esd->certsSetSz + pkcs7->singleCertSz + signerInfoSz;
|
||||
|
||||
esd->innerSeqSz = SetSequence(totalSz + total2Sz, esd->innerSeq);
|
||||
totalSz += esd->innerSeqSz;
|
||||
esd->outerContentSz = SetExplicit(0, totalSz, esd->outerContent);
|
||||
esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, esd->outerContent);
|
||||
totalSz += esd->outerContentSz + outerOidSz;
|
||||
esd->outerSeqSz = SetSequence(totalSz, esd->outerSeq);
|
||||
esd->outerSeqSz = SetSequence(totalSz + total2Sz, esd->outerSeq);
|
||||
totalSz += esd->outerSeqSz;
|
||||
|
||||
if (outputSz < totalSz) {
|
||||
/* if using header/footer, we are not returning the content */
|
||||
if (output2 && output2Sz) {
|
||||
if (total2Sz > *output2Sz) {
|
||||
if (pkcs7->signedAttribsSz != 0)
|
||||
XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||
return BUFFER_E;
|
||||
}
|
||||
totalSz -= pkcs7->contentSz;
|
||||
}
|
||||
|
||||
if (totalSz > *outputSz) {
|
||||
if (pkcs7->signedAttribsSz != 0)
|
||||
XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
|
@ -1250,50 +1209,160 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||
idx += esd->innerContSeqSz;
|
||||
XMEMCPY(output + idx, esd->innerOctets, esd->innerOctetsSz);
|
||||
idx += esd->innerOctetsSz;
|
||||
XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
|
||||
idx += pkcs7->contentSz;
|
||||
XMEMCPY(output + idx, esd->certsSet, esd->certsSetSz);
|
||||
|
||||
/* support returning header and footer without content */
|
||||
if (output2 && output2Sz) {
|
||||
*outputSz = idx;
|
||||
idx = 0;
|
||||
}
|
||||
else {
|
||||
XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
|
||||
idx += pkcs7->contentSz;
|
||||
output2 = output;
|
||||
}
|
||||
XMEMCPY(output2 + idx, esd->certsSet, esd->certsSetSz);
|
||||
idx += esd->certsSetSz;
|
||||
XMEMCPY(output + idx, pkcs7->singleCert, pkcs7->singleCertSz);
|
||||
XMEMCPY(output2 + idx, pkcs7->singleCert, pkcs7->singleCertSz);
|
||||
idx += pkcs7->singleCertSz;
|
||||
XMEMCPY(output + idx, esd->signerInfoSet, esd->signerInfoSetSz);
|
||||
XMEMCPY(output2 + idx, esd->signerInfoSet, esd->signerInfoSetSz);
|
||||
idx += esd->signerInfoSetSz;
|
||||
XMEMCPY(output + idx, esd->signerInfoSeq, esd->signerInfoSeqSz);
|
||||
XMEMCPY(output2 + idx, esd->signerInfoSeq, esd->signerInfoSeqSz);
|
||||
idx += esd->signerInfoSeqSz;
|
||||
XMEMCPY(output + idx, esd->signerVersion, esd->signerVersionSz);
|
||||
XMEMCPY(output2 + idx, esd->signerVersion, esd->signerVersionSz);
|
||||
idx += esd->signerVersionSz;
|
||||
XMEMCPY(output + idx, esd->issuerSnSeq, esd->issuerSnSeqSz);
|
||||
XMEMCPY(output2 + idx, esd->issuerSnSeq, esd->issuerSnSeqSz);
|
||||
idx += esd->issuerSnSeqSz;
|
||||
XMEMCPY(output + idx, esd->issuerName, esd->issuerNameSz);
|
||||
XMEMCPY(output2 + idx, esd->issuerName, esd->issuerNameSz);
|
||||
idx += esd->issuerNameSz;
|
||||
XMEMCPY(output + idx, pkcs7->issuer, pkcs7->issuerSz);
|
||||
XMEMCPY(output2 + idx, pkcs7->issuer, pkcs7->issuerSz);
|
||||
idx += pkcs7->issuerSz;
|
||||
XMEMCPY(output + idx, esd->issuerSn, esd->issuerSnSz);
|
||||
XMEMCPY(output2 + idx, esd->issuerSn, esd->issuerSnSz);
|
||||
idx += esd->issuerSnSz;
|
||||
XMEMCPY(output + idx, esd->signerDigAlgoId, esd->signerDigAlgoIdSz);
|
||||
XMEMCPY(output2 + idx, esd->signerDigAlgoId, esd->signerDigAlgoIdSz);
|
||||
idx += esd->signerDigAlgoIdSz;
|
||||
|
||||
/* SignerInfo:Attributes */
|
||||
if (flatSignedAttribsSz > 0) {
|
||||
XMEMCPY(output + idx, esd->signedAttribSet, esd->signedAttribSetSz);
|
||||
XMEMCPY(output2 + idx, esd->signedAttribSet, esd->signedAttribSetSz);
|
||||
idx += esd->signedAttribSetSz;
|
||||
XMEMCPY(output + idx, flatSignedAttribs, flatSignedAttribsSz);
|
||||
XMEMCPY(output2 + idx, flatSignedAttribs, flatSignedAttribsSz);
|
||||
idx += flatSignedAttribsSz;
|
||||
XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||
}
|
||||
|
||||
XMEMCPY(output + idx, esd->digEncAlgoId, esd->digEncAlgoIdSz);
|
||||
XMEMCPY(output2 + idx, esd->digEncAlgoId, esd->digEncAlgoIdSz);
|
||||
idx += esd->digEncAlgoIdSz;
|
||||
XMEMCPY(output + idx, esd->signerDigest, esd->signerDigestSz);
|
||||
XMEMCPY(output2 + idx, esd->signerDigest, esd->signerDigestSz);
|
||||
idx += esd->signerDigestSz;
|
||||
XMEMCPY(output + idx, esd->encContentDigest, esd->encContentDigestSz);
|
||||
XMEMCPY(output2 + idx, esd->encContentDigest, esd->encContentDigestSz);
|
||||
idx += esd->encContentDigestSz;
|
||||
|
||||
if (output2 && output2Sz) {
|
||||
*output2Sz = idx;
|
||||
idx = 0; /* success */
|
||||
}
|
||||
else {
|
||||
*outputSz = idx;
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
/* hashBuf: The computed digest for the pkcs7->content
|
||||
* hashSz: The size of computed digest for the pkcs7->content based on hashOID
|
||||
* outputHead: The PKCS7 header that goes on top of the raw data signed.
|
||||
* outputFoot: The PKCS7 footer that goes at the end of the raw data signed.
|
||||
* pkcs7->content: Not used
|
||||
* pkcs7->contentSz: Must be provided as actual sign of raw data
|
||||
* return codes: 0=success, negative=error
|
||||
*/
|
||||
int wc_PKCS7_EncodeSignedData_ex(PKCS7* pkcs7, const byte* hashBuf, word32 hashSz,
|
||||
byte* outputHead, word32* outputHeadSz, byte* outputFoot, word32* outputFootSz)
|
||||
{
|
||||
int ret;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
ESD* esd;
|
||||
#else
|
||||
ESD esd[1];
|
||||
#endif
|
||||
|
||||
/* other args checked in wc_PKCS7_EncodeSigned_ex */
|
||||
if (pkcs7 == NULL || outputFoot == NULL || outputFootSz == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (esd == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
XMEMSET(esd, 0, sizeof(ESD));
|
||||
|
||||
ret = PKCS7_EncodeSigned(pkcs7, esd, hashBuf, hashSz,
|
||||
outputHead, outputHeadSz, outputFoot, outputFootSz);
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return idx;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* return codes: >0: Size of signed PKCS7 output buffer, negative: error */
|
||||
int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
||||
{
|
||||
int ret;
|
||||
int hashSz;
|
||||
enum wc_HashType hashType;
|
||||
byte hashBuf[WC_MAX_DIGEST_SIZE];
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
ESD* esd;
|
||||
#else
|
||||
ESD esd[1];
|
||||
#endif
|
||||
|
||||
/* other args checked in wc_PKCS7_EncodeSigned_ex */
|
||||
if (pkcs7 == NULL || pkcs7->contentSz == 0 || pkcs7->content == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* get hash type and size, validate hashOID */
|
||||
hashType = wc_OidGetHash(pkcs7->hashOID);
|
||||
hashSz = wc_HashGetDigestSize(hashType);
|
||||
if (hashSz < 0)
|
||||
return hashSz;
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
esd = (ESD*)XMALLOC(sizeof(ESD), pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (esd == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
XMEMSET(esd, 0, sizeof(ESD));
|
||||
esd->hashType = hashType;
|
||||
|
||||
/* calculate hash for content */
|
||||
ret = wc_HashInit(&esd->hash, esd->hashType);
|
||||
if (ret == 0) {
|
||||
ret = wc_HashUpdate(&esd->hash, esd->hashType,
|
||||
pkcs7->content, pkcs7->contentSz);
|
||||
if (ret == 0) {
|
||||
ret = wc_HashFinal(&esd->hash, esd->hashType, hashBuf);
|
||||
}
|
||||
wc_HashFree(&esd->hash, esd->hashType);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = PKCS7_EncodeSigned(pkcs7, esd, hashBuf, hashSz,
|
||||
output, &outputSz, NULL, NULL);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1310,8 +1379,7 @@ static int wc_PKCS7_RsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
|
|||
RsaKey* key;
|
||||
#else
|
||||
byte digest[MAX_PKCS7_DIGEST_SZ];
|
||||
RsaKey stack_key;
|
||||
RsaKey* key = &stack_key;
|
||||
RsaKey key[1];
|
||||
#endif
|
||||
|
||||
if (pkcs7 == NULL || sig == NULL || hash == NULL) {
|
||||
|
@ -1386,8 +1454,7 @@ static int wc_PKCS7_EcdsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
|
|||
ecc_key* key;
|
||||
#else
|
||||
byte digest[MAX_PKCS7_DIGEST_SZ];
|
||||
ecc_key stack_key;
|
||||
ecc_key* key = &stack_key;
|
||||
ecc_key key[1];
|
||||
#endif
|
||||
word32 idx = 0;
|
||||
|
||||
|
@ -1464,10 +1531,11 @@ static int wc_PKCS7_EcdsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
|
|||
static int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib,
|
||||
word32 signedAttribSz, byte* pkcs7Digest,
|
||||
word32* pkcs7DigestSz, byte** plainDigest,
|
||||
word32* plainDigestSz)
|
||||
word32* plainDigestSz,
|
||||
const byte* hashBuf, word32 hashBufSz)
|
||||
{
|
||||
int ret = 0, digIdx = 0, hashSz;
|
||||
word32 attribSetSz;
|
||||
int ret = 0, digIdx = 0;
|
||||
word32 attribSetSz, hashSz;
|
||||
byte attribSet[MAX_SET_SZ];
|
||||
byte digest[WC_MAX_DIGEST_SIZE];
|
||||
byte digestInfoSeq[MAX_SEQ_SZ];
|
||||
|
@ -1477,7 +1545,7 @@ static int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib,
|
|||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte* digestInfo;
|
||||
#else
|
||||
byte digestInfo[MAX_PKCS7_DIGEST_SZ];
|
||||
byte digestInfo[MAX_PKCS7_DIGEST_SZ];
|
||||
#endif
|
||||
|
||||
wc_HashAlg hash;
|
||||
|
@ -1500,7 +1568,11 @@ static int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib,
|
|||
return BAD_FUNC_ARG;
|
||||
}
|
||||
else {
|
||||
if (pkcs7->content == NULL)
|
||||
if (hashBuf && hashBufSz > 0) {
|
||||
if (hashSz != hashBufSz)
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
else if (pkcs7->content == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
|
@ -1517,36 +1589,40 @@ static int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib,
|
|||
|
||||
|
||||
/* calculate digest */
|
||||
ret = wc_HashInit(&hash, hashType);
|
||||
if (ret < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
if (hashBuf && hashBufSz > 0 && signedAttribSz == 0) {
|
||||
XMEMCPY(digest, hashBuf, hashBufSz);
|
||||
}
|
||||
else {
|
||||
ret = wc_HashInit(&hash, hashType);
|
||||
if (ret < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (signedAttribSz > 0) {
|
||||
attribSetSz = SetSet(signedAttribSz, attribSet);
|
||||
if (signedAttribSz > 0) {
|
||||
attribSetSz = SetSet(signedAttribSz, attribSet);
|
||||
|
||||
/* calculate digest */
|
||||
ret = wc_HashUpdate(&hash, hashType, attribSet, attribSetSz);
|
||||
if (ret == 0)
|
||||
ret = wc_HashUpdate(&hash, hashType, signedAttrib, signedAttribSz);
|
||||
if (ret == 0)
|
||||
ret = wc_HashFinal(&hash, hashType, digest);
|
||||
} else {
|
||||
ret = wc_HashUpdate(&hash, hashType, pkcs7->content, pkcs7->contentSz);
|
||||
if (ret == 0)
|
||||
ret = wc_HashFinal(&hash, hashType, digest);
|
||||
}
|
||||
/* calculate digest */
|
||||
ret = wc_HashUpdate(&hash, hashType, attribSet, attribSetSz);
|
||||
if (ret == 0)
|
||||
ret = wc_HashUpdate(&hash, hashType, signedAttrib, signedAttribSz);
|
||||
if (ret == 0)
|
||||
ret = wc_HashFinal(&hash, hashType, digest);
|
||||
} else {
|
||||
ret = wc_HashUpdate(&hash, hashType, pkcs7->content, pkcs7->contentSz);
|
||||
if (ret == 0)
|
||||
ret = wc_HashFinal(&hash, hashType, digest);
|
||||
}
|
||||
|
||||
wc_HashFree(&hash, hashType);
|
||||
|
||||
if (ret < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
wc_HashFree(&hash, hashType);
|
||||
if (ret < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set algoID, with NULL attributes */
|
||||
|
@ -1591,7 +1667,8 @@ static int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib,
|
|||
* return 0 on success, negative on error */
|
||||
static int wc_PKCS7_SignedDataVerifySignature(PKCS7* pkcs7, byte* sig,
|
||||
word32 sigSz, byte* signedAttrib,
|
||||
word32 signedAttribSz)
|
||||
word32 signedAttribSz,
|
||||
const byte* hashBuf, word32 hashSz)
|
||||
{
|
||||
int ret = 0;
|
||||
word32 plainDigestSz = 0, pkcs7DigestSz;
|
||||
|
@ -1617,7 +1694,7 @@ static int wc_PKCS7_SignedDataVerifySignature(PKCS7* pkcs7, byte* sig,
|
|||
ret = wc_PKCS7_BuildSignedDataDigest(pkcs7, signedAttrib,
|
||||
signedAttribSz, pkcs7Digest,
|
||||
&pkcs7DigestSz, &plainDigest,
|
||||
&plainDigestSz);
|
||||
&plainDigestSz, hashBuf, hashSz);
|
||||
if (ret < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
@ -1818,17 +1895,19 @@ static int wc_PKCS7_ParseAttribs(PKCS7* pkcs7, byte* in, int inSz)
|
|||
return found;
|
||||
}
|
||||
|
||||
|
||||
/* Finds the certificates in the message and saves it. */
|
||||
int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
||||
static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf,
|
||||
word32 hashSz, byte* pkiMsg, word32 pkiMsgSz,
|
||||
byte* pkiMsg2, word32 pkiMsg2Sz)
|
||||
{
|
||||
word32 idx, contentType, hashOID, sigOID;
|
||||
word32 idx, contentType, hashOID, sigOID, totalSz;
|
||||
int length, version, ret;
|
||||
byte* content = NULL;
|
||||
byte* sig = NULL;
|
||||
byte* cert = NULL;
|
||||
byte* signedAttrib = NULL;
|
||||
int contentSz = 0, sigSz = 0, certSz = 0, signedAttribSz = 0;
|
||||
word32 localIdx;
|
||||
byte degenerate;
|
||||
#ifdef ASN_BER_TO_DER
|
||||
byte* der;
|
||||
|
@ -1839,8 +1918,14 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||
|
||||
idx = 0;
|
||||
|
||||
/* determine total message size */
|
||||
totalSz = pkiMsgSz;
|
||||
if (pkiMsg2 && pkiMsg2Sz > 0) {
|
||||
totalSz += pkiMsg2Sz + pkcs7->contentSz;
|
||||
}
|
||||
|
||||
/* Get the contentInfo sequence */
|
||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
if (GetSequence(pkiMsg, &idx, &length, totalSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (length == 0 && pkiMsg[idx-1] == 0x80) {
|
||||
|
@ -1880,11 +1965,11 @@ 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, totalSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* Get the signedData sequence */
|
||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
if (GetSequence(pkiMsg, &idx, &length, totalSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* Get the version */
|
||||
|
@ -1905,7 +1990,7 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||
degenerate = (length == 0)? 1 : 0;
|
||||
|
||||
/* Get the inner ContentInfo sequence */
|
||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
if (GetSequence(pkiMsg, &idx, &length, totalSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* Get the inner ContentInfo contentType */
|
||||
|
@ -1918,34 +2003,51 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||
}
|
||||
|
||||
/* Check for content info, it could be omitted when degenerate */
|
||||
{
|
||||
word32 localIdx = idx;
|
||||
ret = 0;
|
||||
if (pkiMsg[localIdx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
|
||||
ret = ASN_PARSE_E;
|
||||
localIdx = idx;
|
||||
ret = 0;
|
||||
if (pkiMsg[localIdx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
|
||||
ret = ASN_PARSE_E;
|
||||
|
||||
if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, pkiMsgSz) <= 0)
|
||||
ret = ASN_PARSE_E;
|
||||
if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, totalSz) <= 0)
|
||||
ret = ASN_PARSE_E;
|
||||
|
||||
if (ret == 0 && pkiMsg[localIdx++] != ASN_OCTET_STRING)
|
||||
ret = ASN_PARSE_E;
|
||||
if (ret == 0 && pkiMsg[localIdx++] != ASN_OCTET_STRING)
|
||||
ret = ASN_PARSE_E;
|
||||
|
||||
if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, pkiMsgSz) < 0)
|
||||
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 (length > 0) {
|
||||
/* Local pointer for calculating hashes later */
|
||||
/* Save the inner data as the content. */
|
||||
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 = &pkiMsg[localIdx];
|
||||
contentSz = length;
|
||||
localIdx += length;
|
||||
}
|
||||
|
||||
/* update idx if successful */
|
||||
if (ret == 0) {
|
||||
idx = localIdx;
|
||||
pkiMsg2 = pkiMsg;
|
||||
pkiMsg2Sz = pkiMsgSz;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pkiMsg2 = pkiMsg;
|
||||
}
|
||||
|
||||
/* update idx if successful */
|
||||
if (ret == 0) {
|
||||
idx = localIdx;
|
||||
}
|
||||
|
||||
/* If getting the content info failed with non degenerate then return the
|
||||
* error case. Otherwise with a degenerate it is ok if the content
|
||||
|
@ -1955,9 +2057,9 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||
}
|
||||
|
||||
/* Get the implicit[0] set of certificates */
|
||||
if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
|
||||
if (pkiMsg2[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
|
||||
idx++;
|
||||
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (length > 0) {
|
||||
|
@ -1969,11 +2071,11 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||
|
||||
word32 certIdx = idx;
|
||||
|
||||
if (pkiMsg[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
|
||||
if (GetLength(pkiMsg, &certIdx, &certSz, pkiMsgSz) < 0)
|
||||
if (pkiMsg2[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
|
||||
if (GetLength(pkiMsg2, &certIdx, &certSz, pkiMsg2Sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
cert = &pkiMsg[idx];
|
||||
cert = &pkiMsg2[idx];
|
||||
certSz += (certIdx - idx);
|
||||
}
|
||||
|
||||
|
@ -1988,7 +2090,6 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||
|
||||
/* iterate through any additional certificates */
|
||||
if (MAX_PKCS7_CERTS > 0) {
|
||||
word32 localIdx;
|
||||
int sz = 0;
|
||||
int i;
|
||||
|
||||
|
@ -1996,14 +2097,14 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||
pkcs7->certSz[0] = certSz;
|
||||
certIdx = idx + certSz;
|
||||
|
||||
for (i = 1; i < MAX_PKCS7_CERTS && certIdx + 1 < pkiMsgSz; i++) {
|
||||
for (i = 1; i < MAX_PKCS7_CERTS && certIdx + 1 < pkiMsg2Sz; i++) {
|
||||
localIdx = certIdx;
|
||||
|
||||
if (pkiMsg[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
|
||||
if (GetLength(pkiMsg, &certIdx, &sz, pkiMsgSz) < 0)
|
||||
if (pkiMsg2[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
|
||||
if (GetLength(pkiMsg2, &certIdx, &sz, pkiMsg2Sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
pkcs7->cert[i] = &pkiMsg[localIdx];
|
||||
pkcs7->cert[i] = &pkiMsg2[localIdx];
|
||||
pkcs7->certSz[i] = sz + (certIdx - localIdx);
|
||||
certIdx += sz;
|
||||
}
|
||||
|
@ -2018,9 +2119,9 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||
pkcs7->contentSz = contentSz;
|
||||
|
||||
/* Get the implicit[1] set of crls */
|
||||
if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
|
||||
if (pkiMsg2[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) {
|
||||
idx++;
|
||||
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* Skip the set */
|
||||
|
@ -2028,16 +2129,16 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||
}
|
||||
|
||||
/* Get the set of signerInfos */
|
||||
if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
if (GetSet(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (length > 0) {
|
||||
/* Get the sequence of the first signerInfo */
|
||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
if (GetSequence(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* Get the version */
|
||||
if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
|
||||
if (GetMyVersion(pkiMsg2, &idx, &version, pkiMsg2Sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (version != 1) {
|
||||
|
@ -2046,27 +2147,27 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||
}
|
||||
|
||||
/* 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 */
|
||||
idx += length;
|
||||
|
||||
/* Get the sequence of digestAlgorithm */
|
||||
if (GetAlgoId(pkiMsg, &idx, &hashOID, oidHashType, pkiMsgSz) < 0) {
|
||||
if (GetAlgoId(pkiMsg2, &idx, &hashOID, oidHashType, pkiMsg2Sz) < 0) {
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
pkcs7->hashOID = (int)hashOID;
|
||||
|
||||
/* Get the IMPLICIT[0] SET OF signedAttributes */
|
||||
if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
|
||||
if (pkiMsg2[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
|
||||
idx++;
|
||||
|
||||
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* save pointer and length */
|
||||
signedAttrib = &pkiMsg[idx];
|
||||
signedAttrib = &pkiMsg2[idx];
|
||||
signedAttribSz = length;
|
||||
|
||||
if (wc_PKCS7_ParseAttribs(pkcs7, signedAttrib, signedAttribSz) <0) {
|
||||
|
@ -2078,7 +2179,7 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||
}
|
||||
|
||||
/* Get digestEncryptionAlgorithm */
|
||||
if (GetAlgoId(pkiMsg, &idx, &sigOID, oidSigType, pkiMsgSz) < 0) {
|
||||
if (GetAlgoId(pkiMsg2, &idx, &sigOID, oidSigType, pkiMsg2Sz) < 0) {
|
||||
return ASN_PARSE_E;
|
||||
}
|
||||
|
||||
|
@ -2090,14 +2191,14 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||
}
|
||||
|
||||
/* Get the signature */
|
||||
if (pkiMsg[idx] == ASN_OCTET_STRING) {
|
||||
if (pkiMsg2[idx] == ASN_OCTET_STRING) {
|
||||
idx++;
|
||||
|
||||
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* save pointer and length */
|
||||
sig = &pkiMsg[idx];
|
||||
sig = &pkiMsg2[idx];
|
||||
sigSz = length;
|
||||
|
||||
idx += length;
|
||||
|
@ -2107,7 +2208,8 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||
pkcs7->contentSz = contentSz;
|
||||
|
||||
ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,
|
||||
signedAttrib, signedAttribSz);
|
||||
signedAttrib, signedAttribSz,
|
||||
hashBuf, hashSz);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
@ -2116,6 +2218,22 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||
}
|
||||
|
||||
|
||||
/* variant that allows computed data hash and header/foot,
|
||||
* which is useful for large data signing */
|
||||
int wc_PKCS7_VerifySignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
|
||||
word32 hashSz, byte* pkiMsgHead, word32 pkiMsgHeadSz, byte* pkiMsgFoot,
|
||||
word32 pkiMsgFootSz)
|
||||
{
|
||||
return PKCS7_VerifySignedData(pkcs7, hashBuf, hashSz,
|
||||
pkiMsgHead, pkiMsgHeadSz, pkiMsgFoot, pkiMsgFootSz);
|
||||
}
|
||||
|
||||
int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
||||
{
|
||||
return PKCS7_VerifySignedData(pkcs7, NULL, 0, pkiMsg, pkiMsgSz, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
|
||||
/* KARI == KeyAgreeRecipientInfo (key agreement) */
|
||||
|
@ -2916,10 +3034,8 @@ static int wc_CreateRecipientInfo(const byte* cert, word32 certSz,
|
|||
byte serial[MAX_SN_SZ];
|
||||
byte keyAlgArray[MAX_ALGO_SZ];
|
||||
|
||||
RsaKey stack_pubKey;
|
||||
RsaKey* pubKey = &stack_pubKey;
|
||||
DecodedCert stack_decoded;
|
||||
DecodedCert* decoded = &stack_decoded;
|
||||
RsaKey pubKey[1];
|
||||
DecodedCert decoded[1];
|
||||
#endif
|
||||
|
||||
InitDecodedCert(decoded, (byte*)cert, certSz, heap);
|
||||
|
@ -3346,7 +3462,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte* contentKeyEnc;
|
||||
#else
|
||||
byte contentKeyEnc[MAX_ENCRYPTED_KEY_SZ];
|
||||
byte contentKeyEnc[MAX_ENCRYPTED_KEY_SZ];
|
||||
#endif
|
||||
byte* plain;
|
||||
byte* encryptedContent;
|
||||
|
@ -3355,7 +3471,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte* recip;
|
||||
#else
|
||||
byte recip[MAX_RECIP_SZ];
|
||||
byte recip[MAX_RECIP_SZ];
|
||||
#endif
|
||||
byte recipSet[MAX_SET_SZ];
|
||||
|
||||
|
@ -3645,12 +3761,9 @@ static int wc_PKCS7_DecodeKtri(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz,
|
|||
byte* encryptedKey;
|
||||
RsaKey* privKey;
|
||||
#else
|
||||
mp_int stack_serialNum;
|
||||
mp_int* serialNum = &stack_serialNum;
|
||||
mp_int serialNum[1];
|
||||
byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
|
||||
|
||||
RsaKey stack_privKey;
|
||||
RsaKey* privKey = &stack_privKey;
|
||||
RsaKey privKey[1];
|
||||
#endif
|
||||
|
||||
/* remove IssuerAndSerialNumber */
|
||||
|
@ -3996,11 +4109,8 @@ static int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari,
|
|||
mp_int* serial;
|
||||
mp_int* recipSerial;
|
||||
#else
|
||||
mp_int stack_serial;
|
||||
mp_int* serial = &stack_serial;
|
||||
|
||||
mp_int stack_recipSerial;
|
||||
mp_int* recipSerial = &stack_recipSerial;
|
||||
mp_int serial[1];
|
||||
mp_int recipSerial[1];
|
||||
#endif
|
||||
|
||||
/* remove IssuerAndSerialNumber */
|
||||
|
@ -4148,7 +4258,7 @@ static int wc_PKCS7_DecodeKari(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz,
|
|||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte* encryptedKey;
|
||||
#else
|
||||
byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
|
||||
byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
|
||||
#endif
|
||||
|
||||
WC_PKCS7_KARI* kari;
|
||||
|
@ -4399,7 +4509,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte* decryptedKey;
|
||||
#else
|
||||
byte decryptedKey[MAX_ENCRYPTED_KEY_SZ];
|
||||
byte decryptedKey[MAX_ENCRYPTED_KEY_SZ];
|
||||
#endif
|
||||
int encryptedContentSz;
|
||||
byte padLen;
|
||||
|
|
|
@ -79,9 +79,9 @@ enum Pkcs7_Misc {
|
|||
|
||||
|
||||
typedef struct PKCS7Attrib {
|
||||
byte* oid;
|
||||
const byte* oid;
|
||||
word32 oidSz;
|
||||
byte* value;
|
||||
const byte* value;
|
||||
word32 valueSz;
|
||||
} PKCS7Attrib;
|
||||
|
||||
|
@ -160,8 +160,14 @@ WOLFSSL_API int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output,
|
|||
word32 outputSz);
|
||||
WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7,
|
||||
byte* output, word32 outputSz);
|
||||
WOLFSSL_API int wc_PKCS7_EncodeSignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
|
||||
word32 hashSz, byte* outputHead, word32* outputHeadSz, byte* outputFoot,
|
||||
word32* outputFootSz);
|
||||
WOLFSSL_API int wc_PKCS7_VerifySignedData(PKCS7* pkcs7,
|
||||
byte* pkiMsg, word32 pkiMsgSz);
|
||||
WOLFSSL_API int wc_PKCS7_VerifySignedData_ex(PKCS7* pkcs7, const byte* hashBuf,
|
||||
word32 hashSz, byte* pkiMsgHead, word32 pkiMsgHeadSz, byte* pkiMsgFoot,
|
||||
word32 pkiMsgFootSz);
|
||||
WOLFSSL_API int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7,
|
||||
byte* output, word32 outputSz);
|
||||
WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
||||
|
|
Loading…
Reference in New Issue