Index: /trunk/include/iprt/asn1-generator-pass.h
===================================================================
--- /trunk/include/iprt/asn1-generator-pass.h	(revision 74671)
+++ /trunk/include/iprt/asn1-generator-pass.h	(revision 74672)
@@ -490,12 +490,17 @@
 
 # define RTASN1TMPL_END_SEQCORE() \
-   if (RT_SUCCESS(rc)) \
-       rc = RTAsn1CursorCheckEnd(&ThisCursor); \
-   if (RT_SUCCESS(rc)) \
-       return VINF_SUCCESS; \
-   RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
-   RTASN1TMPL_END_COMMON()
-# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_END_SEQCORE()
-
+    if (RT_SUCCESS(rc)) \
+        rc = RTAsn1CursorCheckSeqEnd(&ThisCursor, &pThis->SeqCore); \
+    if (RT_SUCCESS(rc)) \
+        return VINF_SUCCESS; \
+    RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
+    RTASN1TMPL_END_COMMON()
+# define RTASN1TMPL_END_SETCORE() \
+    if (RT_SUCCESS(rc)) \
+        rc = RTAsn1CursorCheckSetEnd(&ThisCursor, &pThis->SetCore); \
+    if (RT_SUCCESS(rc)) \
+        return VINF_SUCCESS; \
+    RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
+    RTASN1TMPL_END_COMMON()
 
 # define RTASN1TMPL_BEGIN_PCHOICE() \
Index: /trunk/include/iprt/asn1.h
===================================================================
--- /trunk/include/iprt/asn1.h	(revision 74671)
+++ /trunk/include/iprt/asn1.h	(revision 74672)
@@ -1649,8 +1649,6 @@
     /** The cursor depth. */
     uint8_t                     cDepth;
-    /** Number of pending indefinite length records. */
-    uint8_t                     cIndefinedRecs;
     /** Two bytes reserved for future tricks. */
-    uint8_t                     abReserved[1];
+    uint8_t                     abReserved[2];
     /** Pointer to the primary cursor. */
     struct RTASN1CURSORPRIMARY *pPrimary;
@@ -1790,4 +1788,28 @@
 RTDECL(int) RTAsn1CursorCheckEnd(PRTASN1CURSOR pCursor);
 
+/**
+ * Specialization of RTAsn1CursorCheckEnd for handling indefinite length sequences.
+ *
+ * Makes sure we've reached the end of the data for the cursor, and in case of a
+ * an indefinite length sequence it may adjust sequence length and the parent
+ * cursor.
+ *
+ * @returns IPRT status code.
+ * @param   pCursor             The cursor we're decoding from.
+ * @param   pSeqCore            The sequence core record.
+ */
+RTDECL(int) RTAsn1CursorCheckSeqEnd(PRTASN1CURSOR pCursor, PRTASN1SEQUENCECORE pSeqCore);
+
+/**
+ * Specialization of RTAsn1CursorCheckEnd for handling indefinite length sets.
+ *
+ * Makes sure we've reached the end of the data for the cursor, and in case of a
+ * an indefinite length sets it may adjust set length and the parent cursor.
+ *
+ * @returns IPRT status code.
+ * @param   pCursor             The cursor we're decoding from.
+ * @param   pSetCore            The set core record.
+ */
+RTDECL(int) RTAsn1CursorCheckSetEnd(PRTASN1CURSOR pCursor, PRTASN1SETCORE pSetCore);
 
 /**
Index: /trunk/include/iprt/mangling.h
===================================================================
--- /trunk/include/iprt/mangling.h	(revision 74671)
+++ /trunk/include/iprt/mangling.h	(revision 74672)
@@ -2741,4 +2741,6 @@
 # define RTAsn1VtDelete                                 RT_MANGLER(RTAsn1VtDelete)
 # define RTAsn1CursorCheckEnd                           RT_MANGLER(RTAsn1CursorCheckEnd)
+# define RTAsn1CursorCheckSeqEnd                        RT_MANGLER(RTAsn1CursorCheckSeqEnd)
+# define RTAsn1CursorCheckSetEnd                        RT_MANGLER(RTAsn1CursorCheckSetEnd)
 # define RTAsn1CursorGetBitString                       RT_MANGLER(RTAsn1CursorGetBitString)
 # define RTAsn1CursorGetBitStringEx                     RT_MANGLER(RTAsn1CursorGetBitStringEx)
Index: /trunk/include/iprt/types.h
===================================================================
--- /trunk/include/iprt/types.h	(revision 74671)
+++ /trunk/include/iprt/types.h	(revision 74672)
@@ -2991,5 +2991,5 @@
     intptr_t                i;
     /** As an unsigned integer. */
-    intptr_t                u;
+    uintptr_t               u;
     /** Pointer to char value. */
     char            RT_FAR *pch;
@@ -3038,5 +3038,5 @@
     intptr_t                i;
     /** As an unsigned integer. */
-    intptr_t                u;
+    uintptr_t               u;
     /** Pointer to char value. */
     char const      RT_FAR *pch;
@@ -3085,5 +3085,5 @@
     intptr_t                i;
     /** As an unsigned integer. */
-    intptr_t                u;
+    uintptr_t               u;
     /** Pointer to char value. */
     char volatile  RT_FAR *pch;
@@ -3132,5 +3132,5 @@
     intptr_t                                i;
     /** As an unsigned integer. */
-    intptr_t                                u;
+    uintptr_t                               u;
     /** Pointer to char value. */
     char const volatile             RT_FAR *pch;
Index: /trunk/src/VBox/Runtime/VBox/VBoxRTImp.def
===================================================================
--- /trunk/src/VBox/Runtime/VBox/VBoxRTImp.def	(revision 74671)
+++ /trunk/src/VBox/Runtime/VBox/VBoxRTImp.def	(revision 74672)
@@ -117,4 +117,6 @@
     RTAsn1Core_SetTagAndFlags
     RTAsn1CursorCheckEnd
+    RTAsn1CursorCheckSeqEnd
+    RTAsn1CursorCheckSetEnd
     RTAsn1CursorGetBitString
     RTAsn1CursorGetBitStringEx
Index: /trunk/src/VBox/Runtime/common/asn1/asn1-cursor.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/asn1/asn1-cursor.cpp	(revision 74671)
+++ /trunk/src/VBox/Runtime/common/asn1/asn1-cursor.cpp	(revision 74672)
@@ -68,6 +68,6 @@
     pPrimaryCursor->Cursor.fFlags           = (uint8_t)fFlags; Assert(fFlags <= UINT8_MAX);
     pPrimaryCursor->Cursor.cDepth           = 0;
-    pPrimaryCursor->Cursor.cIndefinedRecs   = 0;
     pPrimaryCursor->Cursor.abReserved[0]    = 0;
+    pPrimaryCursor->Cursor.abReserved[1]    = 0;
     pPrimaryCursor->Cursor.pPrimary         = pPrimaryCursor;
     pPrimaryCursor->Cursor.pUp              = NULL;
@@ -89,6 +89,6 @@
     pChild->cDepth          = pParent->cDepth + 1;
     AssertReturn(pChild->cDepth < RTASN1_MAX_NESTING, VERR_ASN1_TOO_DEEPLY_NESTED);
-    pChild->cIndefinedRecs  = 0;
     pChild->abReserved[0]   = 0;
+    pChild->abReserved[1]   = 0;
     pChild->pPrimary        = pParent->pPrimary;
     pChild->pUp             = pParent;
@@ -114,6 +114,6 @@
     pChild->cDepth          = pParent->cDepth + 1;
     AssertReturn(pChild->cDepth < RTASN1_MAX_NESTING, VERR_ASN1_TOO_DEEPLY_NESTED);
-    pChild->cIndefinedRecs  = 0;
     pChild->abReserved[0]   = 0;
+    pChild->abReserved[1]   = 0;
     pChild->pPrimary        = pParent->pPrimary;
     pChild->pUp             = pParent;
@@ -194,8 +194,7 @@
     if (!(pCursor->fFlags & RTASN1CURSOR_FLAGS_INDEFINITE_LENGTH))
         return false;
-    /* This isn't quite right. */
-    if (pCursor->cbLeft > pCursor->cIndefinedRecs * (uint32_t)2)
-        return false;
-    return ASMMemIsZero(pCursor->pbCur, pCursor->cbLeft);
+    return pCursor->cbLeft >= 2
+        && pCursor->pbCur[0] == 0
+        && pCursor->pbCur[1] == 0;
 }
 
@@ -205,10 +204,90 @@
     if (pCursor->cbLeft == 0)
         return VINF_SUCCESS;
-    if (   (pCursor->fFlags & RTASN1CURSOR_FLAGS_INDEFINITE_LENGTH)
-        && pCursor->cbLeft == pCursor->cIndefinedRecs * (uint32_t)2
-        && ASMMemIsZero(pCursor->pbCur, pCursor->cbLeft))
-        return VINF_SUCCESS;
+
+    if (pCursor->fFlags & RTASN1CURSOR_FLAGS_INDEFINITE_LENGTH)
+    {
+        /*
+         * If we've got two zeros here we're good.  This helps us handle apple code
+         * signatures, where most of the big structures are of indefinite length.
+         * The problem here is when rtCrPkcs7ContentInfo_DecodeExtra works the
+         * octet string, it appears as if there extra padding at the end.
+         *
+         * It is of course possible that ASN.1 assumes we will parse the content of
+         * that octet string as if it were an ASN.1 substructure, looking for the
+         * end-of-content sequence and propage that up.  However, this works for now.
+         */
+        if (pCursor->cbLeft >= 2)
+        {
+            if (   pCursor->pbCur[0] == 0
+                && pCursor->pbCur[1] == 0)
+                return VINF_SUCCESS;
+            return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_NOT_AT_END,
+                                       "%u (%#x) bytes left over [indef: %.*Rhxs]",
+                                       pCursor->cbLeft, pCursor->cbLeft, RT_MIN(pCursor->cbLeft, 16), pCursor->pbCur);
+        }
+        return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_NOT_AT_END,
+                                   "%u (%#x) bytes left over [indef len]", pCursor->cbLeft, pCursor->cbLeft);
+    }
     return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_NOT_AT_END,
                                "%u (%#x) bytes left over", pCursor->cbLeft, pCursor->cbLeft);
+}
+
+
+/**
+ * Worker for RTAsn1CursorCheckSeqEnd and RTAsn1CursorCheckSetEnd.
+ */
+static int rtAsn1CursorCheckSeqOrSetEnd(PRTASN1CURSOR pCursor, PRTASN1CORE pAsn1Core)
+{
+    if (pCursor->cbLeft == 0)
+        return VINF_SUCCESS;
+
+    if (pAsn1Core->fFlags & RTASN1CORE_F_INDEFINITE_LENGTH)
+    {
+        if (pCursor->cbLeft >= 2)
+        {
+            if (   pCursor->pbCur[0] == 0
+                && pCursor->pbCur[1] == 0)
+            {
+                pAsn1Core->cb = (uint32_t)(pCursor->pbCur - pAsn1Core->uData.pu8);
+                pCursor->cbLeft -= 2;
+                pCursor->pbCur  += 2;
+
+                PRTASN1CURSOR pParentCursor = pCursor->pUp;
+                if (   pParentCursor
+                    && (pParentCursor->fFlags & RTASN1CURSOR_FLAGS_INDEFINITE_LENGTH))
+                {
+                    pParentCursor->pbCur  -= pCursor->cbLeft;
+                    pParentCursor->cbLeft += pCursor->cbLeft;
+                    return VINF_SUCCESS;
+                }
+
+                if (pCursor->cbLeft == 0)
+                    return VINF_SUCCESS;
+
+                return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_NOT_AT_END,
+                                           "%u (%#x) bytes left over (parent not indefinite length)", pCursor->cbLeft, pCursor->cbLeft);
+            }
+            return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_NOT_AT_END, "%u (%#x) bytes left over [indef: %.*Rhxs]",
+                                       pCursor->cbLeft, pCursor->cbLeft, RT_MIN(pCursor->cbLeft, 16), pCursor->pbCur);
+        }
+        return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_NOT_AT_END,
+                                   "1 byte left over, expected two for indefinite length end-of-content sequence");
+    }
+
+    return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_NOT_AT_END,
+                               "%u (%#x) bytes left over", pCursor->cbLeft, pCursor->cbLeft);
+
+}
+
+
+RTDECL(int) RTAsn1CursorCheckSeqEnd(PRTASN1CURSOR pCursor, PRTASN1SEQUENCECORE pSeqCore)
+{
+    return rtAsn1CursorCheckSeqOrSetEnd(pCursor, &pSeqCore->Asn1Core);
+}
+
+
+RTDECL(int) RTAsn1CursorCheckSetEnd(PRTASN1CURSOR pCursor, PRTASN1SETCORE pSetCore)
+{
+    return rtAsn1CursorCheckSeqOrSetEnd(pCursor, &pSetCore->Asn1Core);
 }
 
@@ -337,7 +416,7 @@
                 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_BAD_INDEFINITE_LENGTH,
                                            "%s: Indefinite BER/CER encoding not supported for this tag (uTag=%#x)", pszErrorTag, uTag);
-            else if (pCursor->cIndefinedRecs > 8)
+            else if (pCursor->fFlags & RTASN1CURSOR_FLAGS_INDEFINITE_LENGTH)
                 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_BAD_INDEFINITE_LENGTH,
-                                           "%s: Too many indefinite BER/CER encodings. (uTag=%#x)", pszErrorTag, uTag);
+                                           "%s: Nested indefinite BER/CER encoding. (uTag=%#x)", pszErrorTag, uTag);
             else if (pCursor->cbLeft < 2)
                 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_BAD_INDEFINITE_LENGTH,
@@ -345,10 +424,10 @@
             else
             {
-                pCursor->cIndefinedRecs++;
                 pCursor->fFlags   |= RTASN1CURSOR_FLAGS_INDEFINITE_LENGTH;
                 pAsn1Core->fFlags |= RTASN1CORE_F_INDEFINITE_LENGTH;
-                cb = pCursor->cbLeft - pCursor->cIndefinedRecs * 2; /* tentatively */
+                cb = pCursor->cbLeft - 2; /* tentatively for sequences and sets, definite for others */
             }
         }
+        /* else if (cb == 0 && uTag == 0) { end of content } - callers handle this */
 
         /* Check if the length makes sense. */
@@ -474,7 +553,8 @@
 RTDECL(int) RTAsn1CursorPeek(PRTASN1CURSOR pCursor, PRTASN1CORE pAsn1Core)
 {
-    uint32_t        cbSavedLeft = pCursor->cbLeft;
-    uint8_t const  *pbSavedCur  = pCursor->pbCur;
-    PRTERRINFO      pErrInfo    = pCursor->pPrimary->pErrInfo;
+    uint32_t            cbSavedLeft         = pCursor->cbLeft;
+    uint8_t const      *pbSavedCur          = pCursor->pbCur;
+    uint8_t const       fSavedFlags         = pCursor->fFlags;
+    PRTERRINFO const    pErrInfo            = pCursor->pPrimary->pErrInfo;
     pCursor->pPrimary->pErrInfo = NULL;
 
@@ -482,6 +562,7 @@
 
     pCursor->pPrimary->pErrInfo = pErrInfo;
-    pCursor->pbCur  = pbSavedCur;
-    pCursor->cbLeft = cbSavedLeft;
+    pCursor->pbCur              = pbSavedCur;
+    pCursor->cbLeft             = cbSavedLeft;
+    pCursor->fFlags             = fSavedFlags;
     return rc;
 }
Index: /trunk/src/VBox/Runtime/common/crypto/pkcs7-asn1-decoder.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/pkcs7-asn1-decoder.cpp	(revision 74671)
+++ /trunk/src/VBox/Runtime/common/crypto/pkcs7-asn1-decoder.cpp	(revision 74672)
@@ -90,7 +90,8 @@
     {
         /*
-         * Detect CMS octet string and open the content cursor.
-         * Current we don't have work with any contet which is octet string,
-         * they're all sequences, which make detection so much simpler.
+         * Detect CMS octet string format and open the content cursor.
+         *
+         * Current we don't have any octent string content which, they're all
+         * sequences, which make detection so much simpler.
          */
         PRTASN1OCTETSTRING  pOctetString = &pThis->Content;
Index: /trunk/src/VBox/Runtime/tools/RTSignTool.cpp
===================================================================
--- /trunk/src/VBox/Runtime/tools/RTSignTool.cpp	(revision 74671)
+++ /trunk/src/VBox/Runtime/tools/RTSignTool.cpp	(revision 74672)
@@ -629,4 +629,6 @@
                 if (cVerbosity > 2)
                     RTPrintf("PKCS#7 signature: %u bytes\n", cbActual);
+                if (cVerbosity > 3)
+                    RTPrintf("%.*Rhxd\n", cbActual, pvBuf);
 
                 /*
