forked from wolfSSL/wolfssl
add PKCS7 SignedData with ECDSA
This commit is contained in:
@@ -434,6 +434,352 @@ static int FlattenAttributes(byte* output, EncodedAttrib* ea, int eaSz)
|
||||
}
|
||||
|
||||
|
||||
/* returns size of signature put into out, negative on error */
|
||||
static int wc_PKCS7_RsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
|
||||
{
|
||||
int ret;
|
||||
word32 idx;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
RsaKey* privKey;
|
||||
#else
|
||||
RsaKey stack_privKey;
|
||||
RsaKey* privKey = &stack_privKey;
|
||||
#endif
|
||||
|
||||
if (pkcs7 == NULL || pkcs7->privateKey == NULL || pkcs7->rng == NULL ||
|
||||
in == NULL || esd == NULL || esd->encContentDigest == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (privKey == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
ret = wc_InitRsaKey(privKey, pkcs7->heap);
|
||||
|
||||
if (ret == 0) {
|
||||
ret = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,
|
||||
pkcs7->privateKeySz);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = wc_RsaSSL_Sign(in, inSz, esd->encContentDigest,
|
||||
sizeof(esd->encContentDigest),
|
||||
privKey, pkcs7->rng);
|
||||
}
|
||||
|
||||
wc_FreeRsaKey(privKey);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* returns size of signature put into out, negative on error */
|
||||
static int wc_PKCS7_EcdsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
|
||||
{
|
||||
int ret;
|
||||
word32 outSz, idx;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
ecc_key* privKey;
|
||||
#else
|
||||
ecc_key stack_privKey;
|
||||
ecc_key* privKey = &stack_privKey;
|
||||
#endif
|
||||
|
||||
if (pkcs7 == NULL || pkcs7->privateKey == NULL || pkcs7->rng == NULL ||
|
||||
in == NULL || esd == NULL || esd->encContentDigest == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
privKey = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (privKey == NULL)
|
||||
return MEMORY_E;
|
||||
#endif
|
||||
|
||||
ret = wc_ecc_init_ex(privKey, pkcs7->heap, INVALID_DEVID);
|
||||
|
||||
if (ret == 0) {
|
||||
idx = 0;
|
||||
ret = wc_EccPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,
|
||||
pkcs7->privateKeySz);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
outSz = sizeof(esd->encContentDigest);
|
||||
ret = wc_ecc_sign_hash(in, inSz, esd->encContentDigest,
|
||||
&outSz, pkcs7->rng, privKey);
|
||||
if (ret == 0)
|
||||
ret = (int)outSz;
|
||||
}
|
||||
|
||||
wc_ecc_free(privKey);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* builds up SignedData signed attributes, including default ones.
|
||||
*
|
||||
* pkcs7 - pointer to initialized PKCS7 structure
|
||||
* esd - pointer to initialized ESD structure, used for output
|
||||
*
|
||||
* return 0 on success, negative on error */
|
||||
static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd)
|
||||
{
|
||||
|
||||
byte contentTypeOid[] =
|
||||
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
|
||||
0x09, 0x03 };
|
||||
byte contentType[] =
|
||||
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
|
||||
0x07, 0x01 };
|
||||
byte messageDigestOid[] =
|
||||
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
|
||||
0x09, 0x04 };
|
||||
|
||||
PKCS7Attrib cannedAttribs[2];
|
||||
word32 cannedAttribsCount;
|
||||
|
||||
if (pkcs7 == NULL || esd == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib);
|
||||
|
||||
cannedAttribs[0].oid = contentTypeOid;
|
||||
cannedAttribs[0].oidSz = sizeof(contentTypeOid);
|
||||
cannedAttribs[0].value = contentType;
|
||||
cannedAttribs[0].valueSz = sizeof(contentType);
|
||||
cannedAttribs[1].oid = messageDigestOid;
|
||||
cannedAttribs[1].oidSz = sizeof(messageDigestOid);
|
||||
cannedAttribs[1].value = esd->contentDigest;
|
||||
cannedAttribs[1].valueSz = sizeof(esd->contentDigest);
|
||||
|
||||
esd->signedAttribsCount += cannedAttribsCount;
|
||||
esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[0], 2,
|
||||
cannedAttribs, cannedAttribsCount);
|
||||
|
||||
esd->signedAttribsCount += pkcs7->signedAttribsSz;
|
||||
esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[2], 4,
|
||||
pkcs7->signedAttribs, pkcs7->signedAttribsSz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* gets correct encryption algo ID for SignedData, either RSAk or
|
||||
* CTC_<hash>wECDSA, from pkcs7->publicKeyOID.
|
||||
*
|
||||
* pkcs7 - pointer to PKCS7 structure
|
||||
* digEncAlgoId - [OUT] output int to store correct algo ID in
|
||||
* digEncAlgoType - [OUT] output for algo ID type
|
||||
*
|
||||
* return 0 on success, negative on error */
|
||||
static int wc_PKCS7_SignedDataGetEncAlgoId(PKCS7* pkcs7, int* digEncAlgoId,
|
||||
int* digEncAlgoType)
|
||||
{
|
||||
int algoId = 0;
|
||||
int algoType = 0;
|
||||
|
||||
if (pkcs7 == NULL || digEncAlgoId == NULL || digEncAlgoType == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (pkcs7->publicKeyOID == RSAk) {
|
||||
|
||||
algoId = pkcs7->encryptOID;
|
||||
algoType = oidKeyType;
|
||||
|
||||
} else if (pkcs7->publicKeyOID == ECDSAk) {
|
||||
|
||||
algoType = oidSigType;
|
||||
|
||||
switch (pkcs7->hashOID) {
|
||||
case SHAh:
|
||||
algoId = CTC_SHAwECDSA;
|
||||
break;
|
||||
|
||||
case SHA224h:
|
||||
algoId = CTC_SHA224wECDSA;
|
||||
break;
|
||||
|
||||
case SHA256h:
|
||||
algoId = CTC_SHA256wECDSA;
|
||||
break;
|
||||
|
||||
case SHA384h:
|
||||
algoId = CTC_SHA384wECDSA;
|
||||
break;
|
||||
|
||||
case SHA512h:
|
||||
algoId = CTC_SHA512wECDSA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (algoId == 0) {
|
||||
WOLFSSL_MSG("Invalid signature algorithm type");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
*digEncAlgoId = algoId;
|
||||
*digEncAlgoType = algoType;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* build SignedData DigestInfo for use with PKCS#7/RSA
|
||||
*
|
||||
* pkcs7 - pointer to initialized PKCS7 struct
|
||||
* flatSignedAttribs - flattened, signed attributes
|
||||
* flatSignedAttrbsSz - size of flatSignedAttribs, octets
|
||||
* esd - pointer to initialized ESD struct
|
||||
* digestInfo - [OUT] output array for DigestInfo
|
||||
* digestInfoSz - [IN/OUT] - input size of array, size of digestInfo
|
||||
*
|
||||
* return 0 on success, negative on error */
|
||||
static int wc_PKCS7_BuildDigestInfo(PKCS7* pkcs7, byte* flatSignedAttribs,
|
||||
word32 flatSignedAttribsSz, ESD* esd,
|
||||
byte* digestInfo, word32* digestInfoSz)
|
||||
{
|
||||
int ret, digIdx = 0;
|
||||
byte digestInfoSeq[MAX_SEQ_SZ];
|
||||
byte digestStr[MAX_OCTET_STR_SZ];
|
||||
byte attribSet[MAX_SET_SZ];
|
||||
word32 digestInfoSeqSz, digestStrSz;
|
||||
word32 attribSetSz;
|
||||
|
||||
if (pkcs7 == NULL || esd == NULL || &esd->sha == NULL ||
|
||||
esd->contentDigest == NULL || esd->signerDigAlgoId == NULL ||
|
||||
digestInfo == NULL || digestInfoSz == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (pkcs7->signedAttribsSz != 0) {
|
||||
|
||||
if (flatSignedAttribs == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
attribSetSz = SetSet(flatSignedAttribsSz, attribSet);
|
||||
|
||||
ret = wc_InitSha(&esd->sha);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
wc_ShaUpdate(&esd->sha, attribSet, attribSetSz);
|
||||
wc_ShaUpdate(&esd->sha, flatSignedAttribs, flatSignedAttribsSz);
|
||||
wc_ShaFinal(&esd->sha, esd->contentAttribsDigest);
|
||||
|
||||
} else {
|
||||
/* when no attrs, digest is contentDigest without tag and length */
|
||||
XMEMCPY(esd->contentAttribsDigest, esd->contentDigest + 2,
|
||||
SHA_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
digestStrSz = SetOctetString(SHA_DIGEST_SIZE, digestStr);
|
||||
digestInfoSeqSz = SetSequence(esd->signerDigAlgoIdSz +
|
||||
digestStrSz + SHA_DIGEST_SIZE,
|
||||
digestInfoSeq);
|
||||
|
||||
if (*digestInfoSz < (digestInfoSeqSz + esd->signerDigAlgoIdSz +
|
||||
digestStrSz + SHA_DIGEST_SIZE)) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);
|
||||
digIdx += digestInfoSeqSz;
|
||||
XMEMCPY(digestInfo + digIdx, esd->signerDigAlgoId, esd->signerDigAlgoIdSz);
|
||||
digIdx += esd->signerDigAlgoIdSz;
|
||||
XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);
|
||||
digIdx += digestStrSz;
|
||||
XMEMCPY(digestInfo + digIdx, esd->contentAttribsDigest, SHA_DIGEST_SIZE);
|
||||
digIdx += SHA_DIGEST_SIZE;
|
||||
|
||||
*digestInfoSz = digIdx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* build SignedData signature over DigestInfo or content digest
|
||||
*
|
||||
* pkcs7 - pointer to initizlied PKCS7 struct
|
||||
* flatSignedAttribs - flattened, signed attributes
|
||||
* flatSignedAttribsSz - size of flatSignedAttribs, octets
|
||||
* esd - pointer to initialized ESD struct
|
||||
*
|
||||
* returns length of signature on success, negative on error */
|
||||
static int wc_PKCS7_SignedDataBuildSignature(PKCS7* pkcs7,
|
||||
byte* flatSignedAttribs,
|
||||
word32 flatSignedAttribsSz,
|
||||
ESD* esd)
|
||||
{
|
||||
int ret;
|
||||
word32 digestInfoSz = MAX_SEQ_SZ + MAX_ALGO_SZ +
|
||||
MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte* digestInfo;
|
||||
#else
|
||||
byte digestInfo[digestInfoSz];
|
||||
#endif
|
||||
|
||||
if (pkcs7 == NULL || esd == NULL || esd->contentAttribsDigest == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
digestInfo = (byte*)XMALLOC(digestInfoSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (digestInfo == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = wc_PKCS7_BuildDigestInfo(pkcs7, flatSignedAttribs,
|
||||
flatSignedAttribsSz, esd, digestInfo,
|
||||
&digestInfoSz);
|
||||
if (ret < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* sign digestInfo */
|
||||
switch (pkcs7->publicKeyOID) {
|
||||
|
||||
case RSAk:
|
||||
ret = wc_PKCS7_RsaSign(pkcs7, digestInfo, digestInfoSz, esd);
|
||||
break;
|
||||
|
||||
case ECDSAk:
|
||||
/* CMS with ECDSA does not sign DigestInfo structure
|
||||
* like PKCS#7 with RSA does */
|
||||
ret = wc_PKCS7_EcdsaSign(pkcs7, esd->contentAttribsDigest,
|
||||
SHA_DIGEST_SIZE, esd);
|
||||
break;
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("Unsupported public key type");
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
if (ret >= 0) {
|
||||
esd->encContentDigestSz = (word32)ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* build PKCS#7 signedData content type */
|
||||
int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
||||
{
|
||||
@@ -454,6 +800,7 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
||||
word32 signerInfoSz = 0;
|
||||
word32 totalSz = 0;
|
||||
int idx = 0, ret = 0;
|
||||
int digEncAlgoId, digEncAlgoType;
|
||||
byte* flatSignedAttribs = NULL;
|
||||
word32 flatSignedAttribsSz = 0;
|
||||
word32 innerOidSz = sizeof(innerOid);
|
||||
@@ -508,40 +855,24 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
||||
esd->signerDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd->signerDigAlgoId,
|
||||
oidHashType, 0);
|
||||
signerInfoSz += esd->signerDigAlgoIdSz;
|
||||
esd->digEncAlgoIdSz = SetAlgoID(pkcs7->encryptOID, esd->digEncAlgoId,
|
||||
oidKeyType, 0);
|
||||
|
||||
/* set signatureAlgorithm */
|
||||
ret = wc_PKCS7_SignedDataGetEncAlgoId(pkcs7, &digEncAlgoId,
|
||||
&digEncAlgoType);
|
||||
if (ret < 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
esd->digEncAlgoIdSz = SetAlgoID(digEncAlgoId, esd->digEncAlgoId,
|
||||
digEncAlgoType, 0);
|
||||
signerInfoSz += esd->digEncAlgoIdSz;
|
||||
|
||||
if (pkcs7->signedAttribsSz != 0) {
|
||||
byte contentTypeOid[] =
|
||||
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
|
||||
0x09, 0x03 };
|
||||
byte contentType[] =
|
||||
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
|
||||
0x07, 0x01 };
|
||||
byte messageDigestOid[] =
|
||||
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
|
||||
0x09, 0x04 };
|
||||
|
||||
PKCS7Attrib cannedAttribs[2] ;
|
||||
|
||||
word32 cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib);
|
||||
cannedAttribs[0].oid = contentTypeOid ;
|
||||
cannedAttribs[0].oidSz = sizeof(contentTypeOid) ;
|
||||
cannedAttribs[0].value = contentType ;
|
||||
cannedAttribs[0].valueSz = sizeof(contentType) ;
|
||||
cannedAttribs[1].oid = messageDigestOid ;
|
||||
cannedAttribs[1].oidSz = sizeof(messageDigestOid) ;
|
||||
cannedAttribs[1].value = esd->contentDigest ;
|
||||
cannedAttribs[1].valueSz = sizeof(esd->contentDigest) ;
|
||||
|
||||
esd->signedAttribsCount += cannedAttribsCount;
|
||||
esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[0], 2,
|
||||
cannedAttribs, cannedAttribsCount);
|
||||
|
||||
esd->signedAttribsCount += pkcs7->signedAttribsSz;
|
||||
esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[2], 4,
|
||||
pkcs7->signedAttribs, pkcs7->signedAttribsSz);
|
||||
/* build up signed attributes */
|
||||
ret = wc_PKCS7_BuildSignedAttributes(pkcs7, esd);
|
||||
|
||||
flatSignedAttribs = (byte*)XMALLOC(esd->signedAttribsSz, pkcs7->heap,
|
||||
DYNAMIC_TYPE_PKCS);
|
||||
@@ -552,130 +883,25 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
||||
#endif
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
FlattenAttributes(flatSignedAttribs,
|
||||
esd->signedAttribs, esd->signedAttribsCount);
|
||||
esd->signedAttribSetSz = SetImplicit(ASN_SET, 0, esd->signedAttribsSz,
|
||||
esd->signedAttribSet);
|
||||
}
|
||||
|
||||
/* Calculate the final hash and encrypt it. */
|
||||
{
|
||||
int result;
|
||||
word32 scratch = 0;
|
||||
|
||||
ret = wc_PKCS7_SignedDataBuildSignature(pkcs7, flatSignedAttribs,
|
||||
flatSignedAttribsSz, esd);
|
||||
if (ret < 0) {
|
||||
if (pkcs7->signedAttribsSz != 0)
|
||||
XFREE(flatSignedAttribs, 0, NULL);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte* digestInfo;
|
||||
RsaKey* privKey;
|
||||
#else
|
||||
RsaKey stack_privKey;
|
||||
RsaKey* privKey = &stack_privKey;
|
||||
byte digestInfo[MAX_SEQ_SZ + MAX_ALGO_SZ +
|
||||
MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE];
|
||||
XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
byte digestInfoSeq[MAX_SEQ_SZ];
|
||||
byte digestStr[MAX_OCTET_STR_SZ];
|
||||
word32 digestInfoSeqSz, digestStrSz;
|
||||
int digIdx = 0;
|
||||
|
||||
if (pkcs7->signedAttribsSz != 0) {
|
||||
byte attribSet[MAX_SET_SZ];
|
||||
word32 attribSetSz;
|
||||
|
||||
attribSetSz = SetSet(flatSignedAttribsSz, attribSet);
|
||||
|
||||
ret = wc_InitSha(&esd->sha);
|
||||
if (ret < 0) {
|
||||
XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
wc_ShaUpdate(&esd->sha, attribSet, attribSetSz);
|
||||
wc_ShaUpdate(&esd->sha, flatSignedAttribs, flatSignedAttribsSz);
|
||||
wc_ShaFinal(&esd->sha, esd->contentAttribsDigest);
|
||||
} else {
|
||||
/* when no attrs, digest is contentDigest without tag and length */
|
||||
XMEMCPY(esd->contentAttribsDigest, esd->contentDigest + 2,
|
||||
SHA_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
digestStrSz = SetOctetString(SHA_DIGEST_SIZE, digestStr);
|
||||
digestInfoSeqSz = SetSequence(esd->signerDigAlgoIdSz +
|
||||
digestStrSz + SHA_DIGEST_SIZE,
|
||||
digestInfoSeq);
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
digestInfo = (byte*)XMALLOC(MAX_SEQ_SZ + MAX_ALGO_SZ +
|
||||
MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE,
|
||||
NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (digestInfo == NULL) {
|
||||
if (pkcs7->signedAttribsSz != 0)
|
||||
XFREE(flatSignedAttribs, 0, NULL);
|
||||
XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return MEMORY_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);
|
||||
digIdx += digestInfoSeqSz;
|
||||
XMEMCPY(digestInfo + digIdx,
|
||||
esd->signerDigAlgoId, esd->signerDigAlgoIdSz);
|
||||
digIdx += esd->signerDigAlgoIdSz;
|
||||
XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);
|
||||
digIdx += digestStrSz;
|
||||
XMEMCPY(digestInfo + digIdx, esd->contentAttribsDigest,
|
||||
SHA_DIGEST_SIZE);
|
||||
digIdx += SHA_DIGEST_SIZE;
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (privKey == NULL) {
|
||||
if (pkcs7->signedAttribsSz != 0)
|
||||
XFREE(flatSignedAttribs, 0, NULL);
|
||||
XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return MEMORY_E;
|
||||
}
|
||||
#endif
|
||||
|
||||
result = wc_InitRsaKey(privKey, pkcs7->heap);
|
||||
if (result == 0)
|
||||
result = wc_RsaPrivateKeyDecode(pkcs7->privateKey, &scratch, privKey,
|
||||
pkcs7->privateKeySz);
|
||||
if (result < 0) {
|
||||
if (pkcs7->signedAttribsSz != 0)
|
||||
XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return PUBLIC_KEY_E;
|
||||
}
|
||||
|
||||
result = wc_RsaSSL_Sign(digestInfo, digIdx,
|
||||
esd->encContentDigest,
|
||||
sizeof(esd->encContentDigest),
|
||||
privKey, pkcs7->rng);
|
||||
|
||||
wc_FreeRsaKey(privKey);
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(digestInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
if (result < 0) {
|
||||
if (pkcs7->signedAttribsSz != 0)
|
||||
XFREE(flatSignedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(esd, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
esd->encContentDigestSz = (word32)result;
|
||||
return ret;
|
||||
}
|
||||
|
||||
signerInfoSz += flatSignedAttribsSz + esd->signedAttribSetSz;
|
||||
|
||||
esd->signerDigestSz = SetOctetString(esd->encContentDigestSz,
|
||||
@@ -788,6 +1014,226 @@ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
||||
}
|
||||
|
||||
|
||||
/* returns size of signature put into out, negative on error */
|
||||
static int wc_PKCS7_RsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
|
||||
byte* hash, word32 hashSz)
|
||||
{
|
||||
(void)hash;
|
||||
(void)hashSz;
|
||||
|
||||
int ret = 0;
|
||||
word32 scratch = 0;
|
||||
#define MAX_PKCS7_DIGEST_SZ (MAX_SEQ_SZ + MAX_ALGO_SZ +\
|
||||
MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE)
|
||||
|
||||
if (pkcs7 == NULL || pkcs7->publicKey == NULL || sig == NULL ||
|
||||
hash == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte* digest;
|
||||
RsaKey* key;
|
||||
|
||||
digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
if (digest == NULL)
|
||||
return MEMORY_E;
|
||||
|
||||
key = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (key == NULL) {
|
||||
XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return MEMORY_E;
|
||||
}
|
||||
#else
|
||||
byte digest[MAX_PKCS7_DIGEST_SZ];
|
||||
RsaKey stack_key;
|
||||
RsaKey* key = &stack_key;
|
||||
#endif
|
||||
|
||||
XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
|
||||
|
||||
ret = wc_InitRsaKey(key, pkcs7->heap);
|
||||
if (ret != 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
if (wc_RsaPublicKeyDecode(pkcs7->publicKey, &scratch, key,
|
||||
pkcs7->publicKeySz) < 0) {
|
||||
WOLFSSL_MSG("ASN RSA key decode error");
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return PUBLIC_KEY_E;
|
||||
}
|
||||
|
||||
ret = wc_RsaSSL_Verify(sig, sigSz, digest, MAX_PKCS7_DIGEST_SZ, key);
|
||||
|
||||
wc_FreeRsaKey(key);
|
||||
|
||||
if (XMEMCMP(digest, hash, ret) != 0)
|
||||
ret = SIG_VERIFY_E;
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* returns size of signature put into out, negative on error */
|
||||
static int wc_PKCS7_EcdsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
|
||||
byte* hash, word32 hashSz)
|
||||
{
|
||||
int ret = 0;
|
||||
int stat = 0;
|
||||
#define MAX_PKCS7_DIGEST_SZ (MAX_SEQ_SZ + MAX_ALGO_SZ +\
|
||||
MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE)
|
||||
|
||||
if (pkcs7 == NULL || pkcs7->publicKey == NULL || sig == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte* digest;
|
||||
ecc_key* key;
|
||||
|
||||
digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
if (digest == NULL)
|
||||
return MEMORY_E;
|
||||
|
||||
key = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (key == NULL) {
|
||||
XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return MEMORY_E;
|
||||
}
|
||||
#else
|
||||
byte digest[MAX_PKCS7_DIGEST_SZ];
|
||||
ecc_key stack_key;
|
||||
ecc_key* key = &stack_key;
|
||||
#endif
|
||||
|
||||
XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
|
||||
|
||||
ret = wc_ecc_init_ex(key, pkcs7->heap, INVALID_DEVID);
|
||||
if (ret != 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
if (wc_ecc_import_x963(pkcs7->publicKey, pkcs7->publicKeySz, key) < 0) {
|
||||
WOLFSSL_MSG("ASN ECDSA key decode error");
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return PUBLIC_KEY_E;
|
||||
}
|
||||
|
||||
ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, &stat, key);
|
||||
|
||||
wc_ecc_free(key);
|
||||
|
||||
if (ret == 0 && stat != 1) {
|
||||
ret = SIG_VERIFY_E;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int wc_PKCS7_BuildSignedDataDigest(PKCS7* pkcs7, byte* signedAttrib,
|
||||
word32 signedAttribSz, byte* digAlgId,
|
||||
word32 digAlgIdSz, byte* out,
|
||||
word32 outSz)
|
||||
{
|
||||
int ret = 0;
|
||||
word32 attribSetSz;
|
||||
byte attribSet[MAX_SET_SZ];
|
||||
|
||||
byte digest[SHA_DIGEST_SIZE];
|
||||
|
||||
byte digestInfo[MAX_SEQ_SZ + MAX_ALGO_SZ + MAX_OCTET_STR_SZ +
|
||||
SHA_DIGEST_SIZE];
|
||||
byte digestInfoSeq[MAX_SEQ_SZ];
|
||||
byte digestStr[MAX_OCTET_STR_SZ];
|
||||
word32 digestInfoSeqSz, digestStrSz;
|
||||
int digIdx = 0;
|
||||
|
||||
Sha sha;
|
||||
|
||||
if (pkcs7 == NULL || digAlgId == NULL || out == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
XMEMSET(out, 0, outSz);
|
||||
XMEMSET(digest, 0, SHA_DIGEST_SIZE);
|
||||
|
||||
/* calculate digest */
|
||||
ret = wc_InitSha(&sha);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (signedAttribSz > 0) {
|
||||
|
||||
if (signedAttrib == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
attribSetSz = SetSet(signedAttribSz, attribSet);
|
||||
wc_ShaUpdate(&sha, attribSet, attribSetSz);
|
||||
wc_ShaUpdate(&sha, signedAttrib, signedAttribSz);
|
||||
wc_ShaFinal(&sha, digest);
|
||||
|
||||
} else {
|
||||
|
||||
if (pkcs7->content == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
wc_ShaUpdate(&sha, pkcs7->content, pkcs7->contentSz);
|
||||
wc_ShaFinal(&sha, digest);
|
||||
}
|
||||
|
||||
/* form input to verify operation */
|
||||
if (pkcs7->publicKeyOID == RSAk) {
|
||||
|
||||
digestStrSz = SetOctetString(SHA_DIGEST_SIZE, digestStr);
|
||||
digestInfoSeqSz = SetSequence(digAlgIdSz + digestStrSz +
|
||||
SHA_DIGEST_SIZE, digestInfoSeq);
|
||||
|
||||
XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);
|
||||
digIdx += digestInfoSeqSz;
|
||||
XMEMCPY(digestInfo + digIdx, digAlgId, digAlgIdSz);
|
||||
digIdx += digAlgIdSz;
|
||||
XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);
|
||||
digIdx += digestStrSz;
|
||||
XMEMCPY(digestInfo + digIdx, digest, SHA_DIGEST_SIZE);
|
||||
digIdx += SHA_DIGEST_SIZE;
|
||||
|
||||
XMEMCPY(out, digestInfo, digIdx);
|
||||
|
||||
} else if (pkcs7->publicKeyOID == ECDSAk) {
|
||||
|
||||
XMEMCPY(out, digest, SHA_DIGEST_SIZE);
|
||||
digIdx = SHA_DIGEST_SIZE;
|
||||
}
|
||||
|
||||
return digIdx;
|
||||
}
|
||||
|
||||
|
||||
/* Finds the certificates in the message and saves it. */
|
||||
int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
||||
{
|
||||
@@ -796,7 +1242,10 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
||||
byte* content = NULL;
|
||||
byte* sig = NULL;
|
||||
byte* cert = NULL;
|
||||
int contentSz = 0, sigSz = 0, certSz = 0;
|
||||
byte* signedAttrib = NULL;
|
||||
byte* digAlgId = NULL;
|
||||
int contentSz = 0, sigSz = 0, certSz = 0, signedAttribSz = 0;
|
||||
int digAlgIdSz = 0;
|
||||
|
||||
if (pkcs7 == NULL || pkiMsg == NULL || pkiMsgSz == 0)
|
||||
return BAD_FUNC_ARG;
|
||||
@@ -938,10 +1387,16 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
||||
/* Skip it */
|
||||
idx += length;
|
||||
|
||||
/* Get the sequence of digestAlgorithm */
|
||||
/* Get the sequence of digestAlgorithm, saving pointer */
|
||||
digAlgId = &pkiMsg[idx];
|
||||
digAlgIdSz = idx;
|
||||
|
||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* update digAlgIdSz with sequence and length */
|
||||
digAlgIdSz = length + (idx - digAlgIdSz);
|
||||
|
||||
/* Skip it */
|
||||
idx += length;
|
||||
|
||||
@@ -952,6 +1407,10 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
||||
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* save pointer and length */
|
||||
signedAttrib = &pkiMsg[idx];
|
||||
signedAttribSz = length;
|
||||
|
||||
idx += length;
|
||||
}
|
||||
|
||||
@@ -979,66 +1438,36 @@ int wc_PKCS7_VerifySignedData(PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz)
|
||||
pkcs7->content = content;
|
||||
pkcs7->contentSz = contentSz;
|
||||
|
||||
{
|
||||
word32 scratch = 0;
|
||||
int plainSz = 0;
|
||||
#define MAX_PKCS7_DIGEST_SZ (MAX_SEQ_SZ + MAX_ALGO_SZ +\
|
||||
MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE)
|
||||
#define MAX_PKCS7_DIGEST_SZ (MAX_SEQ_SZ + MAX_ALGO_SZ +\
|
||||
MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE)
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte* digest;
|
||||
RsaKey* key;
|
||||
/* build hash to verify against */
|
||||
byte finalDigest[MAX_PKCS7_DIGEST_SZ];
|
||||
|
||||
digest = (byte*)XMALLOC(MAX_PKCS7_DIGEST_SZ, NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
ret = wc_PKCS7_BuildSignedDataDigest(pkcs7, signedAttrib,
|
||||
signedAttribSz, digAlgId,
|
||||
digAlgIdSz, finalDigest,
|
||||
SHA_DIGEST_SIZE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (digest == NULL)
|
||||
return MEMORY_E;
|
||||
switch (pkcs7->publicKeyOID) {
|
||||
|
||||
key = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (key == NULL) {
|
||||
XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return MEMORY_E;
|
||||
}
|
||||
#else
|
||||
byte digest[MAX_PKCS7_DIGEST_SZ];
|
||||
RsaKey stack_key;
|
||||
RsaKey* key = &stack_key;
|
||||
#endif
|
||||
case RSAk:
|
||||
ret = wc_PKCS7_RsaVerify(pkcs7, sig, sigSz, finalDigest, ret);
|
||||
break;
|
||||
|
||||
XMEMSET(digest, 0, MAX_PKCS7_DIGEST_SZ);
|
||||
case ECDSAk:
|
||||
ret = wc_PKCS7_EcdsaVerify(pkcs7, sig, sigSz, finalDigest, ret);
|
||||
break;
|
||||
|
||||
ret = wc_InitRsaKey(key, pkcs7->heap);
|
||||
if (ret != 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
if (wc_RsaPublicKeyDecode(pkcs7->publicKey, &scratch, key,
|
||||
pkcs7->publicKeySz) < 0) {
|
||||
WOLFSSL_MSG("ASN RSA key decode error");
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return PUBLIC_KEY_E;
|
||||
}
|
||||
|
||||
plainSz = wc_RsaSSL_Verify(sig, sigSz, digest, MAX_PKCS7_DIGEST_SZ,
|
||||
key);
|
||||
wc_FreeRsaKey(key);
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(digest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
if (plainSz < 0)
|
||||
return plainSz;
|
||||
default:
|
||||
WOLFSSL_MSG("Unsupported public key type");
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@@ -12148,6 +12148,128 @@ int compress_test(void)
|
||||
* #define PKCS7_OUTPUT_TEST_BUNDLES
|
||||
*/
|
||||
|
||||
|
||||
/* Loads certs and keys for use with PKCS7 tests, from either files
|
||||
* or buffers.
|
||||
*
|
||||
* rsaCert - output buffer for RSA cert
|
||||
* rsaCertSz - IN/OUT size of output buffer, size of RSA cert
|
||||
* rsaPrivKey - output buffer for RSA private key
|
||||
* rsaPrivKeySz - IN/OUT size of output buffer, size of RSA key
|
||||
* eccCert - output buffer for ECC cert
|
||||
* eccCertSz - IN/OUT size of output buffer, size of ECC cert
|
||||
* eccPrivKey - output buffer for ECC private key
|
||||
* eccPrivKeySz - IN/OUT size of output buffer, size of ECC private key
|
||||
*
|
||||
* Returns 0 on success, negative on error
|
||||
*/
|
||||
static int pkcs7_load_certs_keys(byte* rsaCert, word32* rsaCertSz,
|
||||
byte* rsaPrivKey, word32* rsaPrivKeySz,
|
||||
byte* eccCert, word32* eccCertSz,
|
||||
byte* eccPrivKey, word32* eccPrivKeySz)
|
||||
{
|
||||
#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048)
|
||||
FILE* certFile;
|
||||
FILE* keyFile;
|
||||
#endif
|
||||
|
||||
#ifndef NO_RSA
|
||||
if (rsaCert == NULL || rsaCertSz == NULL ||
|
||||
rsaPrivKey == NULL || rsaPrivKeySz == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
if (eccCert == NULL || eccCertSz == NULL ||
|
||||
eccPrivKey == NULL || eccPrivKeySz == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
#endif
|
||||
|
||||
/* RSA */
|
||||
#ifndef NO_RSA
|
||||
|
||||
#ifdef USE_CERT_BUFFERS_1024
|
||||
if (*rsaCertSz < sizeof_client_cert_der_1024)
|
||||
return -201;
|
||||
|
||||
XMEMCPY(rsaCert, client_cert_der_1024, sizeof_client_cert_der_1024);
|
||||
*rsaCertSz = sizeof_client_cert_der_1024;
|
||||
#elif defined(USE_CERT_BUFFERS_2048)
|
||||
if (*rsaCertSz < sizeof_client_cert_der_2048)
|
||||
return -202;
|
||||
|
||||
XMEMCPY(rsaCert, client_cert_der_2048, sizeof_client_cert_der_2048);
|
||||
rsaCertSz = sizeof_client_cert_der_2048;
|
||||
#else
|
||||
certFile = fopen(clientCert, "rb");
|
||||
if (!certFile)
|
||||
return -203;
|
||||
|
||||
*rsaCertSz = fread(rsaCert, 1, *rsaCertSz, certFile);
|
||||
fclose(certFile);
|
||||
#endif
|
||||
|
||||
#ifdef USE_CERT_BUFFERS_1024
|
||||
if (*rsaKeySz < sizeof_client_key_der_1024)
|
||||
return -204;
|
||||
|
||||
XMEMCPY(rsaPrivKey, client_key_der_1024, sizeof_client_key_der_1024);
|
||||
*rsaPrivKeySz = sizeof_client_key_der_1024;
|
||||
#elif defined(USE_CERT_BUFFERS_2048)
|
||||
if (*rsaKeySz < sizeof_client_key_der_2048)
|
||||
return -205;
|
||||
|
||||
XMEMCPY(rsaPrivKey, client_key_der_2048, sizeof_client_key_der_2048);
|
||||
*rsaPrivKeySz = sizeof_client_key_der_2048;
|
||||
#else
|
||||
keyFile = fopen(clientKey, "rb");
|
||||
if (!keyFile)
|
||||
return -204;
|
||||
|
||||
*rsaPrivKeySz = fread(rsaPrivKey, 1, *rsaPrivKeySz, keyFile);
|
||||
fclose(keyFile);
|
||||
#endif /* USE_CERT_BUFFERS */
|
||||
|
||||
#endif /* NO_RSA */
|
||||
|
||||
/* ECC */
|
||||
#ifdef HAVE_ECC
|
||||
|
||||
#ifdef USE_CERT_BUFFERS_256
|
||||
if (*eccCertSz < sizeof_cliecc_cert_der_256)
|
||||
return -206;
|
||||
|
||||
XMEMCPY(eccCert, cliecc_cert_der_256, sizeof_cliecc_cert_der_256);
|
||||
*eccCertSz = sizeof_cliecc_cert_der_256;
|
||||
#else
|
||||
certFile = fopen(eccClientCert, "rb");
|
||||
if (!certFile)
|
||||
return -207;
|
||||
|
||||
*eccCertSz = fread(eccCert, 1, *eccCertSz, certFile);
|
||||
fclose(certFile);
|
||||
#endif /* USE_CERT_BUFFERS_256 */
|
||||
|
||||
#ifdef USE_CERT_BUFFERS_256
|
||||
if (*eccPrivKeySz < sizeof_ecc_clikey_der_256)
|
||||
return -208;
|
||||
|
||||
XMEMCPY(eccPrivKey, ecc_clikey_der_256, sizeof_ecc_clikey_der_256);
|
||||
*eccPrivKeySz = sizeof_ecc_clikey_der_256;
|
||||
#else
|
||||
keyFile = fopen(eccClientKey, "rb");
|
||||
if (!keyFile)
|
||||
return -208;
|
||||
|
||||
*eccPrivKeySz = fread(eccPrivKey, 1, *eccPrivKeySz, keyFile);
|
||||
fclose(keyFile);
|
||||
#endif /* USE_CERT_BUFFERS_256 */
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
const byte* content;
|
||||
word32 contentSz;
|
||||
@@ -12311,15 +12433,10 @@ int pkcs7enveloped_test(void)
|
||||
byte* rsaPrivKey = NULL;
|
||||
byte* eccPrivKey = NULL;
|
||||
|
||||
size_t rsaCertSz = 0;
|
||||
size_t eccCertSz = 0;
|
||||
size_t rsaPrivKeySz = 0;
|
||||
size_t eccPrivKeySz = 0;
|
||||
|
||||
#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048)
|
||||
FILE* certFile;
|
||||
FILE* keyFile;
|
||||
#endif
|
||||
word32 rsaCertSz = 0;
|
||||
word32 eccCertSz = 0;
|
||||
word32 rsaPrivKeySz = 0;
|
||||
word32 eccPrivKeySz = 0;
|
||||
|
||||
#ifndef NO_RSA
|
||||
/* read client RSA cert and key in DER format */
|
||||
@@ -12333,46 +12450,8 @@ int pkcs7enveloped_test(void)
|
||||
return -202;
|
||||
}
|
||||
|
||||
#ifdef USE_CERT_BUFFERS_1024
|
||||
XMEMCPY(rsaCert, client_cert_der_1024, sizeof_client_cert_der_1024);
|
||||
rsaCertSz = sizeof_client_cert_der_1024;
|
||||
#elif defined(USE_CERT_BUFFERS_2048)
|
||||
XMEMCPY(rsaCert, client_cert_der_2048, sizeof_client_cert_der_2048);
|
||||
rsaCertSz = sizeof_client_cert_der_2048;
|
||||
#else
|
||||
certFile = fopen(clientCert, "rb");
|
||||
if (!certFile) {
|
||||
XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
err_sys("can't open ./certs/client-cert.der, "
|
||||
"Please run from wolfSSL home dir", -42);
|
||||
return -203;
|
||||
}
|
||||
|
||||
rsaCertSz = fread(rsaCert, 1, FOURK_BUF, certFile);
|
||||
fclose(certFile);
|
||||
#endif
|
||||
|
||||
#ifdef USE_CERT_BUFFERS_1024
|
||||
XMEMCPY(rsaPrivKey, client_key_der_1024, sizeof_client_key_der_1024);
|
||||
rsaPrivKeySz = sizeof_client_key_der_1024;
|
||||
#elif defined(USE_CERT_BUFFERS_2048)
|
||||
XMEMCPY(rsaPrivKey, client_key_der_2048, sizeof_client_key_der_2048);
|
||||
rsaPrivKeySz = sizeof_client_key_der_2048;
|
||||
#else
|
||||
keyFile = fopen(clientKey, "rb");
|
||||
if (!keyFile) {
|
||||
XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
err_sys("can't open ./certs/client-key.der, "
|
||||
"Please run from wolfSSL home dir", -43);
|
||||
return -204;
|
||||
}
|
||||
|
||||
rsaPrivKeySz = fread(rsaPrivKey, 1, FOURK_BUF, keyFile);
|
||||
fclose(keyFile);
|
||||
#endif /* USE_CERT_BUFFERS */
|
||||
|
||||
rsaCertSz = FOURK_BUF;
|
||||
rsaPrivKeySz = FOURK_BUF;
|
||||
#endif /* NO_RSA */
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
@@ -12381,7 +12460,7 @@ int pkcs7enveloped_test(void)
|
||||
if (eccCert == NULL) {
|
||||
XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return -205;
|
||||
return -203;
|
||||
}
|
||||
|
||||
eccPrivKey =(byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
@@ -12389,51 +12468,17 @@ int pkcs7enveloped_test(void)
|
||||
XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return -206;
|
||||
return -204;
|
||||
}
|
||||
|
||||
#ifdef USE_CERT_BUFFERS_256
|
||||
XMEMCPY(eccCert, cliecc_cert_der_256, sizeof_cliecc_cert_der_256);
|
||||
eccCertSz = sizeof_cliecc_cert_der_256;
|
||||
#else
|
||||
certFile = fopen(eccClientCert, "rb");
|
||||
if (!certFile) {
|
||||
XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(eccPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
err_sys("can't open ./certs/client-ecc-cert.der, "
|
||||
"Please run from wolfSSL home dir", -42);
|
||||
return -207;
|
||||
}
|
||||
eccCertSz = fread(eccCert, 1, FOURK_BUF, certFile);
|
||||
fclose(certFile);
|
||||
#endif /* USE_CERT_BUFFERS_256 */
|
||||
|
||||
#ifdef USE_CERT_BUFFERS_256
|
||||
XMEMCPY(eccPrivKey, ecc_clikey_der_256, sizeof_ecc_clikey_der_256);
|
||||
eccPrivKeySz = sizeof_ecc_clikey_der_256;
|
||||
#else
|
||||
keyFile = fopen(eccClientKey, "rb");
|
||||
if (!keyFile) {
|
||||
XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(eccPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
err_sys("can't open ./certs/ecc-client-key.der, "
|
||||
"Please run from wolfSSL home dir", -43);
|
||||
return -208;
|
||||
}
|
||||
eccPrivKeySz = fread(eccPrivKey, 1, FOURK_BUF, keyFile);
|
||||
fclose(keyFile);
|
||||
#endif /* USE_CERT_BUFFERS_256 */
|
||||
eccCertSz = FOURK_BUF;
|
||||
eccPrivKeySz = FOURK_BUF;
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
ret = pkcs7enveloped_run_vectors(rsaCert, (word32)rsaCertSz,
|
||||
rsaPrivKey, (word32)rsaPrivKeySz,
|
||||
eccCert, (word32)eccCertSz,
|
||||
eccPrivKey, (word32)eccPrivKeySz);
|
||||
if (ret != 0) {
|
||||
ret = pkcs7_load_certs_keys(rsaCert, &rsaCertSz, rsaPrivKey,
|
||||
&rsaPrivKeySz, eccCert, &eccCertSz,
|
||||
eccPrivKey, &eccPrivKeySz);
|
||||
if (ret < 0) {
|
||||
XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
@@ -12441,12 +12486,17 @@ int pkcs7enveloped_test(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = pkcs7enveloped_run_vectors(rsaCert, (word32)rsaCertSz,
|
||||
rsaPrivKey, (word32)rsaPrivKeySz,
|
||||
eccCert, (word32)eccCertSz,
|
||||
eccPrivKey, (word32)eccPrivKeySz);
|
||||
|
||||
XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(eccPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -12650,19 +12700,40 @@ int pkcs7encrypted_test(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int pkcs7signed_test(void)
|
||||
|
||||
typedef struct {
|
||||
const byte* content;
|
||||
word32 contentSz;
|
||||
int hashOID;
|
||||
int encryptOID;
|
||||
byte* privateKey;
|
||||
word32 privateKeySz;
|
||||
byte* cert;
|
||||
size_t certSz;
|
||||
PKCS7Attrib* signedAttribs;
|
||||
word32 signedAttribsSz;
|
||||
const char* outFileName;
|
||||
} pkcs7SignedVector;
|
||||
|
||||
|
||||
static int pkcs7signed_run_vectors(byte* rsaCert, word32 rsaCertSz,
|
||||
byte* rsaPrivKey, word32 rsaPrivKeySz,
|
||||
byte* eccCert, word32 eccCertSz,
|
||||
byte* eccPrivKey, word32 eccPrivKeySz)
|
||||
{
|
||||
int ret = 0;
|
||||
#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048)
|
||||
FILE* file;
|
||||
#endif
|
||||
byte* certDer;
|
||||
byte* keyDer;
|
||||
byte* out;
|
||||
char data[] = "Hello World";
|
||||
word32 dataSz, outSz, certDerSz, keyDerSz;
|
||||
PKCS7 msg;
|
||||
int ret, testSz, i;
|
||||
byte* out;
|
||||
word32 outSz;
|
||||
WC_RNG rng;
|
||||
PKCS7 pkcs7;
|
||||
#ifdef PKCS7_OUTPUT_TEST_BUNDLES
|
||||
FILE* file;
|
||||
#endif
|
||||
|
||||
const byte data[] = { /* Hello World */
|
||||
0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,
|
||||
0x72,0x6c,0x64
|
||||
};
|
||||
|
||||
static byte transIdOid[] =
|
||||
{ 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01,
|
||||
@@ -12687,64 +12758,30 @@ int pkcs7signed_test(void)
|
||||
senderNonce, sizeof(senderNonce) }
|
||||
};
|
||||
|
||||
dataSz = (word32) XSTRLEN(data);
|
||||
const pkcs7SignedVector testVectors[] =
|
||||
{
|
||||
/* RSA with SHA */
|
||||
{data, (word32)sizeof(data), SHAh, RSAk, rsaPrivKey, rsaPrivKeySz,
|
||||
rsaCert, rsaCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)),
|
||||
"pkcs7signedData_RSA_SHA.der"},
|
||||
|
||||
/* ECDSA with SHA */
|
||||
{data, (word32)sizeof(data), SHAh, ECDSAk, eccPrivKey, eccPrivKeySz,
|
||||
eccCert, eccCertSz, attribs, (sizeof(attribs)/sizeof(PKCS7Attrib)),
|
||||
"pkcs7signedData_ECDSA_SHA.der"},
|
||||
|
||||
/* ECDSA with SHA, no signed attributes */
|
||||
{data, (word32)sizeof(data), SHAh, ECDSAk, eccPrivKey, eccPrivKeySz,
|
||||
eccCert, eccCertSz, NULL, 0,
|
||||
"pkcs7signedData_ECDSA_SHA_noattr.der"},
|
||||
};
|
||||
|
||||
testSz = sizeof(testVectors) / sizeof(pkcs7SignedVector);
|
||||
|
||||
outSz = FOURK_BUF;
|
||||
|
||||
certDer =(byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (certDer == NULL)
|
||||
return -207;
|
||||
keyDer = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (keyDer == NULL) {
|
||||
XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return -208;
|
||||
}
|
||||
out = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (out == NULL) {
|
||||
XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
out = (byte*)XMALLOC(outSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (out == NULL)
|
||||
return -209;
|
||||
}
|
||||
|
||||
/* read in DER cert of recipient, into cert of size certSz */
|
||||
#ifdef USE_CERT_BUFFERS_1024
|
||||
XMEMCPY(certDer, client_cert_der_1024, sizeof_client_cert_der_1024);
|
||||
certDerSz = sizeof_client_cert_der_1024;
|
||||
#elif defined(USE_CERT_BUFFERS_2048)
|
||||
XMEMCPY(certDer, client_cert_der_2048, sizeof_client_cert_der_2048);
|
||||
certDerSz = sizeof_client_cert_der_2048;
|
||||
#else
|
||||
file = fopen(clientCert, "rb");
|
||||
if (!file) {
|
||||
XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
err_sys("can't open ./certs/client-cert.der, "
|
||||
"Please run from wolfSSL home dir", -44);
|
||||
return -44;
|
||||
}
|
||||
certDerSz = (word32)fread(certDer, 1, FOURK_BUF, file);
|
||||
fclose(file);
|
||||
#endif /* USE_CERT_BUFFER_ */
|
||||
|
||||
#ifdef USE_CERT_BUFFERS_1024
|
||||
XMEMCPY(keyDer, client_key_der_1024, sizeof_client_key_der_1024);
|
||||
keyDerSz = sizeof_client_key_der_1024;
|
||||
#elif defined(USE_CERT_BUFFERS_2048)
|
||||
XMEMCPY(keyDer, client_key_der_2048, sizeof_client_key_der_2048);
|
||||
keyDerSz = sizeof_client_key_der_2048;
|
||||
#else
|
||||
file = fopen(clientKey, "rb");
|
||||
if (!file) {
|
||||
XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
err_sys("can't open ./certs/client-key.der, "
|
||||
"Please run from wolfSSL home dir", -45);
|
||||
return -45;
|
||||
}
|
||||
keyDerSz = (word32)fread(keyDer, 1, FOURK_BUF, file);
|
||||
fclose(file);
|
||||
#endif /* USE_CERT_BUFFER_ */
|
||||
|
||||
#ifndef HAVE_FIPS
|
||||
ret = wc_InitRng_ex(&rng, HEAP_HINT, devId);
|
||||
@@ -12752,126 +12789,122 @@ int pkcs7signed_test(void)
|
||||
ret = wc_InitRng(&rng);
|
||||
#endif
|
||||
if (ret != 0) {
|
||||
XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return -210;
|
||||
}
|
||||
|
||||
senderNonce[0] = 0x04;
|
||||
senderNonce[1] = PKCS7_NONCE_SZ;
|
||||
for (i = 0; i < testSz; i++) {
|
||||
|
||||
ret = wc_RNG_GenerateBlock(&rng, &senderNonce[2], PKCS7_NONCE_SZ);
|
||||
if (ret != 0) {
|
||||
XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return -211;
|
||||
}
|
||||
ret = wc_PKCS7_InitWithCert(&pkcs7, testVectors[i].cert,
|
||||
(word32)testVectors[i].certSz);
|
||||
|
||||
wc_PKCS7_InitWithCert(&msg, certDer, certDerSz);
|
||||
msg.privateKey = keyDer;
|
||||
msg.privateKeySz = keyDerSz;
|
||||
msg.content = (byte*)data;
|
||||
msg.contentSz = dataSz;
|
||||
msg.hashOID = SHAh;
|
||||
msg.encryptOID = RSAk;
|
||||
msg.signedAttribs = attribs;
|
||||
msg.signedAttribsSz = sizeof(attribs)/sizeof(PKCS7Attrib);
|
||||
msg.rng = &rng;
|
||||
{
|
||||
Sha sha;
|
||||
byte digest[SHA_DIGEST_SIZE];
|
||||
int i,j;
|
||||
if (ret != 0)
|
||||
return -211;
|
||||
|
||||
transId[0] = 0x13;
|
||||
transId[1] = SHA_DIGEST_SIZE * 2;
|
||||
pkcs7.rng = &rng;
|
||||
pkcs7.content = (byte*)testVectors[i].content;
|
||||
pkcs7.contentSz = testVectors[i].contentSz;
|
||||
pkcs7.hashOID = testVectors[i].hashOID;
|
||||
pkcs7.encryptOID = testVectors[i].encryptOID;
|
||||
pkcs7.privateKey = testVectors[i].privateKey;
|
||||
pkcs7.privateKeySz = testVectors[i].privateKeySz;
|
||||
pkcs7.signedAttribs = testVectors[i].signedAttribs;
|
||||
pkcs7.signedAttribsSz = testVectors[i].signedAttribsSz;
|
||||
|
||||
ret = wc_InitSha_ex(&sha, HEAP_HINT, devId);
|
||||
if (ret != 0) {
|
||||
XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
/* generate senderNonce */
|
||||
{
|
||||
senderNonce[0] = 0x04;
|
||||
senderNonce[1] = PKCS7_NONCE_SZ;
|
||||
|
||||
ret = wc_RNG_GenerateBlock(&rng, &senderNonce[2], PKCS7_NONCE_SZ);
|
||||
if (ret != 0) {
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
return -212;
|
||||
}
|
||||
}
|
||||
|
||||
/* generate trans ID */
|
||||
{
|
||||
Sha sha;
|
||||
byte digest[SHA_DIGEST_SIZE];
|
||||
int j,k;
|
||||
|
||||
transId[0] = 0x13;
|
||||
transId[1] = SHA_DIGEST_SIZE * 2;
|
||||
|
||||
ret = wc_InitSha_ex(&sha, HEAP_HINT, devId);
|
||||
if (ret != 0) {
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
return -213;
|
||||
}
|
||||
wc_ShaUpdate(&sha, pkcs7.publicKey, pkcs7.publicKeySz);
|
||||
wc_ShaFinal(&sha, digest);
|
||||
wc_ShaFree(&sha);
|
||||
|
||||
for (j = 0, k = 2; j < SHA_DIGEST_SIZE; j++, k += 2) {
|
||||
snprintf((char*)&transId[k], 3, "%02x", digest[j]);
|
||||
}
|
||||
}
|
||||
|
||||
ret = wc_PKCS7_EncodeSignedData(&pkcs7, out, outSz);
|
||||
if (ret < 0) {
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return -4003;
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
return -214;
|
||||
}
|
||||
wc_ShaUpdate(&sha, msg.publicKey, msg.publicKeySz);
|
||||
wc_ShaFinal(&sha, digest);
|
||||
wc_ShaFree(&sha);
|
||||
else
|
||||
outSz = ret;
|
||||
|
||||
for (i = 0, j = 2; i < SHA_DIGEST_SIZE; i++, j += 2) {
|
||||
snprintf((char*)&transId[j], 3, "%02x", digest[i]);
|
||||
#ifdef PKCS7_OUTPUT_TEST_BUNDLES
|
||||
/* write PKCS#7 to output file for more testing */
|
||||
file = fopen(testVectors[i].outFileName, "wb");
|
||||
if (!file) {
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
return -215;
|
||||
}
|
||||
}
|
||||
ret = wc_PKCS7_EncodeSignedData(&msg, out, outSz);
|
||||
if (ret < 0) {
|
||||
XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wc_PKCS7_Free(&msg);
|
||||
return -212;
|
||||
}
|
||||
else
|
||||
outSz = ret;
|
||||
ret = (int)fwrite(out, 1, outSz, file);
|
||||
fclose(file);
|
||||
if (ret != (int)outSz) {
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
return -216;
|
||||
}
|
||||
#endif /* PKCS7_OUTPUT_TEST_BUNDLES */
|
||||
|
||||
#ifdef PKCS7_OUTPUT_TEST_BUNDLES
|
||||
/* write PKCS#7 to output file for more testing */
|
||||
file = fopen("./pkcs7signedData.der", "wb");
|
||||
if (!file) {
|
||||
XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wc_PKCS7_Free(&msg);
|
||||
return -213;
|
||||
}
|
||||
ret = (int)fwrite(out, 1, outSz, file);
|
||||
fclose(file);
|
||||
if (ret != (int)outSz) {
|
||||
XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wc_PKCS7_Free(&msg);
|
||||
return -218;
|
||||
}
|
||||
#endif /* PKCS7_OUTPUT_TEST_BUNDLES */
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
wc_PKCS7_InitWithCert(&pkcs7, NULL, 0);
|
||||
|
||||
wc_PKCS7_Free(&msg);
|
||||
wc_PKCS7_InitWithCert(&msg, NULL, 0);
|
||||
ret = wc_PKCS7_VerifySignedData(&pkcs7, out, outSz);
|
||||
if (ret < 0) {
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
return -217;
|
||||
}
|
||||
|
||||
ret = wc_PKCS7_VerifySignedData(&msg, out, outSz);
|
||||
if (ret < 0) {
|
||||
XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wc_PKCS7_Free(&msg);
|
||||
return -214;
|
||||
if (pkcs7.singleCert == NULL || pkcs7.singleCertSz == 0) {
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
return -218;
|
||||
}
|
||||
|
||||
#ifdef PKCS7_OUTPUT_TEST_BUNDLES
|
||||
file = fopen("./pkcs7cert.der", "wb");
|
||||
if (!file) {
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
return -219;
|
||||
}
|
||||
ret = (int)fwrite(pkcs7.singleCert, 1, pkcs7.singleCertSz, file);
|
||||
fclose(file);
|
||||
#endif /* PKCS7_OUTPUT_TEST_BUNDLES */
|
||||
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
}
|
||||
|
||||
if (msg.singleCert == NULL || msg.singleCertSz == 0) {
|
||||
XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wc_PKCS7_Free(&msg);
|
||||
return -215;
|
||||
}
|
||||
|
||||
#ifdef PKCS7_OUTPUT_TEST_BUNDLES
|
||||
file = fopen("./pkcs7cert.der", "wb");
|
||||
if (!file) {
|
||||
XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wc_PKCS7_Free(&msg);
|
||||
return -216;
|
||||
}
|
||||
ret = (int)fwrite(msg.singleCert, 1, msg.singleCertSz, file);
|
||||
fclose(file);
|
||||
#endif /* PKCS7_OUTPUT_TEST_BUNDLES */
|
||||
|
||||
XFREE(certDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(keyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wc_PKCS7_Free(&msg);
|
||||
|
||||
wc_FreeRng(&rng);
|
||||
|
||||
if (ret > 0)
|
||||
@@ -12880,6 +12913,82 @@ int pkcs7signed_test(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int pkcs7signed_test(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
byte* rsaCert = NULL;
|
||||
byte* eccCert = NULL;
|
||||
byte* rsaPrivKey = NULL;
|
||||
byte* eccPrivKey = NULL;
|
||||
|
||||
word32 rsaCertSz = 0;
|
||||
word32 eccCertSz = 0;
|
||||
word32 rsaPrivKeySz = 0;
|
||||
word32 eccPrivKeySz = 0;
|
||||
|
||||
#ifndef NO_RSA
|
||||
/* read client RSA cert and key in DER format */
|
||||
rsaCert = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (rsaCert == NULL)
|
||||
return -201;
|
||||
|
||||
rsaPrivKey = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (rsaPrivKey == NULL) {
|
||||
XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return -202;
|
||||
}
|
||||
|
||||
rsaCertSz = FOURK_BUF;
|
||||
rsaPrivKeySz = FOURK_BUF;
|
||||
#endif /* NO_RSA */
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
/* read client ECC cert and key in DER format */
|
||||
eccCert = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (eccCert == NULL) {
|
||||
XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return -203;
|
||||
}
|
||||
|
||||
eccPrivKey =(byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (eccPrivKey == NULL) {
|
||||
XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return -204;
|
||||
}
|
||||
|
||||
eccCertSz = FOURK_BUF;
|
||||
eccPrivKeySz = FOURK_BUF;
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
ret = pkcs7_load_certs_keys(rsaCert, &rsaCertSz, rsaPrivKey,
|
||||
&rsaPrivKeySz, eccCert, &eccCertSz,
|
||||
eccPrivKey, &eccPrivKeySz);
|
||||
if (ret < 0) {
|
||||
XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(eccPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = pkcs7signed_run_vectors(rsaCert, (word32)rsaCertSz,
|
||||
rsaPrivKey, (word32)rsaPrivKeySz,
|
||||
eccCert, (word32)eccCertSz,
|
||||
eccPrivKey, (word32)eccPrivKeySz);
|
||||
|
||||
XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(eccPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* HAVE_PKCS7 */
|
||||
|
||||
#ifdef HAVE_VALGRIND
|
||||
|
Reference in New Issue
Block a user