/* * SecCmsContentInfoGetInnerContent - get pointer to innermost content * * this is typically only called by SecCmsMessageGetContent() */ CSSM_DATA_PTR SecCmsContentInfoGetInnerContent(SecCmsContentInfoRef cinfo) { SECOidTag tag; for(;;) { tag = SecCmsContentInfoGetContentTypeTag(cinfo); switch (tag) { case SEC_OID_PKCS7_DATA: case SEC_OID_OTHER: /* end of recursion - every message has to have a data cinfo */ return cinfo->content.data; case SEC_OID_PKCS7_DIGESTED_DATA: case SEC_OID_PKCS7_ENCRYPTED_DATA: case SEC_OID_PKCS7_ENVELOPED_DATA: case SEC_OID_PKCS7_SIGNED_DATA: cinfo = SecCmsContentInfoGetChildContentInfo(cinfo); if (cinfo == NULL) { return NULL; } /* else recurse */ break; case SEC_OID_PKCS9_ID_CT_TSTInfo: /* end of recursion - every message has to have a data cinfo */ return cinfo->rawContent; default: PORT_Assert(0); return NULL; } } /* NOT REACHED */ return NULL; }
/* * SecCmsMessageContentLevel - find content level #n * * CMS data content objects do not count. */ SecCmsContentInfoRef SecCmsMessageContentLevel(SecCmsMessageRef cmsg, int n) { int count = 0; SecCmsContentInfoRef cinfo; /* walk down the chain of contentinfos */ for (cinfo = &(cmsg->contentInfo); cinfo != NULL && count < n; cinfo = SecCmsContentInfoGetChildContentInfo(cinfo)) { count++; } return cinfo; }
/* * SecCmsMessageContentLevelCount - count number of levels of CMS content objects in this message * * CMS data content objects do not count. */ int SecCmsMessageContentLevelCount(SecCmsMessageRef cmsg) { int count = 0; SecCmsContentInfoRef cinfo; /* walk down the chain of contentinfos */ for (cinfo = &(cmsg->contentInfo); cinfo != NULL; ) { count++; cinfo = SecCmsContentInfoGetChildContentInfo(cinfo); } return count; }
/* * SecCmsMessageContainsCertsOrCrls - see if message contains certs along the way */ Boolean SecCmsMessageContainsCertsOrCrls(SecCmsMessageRef cmsg) { SecCmsContentInfoRef cinfo; /* descend into CMS message */ for (cinfo = &(cmsg->contentInfo); cinfo != NULL; cinfo = SecCmsContentInfoGetChildContentInfo(cinfo)) { if (SecCmsContentInfoGetContentTypeTag(cinfo) != SEC_OID_PKCS7_SIGNED_DATA) continue; /* next level */ if (SecCmsSignedDataContainsCertsOrCrls(cinfo->content.signedData)) return PR_TRUE; } return PR_FALSE; }
/* * SecCmsMessageIsEncrypted - see if message contains a encrypted submessage */ Boolean SecCmsMessageIsEncrypted(SecCmsMessageRef cmsg) { SecCmsContentInfoRef cinfo; /* walk down the chain of contentinfos */ for (cinfo = &(cmsg->contentInfo); cinfo != NULL; cinfo = SecCmsContentInfoGetChildContentInfo(cinfo)) { switch (SecCmsContentInfoGetContentTypeTag(cinfo)) { case SEC_OID_PKCS7_ENVELOPED_DATA: case SEC_OID_PKCS7_ENCRYPTED_DATA: return PR_TRUE; default: break; } } return PR_FALSE; }
/* * SecCmsMessageIsSigned - see if message contains a signed submessage * * If the CMS message has a SignedData with a signature (not just a SignedData) * return true; false otherwise. This can/should be called before calling * VerifySignature, which will always indicate failure if no signature is * present, but that does not mean there even was a signature! * Note that the content itself can be empty (detached content was sent * another way); it is the presence of the signature that matters. */ Boolean SecCmsMessageIsSigned(SecCmsMessageRef cmsg) { SecCmsContentInfoRef cinfo; /* walk down the chain of contentinfos */ for (cinfo = &(cmsg->contentInfo); cinfo != NULL; cinfo = SecCmsContentInfoGetChildContentInfo(cinfo)) { switch (SecCmsContentInfoGetContentTypeTag(cinfo)) { case SEC_OID_PKCS7_SIGNED_DATA: if (!SecCmsArrayIsEmpty((void **)cinfo->content.signedData->signerInfos)) return PR_TRUE; break; default: break; } } return PR_FALSE; }