mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 18:57:27 +02:00
Added new PKCS7 ex API's for supporting signing and validation of large data blobs. New API's are wc_PKCS7_EncodeSignedData_ex
and wc_PKCS7_VerifySignedData_ex
. Includes header docx and unit tests for new API's. Cleanup for the PKCS7 small stack and const oid's.
This commit is contained in:
@ -174,6 +174,7 @@ WOLFSSL_API int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output,
|
|||||||
PKCS7 pkcs7;
|
PKCS7 pkcs7;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
byte data[] = {}; // initialize with data to sign
|
||||||
byte derBuff[] = { }; // initialize with DER-encoded certificate
|
byte derBuff[] = { }; // initialize with DER-encoded certificate
|
||||||
byte pkcs7Buff[FOURK_BUF];
|
byte pkcs7Buff[FOURK_BUF];
|
||||||
|
|
||||||
@ -183,12 +184,16 @@ WOLFSSL_API int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output,
|
|||||||
pkcs7.privateKeySz = keySz;
|
pkcs7.privateKeySz = keySz;
|
||||||
pkcs7.content = data;
|
pkcs7.content = data;
|
||||||
pkcs7.contentSz = dataSz;
|
pkcs7.contentSz = dataSz;
|
||||||
|
pkcs7.hashOID = SHAh;
|
||||||
|
pkcs7.rng = &rng;
|
||||||
... etc.
|
... etc.
|
||||||
|
|
||||||
ret = wc_PKCS7_EncodeSignedData(&pkcs7, pkcs7Buff, sizeof(pkcs7Buff));
|
ret = wc_PKCS7_EncodeSignedData(&pkcs7, pkcs7Buff, sizeof(pkcs7Buff));
|
||||||
if ( ret != 0 ) {
|
if ( ret != 0 ) {
|
||||||
// error encoding into output buffer
|
// error encoding into output buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wc_PKCS7_Free(&pkcs7);
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
\sa wc_PKCS7_InitWithCert
|
\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,
|
WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7,
|
||||||
byte* output, word32 outputSz);
|
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
|
\ingroup PKCS7
|
||||||
|
|
||||||
@ -250,11 +356,9 @@ WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7,
|
|||||||
\code
|
\code
|
||||||
PKCS7 pkcs7;
|
PKCS7 pkcs7;
|
||||||
int ret;
|
int ret;
|
||||||
|
byte pkcs7Buff[] = {}; // the PKCS7 signature
|
||||||
|
|
||||||
byte derBuff[] = { }; // initialize with DER-encoded certificate
|
wc_PKCS7_InitWithCert(&pkcs7, NULL, 0);
|
||||||
byte pkcs7Buff[FOURK_BUF];
|
|
||||||
|
|
||||||
wc_PKCS7_InitWithCert(&pkcs7, derBuff, sizeof(derBuff));
|
|
||||||
// update message and data to encode
|
// update message and data to encode
|
||||||
pkcs7.privateKey = key;
|
pkcs7.privateKey = key;
|
||||||
pkcs7.privateKeySz = keySz;
|
pkcs7.privateKeySz = keySz;
|
||||||
@ -262,10 +366,12 @@ WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7,
|
|||||||
pkcs7.contentSz = dataSz;
|
pkcs7.contentSz = dataSz;
|
||||||
... etc.
|
... etc.
|
||||||
|
|
||||||
ret = wc_PKCS7_EncodeSignedData(&pkcs7, pkcs7Buff, sizeof(pkcs7Buff));
|
ret = wc_PKCS7_VerifySignedData(&pkcs7, pkcs7Buff, sizeof(pkcs7Buff));
|
||||||
if ( ret != 0 ) {
|
if ( ret != 0 ) {
|
||||||
// error encoding into output buffer
|
// error encoding into output buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wc_PKCS7_Free(&pkcs7);
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
\sa wc_PKCS7_InitWithCert
|
\sa wc_PKCS7_InitWithCert
|
||||||
@ -274,6 +380,107 @@ WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7,
|
|||||||
WOLFSSL_API int wc_PKCS7_VerifySignedData(PKCS7* pkcs7,
|
WOLFSSL_API int wc_PKCS7_VerifySignedData(PKCS7* pkcs7,
|
||||||
byte* pkiMsg, word32 pkiMsgSz);
|
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
|
\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()
|
* Testing wc_PKCS7_EncodeSignedData()
|
||||||
*/
|
*/
|
||||||
static void test_wc_PKCS7_EncodeSignedData (void)
|
static void test_wc_PKCS7_EncodeSignedData(void)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_PKCS7)
|
#if defined(HAVE_PKCS7)
|
||||||
PKCS7 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, NULL, outputSz), BAD_FUNC_ARG);
|
||||||
AssertIntEQ(wc_PKCS7_EncodeSignedData(&pkcs7, badOut,
|
AssertIntEQ(wc_PKCS7_EncodeSignedData(&pkcs7, badOut,
|
||||||
badOutSz), BAD_FUNC_ARG);
|
badOutSz), BAD_FUNC_ARG);
|
||||||
|
pkcs7.hashOID = 0; /* bad hashOID */
|
||||||
|
AssertIntEQ(wc_PKCS7_EncodeSignedData(&pkcs7, output, outputSz), BAD_FUNC_ARG);
|
||||||
|
|
||||||
printf(resultFmt, passed);
|
printf(resultFmt, passed);
|
||||||
|
|
||||||
@ -14637,6 +14639,197 @@ static void test_wc_PKCS7_EncodeSignedData (void)
|
|||||||
#endif
|
#endif
|
||||||
} /* END test_wc_PKCS7_EncodeSignedData */
|
} /* 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()
|
* Testing wc_PKCS_VerifySignedData()
|
||||||
@ -20656,6 +20849,7 @@ void ApiTest(void)
|
|||||||
test_wc_PKCS7_InitWithCert();
|
test_wc_PKCS7_InitWithCert();
|
||||||
test_wc_PKCS7_EncodeData();
|
test_wc_PKCS7_EncodeData();
|
||||||
test_wc_PKCS7_EncodeSignedData();
|
test_wc_PKCS7_EncodeSignedData();
|
||||||
|
test_wc_PKCS7_EncodeSignedData_ex();
|
||||||
test_wc_PKCS7_VerifySignedData();
|
test_wc_PKCS7_VerifySignedData();
|
||||||
test_wc_PKCS7_EncodeDecodeEnvelopedData();
|
test_wc_PKCS7_EncodeDecodeEnvelopedData();
|
||||||
test_wc_PKCS7_EncodeEncryptedData();
|
test_wc_PKCS7_EncodeEncryptedData();
|
||||||
|
@ -303,8 +303,7 @@ int wc_PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz)
|
|||||||
if (dCert == NULL)
|
if (dCert == NULL)
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
#else
|
#else
|
||||||
DecodedCert stack_dCert;
|
DecodedCert dCert[1];
|
||||||
DecodedCert* dCert = &stack_dCert;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pkcs7->singleCert = cert;
|
pkcs7->singleCert = cert;
|
||||||
@ -611,8 +610,7 @@ static int wc_PKCS7_RsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
|
|||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
RsaKey* privKey;
|
RsaKey* privKey;
|
||||||
#else
|
#else
|
||||||
RsaKey stack_privKey;
|
RsaKey privKey[1];
|
||||||
RsaKey* privKey = &stack_privKey;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (pkcs7 == NULL || pkcs7->rng == NULL || in == NULL || esd == NULL) {
|
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
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
ecc_key* privKey;
|
ecc_key* privKey;
|
||||||
#else
|
#else
|
||||||
ecc_key stack_privKey;
|
ecc_key privKey[1];
|
||||||
ecc_key* privKey = &stack_privKey;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (pkcs7 == NULL || pkcs7->rng == NULL || in == NULL || esd == NULL) {
|
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 */
|
* return 0 on success, negative on error */
|
||||||
static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd,
|
static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd,
|
||||||
byte* contentTypeOid, word32 contentTypeOidSz,
|
const byte* contentTypeOid, word32 contentTypeOidSz,
|
||||||
byte* contentType, word32 contentTypeSz,
|
const byte* contentType, word32 contentTypeSz,
|
||||||
byte* messageDigestOid, word32 messageDigestOidSz)
|
const byte* messageDigestOid, word32 messageDigestOidSz)
|
||||||
{
|
{
|
||||||
int hashSz;
|
int hashSz;
|
||||||
|
|
||||||
@ -941,7 +938,7 @@ static int wc_PKCS7_BuildDigestInfo(PKCS7* pkcs7, byte* flatSignedAttribs,
|
|||||||
|
|
||||||
/* build SignedData signature over DigestInfo or content digest
|
/* build SignedData signature over DigestInfo or content digest
|
||||||
*
|
*
|
||||||
* pkcs7 - pointer to initizlied PKCS7 struct
|
* pkcs7 - pointer to initialized PKCS7 struct
|
||||||
* flatSignedAttribs - flattened, signed attributes
|
* flatSignedAttribs - flattened, signed attributes
|
||||||
* flatSignedAttribsSz - size of flatSignedAttribs, octets
|
* flatSignedAttribsSz - size of flatSignedAttribs, octets
|
||||||
* esd - pointer to initialized ESD struct
|
* esd - pointer to initialized ESD struct
|
||||||
@ -960,7 +957,7 @@ static int wc_PKCS7_SignedDataBuildSignature(PKCS7* pkcs7,
|
|||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
byte* digestInfo;
|
byte* digestInfo;
|
||||||
#else
|
#else
|
||||||
byte digestInfo[MAX_PKCS7_DIGEST_SZ];
|
byte digestInfo[MAX_PKCS7_DIGEST_SZ];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (pkcs7 == NULL || esd == NULL)
|
if (pkcs7 == NULL || esd == NULL)
|
||||||
@ -1027,88 +1024,55 @@ static int wc_PKCS7_SignedDataBuildSignature(PKCS7* pkcs7,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* build PKCS#7 signedData content type */
|
/* 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[] =
|
const byte outerOid[] =
|
||||||
{ ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
|
{ ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
|
||||||
0x07, 0x02 };
|
0x07, 0x02 };
|
||||||
static const byte innerOid[] =
|
const byte innerOid[] =
|
||||||
{ ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
|
{ ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
|
||||||
0x07, 0x01 };
|
0x07, 0x01 };
|
||||||
|
|
||||||
byte contentTypeOid[] =
|
const byte contentTypeOid[] =
|
||||||
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
|
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
|
||||||
0x09, 0x03 };
|
0x09, 0x03 };
|
||||||
byte contentType[] =
|
const byte contentType[] =
|
||||||
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
|
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
|
||||||
0x07, 0x01 };
|
0x07, 0x01 };
|
||||||
byte messageDigestOid[] =
|
const byte messageDigestOid[] =
|
||||||
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
|
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
|
||||||
0x09, 0x04 };
|
0x09, 0x04 };
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
ESD* esd = NULL;
|
|
||||||
#else
|
|
||||||
ESD stack_esd;
|
|
||||||
ESD* esd = &stack_esd;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
word32 signerInfoSz = 0;
|
word32 signerInfoSz = 0;
|
||||||
word32 totalSz = 0;
|
word32 totalSz, total2Sz;
|
||||||
int idx = 0, ret = 0;
|
int idx = 0, ret = 0;
|
||||||
int digEncAlgoId, digEncAlgoType, hashSz;
|
int digEncAlgoId, digEncAlgoType;
|
||||||
byte* flatSignedAttribs = NULL;
|
byte* flatSignedAttribs = NULL;
|
||||||
word32 flatSignedAttribsSz = 0;
|
word32 flatSignedAttribsSz = 0;
|
||||||
word32 innerOidSz = sizeof(innerOid);
|
word32 innerOidSz = sizeof(innerOid);
|
||||||
word32 outerOidSz = sizeof(outerOid);
|
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->encryptOID == 0 || pkcs7->hashOID == 0 || pkcs7->rng == 0 ||
|
||||||
pkcs7->singleCert == NULL || pkcs7->singleCertSz == 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;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
/* verify the hash size matches */
|
||||||
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 = wc_OidGetHash(pkcs7->hashOID);
|
esd->hashType = wc_OidGetHash(pkcs7->hashOID);
|
||||||
ret = wc_HashGetDigestSize(esd->hashType);
|
if (wc_HashGetDigestSize(esd->hashType) != (int)hashSz) {
|
||||||
if (ret < 0) {
|
WOLFSSL_MSG("hashSz did not match hashOID");
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
return BUFFER_E;
|
||||||
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
hashSz = ret;
|
|
||||||
|
|
||||||
if (pkcs7->contentSz != 0)
|
/* include hash */
|
||||||
{
|
esd->contentDigest[0] = ASN_OCTET_STRING;
|
||||||
ret = wc_HashInit(&esd->hash, esd->hashType);
|
esd->contentDigest[1] = (byte)hashSz;
|
||||||
if (ret == 0) {
|
XMEMCPY(&esd->contentDigest[2], hashBuf, hashSz);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets);
|
esd->innerOctetsSz = SetOctetString(pkcs7->contentSz, esd->innerOctets);
|
||||||
esd->innerContSeqSz = SetExplicit(0, esd->innerOctetsSz + pkcs7->contentSz,
|
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,
|
ret = wc_PKCS7_SignedDataGetEncAlgoId(pkcs7, &digEncAlgoId,
|
||||||
&digEncAlgoType);
|
&digEncAlgoType);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
esd->digEncAlgoIdSz = SetAlgoID(digEncAlgoId, esd->digEncAlgoId,
|
esd->digEncAlgoIdSz = SetAlgoID(digEncAlgoId, esd->digEncAlgoId,
|
||||||
@ -1151,9 +1112,6 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
contentType, sizeof(contentType),
|
contentType, sizeof(contentType),
|
||||||
messageDigestOid, sizeof(messageDigestOid));
|
messageDigestOid, sizeof(messageDigestOid));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1161,9 +1119,6 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
DYNAMIC_TYPE_PKCS7);
|
DYNAMIC_TYPE_PKCS7);
|
||||||
flatSignedAttribsSz = esd->signedAttribsSz;
|
flatSignedAttribsSz = esd->signedAttribsSz;
|
||||||
if (flatSignedAttribs == NULL) {
|
if (flatSignedAttribs == NULL) {
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1179,9 +1134,6 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (pkcs7->signedAttribsSz != 0)
|
if (pkcs7->signedAttribsSz != 0)
|
||||||
XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1207,23 +1159,30 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
esd->versionSz = SetMyVersion(1, esd->version, 0);
|
esd->versionSz = SetMyVersion(1, esd->version, 0);
|
||||||
|
|
||||||
totalSz = esd->versionSz + esd->singleDigAlgoIdSz + esd->digAlgoIdSetSz +
|
totalSz = esd->versionSz + esd->singleDigAlgoIdSz + esd->digAlgoIdSetSz +
|
||||||
esd->contentInfoSeqSz + esd->certsSetSz + pkcs7->singleCertSz +
|
esd->contentInfoSeqSz + innerOidSz + esd->innerContSeqSz +
|
||||||
esd->innerOctetsSz + esd->innerContSeqSz +
|
esd->innerOctetsSz + pkcs7->contentSz;
|
||||||
innerOidSz + pkcs7->contentSz +
|
total2Sz = esd->certsSetSz + pkcs7->singleCertSz + signerInfoSz;
|
||||||
signerInfoSz;
|
|
||||||
esd->innerSeqSz = SetSequence(totalSz, esd->innerSeq);
|
esd->innerSeqSz = SetSequence(totalSz + total2Sz, esd->innerSeq);
|
||||||
totalSz += esd->innerSeqSz;
|
totalSz += esd->innerSeqSz;
|
||||||
esd->outerContentSz = SetExplicit(0, totalSz, esd->outerContent);
|
esd->outerContentSz = SetExplicit(0, totalSz + total2Sz, esd->outerContent);
|
||||||
totalSz += esd->outerContentSz + outerOidSz;
|
totalSz += esd->outerContentSz + outerOidSz;
|
||||||
esd->outerSeqSz = SetSequence(totalSz, esd->outerSeq);
|
esd->outerSeqSz = SetSequence(totalSz + total2Sz, esd->outerSeq);
|
||||||
totalSz += esd->outerSeqSz;
|
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)
|
if (pkcs7->signedAttribsSz != 0)
|
||||||
XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1250,50 +1209,160 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
idx += esd->innerContSeqSz;
|
idx += esd->innerContSeqSz;
|
||||||
XMEMCPY(output + idx, esd->innerOctets, esd->innerOctetsSz);
|
XMEMCPY(output + idx, esd->innerOctets, esd->innerOctetsSz);
|
||||||
idx += esd->innerOctetsSz;
|
idx += esd->innerOctetsSz;
|
||||||
XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
|
|
||||||
idx += pkcs7->contentSz;
|
/* support returning header and footer without content */
|
||||||
XMEMCPY(output + idx, esd->certsSet, esd->certsSetSz);
|
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;
|
idx += esd->certsSetSz;
|
||||||
XMEMCPY(output + idx, pkcs7->singleCert, pkcs7->singleCertSz);
|
XMEMCPY(output2 + idx, pkcs7->singleCert, pkcs7->singleCertSz);
|
||||||
idx += pkcs7->singleCertSz;
|
idx += pkcs7->singleCertSz;
|
||||||
XMEMCPY(output + idx, esd->signerInfoSet, esd->signerInfoSetSz);
|
XMEMCPY(output2 + idx, esd->signerInfoSet, esd->signerInfoSetSz);
|
||||||
idx += esd->signerInfoSetSz;
|
idx += esd->signerInfoSetSz;
|
||||||
XMEMCPY(output + idx, esd->signerInfoSeq, esd->signerInfoSeqSz);
|
XMEMCPY(output2 + idx, esd->signerInfoSeq, esd->signerInfoSeqSz);
|
||||||
idx += esd->signerInfoSeqSz;
|
idx += esd->signerInfoSeqSz;
|
||||||
XMEMCPY(output + idx, esd->signerVersion, esd->signerVersionSz);
|
XMEMCPY(output2 + idx, esd->signerVersion, esd->signerVersionSz);
|
||||||
idx += esd->signerVersionSz;
|
idx += esd->signerVersionSz;
|
||||||
XMEMCPY(output + idx, esd->issuerSnSeq, esd->issuerSnSeqSz);
|
XMEMCPY(output2 + idx, esd->issuerSnSeq, esd->issuerSnSeqSz);
|
||||||
idx += esd->issuerSnSeqSz;
|
idx += esd->issuerSnSeqSz;
|
||||||
XMEMCPY(output + idx, esd->issuerName, esd->issuerNameSz);
|
XMEMCPY(output2 + idx, esd->issuerName, esd->issuerNameSz);
|
||||||
idx += esd->issuerNameSz;
|
idx += esd->issuerNameSz;
|
||||||
XMEMCPY(output + idx, pkcs7->issuer, pkcs7->issuerSz);
|
XMEMCPY(output2 + idx, pkcs7->issuer, pkcs7->issuerSz);
|
||||||
idx += pkcs7->issuerSz;
|
idx += pkcs7->issuerSz;
|
||||||
XMEMCPY(output + idx, esd->issuerSn, esd->issuerSnSz);
|
XMEMCPY(output2 + idx, esd->issuerSn, esd->issuerSnSz);
|
||||||
idx += esd->issuerSnSz;
|
idx += esd->issuerSnSz;
|
||||||
XMEMCPY(output + idx, esd->signerDigAlgoId, esd->signerDigAlgoIdSz);
|
XMEMCPY(output2 + idx, esd->signerDigAlgoId, esd->signerDigAlgoIdSz);
|
||||||
idx += esd->signerDigAlgoIdSz;
|
idx += esd->signerDigAlgoIdSz;
|
||||||
|
|
||||||
/* SignerInfo:Attributes */
|
/* SignerInfo:Attributes */
|
||||||
if (flatSignedAttribsSz > 0) {
|
if (flatSignedAttribsSz > 0) {
|
||||||
XMEMCPY(output + idx, esd->signedAttribSet, esd->signedAttribSetSz);
|
XMEMCPY(output2 + idx, esd->signedAttribSet, esd->signedAttribSetSz);
|
||||||
idx += esd->signedAttribSetSz;
|
idx += esd->signedAttribSetSz;
|
||||||
XMEMCPY(output + idx, flatSignedAttribs, flatSignedAttribsSz);
|
XMEMCPY(output2 + idx, flatSignedAttribs, flatSignedAttribsSz);
|
||||||
idx += flatSignedAttribsSz;
|
idx += flatSignedAttribsSz;
|
||||||
XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||||
}
|
}
|
||||||
|
|
||||||
XMEMCPY(output + idx, esd->digEncAlgoId, esd->digEncAlgoIdSz);
|
XMEMCPY(output2 + idx, esd->digEncAlgoId, esd->digEncAlgoIdSz);
|
||||||
idx += esd->digEncAlgoIdSz;
|
idx += esd->digEncAlgoIdSz;
|
||||||
XMEMCPY(output + idx, esd->signerDigest, esd->signerDigestSz);
|
XMEMCPY(output2 + idx, esd->signerDigest, esd->signerDigestSz);
|
||||||
idx += esd->signerDigestSz;
|
idx += esd->signerDigestSz;
|
||||||
XMEMCPY(output + idx, esd->encContentDigest, esd->encContentDigestSz);
|
XMEMCPY(output2 + idx, esd->encContentDigest, esd->encContentDigestSz);
|
||||||
idx += 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
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
#endif
|
#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;
|
RsaKey* key;
|
||||||
#else
|
#else
|
||||||
byte digest[MAX_PKCS7_DIGEST_SZ];
|
byte digest[MAX_PKCS7_DIGEST_SZ];
|
||||||
RsaKey stack_key;
|
RsaKey key[1];
|
||||||
RsaKey* key = &stack_key;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (pkcs7 == NULL || sig == NULL || hash == NULL) {
|
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;
|
ecc_key* key;
|
||||||
#else
|
#else
|
||||||
byte digest[MAX_PKCS7_DIGEST_SZ];
|
byte digest[MAX_PKCS7_DIGEST_SZ];
|
||||||
ecc_key stack_key;
|
ecc_key key[1];
|
||||||
ecc_key* key = &stack_key;
|
|
||||||
#endif
|
#endif
|
||||||
word32 idx = 0;
|
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,
|
static int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib,
|
||||||
word32 signedAttribSz, byte* pkcs7Digest,
|
word32 signedAttribSz, byte* pkcs7Digest,
|
||||||
word32* pkcs7DigestSz, byte** plainDigest,
|
word32* pkcs7DigestSz, byte** plainDigest,
|
||||||
word32* plainDigestSz)
|
word32* plainDigestSz,
|
||||||
|
const byte* hashBuf, word32 hashBufSz)
|
||||||
{
|
{
|
||||||
int ret = 0, digIdx = 0, hashSz;
|
int ret = 0, digIdx = 0;
|
||||||
word32 attribSetSz;
|
word32 attribSetSz, hashSz;
|
||||||
byte attribSet[MAX_SET_SZ];
|
byte attribSet[MAX_SET_SZ];
|
||||||
byte digest[WC_MAX_DIGEST_SIZE];
|
byte digest[WC_MAX_DIGEST_SIZE];
|
||||||
byte digestInfoSeq[MAX_SEQ_SZ];
|
byte digestInfoSeq[MAX_SEQ_SZ];
|
||||||
@ -1477,7 +1545,7 @@ static int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib,
|
|||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
byte* digestInfo;
|
byte* digestInfo;
|
||||||
#else
|
#else
|
||||||
byte digestInfo[MAX_PKCS7_DIGEST_SZ];
|
byte digestInfo[MAX_PKCS7_DIGEST_SZ];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wc_HashAlg hash;
|
wc_HashAlg hash;
|
||||||
@ -1500,7 +1568,11 @@ static int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib,
|
|||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
else {
|
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;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1517,36 +1589,40 @@ static int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib,
|
|||||||
|
|
||||||
|
|
||||||
/* calculate digest */
|
/* calculate digest */
|
||||||
ret = wc_HashInit(&hash, hashType);
|
if (hashBuf && hashBufSz > 0 && signedAttribSz == 0) {
|
||||||
if (ret < 0) {
|
XMEMCPY(digest, hashBuf, hashBufSz);
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
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) {
|
if (signedAttribSz > 0) {
|
||||||
attribSetSz = SetSet(signedAttribSz, attribSet);
|
attribSetSz = SetSet(signedAttribSz, attribSet);
|
||||||
|
|
||||||
/* calculate digest */
|
/* calculate digest */
|
||||||
ret = wc_HashUpdate(&hash, hashType, attribSet, attribSetSz);
|
ret = wc_HashUpdate(&hash, hashType, attribSet, attribSetSz);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = wc_HashUpdate(&hash, hashType, signedAttrib, signedAttribSz);
|
ret = wc_HashUpdate(&hash, hashType, signedAttrib, signedAttribSz);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = wc_HashFinal(&hash, hashType, digest);
|
ret = wc_HashFinal(&hash, hashType, digest);
|
||||||
} else {
|
} else {
|
||||||
ret = wc_HashUpdate(&hash, hashType, pkcs7->content, pkcs7->contentSz);
|
ret = wc_HashUpdate(&hash, hashType, pkcs7->content, pkcs7->contentSz);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = wc_HashFinal(&hash, hashType, digest);
|
ret = wc_HashFinal(&hash, hashType, digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
wc_HashFree(&hash, hashType);
|
wc_HashFree(&hash, hashType);
|
||||||
|
if (ret < 0) {
|
||||||
if (ret < 0) {
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
#endif
|
||||||
#endif
|
return ret;
|
||||||
return ret;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set algoID, with NULL attributes */
|
/* 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 */
|
* return 0 on success, negative on error */
|
||||||
static int wc_PKCS7_SignedDataVerifySignature(PKCS7* pkcs7, byte* sig,
|
static int wc_PKCS7_SignedDataVerifySignature(PKCS7* pkcs7, byte* sig,
|
||||||
word32 sigSz, byte* signedAttrib,
|
word32 sigSz, byte* signedAttrib,
|
||||||
word32 signedAttribSz)
|
word32 signedAttribSz,
|
||||||
|
const byte* hashBuf, word32 hashSz)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
word32 plainDigestSz = 0, pkcs7DigestSz;
|
word32 plainDigestSz = 0, pkcs7DigestSz;
|
||||||
@ -1617,7 +1694,7 @@ static int wc_PKCS7_SignedDataVerifySignature(PKCS7* pkcs7, byte* sig,
|
|||||||
ret = wc_PKCS7_BuildSignedDataDigest(pkcs7, signedAttrib,
|
ret = wc_PKCS7_BuildSignedDataDigest(pkcs7, signedAttrib,
|
||||||
signedAttribSz, pkcs7Digest,
|
signedAttribSz, pkcs7Digest,
|
||||||
&pkcs7DigestSz, &plainDigest,
|
&pkcs7DigestSz, &plainDigest,
|
||||||
&plainDigestSz);
|
&plainDigestSz, hashBuf, hashSz);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
XFREE(pkcs7Digest, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
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;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Finds the certificates in the message and saves it. */
|
/* 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;
|
int length, version, ret;
|
||||||
byte* content = NULL;
|
byte* content = NULL;
|
||||||
byte* sig = NULL;
|
byte* sig = NULL;
|
||||||
byte* cert = NULL;
|
byte* cert = NULL;
|
||||||
byte* signedAttrib = NULL;
|
byte* signedAttrib = NULL;
|
||||||
int contentSz = 0, sigSz = 0, certSz = 0, signedAttribSz = 0;
|
int contentSz = 0, sigSz = 0, certSz = 0, signedAttribSz = 0;
|
||||||
|
word32 localIdx;
|
||||||
byte degenerate;
|
byte degenerate;
|
||||||
#ifdef ASN_BER_TO_DER
|
#ifdef ASN_BER_TO_DER
|
||||||
byte* der;
|
byte* der;
|
||||||
@ -1839,8 +1918,14 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||||||
|
|
||||||
idx = 0;
|
idx = 0;
|
||||||
|
|
||||||
|
/* determine total message size */
|
||||||
|
totalSz = pkiMsgSz;
|
||||||
|
if (pkiMsg2 && pkiMsg2Sz > 0) {
|
||||||
|
totalSz += pkiMsg2Sz + pkcs7->contentSz;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the contentInfo sequence */
|
/* Get the contentInfo sequence */
|
||||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
if (GetSequence(pkiMsg, &idx, &length, totalSz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
if (length == 0 && pkiMsg[idx-1] == 0x80) {
|
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))
|
if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
if (GetLength(pkiMsg, &idx, &length, totalSz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
/* Get the signedData sequence */
|
/* Get the signedData sequence */
|
||||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
if (GetSequence(pkiMsg, &idx, &length, totalSz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
/* Get the version */
|
/* Get the version */
|
||||||
@ -1905,7 +1990,7 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||||||
degenerate = (length == 0)? 1 : 0;
|
degenerate = (length == 0)? 1 : 0;
|
||||||
|
|
||||||
/* Get the inner ContentInfo sequence */
|
/* Get the inner ContentInfo sequence */
|
||||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
if (GetSequence(pkiMsg, &idx, &length, totalSz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
/* Get the inner ContentInfo contentType */
|
/* 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 */
|
/* Check for content info, it could be omitted when degenerate */
|
||||||
{
|
localIdx = idx;
|
||||||
word32 localIdx = idx;
|
ret = 0;
|
||||||
ret = 0;
|
if (pkiMsg[localIdx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
|
||||||
if (pkiMsg[localIdx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
|
ret = ASN_PARSE_E;
|
||||||
ret = ASN_PARSE_E;
|
|
||||||
|
|
||||||
if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, pkiMsgSz) <= 0)
|
if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, totalSz) <= 0)
|
||||||
ret = ASN_PARSE_E;
|
ret = ASN_PARSE_E;
|
||||||
|
|
||||||
if (ret == 0 && pkiMsg[localIdx++] != ASN_OCTET_STRING)
|
if (ret == 0 && pkiMsg[localIdx++] != ASN_OCTET_STRING)
|
||||||
ret = ASN_PARSE_E;
|
ret = ASN_PARSE_E;
|
||||||
|
|
||||||
if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, pkiMsgSz) < 0)
|
if (ret == 0 && GetLength(pkiMsg, &localIdx, &length, totalSz) < 0)
|
||||||
ret = ASN_PARSE_E;
|
ret = ASN_PARSE_E;
|
||||||
|
|
||||||
/* Save the inner data as the content. */
|
/* Save the inner data as the content. */
|
||||||
if (length > 0) {
|
if (ret == 0 && length > 0) {
|
||||||
/* Local pointer for calculating hashes later */
|
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];
|
content = &pkiMsg[localIdx];
|
||||||
contentSz = length;
|
|
||||||
localIdx += length;
|
localIdx += length;
|
||||||
}
|
|
||||||
|
|
||||||
/* update idx if successful */
|
pkiMsg2 = pkiMsg;
|
||||||
if (ret == 0) {
|
pkiMsg2Sz = pkiMsgSz;
|
||||||
idx = localIdx;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
pkiMsg2 = pkiMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update idx if successful */
|
||||||
|
if (ret == 0) {
|
||||||
|
idx = localIdx;
|
||||||
|
}
|
||||||
|
|
||||||
/* 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
|
||||||
@ -1955,9 +2057,9 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get the implicit[0] set of certificates */
|
/* 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++;
|
idx++;
|
||||||
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
@ -1969,11 +2071,11 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||||||
|
|
||||||
word32 certIdx = idx;
|
word32 certIdx = idx;
|
||||||
|
|
||||||
if (pkiMsg[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
|
if (pkiMsg2[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
|
||||||
if (GetLength(pkiMsg, &certIdx, &certSz, pkiMsgSz) < 0)
|
if (GetLength(pkiMsg2, &certIdx, &certSz, pkiMsg2Sz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
cert = &pkiMsg[idx];
|
cert = &pkiMsg2[idx];
|
||||||
certSz += (certIdx - idx);
|
certSz += (certIdx - idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1988,7 +2090,6 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||||||
|
|
||||||
/* iterate through any additional certificates */
|
/* iterate through any additional certificates */
|
||||||
if (MAX_PKCS7_CERTS > 0) {
|
if (MAX_PKCS7_CERTS > 0) {
|
||||||
word32 localIdx;
|
|
||||||
int sz = 0;
|
int sz = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -1996,14 +2097,14 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||||||
pkcs7->certSz[0] = certSz;
|
pkcs7->certSz[0] = certSz;
|
||||||
certIdx = idx + 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;
|
localIdx = certIdx;
|
||||||
|
|
||||||
if (pkiMsg[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
|
if (pkiMsg2[certIdx++] == (ASN_CONSTRUCTED | ASN_SEQUENCE)) {
|
||||||
if (GetLength(pkiMsg, &certIdx, &sz, pkiMsgSz) < 0)
|
if (GetLength(pkiMsg2, &certIdx, &sz, pkiMsg2Sz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
pkcs7->cert[i] = &pkiMsg[localIdx];
|
pkcs7->cert[i] = &pkiMsg2[localIdx];
|
||||||
pkcs7->certSz[i] = sz + (certIdx - localIdx);
|
pkcs7->certSz[i] = sz + (certIdx - localIdx);
|
||||||
certIdx += sz;
|
certIdx += sz;
|
||||||
}
|
}
|
||||||
@ -2018,9 +2119,9 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||||||
pkcs7->contentSz = contentSz;
|
pkcs7->contentSz = contentSz;
|
||||||
|
|
||||||
/* Get the implicit[1] set of crls */
|
/* 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++;
|
idx++;
|
||||||
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
/* Skip the set */
|
/* Skip the set */
|
||||||
@ -2028,16 +2129,16 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get the set of signerInfos */
|
/* Get the set of signerInfos */
|
||||||
if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
if (GetSet(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
/* Get the sequence of the first signerInfo */
|
/* 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;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
/* Get the version */
|
/* Get the version */
|
||||||
if (GetMyVersion(pkiMsg, &idx, &version, pkiMsgSz) < 0)
|
if (GetMyVersion(pkiMsg2, &idx, &version, pkiMsg2Sz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
if (version != 1) {
|
if (version != 1) {
|
||||||
@ -2046,27 +2147,27 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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 */
|
||||||
idx += length;
|
idx += length;
|
||||||
|
|
||||||
/* Get the sequence of digestAlgorithm */
|
/* 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;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
pkcs7->hashOID = (int)hashOID;
|
pkcs7->hashOID = (int)hashOID;
|
||||||
|
|
||||||
/* Get the IMPLICIT[0] SET OF signedAttributes */
|
/* Get the IMPLICIT[0] SET OF signedAttributes */
|
||||||
if (pkiMsg[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
|
if (pkiMsg2[idx] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
/* save pointer and length */
|
/* save pointer and length */
|
||||||
signedAttrib = &pkiMsg[idx];
|
signedAttrib = &pkiMsg2[idx];
|
||||||
signedAttribSz = length;
|
signedAttribSz = length;
|
||||||
|
|
||||||
if (wc_PKCS7_ParseAttribs(pkcs7, signedAttrib, signedAttribSz) <0) {
|
if (wc_PKCS7_ParseAttribs(pkcs7, signedAttrib, signedAttribSz) <0) {
|
||||||
@ -2078,7 +2179,7 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get digestEncryptionAlgorithm */
|
/* Get digestEncryptionAlgorithm */
|
||||||
if (GetAlgoId(pkiMsg, &idx, &sigOID, oidSigType, pkiMsgSz) < 0) {
|
if (GetAlgoId(pkiMsg2, &idx, &sigOID, oidSigType, pkiMsg2Sz) < 0) {
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2090,14 +2191,14 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get the signature */
|
/* Get the signature */
|
||||||
if (pkiMsg[idx] == ASN_OCTET_STRING) {
|
if (pkiMsg2[idx] == ASN_OCTET_STRING) {
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
if (GetLength(pkiMsg2, &idx, &length, pkiMsg2Sz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
/* save pointer and length */
|
/* save pointer and length */
|
||||||
sig = &pkiMsg[idx];
|
sig = &pkiMsg2[idx];
|
||||||
sigSz = length;
|
sigSz = length;
|
||||||
|
|
||||||
idx += length;
|
idx += length;
|
||||||
@ -2107,7 +2208,8 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
|||||||
pkcs7->contentSz = contentSz;
|
pkcs7->contentSz = contentSz;
|
||||||
|
|
||||||
ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,
|
ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, sigSz,
|
||||||
signedAttrib, signedAttribSz);
|
signedAttrib, signedAttribSz,
|
||||||
|
hashBuf, hashSz);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
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
|
#ifdef HAVE_ECC
|
||||||
|
|
||||||
/* KARI == KeyAgreeRecipientInfo (key agreement) */
|
/* KARI == KeyAgreeRecipientInfo (key agreement) */
|
||||||
@ -2916,10 +3034,8 @@ static int wc_CreateRecipientInfo(const byte* cert, word32 certSz,
|
|||||||
byte serial[MAX_SN_SZ];
|
byte serial[MAX_SN_SZ];
|
||||||
byte keyAlgArray[MAX_ALGO_SZ];
|
byte keyAlgArray[MAX_ALGO_SZ];
|
||||||
|
|
||||||
RsaKey stack_pubKey;
|
RsaKey pubKey[1];
|
||||||
RsaKey* pubKey = &stack_pubKey;
|
DecodedCert decoded[1];
|
||||||
DecodedCert stack_decoded;
|
|
||||||
DecodedCert* decoded = &stack_decoded;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
InitDecodedCert(decoded, (byte*)cert, certSz, heap);
|
InitDecodedCert(decoded, (byte*)cert, certSz, heap);
|
||||||
@ -3346,7 +3462,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
byte* contentKeyEnc;
|
byte* contentKeyEnc;
|
||||||
#else
|
#else
|
||||||
byte contentKeyEnc[MAX_ENCRYPTED_KEY_SZ];
|
byte contentKeyEnc[MAX_ENCRYPTED_KEY_SZ];
|
||||||
#endif
|
#endif
|
||||||
byte* plain;
|
byte* plain;
|
||||||
byte* encryptedContent;
|
byte* encryptedContent;
|
||||||
@ -3355,7 +3471,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
byte* recip;
|
byte* recip;
|
||||||
#else
|
#else
|
||||||
byte recip[MAX_RECIP_SZ];
|
byte recip[MAX_RECIP_SZ];
|
||||||
#endif
|
#endif
|
||||||
byte recipSet[MAX_SET_SZ];
|
byte recipSet[MAX_SET_SZ];
|
||||||
|
|
||||||
@ -3645,12 +3761,9 @@ static int wc_PKCS7_DecodeKtri(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz,
|
|||||||
byte* encryptedKey;
|
byte* encryptedKey;
|
||||||
RsaKey* privKey;
|
RsaKey* privKey;
|
||||||
#else
|
#else
|
||||||
mp_int stack_serialNum;
|
mp_int serialNum[1];
|
||||||
mp_int* serialNum = &stack_serialNum;
|
|
||||||
byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
|
byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
|
||||||
|
RsaKey privKey[1];
|
||||||
RsaKey stack_privKey;
|
|
||||||
RsaKey* privKey = &stack_privKey;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* remove IssuerAndSerialNumber */
|
/* remove IssuerAndSerialNumber */
|
||||||
@ -3996,11 +4109,8 @@ static int wc_PKCS7_KariGetIssuerAndSerialNumber(WC_PKCS7_KARI* kari,
|
|||||||
mp_int* serial;
|
mp_int* serial;
|
||||||
mp_int* recipSerial;
|
mp_int* recipSerial;
|
||||||
#else
|
#else
|
||||||
mp_int stack_serial;
|
mp_int serial[1];
|
||||||
mp_int* serial = &stack_serial;
|
mp_int recipSerial[1];
|
||||||
|
|
||||||
mp_int stack_recipSerial;
|
|
||||||
mp_int* recipSerial = &stack_recipSerial;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* remove IssuerAndSerialNumber */
|
/* remove IssuerAndSerialNumber */
|
||||||
@ -4148,7 +4258,7 @@ static int wc_PKCS7_DecodeKari(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz,
|
|||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
byte* encryptedKey;
|
byte* encryptedKey;
|
||||||
#else
|
#else
|
||||||
byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
|
byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WC_PKCS7_KARI* kari;
|
WC_PKCS7_KARI* kari;
|
||||||
@ -4399,7 +4509,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
byte* decryptedKey;
|
byte* decryptedKey;
|
||||||
#else
|
#else
|
||||||
byte decryptedKey[MAX_ENCRYPTED_KEY_SZ];
|
byte decryptedKey[MAX_ENCRYPTED_KEY_SZ];
|
||||||
#endif
|
#endif
|
||||||
int encryptedContentSz;
|
int encryptedContentSz;
|
||||||
byte padLen;
|
byte padLen;
|
||||||
|
@ -79,9 +79,9 @@ enum Pkcs7_Misc {
|
|||||||
|
|
||||||
|
|
||||||
typedef struct PKCS7Attrib {
|
typedef struct PKCS7Attrib {
|
||||||
byte* oid;
|
const byte* oid;
|
||||||
word32 oidSz;
|
word32 oidSz;
|
||||||
byte* value;
|
const byte* value;
|
||||||
word32 valueSz;
|
word32 valueSz;
|
||||||
} PKCS7Attrib;
|
} PKCS7Attrib;
|
||||||
|
|
||||||
@ -160,8 +160,14 @@ WOLFSSL_API int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output,
|
|||||||
word32 outputSz);
|
word32 outputSz);
|
||||||
WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7,
|
WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7,
|
||||||
byte* output, word32 outputSz);
|
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,
|
WOLFSSL_API int wc_PKCS7_VerifySignedData(PKCS7* pkcs7,
|
||||||
byte* pkiMsg, word32 pkiMsgSz);
|
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,
|
WOLFSSL_API int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7,
|
||||||
byte* output, word32 outputSz);
|
byte* output, word32 outputSz);
|
||||||
WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
||||||
|
Reference in New Issue
Block a user