diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 437327712..b5ec1d82f 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -1929,7 +1929,7 @@ static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd, return BAD_FUNC_ARG; } - if (pkcs7->skipDefaultSignedAttribs == 0) { + if (pkcs7->defaultSignedAttribs != WOLFSSL_NO_ATTRIBUTES) { hashSz = wc_HashGetDigestSize(esd->hashType); if (hashSz < 0) return hashSz; @@ -1946,23 +1946,34 @@ static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd, cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib); - cannedAttribs[idx].oid = contentTypeOid; - cannedAttribs[idx].oidSz = contentTypeOidSz; - cannedAttribs[idx].value = contentType; - cannedAttribs[idx].valueSz = contentTypeSz; - idx++; + if ((pkcs7->defaultSignedAttribs & WOLFSSL_CONTENT_TYPE_ATTRIBUTE) || + pkcs7->defaultSignedAttribs == 0) { + 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++; + if ((pkcs7->defaultSignedAttribs & WOLFSSL_SIGNING_TIME_ATTRIBUTE) || + pkcs7->defaultSignedAttribs == 0) { + 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 */ - idx++; + + if ((pkcs7->defaultSignedAttribs & WOLFSSL_MESSAGE_DIGEST_ATTRIBUTE) || + pkcs7->defaultSignedAttribs == 0) { + cannedAttribs[idx].oid = messageDigestOid; + cannedAttribs[idx].oidSz = messageDigestOidSz; + cannedAttribs[idx].value = esd->contentDigest; + cannedAttribs[idx].valueSz = hashSz + 2; /* ASN.1 heading */ + idx++; + } esd->signedAttribsCount += cannedAttribsCount; esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[atrIdx], @@ -1976,15 +1987,9 @@ static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd, /* 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[atrIdx], esd->signedAttribsCount, pkcs7->signedAttribs, pkcs7->signedAttribsSz); - #else - esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[atrIdx], - esd->signedAttribsCount, - pkcs7->signedAttribs, pkcs7->signedAttribsSz); - #endif } #ifdef NO_ASN_TIME @@ -2839,14 +2844,49 @@ int wc_PKCS7_SetDetached(PKCS7* pkcs7, word16 flag) * Returns 0 on success, negative upon error. */ int wc_PKCS7_NoDefaultSignedAttribs(PKCS7* pkcs7) { - if (pkcs7 == NULL) + return wc_PKCS7_SetDefaultSignedAttribs(pkcs7, WOLFSSL_NO_ATTRIBUTES); +} + + +/* By default, SignedData bundles have the following signed attributes attached: + * contentType (1.2.840.113549.1.9.3) + * signingTime (1.2.840.113549.1.9.5) + * messageDigest (1.2.840.113549.1.9.4) + * + * Calling this API before wc_PKCS7_EncodeSignedData() allows control over which + * default attributes are added. + * + * pkcs7 - pointer to initialized PKCS7 structure + * + * Returns 0 on success, negative upon error. */ +int wc_PKCS7_SetDefaultSignedAttribs(PKCS7* pkcs7, word16 flag) +{ + if (pkcs7 == NULL) { return BAD_FUNC_ARG; + } - pkcs7->skipDefaultSignedAttribs = 1; + if (flag & WOLFSSL_NO_ATTRIBUTES) { + if (flag ^ WOLFSSL_NO_ATTRIBUTES) { + WOLFSSL_MSG("Error, can not have additional flags with no " + "attributes flag set"); + return BAD_FUNC_ARG; + } + pkcs7->defaultSignedAttribs = 0; + } + /* check for unknown flags */ + if (flag & ~(WOLFSSL_CONTENT_TYPE_ATTRIBUTE | + WOLFSSL_SIGNING_TIME_ATTRIBUTE | + WOLFSSL_MESSAGE_DIGEST_ATTRIBUTE | WOLFSSL_NO_ATTRIBUTES)) { + WOLFSSL_MSG("Unknown attribute flags found"); + return BAD_FUNC_ARG; + } + + pkcs7->defaultSignedAttribs |= flag; 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 b87066675..8f28fdbae 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -75,6 +75,12 @@ #define MAX_UNAUTH_ATTRIBS_SZ 7 #endif +/* bitmap flag for attributes */ +#define WOLFSSL_NO_ATTRIBUTES 0x1 +#define WOLFSSL_CONTENT_TYPE_ATTRIBUTE 0x2 +#define WOLFSSL_SIGNING_TIME_ATTRIBUTE 0x4 +#define WOLFSSL_MESSAGE_DIGEST_ATTRIBUTE 0x8 + /* PKCS#7 content types, ref RFC 2315 (Section 14) */ enum PKCS7_TYPES { PKCS7_MSG = 650, /* 1.2.840.113549.1.7 */ @@ -312,7 +318,7 @@ struct PKCS7 { #endif word32 state; - word16 skipDefaultSignedAttribs:1; /* skip adding default signed attribs */ + word16 defaultSignedAttribs; /* set which default signed attribs */ byte version; /* 1 for RFC 2315 and 3 for RFC 4108 */ PKCS7SignerInfo* signerInfo; @@ -361,6 +367,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_SetDefaultSignedAttribs(PKCS7* pkcs7, word16 flag); WOLFSSL_API int wc_PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz); WOLFSSL_API int wc_PKCS7_EncodeSignedData_ex(PKCS7* pkcs7, const byte* hashBuf,