bug 1357815 - 1/4: move VerifyCMSDetachedSignatureIncludingCertificate to where it's used r?jcj draft
authorDavid Keeler <dkeeler@mozilla.com>
Tue, 24 Oct 2017 13:18:14 -0700
changeset 689669 b71cd89080bb493a59d076568dd666a15bd8a572
parent 689459 0a7ff6e19bcc229500d92597fac9340d9bdef959
child 689670 f6120ea5356f123644d0d3b2c480d0ecc4190f55
push id87085
push userbmo:dkeeler@mozilla.com
push dateTue, 31 Oct 2017 21:34:47 +0000
reviewersjcj
bugs1357815
milestone58.0a1
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 {