From 70a3575adec56a7189be09c501087420c10ee25f Mon Sep 17 00:00:00 2001 From: David Keeler Date: Mon, 16 Apr 2018 15:19:51 -0700 Subject: [PATCH] bug 1454504 - use a more performant API to find a root certificate in CertUtils.checkCert r=kmag,mossop nsIX509Cert.issuer performs synchronous certificate verification and isn't even guaranteed to return a verified result. Luckily we can replace this with nsISSLStatus.succeededCertChain, which contains the already-verified certificate chain of the connection we're interested in. MozReview-Commit-ID: I8jPDVlUOvf --HG-- extra : rebase_source : cb426a250946aa92172a077dc9ccf708304af846 --- toolkit/modules/CertUtils.jsm | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/toolkit/modules/CertUtils.jsm b/toolkit/modules/CertUtils.jsm index fc3448d23a3e..76185cade712 100644 --- a/toolkit/modules/CertUtils.jsm +++ b/toolkit/modules/CertUtils.jsm @@ -7,6 +7,7 @@ var EXPORTED_SYMBOLS = ["CertUtils"]; const Ce = Components.Exception; ChromeUtils.import("resource://gre/modules/Services.jsm"); +const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", {}); /** * Reads a set of expected certificate attributes from preferences. The returned @@ -142,25 +143,29 @@ function checkCert(aChannel, aAllowNonBuiltInCerts, aCerts) { return; } - var cert = - aChannel.securityInfo.QueryInterface(Ci.nsISSLStatusProvider). - SSLStatus.QueryInterface(Ci.nsISSLStatus).serverCert; + let sslStatus = aChannel.securityInfo.QueryInterface(Ci.nsISSLStatusProvider) + .SSLStatus; + let cert = sslStatus.serverCert; validateCert(cert, aCerts); - if (aAllowNonBuiltInCerts === true) + if (aAllowNonBuiltInCerts === true) { return; + } - var issuerCert = cert; - while (issuerCert.issuer && !issuerCert.issuer.equals(issuerCert)) - issuerCert = issuerCert.issuer; + let certEnumerator = sslStatus.succeededCertChain.getEnumerator(); + let issuerCert = null; + for (issuerCert of XPCOMUtils.IterSimpleEnumerator(certEnumerator, + Ci.nsIX509Cert)); const certNotBuiltInErr = "Certificate issuer is not built-in."; - if (!issuerCert) + if (!issuerCert) { throw new Ce(certNotBuiltInErr, Cr.NS_ERROR_ABORT); + } - if (!issuerCert.isBuiltInRoot) + if (!issuerCert.isBuiltInRoot) { throw new Ce(certNotBuiltInErr, Cr.NS_ERROR_ABORT); + } } /**