]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_cms/lib/CMSDecoder.cpp
Security-58286.260.20.tar.gz
[apple/security.git] / OSX / libsecurity_cms / lib / CMSDecoder.cpp
index 83775b23cfa2e03c7572006aa03baaa0925adf7c..a6fb2688d59f524e97190d29f63f3d31125844de 100644 (file)
@@ -311,7 +311,9 @@ OSStatus CMSDecoderFinalizeMessage(
                 (SecCmsSignedDataRef)SecCmsContentInfoGetContent(ci);
                                /* dig down one more layer for eContentType */
                                ci = SecCmsSignedDataGetContentInfo(cmsDecoder->signedData);
-                               cmsDecoder->eContentType = SecCmsContentInfoGetContentTypeOID(ci);
+                               if (ci) {
+                                       cmsDecoder->eContentType = SecCmsContentInfoGetContentTypeOID(ci);
+                               }
                                break;
                        default:
                                break;
@@ -1003,8 +1005,8 @@ OSStatus CMSDecoderCopySignerAppleCodesigningHashAgility(
     int numContentInfos = 0;
     CFDataRef returnedValue = NULL;
 
-    require(cmsDecoder && hashAgilityAttrValue, xit);
-    require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), xit);
+    require(cmsDecoder && hashAgilityAttrValue, exit);
+    require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), exit);
     numContentInfos = SecCmsMessageContentLevelCount(cmsg);
     for (int dex = 0; !signedData && dex < numContentInfos; dex++)
     {
@@ -1018,7 +1020,7 @@ OSStatus CMSDecoderCopySignerAppleCodesigningHashAgility(
                     break;
                 }
     }
-xit:
+exit:
     if (status == errSecSuccess && returnedValue) {
         *hashAgilityAttrValue = (CFDataRef) CFRetain(returnedValue);
     } else {
@@ -1026,3 +1028,88 @@ xit:
     }
     return status;
 }
+
+/*
+ * Obtain the Hash Agility V2 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 CMSDecoderCopySignerAppleCodesigningHashAgilityV2(
+    CMSDecoderRef        cmsDecoder,
+    size_t                signerIndex,            /* usually 0 */
+    CFDictionaryRef  CF_RETURNS_RETAINED *hashAgilityV2AttrValues)            /* RETURNED */
+{
+    OSStatus status = errSecParam;
+    SecCmsMessageRef cmsg;
+    SecCmsSignedDataRef signedData = NULL;
+    int numContentInfos = 0;
+    CFDictionaryRef returnedValue = NULL;
+
+    require(cmsDecoder && hashAgilityV2AttrValues, exit);
+    require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), exit);
+    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))) {
+                SecCmsSignerInfoRef signerInfo = SecCmsSignedDataGetSignerInfo(signedData, (int)signerIndex);
+                if (signerInfo)
+                {
+                    status = SecCmsSignerInfoGetAppleCodesigningHashAgilityV2(signerInfo, &returnedValue);
+                    break;
+                }
+            }
+    }
+exit:
+    if (status == errSecSuccess && returnedValue) {
+        *hashAgilityV2AttrValues = (CFDictionaryRef) CFRetain(returnedValue);
+    } else {
+        *hashAgilityV2AttrValues = NULL;
+    }
+    return status;
+}
+
+/*
+ * Obtain the expiration time of signer 'signerIndex' of a CMS message, if
+ * present. This is part of the signed attributes of the message.
+ *
+ * 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 CMSDecoderCopySignerAppleExpirationTime(
+    CMSDecoderRef      cmsDecoder,
+    size_t             signerIndex,
+    CFAbsoluteTime     *expirationTime)            /* RETURNED */
+{
+    OSStatus status = errSecParam;
+    SecCmsMessageRef cmsg = NULL;
+    int numContentInfos  = 0;
+    SecCmsSignedDataRef signedData = NULL;
+
+    require(cmsDecoder && expirationTime, 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))) {
+                SecCmsSignerInfoRef signerInfo = SecCmsSignedDataGetSignerInfo(signedData, (int)signerIndex);
+                if (signerInfo) {
+                    status = SecCmsSignerInfoGetAppleExpirationTime(signerInfo, expirationTime);
+                    break;
+                }
+            }
+        }
+    }
+xit:
+    return status;
+}