Index: /trunk/include/iprt/err.h
===================================================================
--- /trunk/include/iprt/err.h	(revision 74655)
+++ /trunk/include/iprt/err.h	(revision 74656)
@@ -2340,7 +2340,7 @@
 #define VERR_ASN1_CURSOR_BAD_LENGTH_ENCODING        (-22831)
 /** Indefinite length form is against the rules. */
-#define VERR_ASN1_CURSOR_ILLEGAL_IDEFINITE_LENGTH   (-22832)
-/** Indefinite length form is not implemented. */
-#define VERR_ASN1_CURSOR_IDEFINITE_LENGTH_NOT_SUP   (-22833)
+#define VERR_ASN1_CURSOR_ILLEGAL_INDEFINITE_LENGTH  (-22832)
+/** Malformed indefinite length encoding. */
+#define VERR_ASN1_CURSOR_BAD_INDEFINITE_LENGTH      (-22833)
 /** ASN.1 object length goes beyond the end of the byte stream being decoded. */
 #define VERR_ASN1_CURSOR_BAD_LENGTH                 (-22834)
@@ -2471,4 +2471,6 @@
 /** Image hash mismatch. */
 #define VERR_LDRVI_IMAGE_HASH_MISMATCH              (-22929)
+/** Malformed code signing structure. */
+#define VERR_LDRVI_BAD_CERT_FORMAT                  (-22930)
 
 /** Cannot resolve symbol because it's a forwarder. */
Index: /trunk/src/VBox/Runtime/common/asn1/asn1-cursor.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/asn1/asn1-cursor.cpp	(revision 74655)
+++ /trunk/src/VBox/Runtime/common/asn1/asn1-cursor.cpp	(revision 74656)
@@ -314,9 +314,27 @@
             /* Indefinite form. */
             else if (pCursor->fFlags & RTASN1CURSOR_FLAGS_DER)
-                return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_ILLEGAL_IDEFINITE_LENGTH,
+                return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_ILLEGAL_INDEFINITE_LENGTH,
                                            "%s: Indefinite length form not allowed in DER mode (uTag=%#x).", pszErrorTag, uTag);
+            else if (pCursor->cbLeft < 2)
+                return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_BAD_INDEFINITE_LENGTH,
+                                           "%s: Too little data left for indefinite BER/CER encoding (uTag=%#x)", pszErrorTag, uTag);
             else
-                return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_IDEFINITE_LENGTH_NOT_SUP,
-                                           "%s: Indefinite BER/CER length not supported (uTag=%#x)", pszErrorTag, uTag);
+            {
+                /* Search forward till we find the two terminating zero bytes. */
+                cb = 0;
+                for (;;)
+                {
+                    uint8_t const *pb = (uint8_t const *)memchr(&pCursor->pbCur[cb], 0x00, pCursor->cbLeft - cb - 1);
+                    if (pb && pb[1] == 0x00)
+                    {
+                        cb = &pb[2] - pCursor->pbCur;
+                        break;
+                    }
+                    if (!pb)
+                        return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_BAD_INDEFINITE_LENGTH,
+                                                   "%s: Could not find end of indefinite BER/CER record (uTag=%#x)", pszErrorTag, uTag);
+                    cb = &pb[1] - pCursor->pbCur;
+                }
+            }
         }
 
Index: /trunk/src/VBox/Runtime/common/ldr/ldrMachO.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/ldr/ldrMachO.cpp	(revision 74655)
+++ /trunk/src/VBox/Runtime/common/ldr/ldrMachO.cpp	(revision 74656)
@@ -5,4 +5,17 @@
 
 /*
+ * Copyright (C) 2018 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ * --------------------------------------------------------------------
+ *
+ * This code is based on:
+ *
  * Copyright (c) 2006-2013 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net>
  *
@@ -45,4 +58,5 @@
 
 #include <iprt/formats/mach-o.h>
+#include <iprt/crypto/applecodesign.h>
 #include "internal/ldr.h"
 
@@ -201,4 +215,15 @@
     uint8_t                 abImageUuid[16];
 
+    /** The code signature offset.   */
+    uint32_t                offCodeSignature;
+    /** The code signature size (0 if not signed). */
+    uint32_t                cbCodeSignature;
+    /** Pointer to the code signature blob if loaded. */
+    union
+    {
+        uint8_t                *pb;
+        PCRTCRAPLCSSUPERBLOB    pSuper;
+    }                       PtrCodeSignature;
+
     /** The RVA of the Global Offset Table. */
     RTLDRADDR               GotRVA;
@@ -228,5 +253,5 @@
 
 
-static int  kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr, PRTLDRREADER pRdr, RTFOFF   offImage,
+static int  kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr, PRTLDRREADER pRdr, RTFOFF offImage,
                                              uint32_t fOpenFlags, uint32_t *pcSegments, uint32_t *pcSections, uint32_t *pcbStringPool,
                                              bool *pfCanLoad, PRTLDRADDR pLinkAddress, uint8_t *puEffFileType, PRTERRINFO pErrInfo);
@@ -467,4 +492,7 @@
     pThis->pchStrings = NULL;
     memset(pThis->abImageUuid, 0, sizeof(pThis->abImageUuid));
+    pThis->offCodeSignature = 0;
+    pThis->cbCodeSignature = 0;
+    pThis->PtrCodeSignature.pb = NULL;
     pThis->GotRVA = NIL_RTLDRADDR;
     pThis->JmpStubsRVA = NIL_RTLDRADDR;
@@ -1074,10 +1102,11 @@
     union
     {
-        const uint8_t              *pb;
-        const load_command_t       *pLoadCmd;
-        const segment_command_32_t *pSeg32;
-        const segment_command_64_t *pSeg64;
-        const symtab_command_t     *pSymTab;
-        const uuid_command_t       *pUuid;
+        const uint8_t                 *pb;
+        const load_command_t          *pLoadCmd;
+        const segment_command_32_t    *pSeg32;
+        const segment_command_64_t    *pSeg64;
+        const symtab_command_t        *pSymTab;
+        const uuid_command_t          *pUuid;
+        const linkedit_data_command_t *pData;
     } u;
     uint32_t cLeft = pThis->Hdr.ncmds;
@@ -1275,4 +1304,9 @@
                 break;
 
+            case LC_CODE_SIGNATURE:
+                pThis->offCodeSignature = u.pData->dataoff;
+                pThis->cbCodeSignature  = u.pData->datasize;
+                break;
+
             default:
                 break;
@@ -1443,4 +1477,6 @@
     RTMemFree(pThis->pvaSymbols);
     pThis->pvaSymbols = NULL;
+    RTMemFree(pThis->PtrCodeSignature.pb);
+    pThis->PtrCodeSignature.pb = NULL;
 
     return VINF_SUCCESS;
@@ -3757,10 +3793,118 @@
 
 
+/**
+ * Loads the code signing blob if necessary (RTLDRMODMACHO::PtrCodeSignature).
+ *
+ * @returns IPRT status code.
+ * @param   pThis               The mach-o instance.
+ */
+static int rtldrMachO_LoadSignatureBlob(PRTLDRMODMACHO pThis)
+{
+    Assert(pThis->cbCodeSignature > 0);
+    if (pThis->PtrCodeSignature.pb != NULL)
+        return VINF_SUCCESS;
+
+    if (   pThis->cbCodeSignature > sizeof(RTCRAPLCSHDR)
+        && pThis->cbCodeSignature <= _1M)
+    {
+        /* Allocate and read. */
+        void *pv = RTMemAllocZ(RT_ALIGN_Z(pThis->cbCodeSignature, 16));
+        AssertReturn(pv, VERR_NO_MEMORY);
+        int rc = pThis->Core.pReader->pfnRead(pThis->Core.pReader, pv, pThis->cbCodeSignature, pThis->offCodeSignature);
+        if (RT_SUCCESS(rc))
+        {
+            /* Check blob signature. */
+            PCRTCRAPLCSSUPERBLOB pSuper = (PCRTCRAPLCSSUPERBLOB)pv;
+            if (pSuper->Hdr.uMagic == RTCRAPLCS_MAGIC_EMBEDDED_SIGNATURE)
+            {
+                uint32_t cbHdr  = RT_BE2H_U32(pSuper->Hdr.cb);
+                uint32_t cSlots = RT_BE2H_U32(pSuper->cSlots);
+                if (   cbHdr  <= pThis->cbCodeSignature
+                    && cbHdr  >  RT_UOFFSETOF(RTCRAPLCSSUPERBLOB, aSlots)
+                    && cSlots >  0
+                    && cSlots <  128
+                    && RT_UOFFSETOF_DYN(RTCRAPLCSSUPERBLOB, aSlots[cSlots]) <= cbHdr)
+                {
+                    pThis->PtrCodeSignature.pSuper = pSuper;
+                    return VINF_SUCCESS;
+                }
+                rc = VERR_LDRVI_BAD_CERT_HDR_LENGTH;
+            }
+            else
+                rc = VERR_LDRVI_BAD_CERT_HDR_TYPE;
+        }
+        RTMemFree(pv);
+        return rc;
+    }
+    return VERR_LDRVI_INVALID_SECURITY_DIR_ENTRY;
+}
+
+
+/**
+ * Handles a RTLDRPROP_PKCS7_SIGNED_DATA query.
+ */
+static int rtldrMachO_QueryPkcs7SignedData(PRTLDRMODMACHO pThis, void *pvBuf, size_t cbBuf, size_t *pcbRet)
+{
+    int rc = rtldrMachO_LoadSignatureBlob(pThis);
+    if (RT_SUCCESS(rc))
+    {
+        /*
+         * Locate the signature slot.
+         */
+        uint32_t            iSlot = RT_BE2H_U32(pThis->PtrCodeSignature.pSuper->cSlots);
+        PCRTCRAPLCSBLOBSLOT pSlot = &pThis->PtrCodeSignature.pSuper->aSlots[iSlot];
+        while (iSlot-- > 0)
+        {
+            pSlot--;
+            if (pSlot->uType == RTCRAPLCS_SLOT_SIGNATURE)
+            {
+                /*
+                 * Validate the data offset.
+                 */
+                uint32_t offData = RT_BE2H_U32(pSlot->offData);
+                if (   offData < pThis->cbCodeSignature - sizeof(RTCRAPLCSHDR)
+                    || !(offData & 3) )
+                {
+                    /*
+                     * The data is prefixed by a header with magic set to blob wrapper.
+                     * Check that the size is within the bounds of the code signing blob.
+                     */
+                    PCRTCRAPLCSHDR pHdr = (PCRTCRAPLCSHDR)&pThis->PtrCodeSignature.pb[offData];
+                    if (pHdr->uMagic == RTCRAPLCS_MAGIC_BLOBWRAPPER)
+                    {
+                        uint32_t cbData = RT_BE2H_U32(pHdr->cb);
+                        uint32_t cbMax  = pThis->cbCodeSignature - offData ;
+                        if (   cbData <= cbMax
+                            && cbData > sizeof(RTCRAPLCSHDR))
+                        {
+                            /*
+                             * Copy out the requirest data.
+                             */
+                            *pcbRet = cbData;
+                            if (cbData <= cbBuf)
+                            {
+                                memcpy(pvBuf, pHdr + 1, cbData);
+                                return VINF_SUCCESS;
+                            }
+                            memcpy(pvBuf, pHdr + 1, cbBuf);
+                            return VERR_BUFFER_OVERFLOW;
+                        }
+                    }
+                }
+                return VERR_LDRVI_BAD_CERT_FORMAT;
+            }
+        }
+        rc = VERR_NOT_FOUND;
+    }
+    return rc;
+}
+
+
 /** @interface_method_impl{RTLDROPS,pfnQueryProp} */
 static DECLCALLBACK(int) rtldrMachO_QueryProp(PRTLDRMODINTERNAL pMod, RTLDRPROP enmProp, void const *pvBits,
                                               void *pvBuf, size_t cbBuf, size_t *pcbRet)
 {
-    PRTLDRMODMACHO pThis = RT_FROM_MEMBER(pMod, RTLDRMODMACHO, Core);
-    int           rc;
+    PRTLDRMODMACHO  pThis = RT_FROM_MEMBER(pMod, RTLDRMODMACHO, Core);
+    int             rc    = VERR_NOT_FOUND;
     switch (enmProp)
     {
@@ -3771,9 +3915,27 @@
                 *pcbRet = sizeof(pThis->abImageUuid);
                 memcpy(pvBuf, pThis->abImageUuid, sizeof(pThis->abImageUuid));
-                rc = VINF_SUCCESS;
+                return VINF_SUCCESS;
             }
+            break;
+
+        case RTLDRPROP_FILE_OFF_HEADER:
+            Assert(cbBuf == sizeof(uint32_t) || cbBuf == sizeof(uint64_t));
+            if (cbBuf == sizeof(uint32_t))
+                *(uint32_t *)pvBuf = pThis->offImage;
             else
-                rc = VERR_NOT_FOUND;
+                *(uint64_t *)pvBuf = pThis->offImage;
+            return VINF_SUCCESS;
+
+        case RTLDRPROP_IS_SIGNED:
+            Assert(cbBuf == sizeof(bool));
+            Assert(*pcbRet == cbBuf);
+            *(bool *)pvBuf = pThis->cbCodeSignature > 0;
+            return VINF_SUCCESS;
+
+        case RTLDRPROP_PKCS7_SIGNED_DATA:
+            if (pThis->cbCodeSignature > 0)
+                return rtldrMachO_QueryPkcs7SignedData(pThis, pvBuf, cbBuf, pcbRet);
             break;
+
 
 #if 0 /** @todo return LC_ID_DYLIB */
@@ -3782,5 +3944,4 @@
 
         default:
-            rc = VERR_NOT_FOUND;
             break;
     }
