/* * SecCmsSignedDataVerifySignerInfo - check the signatures. * * The digests were either calculated during decoding (and are stored in the * signedData itself) or set after decoding using SecCmsSignedDataSetDigests. * * The verification checks if the signing cert is valid and has a trusted chain * for the purpose specified by "policies". * * If trustRef is NULL the cert chain is verified and the VerificationStatus is set accordingly. * Otherwise a SecTrust object is returned for the caller to evaluate using SecTrustEvaluate(). */ OSStatus SecCmsSignedDataVerifySignerInfo(SecCmsSignedDataRef sigd, int i, SecKeychainRef keychainOrArray, CFTypeRef policies, SecTrustRef *trustRef) { SecCmsSignerInfoRef signerinfo; SecCmsContentInfoRef cinfo; SECOidData *algiddata; CSSM_DATA_PTR contentType, digest; OSStatus status, status2; cinfo = &(sigd->contentInfo); signerinfo = sigd->signerInfos[i]; /* Signature or digest level verificationStatus errors should supercede certificate level errors, so check the digest and signature first. */ /* Find digest and contentType for signerinfo */ algiddata = SecCmsSignerInfoGetDigestAlg(signerinfo); if (algiddata == NULL) { return errSecInternalError; // shouldn't have happened, this is likely due to corrupted data } digest = SecCmsSignedDataGetDigestByAlgTag(sigd, algiddata->offset); if(digest == NULL) { /* * No digests; this probably had detached content the caller has to * deal with. * FIXME: need some error return for this (as well as many * other places in this library). */ return errSecDataNotAvailable; } contentType = SecCmsContentInfoGetContentTypeOID(cinfo); /* verify signature */ CFTypeRef timeStampPolicies=SecPolicyCreateAppleTimeStampingAndRevocationPolicies(policies); status = SecCmsSignerInfoVerifyWithPolicy(signerinfo, timeStampPolicies, digest, contentType); CFReleaseSafe(timeStampPolicies); /* Now verify the certificate. We do this even if the signature failed to verify so we can return a trustRef to the caller for display purposes. */ status2 = SecCmsSignerInfoVerifyCertificate(signerinfo, keychainOrArray, policies, trustRef); dprintf("SecCmsSignedDataVerifySignerInfo: status %d status2 %d\n", (int) status, (int)status2); /* The error from SecCmsSignerInfoVerify() supercedes error from SecCmsSignerInfoVerifyCertificate(). */ if (status) return status; return status2; }
/* * SecCmsSignerInfoVerify - verify the signature of a single SignerInfo * * Just verifies the signature. The assumption is that verification of the certificate * is done already. */ OSStatus SecCmsSignerInfoVerify(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR digest, CSSM_DATA_PTR contentType) { return SecCmsSignerInfoVerifyWithPolicy(signerinfo,NULL, digest,contentType); }