Index: /trunk/src/VBox/Frontends/VirtualBox/src/net/UINetworkReply.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/net/UINetworkReply.cpp	(revision 57580)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/net/UINetworkReply.cpp	(revision 57581)
@@ -80,9 +80,11 @@
         uint16_t    cbEncoded;
         /** Gives the s_aCerts index this certificate is an alternative edition of,
-         * UINT16_MAX if no alternative.  This is a complication caused by VeriSign
+         * UINT8_MAX if no alternative.  This is a complication caused by VeriSign
          * reissuing certificates signed with md2WithRSAEncryption using
          * sha1WithRSAEncryption, since MD2 is comprimised.  (Public key unmodified.)
          * It has no practical meaning for the trusted root anchor use we put it to.  */
-        uint16_t    iAlternativeTo;
+        uint8_t     iAlternativeTo;
+        /** Set if mandatory. */
+        bool        fMandatory;
         /** The SHA-1 fingerprint (of the encoded data).   */
         uint8_t     abSha1[RTSHA1_HASH_SIZE];
@@ -112,5 +114,5 @@
     static int applyProxyRules(RTHTTP hHttp, const QString &strHostName, int iPort);
     static int applyRawHeaders(RTHTTP hHttp, const QList<QByteArray> &headers, const QNetworkRequest &request);
-    static uint64_t certAllFoundMask(void);
+    static bool allCertsFound(uint64_t fFoundCerts, bool fOnlyMandatory);
     static uint64_t certEntryFoundMask(uint32_t iCert);
     static bool checkCertificatesInFile(const char *pszCaCertFile);
@@ -143,4 +145,5 @@
 {
     /*[0] =*/   /* The reissued version with the SHA-1 signature. */
+/** @todo r=bird: Why do we need this certificate? Neither update.virtualbox.org nor www.virtualbox.org uses it...  ElCapitan doesn't ship this. */
     {
         /*.pszSubject =*/
@@ -148,4 +151,5 @@
         /*.cbEncoded      =*/   0x240,
         /*.iAlternativeTo =*/   1,
+        /*.fMandatory     =*/   false,
         /*.abSha1         =*/
         {
@@ -180,4 +184,5 @@
         /*.cbEncoded      =*/   0x240,
         /*.iAlternativeTo =*/   0,
+        /*.fMandatory     =*/   false,
         /*.abSha1         =*/
         {
@@ -205,5 +210,6 @@
         "CN=VeriSign Class 3 Public Primary Certification Authority - G5",
         /*.cbEncoded      =*/   0x4d7,
-        /*.iAlternativeTo =*/   UINT16_MAX,
+        /*.iAlternativeTo =*/   UINT8_MAX,
+        /*.fMandatory     =*/   true,
         /*.abSha1         =*/
         {
@@ -476,13 +482,26 @@
 
 /**
- * Calculates the 64-bit all-certs found mask.
+ * Checks if we've found all the necessary certificates or not.
  *
- * @returns 64-bit mask.
+ * @returns true if we have, false if we haven't.
+ * @param   fFoundCerts         The mask of found certificates (see
+ *                              certEntryFoundMask).
+ * @param   fOnlyMandatory      Only require mandatory certificates to be
+ *                              present.  If false, all certificates must be
+ *                              found before we return true.
  */
-/*static*/ uint64_t
-UINetworkReplyPrivateThread::certAllFoundMask()
+/*static*/ bool
+UINetworkReplyPrivateThread::allCertsFound(uint64_t fFoundCerts, bool fOnlyMandatory)
 {
     AssertCompile(RT_ELEMENTS(s_aCerts) < 64);
-    return RT_BIT_64(RT_ELEMENTS(s_aCerts)) - UINT64_C(1);
+
+    /* Add non-mandatory flags before comparing. */
+    if (   fOnlyMandatory
+        && fFoundCerts != RT_BIT_64(RT_ELEMENTS(s_aCerts)) - UINT64_C(1))
+        for (uint32_t i = 0; i < RT_ELEMENTS(s_aCerts); i++)
+            if (!s_aCerts[i].fMandatory)
+                fFoundCerts |= RT_BIT_64(i);
+
+    return fFoundCerts == RT_BIT_64(RT_ELEMENTS(s_aCerts)) - UINT64_C(1);
 }
 
@@ -503,6 +522,6 @@
      *         the public key once.
      */
-    uint16_t iAlt = s_aCerts[iCert].iAlternativeTo;
-    if (iAlt != UINT16_MAX)
+    uint8_t iAlt = s_aCerts[iCert].iAlternativeTo;
+    if (iAlt != UINT8_MAX)
     {
         unsigned cMax = 10;
@@ -582,5 +601,5 @@
          * Did we locate all of them?
          */
-        if (fFoundCerts == certAllFoundMask())
+        if (allCertsFound(fFoundCerts, true /* fOnlyMandatory */)) /** @todo combine the two certificate retrieval approaches */
             return true;
     }
@@ -635,5 +654,5 @@
                 }
             RTHttpFreeResponse(pvRootsZip);
-            if (fFoundCerts == certAllFoundMask())
+            if (allCertsFound(fFoundCerts, false /* fOnlyMandatory */))
                 break;
         }
@@ -643,5 +662,5 @@
      * Fallback: Try download certificates separately.
      */
-    if (fFoundCerts != certAllFoundMask())
+    if (allCertsFound(fFoundCerts, false /* fOnlyMandatory */))
         for (uint32_t i = 0; i < RT_ELEMENTS(s_aCerts); i++)
             if (!(fFoundCerts & RT_BIT_64(i)))
@@ -667,5 +686,5 @@
      * See if we've got the certificates we want, save it we do.
      */
-    if (fFoundCerts == certAllFoundMask())
+    if (allCertsFound(fFoundCerts, true /*fOnlyMandatory*/))
         rc = RTCrStoreCertExportAsPem(hStore, 0 /*fFlags*/, pszCaCertFile);
     else if (RT_SUCCESS(rc))
