Index: /trunk/include/iprt/crypto/pkcs7.h
===================================================================
--- /trunk/include/iprt/crypto/pkcs7.h	(revision 74715)
+++ /trunk/include/iprt/crypto/pkcs7.h	(revision 74716)
@@ -107,4 +107,6 @@
     /** Microsoft statement type, use pObjIdSeqs. */
     RTCRPKCS7ATTRIBUTETYPE_MS_STATEMENT_TYPE,
+    /** Apple plist with the all code directory digests, use pOctetStrings. */
+    RTCRPKCS7ATTRIBUTETYPE_APPLE_MULTI_CD_PLIST,
     /** Blow the type up to 32-bits. */
     RTCRPKCS7ATTRIBUTETYPE_32BIT_HACK = 0x7fffffff
@@ -212,4 +214,7 @@
  * @remarks This isn't defined by PKCS \#9, but lumped in here for convenience. It's actually listed as SPC by MS. */
 #define RTCR_PKCS9_ID_MS_SP_OPUS_INFO       "1.3.6.1.4.1.311.2.1.12"
+/** Apple code signing multi-code-directory plist.
+ * @remarks This isn't defined by PKCS \#9, but lumped in here for convenience. */
+#define RTCR_PKCS9_ID_APPLE_MULTI_CD_PLIST  "1.2.840.113635.100.9.1"
 /** @} */
 
Index: /trunk/src/VBox/Runtime/common/crypto/pkcs7-template.h
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/pkcs7-template.h	(revision 74715)
+++ /trunk/src/VBox/Runtime/common/crypto/pkcs7-template.h	(revision 74716)
@@ -65,4 +65,6 @@
 RTASN1TMPL_MEMBER_DYN(          uValues,    pObjIdSeqs,     RTASN1SETOFOBJIDSEQS,       RTAsn1SetOfObjIdSeqs,       Allocation,
     enmType, RTCRPKCS7ATTRIBUTETYPE_MS_STATEMENT_TYPE, RTAsn1ObjId_CompareWithString(&pThis->Type, RTCR_PKCS9_ID_MS_STATEMENT_TYPE) == 0);
+RTASN1TMPL_MEMBER_DYN(          uValues,    pOctetStrings,  RTASN1SETOFOCTETSTRINGS,    RTAsn1SetOfOctetStrings,    Allocation,
+    enmType, RTCRPKCS7ATTRIBUTETYPE_APPLE_MULTI_CD_PLIST,  RTAsn1ObjId_CompareWithString(&pThis->Type, RTCR_PKCS9_ID_APPLE_MULTI_CD_PLIST) == 0);
 RTASN1TMPL_MEMBER_DYN_DEFAULT(  uValues,    pCores,         RTASN1SETOFCORES,           RTAsn1SetOfCores,           Allocation,
     enmType, RTCRPKCS7ATTRIBUTETYPE_UNKNOWN);
Index: /trunk/src/VBox/Runtime/tools/RTSignTool.cpp
===================================================================
--- /trunk/src/VBox/Runtime/tools/RTSignTool.cpp	(revision 74715)
+++ /trunk/src/VBox/Runtime/tools/RTSignTool.cpp	(revision 74716)
@@ -1789,4 +1789,47 @@
             break;
 
+        case RTCRPKCS7ATTRIBUTETYPE_APPLE_MULTI_CD_PLIST:
+            if (pAttr->uValues.pContentInfos->cItems != 1)
+                RTPrintf("%s%u plists, expected only 1.\n", pThis->szPrefix, pAttr->uValues.pOctetStrings->cItems);
+            for (unsigned i = 0; i < pAttr->uValues.pOctetStrings->cItems; i++)
+            {
+                PCRTASN1OCTETSTRING pOctetString = pAttr->uValues.pOctetStrings->papItems[i];
+                size_t              cbContent    = pOctetString->Asn1Core.cb;
+                char  const        *pchContent   = pOctetString->Asn1Core.uData.pch;
+                rc = RTStrValidateEncodingEx(pchContent, cbContent, RTSTR_VALIDATE_ENCODING_EXACT_LENGTH);
+                if (RT_SUCCESS(rc))
+                {
+                    while (cbContent > 0)
+                    {
+                        const char *pchNewLine = (const char *)memchr(pchContent, '\n', cbContent);
+                        size_t      cchToWrite = pchNewLine ? pchNewLine - pchContent : cbContent;
+                        if (pAttr->uValues.pOctetStrings->cItems == 1)
+                            RTPrintf("%s %.*s\n", pThis->szPrefix, cchToWrite, pchContent);
+                        else
+                            RTPrintf("%s plist[%u]: %.*s\n", pThis->szPrefix, i, cchToWrite, pchContent);
+                        if (!pchNewLine)
+                            break;
+                        pchContent = pchNewLine + 1;
+                        cbContent -= cchToWrite + 1;
+                    }
+                }
+                else
+                {
+                    if (pAttr->uValues.pContentInfos->cItems != 1)
+                        RTPrintf("%s: plist[%u]: Invalid UTF-8: %Rrc\n", pThis->szPrefix, i, rc);
+                    else
+                        RTPrintf("%s: Invalid UTF-8: %Rrc\n", pThis->szPrefix, rc);
+                    for (uint32_t off = 0; off < cbContent; off += 16)
+                    {
+                        size_t cbNow = RT_MIN(cbContent - off, 16);
+                        if (pAttr->uValues.pOctetStrings->cItems == 1)
+                            RTPrintf("%s %#06x: %.*Rhxs\n", pThis->szPrefix, off, cbNow, &pchContent[off]);
+                        else
+                            RTPrintf("%s plist[%u]: %#06x: %.*Rhxs\n", pThis->szPrefix, i, off, cbNow, &pchContent[off]);
+                    }
+                }
+            }
+            break;
+
         case RTCRPKCS7ATTRIBUTETYPE_INVALID:
             RTPrintf("%sINVALID!\n", pThis->szPrefix);
