bug 1277240 - don't import trust anchors in SaveIntermediateCerts r?Cykesiopka draft
authorDavid Keeler <dkeeler@mozilla.com>
Thu, 02 Jun 2016 13:17:14 -0700
changeset 375241 ee8355cae291faf01eb96982bba037f221e0039a
parent 374456 92e0c73391e71a400e2c6674bca5ca70804ab081
child 522794 b82bdcfe80652fa80bf845d4c0ceb80505233d37
push id20197
push userbmo:dkeeler@mozilla.com
push dateFri, 03 Jun 2016 18:27:34 +0000
reviewersCykesiopka
bugs1277240
milestone49.0a1
bug 1277240 - don't import trust anchors in SaveIntermediateCerts r?Cykesiopka MozReview-Commit-ID: KHwA2LJSeUS
security/certverifier/NSSCertDBTrustDomain.cpp
--- a/security/certverifier/NSSCertDBTrustDomain.cpp
+++ b/security/certverifier/NSSCertDBTrustDomain.cpp
@@ -1094,16 +1094,25 @@ DefaultServerNicknameForCert(const CERTC
     if (!conflict) {
       return NS_OK;
     }
   }
 
   return NS_ERROR_FAILURE;
 }
 
+/**
+ * Given a list of certificates representing a verified certificate path from an
+ * end-entity certificate to a trust anchor, imports the intermediate
+ * certificates into the permanent certificate database. This is an attempt to
+ * cope with misconfigured servers that don't include the appropriate
+ * intermediate certificates in the TLS handshake.
+ *
+ * @param certList the verified certificate list
+ */
 void
 SaveIntermediateCerts(const UniqueCERTCertList& certList)
 {
   if (!certList) {
     return;
   }
 
   UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
@@ -1126,16 +1135,26 @@ SaveIntermediateCerts(const UniqueCERTCe
       continue;
     }
 
     if (node->cert->isperm) {
       // We don't need to remember certs already stored in perm db.
       continue;
     }
 
+    // No need to save the trust anchor - it's either already a permanent
+    // certificate or it's the Microsoft Family Safety root or an enterprise
+    // root temporarily imported via the child mode or enterprise root features.
+    // We don't want to import these because they're intended to be temporary
+    // (and because importing them happens to reset their trust settings, which
+    // breaks these features).
+    if (node == CERT_LIST_TAIL(certList)) {
+      continue;
+    }
+
     // We have found a signer cert that we want to remember.
     nsAutoCString nickname;
     nsresult rv = DefaultServerNicknameForCert(node->cert, nickname);
     if (NS_FAILED(rv)) {
       continue;
     }
 
     // Saving valid intermediate certs to the database is a compatibility hack