bug 1357815 - 1/4: move VerifyCMSDetachedSignatureIncludingCertificate to where it's used r=jcj
authorDavid Keeler <dkeeler@mozilla.com>
Tue, 24 Oct 2017 13:18:14 -0700
changeset 443125 d0104efea23b0ae7d504dca297ea3761bb5ccc7c
parent 443124 8dd4ccaed43e0e5102c35dab980c14f82c3870a4
child 443126 89b22be1685c2bb3ff3b8ff3c9f5a0e6744b8bdb
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjcj
bugs1357815
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 1357815 - 1/4: move VerifyCMSDetachedSignatureIncludingCertificate to where it's used r=jcj MozReview-Commit-ID: JsBPGhDxQoS
security/apps/AppSignatureVerification.cpp
security/manager/ssl/nsDataSignatureVerifier.cpp
security/manager/ssl/nsDataSignatureVerifier.h
security/manager/ssl/nsNSSCallbacks.cpp
--- a/security/apps/AppSignatureVerification.cpp
+++ b/security/apps/AppSignatureVerification.cpp
@@ -5,25 +5,27 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsNSSCertificateDB.h"
 
 #include "AppTrustDomain.h"
 #include "CryptoTask.h"
 #include "NSSCertDBTrustDomain.h"
 #include "ScopedNSSTypes.h"
+#include "SharedCertVerifier.h"
 #include "certdb.h"
+#include "cms.h"
 #include "mozilla/Base64.h"
 #include "mozilla/Casting.h"
 #include "mozilla/Logging.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/UniquePtr.h"
+#include "mozilla/Unused.h"
 #include "nsCOMPtr.h"
 #include "nsComponentManagerUtils.h"
-#include "nsDataSignatureVerifier.h"
 #include "nsDependentString.h"
 #include "nsHashKeys.h"
 #include "nsIDirectoryEnumerator.h"
 #include "nsIFile.h"
 #include "nsIFileStreams.h"
 #include "nsIInputStream.h"
 #include "nsIStringEnumerator.h"
 #include "nsIZipReader.h"
@@ -759,16 +761,126 @@ VerifyCertificate(CERTCertificate* signe
   if (result != Success) {
     return mozilla::psm::GetXPCOMFromNSSError(MapResultToPRErrorCode(result));
   }
 
   return NS_OK;
 }
 
 nsresult
+VerifyCMSDetachedSignatureIncludingCertificate(
+  const SECItem& buffer, const SECItem& detachedDigest,
+  nsresult (*verifyCertificate)(CERTCertificate* cert, void* context,
+                                void* pinArg),
+  void* verifyCertificateContext, void* pinArg,
+  const nsNSSShutDownPreventionLock& /*proofOfLock*/)
+{
+  // XXX: missing pinArg is tolerated.
+  if (NS_WARN_IF(!buffer.data && buffer.len > 0) ||
+      NS_WARN_IF(!detachedDigest.data && detachedDigest.len > 0) ||
+      (!verifyCertificate) ||
+      NS_WARN_IF(!verifyCertificateContext)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  UniqueNSSCMSMessage
+    cmsMsg(NSS_CMSMessage_CreateFromDER(const_cast<SECItem*>(&buffer), nullptr,
+                                        nullptr, nullptr, nullptr, nullptr,
+                                        nullptr));
+  if (!cmsMsg) {
+    return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
+  }
+
+  if (!NSS_CMSMessage_IsSigned(cmsMsg.get())) {
+    return NS_ERROR_CMS_VERIFY_NOT_SIGNED;
+  }
+
+  NSSCMSContentInfo* cinfo = NSS_CMSMessage_ContentLevel(cmsMsg.get(), 0);
+  if (!cinfo) {
+    return NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO;
+  }
+
+  // We're expecting this to be a PKCS#7 signedData content info.
+  if (NSS_CMSContentInfo_GetContentTypeTag(cinfo)
+        != SEC_OID_PKCS7_SIGNED_DATA) {
+    return NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO;
+  }
+
+  // signedData is non-owning
+  NSSCMSSignedData* signedData =
+    static_cast<NSSCMSSignedData*>(NSS_CMSContentInfo_GetContent(cinfo));
+  if (!signedData) {
+    return NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO;
+  }
+
+  // Set digest value.
+  if (NSS_CMSSignedData_SetDigestValue(signedData, SEC_OID_SHA1,
+                                       const_cast<SECItem*>(&detachedDigest))) {
+    return NS_ERROR_CMS_VERIFY_BAD_DIGEST;
+  }
+
+  // Parse the certificates into CERTCertificate objects held in memory so
+  // verifyCertificate will be able to find them during path building.
+  UniqueCERTCertList certs(CERT_NewCertList());
+  if (!certs) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+  if (signedData->rawCerts) {
+    for (size_t i = 0; signedData->rawCerts[i]; ++i) {
+      UniqueCERTCertificate
+        cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
+                                     signedData->rawCerts[i], nullptr, false,
+                                     true));
+      // Skip certificates that fail to parse
+      if (!cert) {
+        continue;
+      }
+
+      if (CERT_AddCertToListTail(certs.get(), cert.get()) != SECSuccess) {
+        return NS_ERROR_OUT_OF_MEMORY;
+      }
+
+      Unused << cert.release(); // Ownership transferred to the cert list.
+    }
+  }
+
+  // Get the end-entity certificate.
+  int numSigners = NSS_CMSSignedData_SignerInfoCount(signedData);
+  if (NS_WARN_IF(numSigners != 1)) {
+    return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
+  }
+  // signer is non-owning.
+  NSSCMSSignerInfo* signer = NSS_CMSSignedData_GetSignerInfo(signedData, 0);
+  if (NS_WARN_IF(!signer)) {
+    return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
+  }
+  CERTCertificate* signerCert =
+    NSS_CMSSignerInfo_GetSigningCertificate(signer, CERT_GetDefaultCertDB());
+  if (!signerCert) {
+    return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
+  }
+
+  nsresult rv = verifyCertificate(signerCert, verifyCertificateContext, pinArg);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  // See NSS_CMSContentInfo_GetContentTypeOID, which isn't exported from NSS.
+  SECOidData* contentTypeOidData =
+    SECOID_FindOID(&signedData->contentInfo.contentType);
+  if (!contentTypeOidData) {
+    return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
+  }
+
+  return MapSECStatus(NSS_CMSSignerInfo_Verify(signer,
+                         const_cast<SECItem*>(&detachedDigest),
+                         &contentTypeOidData->oid));
+}
+
+nsresult
 VerifySignature(AppTrustedRoot trustedRoot, const SECItem& buffer,
                 const SECItem& detachedDigest,
                 /*out*/ UniqueCERTCertList& builtChain)
 {
   // Currently, this function is only called within the CalculateResult() method
   // of CryptoTasks. As such, NSS should not be shut down at this point and the
   // CryptoTask implementation should already hold a nsNSSShutDownPreventionLock.
   // We acquire a nsNSSShutDownPreventionLock here solely to prove we did to
--- a/security/manager/ssl/nsDataSignatureVerifier.cpp
+++ b/security/manager/ssl/nsDataSignatureVerifier.cpp
@@ -1,31 +1,21 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDataSignatureVerifier.h"
 
 #include "ScopedNSSTypes.h"
-#include "SharedCertVerifier.h"
-#include "cms.h"
-#include "cryptohi.h"
-#include "keyhi.h"
 #include "mozilla/Base64.h"
-#include "mozilla/Casting.h"
-#include "mozilla/Unused.h"
 #include "nsCOMPtr.h"
-#include "nsNSSComponent.h"
 #include "nsString.h"
-#include "pkix/pkixnss.h"
-#include "pkix/pkixtypes.h"
 #include "secerr.h"
 
 using namespace mozilla;
-using namespace mozilla::pkix;
 using namespace mozilla::psm;
 
 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
 
 NS_IMPL_ISUPPORTS(nsDataSignatureVerifier, nsIDataSignatureVerifier)
 
 const SEC_ASN1Template CERT_SignatureDataTemplate[] =
 {
@@ -129,122 +119,8 @@ nsDataSignatureVerifier::VerifyData(cons
       PromiseFlatCString(aData).get()),
     aData.Length(), publicKey.get(), &(sigData.signature),
     &(sigData.signatureAlgorithm), nullptr, nullptr);
 
   *_retval = (srv == SECSuccess);
 
   return NS_OK;
 }
-
-namespace mozilla {
-
-nsresult
-VerifyCMSDetachedSignatureIncludingCertificate(
-  const SECItem& buffer, const SECItem& detachedDigest,
-  nsresult (*verifyCertificate)(CERTCertificate* cert, void* context,
-                                void* pinArg),
-  void* verifyCertificateContext, void* pinArg,
-  const nsNSSShutDownPreventionLock& /*proofOfLock*/)
-{
-  // XXX: missing pinArg is tolerated.
-  if (NS_WARN_IF(!buffer.data && buffer.len > 0) ||
-      NS_WARN_IF(!detachedDigest.data && detachedDigest.len > 0) ||
-      (!verifyCertificate) ||
-      NS_WARN_IF(!verifyCertificateContext)) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  UniqueNSSCMSMessage
-    cmsMsg(NSS_CMSMessage_CreateFromDER(const_cast<SECItem*>(&buffer), nullptr,
-                                        nullptr, nullptr, nullptr, nullptr,
-                                        nullptr));
-  if (!cmsMsg) {
-    return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
-  }
-
-  if (!NSS_CMSMessage_IsSigned(cmsMsg.get())) {
-    return NS_ERROR_CMS_VERIFY_NOT_SIGNED;
-  }
-
-  NSSCMSContentInfo* cinfo = NSS_CMSMessage_ContentLevel(cmsMsg.get(), 0);
-  if (!cinfo) {
-    return NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO;
-  }
-
-  // We're expecting this to be a PKCS#7 signedData content info.
-  if (NSS_CMSContentInfo_GetContentTypeTag(cinfo)
-        != SEC_OID_PKCS7_SIGNED_DATA) {
-    return NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO;
-  }
-
-  // signedData is non-owning
-  NSSCMSSignedData* signedData =
-    static_cast<NSSCMSSignedData*>(NSS_CMSContentInfo_GetContent(cinfo));
-  if (!signedData) {
-    return NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO;
-  }
-
-  // Set digest value.
-  if (NSS_CMSSignedData_SetDigestValue(signedData, SEC_OID_SHA1,
-                                       const_cast<SECItem*>(&detachedDigest))) {
-    return NS_ERROR_CMS_VERIFY_BAD_DIGEST;
-  }
-
-  // Parse the certificates into CERTCertificate objects held in memory so
-  // verifyCertificate will be able to find them during path building.
-  UniqueCERTCertList certs(CERT_NewCertList());
-  if (!certs) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-  if (signedData->rawCerts) {
-    for (size_t i = 0; signedData->rawCerts[i]; ++i) {
-      UniqueCERTCertificate
-        cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
-                                     signedData->rawCerts[i], nullptr, false,
-                                     true));
-      // Skip certificates that fail to parse
-      if (!cert) {
-        continue;
-      }
-
-      if (CERT_AddCertToListTail(certs.get(), cert.get()) != SECSuccess) {
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-
-      Unused << cert.release(); // Ownership transferred to the cert list.
-    }
-  }
-
-  // Get the end-entity certificate.
-  int numSigners = NSS_CMSSignedData_SignerInfoCount(signedData);
-  if (NS_WARN_IF(numSigners != 1)) {
-    return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
-  }
-  // signer is non-owning.
-  NSSCMSSignerInfo* signer = NSS_CMSSignedData_GetSignerInfo(signedData, 0);
-  if (NS_WARN_IF(!signer)) {
-    return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
-  }
-  CERTCertificate* signerCert =
-    NSS_CMSSignerInfo_GetSigningCertificate(signer, CERT_GetDefaultCertDB());
-  if (!signerCert) {
-    return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
-  }
-
-  nsresult rv = verifyCertificate(signerCert, verifyCertificateContext, pinArg);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  // See NSS_CMSContentInfo_GetContentTypeOID, which isn't exported from NSS.
-  SECOidData* contentTypeOidData =
-    SECOID_FindOID(&signedData->contentInfo.contentType);
-  if (!contentTypeOidData) {
-    return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
-  }
-
-  return MapSECStatus(NSS_CMSSignerInfo_Verify(signer,
-                         const_cast<SECItem*>(&detachedDigest),
-                         &contentTypeOidData->oid));
-}
-
-} // namespace mozilla
--- a/security/manager/ssl/nsDataSignatureVerifier.h
+++ b/security/manager/ssl/nsDataSignatureVerifier.h
@@ -1,16 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsDataSignatureVerifier_h
 #define nsDataSignatureVerifier_h
 
-#include "certt.h"
 #include "nsIDataSignatureVerifier.h"
 #include "nsNSSShutDown.h"
 
 #define NS_DATASIGNATUREVERIFIER_CID \
     { 0x296d76aa, 0x275b, 0x4f3c, \
     { 0xaf, 0x8a, 0x30, 0xa4, 0x02, 0x6c, 0x18, 0xfc } }
 #define NS_DATASIGNATUREVERIFIER_CONTRACTID \
     "@mozilla.org/security/datasignatureverifier;1"
@@ -28,20 +27,9 @@ public:
 
 private:
   ~nsDataSignatureVerifier();
 
   // Nothing to release.
   virtual void virtualDestroyNSSReference() override {}
 };
 
-namespace mozilla {
-
-nsresult VerifyCMSDetachedSignatureIncludingCertificate(
-  const SECItem& buffer, const SECItem& detachedDigest,
-  nsresult (*verifyCertificate)(CERTCertificate* cert, void* context,
-                                void* pinArg),
-  void* verifyCertificateContext, void* pinArg,
-  const nsNSSShutDownPreventionLock& proofOfLock);
-
-} // namespace mozilla
-
 #endif // nsDataSignatureVerifier_h
--- a/security/manager/ssl/nsNSSCallbacks.cpp
+++ b/security/manager/ssl/nsNSSCallbacks.cpp
@@ -30,16 +30,17 @@
 #include "nsNetUtil.h"
 #include "nsProtectedAuthThread.h"
 #include "nsProxyRelease.h"
 #include "pkix/pkixtypes.h"
 #include "ssl.h"
 #include "sslproto.h"
 
 using namespace mozilla;
+using namespace mozilla::pkix;
 using namespace mozilla::psm;
 
 extern LazyLogModule gPIPNSSLog;
 
 static void AccumulateCipherSuite(Telemetry::HistogramID probe,
                                   const SSLChannelInfo& channelInfo);
 
 namespace {