]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_cms/lib/CMSDecoder.cpp
Security-57337.50.23.tar.gz
[apple/security.git] / OSX / libsecurity_cms / lib / CMSDecoder.cpp
index a420e5eba76d6305bf7034e8ce52566ddeef2d80..a8d81d095e1077a502396eb4412331b9367cd076 100644 (file)
@@ -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;
+}