X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/e0e0d90ebff497686991a933ae2f7db24e7d8e0f..ce3c8656732c924baf7e88df75eab50891bdc471:/OSX/libsecurity_cms/lib/CMSDecoder.cpp diff --git a/OSX/libsecurity_cms/lib/CMSDecoder.cpp b/OSX/libsecurity_cms/lib/CMSDecoder.cpp index a420e5eb..a8d81d09 100644 --- a/OSX/libsecurity_cms/lib/CMSDecoder.cpp +++ b/OSX/libsecurity_cms/lib/CMSDecoder.cpp @@ -999,3 +999,47 @@ OSStatus CMSDecoderCopySignerTimestampCertificates( xit: return status; } + +/* + * Obtain the Hash Agility attribute value of signer 'signerIndex' + * of a CMS message, if present. + * + * Returns errSecParam if the CMS message was not signed or if signerIndex + * is greater than the number of signers of the message minus one. + * + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopySignerAppleCodesigningHashAgility( + CMSDecoderRef cmsDecoder, + size_t signerIndex, /* usually 0 */ + CFDataRef CF_RETURNS_RETAINED *hashAgilityAttrValue) /* RETURNED */ +{ + OSStatus status = errSecParam; + SecCmsMessageRef cmsg; + SecCmsSignedDataRef signedData = NULL; + int numContentInfos = 0; + CFDataRef returnedValue = NULL; + + require(cmsDecoder && hashAgilityAttrValue, xit); + require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), xit); + numContentInfos = SecCmsMessageContentLevelCount(cmsg); + for (int dex = 0; !signedData && dex < numContentInfos; dex++) + { + SecCmsContentInfoRef ci = SecCmsMessageContentLevel(cmsg, dex); + SECOidTag tag = SecCmsContentInfoGetContentTypeTag(ci); + if (tag == SEC_OID_PKCS7_SIGNED_DATA) + if ((signedData = SecCmsSignedDataRef(SecCmsContentInfoGetContent(ci)))) + if (SecCmsSignerInfoRef signerInfo = SecCmsSignedDataGetSignerInfo(signedData, (int)signerIndex)) + { + status = SecCmsSignerInfoGetAppleCodesigningHashAgility(signerInfo, &returnedValue); + break; + } + } +xit: + if (status == errSecSuccess && returnedValue) { + *hashAgilityAttrValue = (CFDataRef) CFRetain(returnedValue); + } else { + *hashAgilityAttrValue = NULL; + } + return status; +}