I'm in the process of refactoring my code to use the new CMS API instead of PKCS7.
In my code before I was able to determine the type of pkcs7, and even distinguish between a signed data (.p7m), signature (.p7s) and cert chain (.p7b), using this function: PKCS7Type determine_pkcs7_type(PKCS7* p7) { int nid = OBJ_obj2nid(p7->type); switch( nid ) { case NID_pkcs7_data: return PKCS7Type_Data; case NID_pkcs7_enveloped: case NID_pkcs7_encrypted: return PKCS7Type_EncData; case NID_pkcs7_digest: return PKCS7Type_Digest; case NID_pkcs7_signed: if( p7->d.sign->contents && OBJ_obj2nid(p7->d.sign->contents->type) == NID_pkcs7_data && p7->d.sign->contents->d.data != NULL ) return PKCS7Type_SignedData; if( sk_PKCS7_SIGNER_INFO_num(p7->d.sign->signer_info) > 0 ) return PKCS7Type_Signature; if( sk_X509_num(p7->d.sign->cert) > 0 || sk_X509_CRL_num(p7->d.sign->crl) > 0 ) return PKCS7Type_Certs; return PKCS7Type_UNKNOWN; } return PKCS7Type_UNKNOWN; } Now I am trying to do the same thing with CMS, but the struct contents are encapsulated from me (yes yes, that is good I know), so I'm currently at a loss as to how to differentiate the types, see below: PKCS7Type determine_pkcs7_type(CMS_ContentInfo* cms) { int nid = OBJ_obj2nid(CMS_get0_type(cms)); switch( nid ) { case NID_pkcs7_data: return PKCS7Type_Data; case NID_id_smime_ct_compressedData: return PKCS7Type_CompData; case NID_pkcs7_enveloped: case NID_pkcs7_encrypted: return PKCS7Type_EncData; case NID_pkcs7_digest: return PKCS7Type_Digest; case NID_pkcs7_signed: { // HELP!! How can I tell if this is a signed data, or just a signature (i.e., a .p7s with no data), or it is a cert chain (i.e., a .p7b with just certs) } } return PKCS7Type_UNKNOWN; } Thanks, Phillip