bug 1357815 - 1/4: move VerifyCMSDetachedSignatureIncludingCertificate to where it's used r?jcj
MozReview-Commit-ID: JsBPGhDxQoS
--- 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 {