add PKCS7 SignedData with ECDSA

This commit is contained in:
Chris Conlon
2017-04-14 08:57:39 -06:00
parent f2ac410f1e
commit 74aafb1679
2 changed files with 999 additions and 461 deletions

View File

@@ -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;

View File

@@ -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