diff --git a/tests/api.c b/tests/api.c index 958e5581f..6a4748ffe 100644 --- a/tests/api.c +++ b/tests/api.c @@ -21933,8 +21933,18 @@ static void test_wolfssl_PKCS7(void) AssertNotNull(pkcs7 = d2i_PKCS7(NULL, &p, len)); AssertIntEQ(wolfSSL_PKCS7_verify(NULL, NULL, NULL, NULL, NULL, PKCS7_NOVERIFY), WOLFSSL_FAILURE); + PKCS7_free(pkcs7); + + /* fail case, without PKCS7_NOVERIFY */ + p = data; + AssertNotNull(pkcs7 = d2i_PKCS7(NULL, &p, len)); AssertIntEQ(wolfSSL_PKCS7_verify(pkcs7, NULL, NULL, NULL, NULL, 0), WOLFSSL_FAILURE); + PKCS7_free(pkcs7); + + /* success case, with PKCS7_NOVERIFY */ + p = data; + AssertNotNull(pkcs7 = d2i_PKCS7(NULL, &p, len)); AssertIntEQ(wolfSSL_PKCS7_verify(pkcs7, NULL, NULL, NULL, NULL, PKCS7_NOVERIFY), WOLFSSL_SUCCESS); diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index ee14b38c2..5a741896c 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -1458,6 +1458,7 @@ static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd, int timeSz; PKCS7Attrib cannedAttribs[3]; #endif + word32 idx = 0; word32 cannedAttribsCount; if (pkcs7 == NULL || esd == NULL || contentType == NULL || @@ -1466,49 +1467,59 @@ static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd, return BAD_FUNC_ARG; } - hashSz = wc_HashGetDigestSize(esd->hashType); - if (hashSz < 0) - return hashSz; + if (pkcs7->skipDefaultSignedAttribs == 0) { + hashSz = wc_HashGetDigestSize(esd->hashType); + if (hashSz < 0) + return hashSz; -#ifndef NO_ASN_TIME - if (signingTime == NULL || signingTimeSz == 0) - return BAD_FUNC_ARG; + #ifndef NO_ASN_TIME + if (signingTime == NULL || signingTimeSz == 0) + return BAD_FUNC_ARG; - tm = XTIME(0); - timeSz = GetAsnTimeString(&tm, signingTime, signingTimeSz); - if (timeSz < 0) - return timeSz; -#endif + tm = XTIME(0); + timeSz = GetAsnTimeString(&tm, signingTime, signingTimeSz); + if (timeSz < 0) + return timeSz; + #endif - cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib); + cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib); - cannedAttribs[0].oid = contentTypeOid; - cannedAttribs[0].oidSz = contentTypeOidSz; - cannedAttribs[0].value = contentType; - cannedAttribs[0].valueSz = contentTypeSz; - cannedAttribs[1].oid = messageDigestOid; - cannedAttribs[1].oidSz = messageDigestOidSz; - cannedAttribs[1].value = esd->contentDigest; - cannedAttribs[1].valueSz = hashSz + 2; /* ASN.1 heading */ -#ifndef NO_ASN_TIME - cannedAttribs[2].oid = signingTimeOid; - cannedAttribs[2].oidSz = signingTimeOidSz; - cannedAttribs[2].value = signingTime; - cannedAttribs[2].valueSz = timeSz; -#endif + cannedAttribs[idx].oid = contentTypeOid; + cannedAttribs[idx].oidSz = contentTypeOidSz; + cannedAttribs[idx].value = contentType; + cannedAttribs[idx].valueSz = contentTypeSz; + idx++; + #ifndef NO_ASN_TIME + cannedAttribs[idx].oid = signingTimeOid; + cannedAttribs[idx].oidSz = signingTimeOidSz; + cannedAttribs[idx].value = signingTime; + cannedAttribs[idx].valueSz = timeSz; + idx++; + #endif + cannedAttribs[idx].oid = messageDigestOid; + cannedAttribs[idx].oidSz = messageDigestOidSz; + cannedAttribs[idx].value = esd->contentDigest; + cannedAttribs[idx].valueSz = hashSz + 2; /* ASN.1 heading */ - esd->signedAttribsCount += cannedAttribsCount; - esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[0], 3, - cannedAttribs, cannedAttribsCount); + esd->signedAttribsCount += cannedAttribsCount; + esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[0], 3, + cannedAttribs, cannedAttribsCount); + } else { + esd->signedAttribsCount = 0; + esd->signedAttribsSz = 0; + } - esd->signedAttribsCount += pkcs7->signedAttribsSz; -#ifdef NO_ASN_TIME - esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[2], 4, - pkcs7->signedAttribs, pkcs7->signedAttribsSz); -#else - esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[3], 4, - pkcs7->signedAttribs, pkcs7->signedAttribsSz); -#endif + /* add custom signed attributes if set */ + if (pkcs7->signedAttribsSz > 0 && pkcs7->signedAttribs != NULL) { + esd->signedAttribsCount += pkcs7->signedAttribsSz; + #ifdef NO_ASN_TIME + esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[2], 4, + pkcs7->signedAttribs, pkcs7->signedAttribsSz); + #else + esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[3], 4, + pkcs7->signedAttribs, pkcs7->signedAttribsSz); + #endif + } #ifdef NO_ASN_TIME (void)signingTimeOidSz; @@ -1648,7 +1659,7 @@ static int wc_PKCS7_BuildDigestInfo(PKCS7* pkcs7, byte* flatSignedAttribs, if (hashSz < 0) return hashSz; - if (pkcs7->signedAttribsSz != 0) { + if (flatSignedAttribsSz != 0) { if (flatSignedAttribs == NULL) return BAD_FUNC_ARG; @@ -1951,22 +1962,22 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, digEncAlgoType, 0); signerInfoSz += esd->digEncAlgoIdSz; - if (pkcs7->signedAttribsSz != 0) { - - /* build up signed attributes */ - ret = wc_PKCS7_BuildSignedAttributes(pkcs7, esd, pkcs7->contentType, - pkcs7->contentTypeSz, - contentTypeOid, sizeof(contentTypeOid), - messageDigestOid, sizeof(messageDigestOid), - signingTimeOid, sizeof(signingTimeOid), - signingTime, sizeof(signingTime)); - if (ret < 0) { - #ifdef WOLFSSL_SMALL_STACK - XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return ret; - } + /* build up signed attributes, include contentType, signingTime, and + messageDigest by default */ + ret = wc_PKCS7_BuildSignedAttributes(pkcs7, esd, pkcs7->contentType, + pkcs7->contentTypeSz, + contentTypeOid, sizeof(contentTypeOid), + messageDigestOid, sizeof(messageDigestOid), + signingTimeOid, sizeof(signingTimeOid), + signingTime, sizeof(signingTime)); + if (ret < 0) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(esd, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return ret; + } + if (esd->signedAttribsSz > 0) { flatSignedAttribs = (byte*)XMALLOC(esd->signedAttribsSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7); flatSignedAttribsSz = esd->signedAttribsSz; @@ -1981,6 +1992,8 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, esd->signedAttribs, esd->signedAttribsCount); esd->signedAttribSetSz = SetImplicit(ASN_SET, 0, esd->signedAttribsSz, esd->signedAttribSet); + } else { + esd->signedAttribSetSz = 0; } /* Calculate the final hash and encrypt it. */ @@ -2241,6 +2254,27 @@ int wc_PKCS7_SetDetached(PKCS7* pkcs7, word16 flag) return 0; } +/* By default, SignedData bundles have the following signed attributes attached: + * contentType (1.2.840.113549.1.9.3) + * signgingTime (1.2.840.113549.1.9.5) + * messageDigest (1.2.840.113549.1.9.4) + * + * Calling this API before wc_PKCS7_EncodeSignedData() will disable the + * inclusion of those attributes. + * + * pkcs7 - pointer to initialized PKCS7 structure + * + * Returns 0 on success, negative upon error. */ +int wc_PKCS7_NoDefaultSignedAttribs(PKCS7* pkcs7) +{ + if (pkcs7 == NULL) + return BAD_FUNC_ARG; + + pkcs7->skipDefaultSignedAttribs = 1; + + return 0; +} + /* return codes: >0: Size of signed PKCS7 output buffer, negative: error */ int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) { diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 15461dc32..77089ed24 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -284,6 +284,8 @@ struct PKCS7 { #endif word32 state; + word16 skipDefaultSignedAttribs:1; /* skip adding default signed attribs */ + /* !! NEW DATA MEMBERS MUST BE ADDED AT END !! */ }; @@ -310,6 +312,7 @@ WOLFSSL_API int wc_PKCS7_EncodeData(PKCS7* pkcs7, byte* output, /* CMS/PKCS#7 SignedData */ WOLFSSL_API int wc_PKCS7_SetDetached(PKCS7* pkcs7, word16 flag); +WOLFSSL_API int wc_PKCS7_NoDefaultSignedAttribs(PKCS7* pkcs7); WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz); WOLFSSL_API int wc_PKCS7_EncodeSignedData_ex(PKCS7* pkcs7, const byte* hashBuf,