From bd8f23ccd6c05a6440fa269146a706e046b42b65 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sun, 22 Jun 2014 18:50:22 -0700 Subject: [PATCH] Bug 1028643: Convert nsISignatureVerifier to use CertVerifier (mozilla::pkix) and move nsISignatureVerifier functionality to nsIDataSignatureVerifier, r=keeler --HG-- extra : rebase_source : 14f6f5dedd7145d574ac5b4c86b6ad42b6716ae8 extra : histedit_source : f891fbe80c4ca9fc62849bc2d6d8ffad372a6bf0 --- modules/libjar/nsJAR.cpp | 10 +- modules/libjar/nsJAR.h | 3 +- security/apps/AppSignatureVerification.cpp | 113 ++------- security/manager/ssl/public/moz.build | 1 - .../ssl/public/nsIDataSignatureVerifier.idl | 17 +- .../ssl/public/nsISignatureVerifier.idl | 30 --- .../ssl/src/nsDataSignatureVerifier.cpp | 238 +++++++++++++++++- .../manager/ssl/src/nsDataSignatureVerifier.h | 12 + security/manager/ssl/src/nsNSSComponent.cpp | 133 ---------- security/manager/ssl/src/nsNSSComponent.h | 5 +- 10 files changed, 295 insertions(+), 267 deletions(-) delete mode 100644 security/manager/ssl/public/nsISignatureVerifier.idl diff --git a/modules/libjar/nsJAR.cpp b/modules/libjar/nsJAR.cpp index 4fc562ea76dc..01aec919455e 100644 --- a/modules/libjar/nsJAR.cpp +++ b/modules/libjar/nsJAR.cpp @@ -6,8 +6,10 @@ #include "nsJARInputStream.h" #include "nsJAR.h" #include "nsIFile.h" +#include "nsICertificatePrincipal.h" #include "nsIConsoleService.h" #include "nsICryptoHash.h" +#include "nsIDataSignatureVerifier.h" #include "prprf.h" #include "mozilla/Omnijar.h" @@ -555,8 +557,8 @@ nsJAR::ParseManifest() } //-- Get the signature verifier service - nsCOMPtr verifier = - do_GetService(SIGNATURE_VERIFIER_CONTRACTID, &rv); + nsCOMPtr verifier( + do_GetService("@mozilla.org/security/datasignatureverifier;1", &rv)); if (NS_FAILED(rv)) // No signature verifier available { mGlobalStatus = JAR_NO_MANIFEST; @@ -569,9 +571,9 @@ nsJAR::ParseManifest() rv = verifier->VerifySignature(sigBuffer, sigLen, manifestBuffer, manifestLen, &verifyError, getter_AddRefs(mPrincipal)); if (NS_FAILED(rv)) return rv; - if (mPrincipal && verifyError == 0) + if (mPrincipal && verifyError == nsIDataSignatureVerifier::VERIFY_OK) mGlobalStatus = JAR_VALID_MANIFEST; - else if (verifyError == nsISignatureVerifier::VERIFY_ERROR_UNKNOWN_CA) + else if (verifyError == nsIDataSignatureVerifier::VERIFY_ERROR_UNKNOWN_ISSUER) mGlobalStatus = JAR_INVALID_UNKNOWN_CA; else mGlobalStatus = JAR_INVALID_SIG; diff --git a/modules/libjar/nsJAR.h b/modules/libjar/nsJAR.h index 495d3dbf2430..ccc425dd9a46 100644 --- a/modules/libjar/nsJAR.h +++ b/modules/libjar/nsJAR.h @@ -24,13 +24,12 @@ #include "nsTHashtable.h" #include "nsIZipReader.h" #include "nsZipArchive.h" -#include "nsICertificatePrincipal.h" -#include "nsISignatureVerifier.h" #include "nsIObserverService.h" #include "nsWeakReference.h" #include "nsIObserver.h" #include "mozilla/Attributes.h" +class nsICertificatePrincipal; class nsIInputStream; class nsJARManifestItem; class nsZipReaderCache; diff --git a/security/apps/AppSignatureVerification.cpp b/security/apps/AppSignatureVerification.cpp index 50f54d50fb75..2a7d9e37250e 100644 --- a/security/apps/AppSignatureVerification.cpp +++ b/security/apps/AppSignatureVerification.cpp @@ -16,6 +16,7 @@ #include "AppTrustDomain.h" #include "nsComponentManagerUtils.h" #include "nsCOMPtr.h" +#include "nsDataSignatureVerifier.h" #include "nsHashKeys.h" #include "nsIFile.h" #include "nsIInputStream.h" @@ -522,85 +523,23 @@ ParseMF(const char* filebuf, nsIZipReader * zip, return NS_OK; } +struct VerifyCertificateContext { + AppTrustedRoot trustedRoot; + mozilla::pkix::ScopedCERTCertList& builtChain; +}; + nsresult -VerifySignature(AppTrustedRoot trustedRoot, - const SECItem& buffer, const SECItem& detachedDigest, - /*out*/ mozilla::pkix::ScopedCERTCertList& builtChain) +VerifyCertificate(CERTCertificate* signerCert, void* voidContext, void* pinArg) { - mozilla::pkix::ScopedPtr - cmsMsg(NSS_CMSMessage_CreateFromDER(const_cast(&buffer), nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr)); - if (!cmsMsg) { - return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING; + // TODO: null pinArg is tolerated. + if (NS_WARN_IF(!signerCert) || NS_WARN_IF(!voidContext)) { + return NS_ERROR_INVALID_ARG; } + const VerifyCertificateContext& context = + *reinterpret_cast(voidContext); - if (!NSS_CMSMessage_IsSigned(cmsMsg.get())) { - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CMS message isn't signed")); - 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; - } - - // signedData is non-owning - NSSCMSSignedData* signedData = - reinterpret_cast(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(&detachedDigest))) { - return NS_ERROR_CMS_VERIFY_BAD_DIGEST; - } - - // Parse the certificates into CERTCertificate objects held in memory, so that - // AppTrustDomain will be able to find them during path building. - mozilla::pkix::ScopedCERTCertList certs(CERT_NewCertList()); - if (!certs) { - return NS_ERROR_OUT_OF_MEMORY; - } - if (signedData->rawCerts) { - for (size_t i = 0; signedData->rawCerts[i]; ++i) { - mozilla::pkix::ScopedCERTCertificate - cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(), - signedData->rawCerts[i], nullptr, false, - true)); - // Skip certificates that fail to parse - if (cert) { - if (CERT_AddCertToListTail(certs.get(), cert.get()) == SECSuccess) { - cert.release(); // ownership transfered - } else { - return NS_ERROR_OUT_OF_MEMORY; - } - } - } - } - - // 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; - } - // cert is signerCert - CERTCertificate* signerCert = - NSS_CMSSignerInfo_GetSigningCertificate(signer, CERT_GetDefaultCertDB()); - if (!signerCert) { - return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING; - } - - // Verify certificate. - AppTrustDomain trustDomain(nullptr); // TODO: null pinArg - if (trustDomain.SetTrustedRoot(trustedRoot) != SECSuccess) { + AppTrustDomain trustDomain(pinArg); + if (trustDomain.SetTrustedRoot(context.trustedRoot) != SECSuccess) { return MapSECStatus(SECFailure); } if (BuildCertChain(trustDomain, signerCert, PR_Now(), @@ -608,21 +547,23 @@ VerifySignature(AppTrustedRoot trustedRoot, KeyUsage::digitalSignature, KeyPurposeId::id_kp_codeSigning, CertPolicyId::anyPolicy, - nullptr, builtChain) - != SECSuccess) { + nullptr, context.builtChain) != SECSuccess) { return MapSECStatus(SECFailure); } - // 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 NS_OK; +} - return MapSECStatus(NSS_CMSSignerInfo_Verify(signer, - const_cast(&detachedDigest), - &contentTypeOidData->oid)); +nsresult +VerifySignature(AppTrustedRoot trustedRoot, const SECItem& buffer, + const SECItem& detachedDigest, + /*out*/ mozilla::pkix::ScopedCERTCertList& builtChain) +{ + VerifyCertificateContext context = { trustedRoot, builtChain }; + // XXX: missing pinArg + return VerifyCMSDetachedSignatureIncludingCertificate(buffer, detachedDigest, + VerifyCertificate, + &context, nullptr); } NS_IMETHODIMP diff --git a/security/manager/ssl/public/moz.build b/security/manager/ssl/public/moz.build index 29237ee19705..f3fd5dacf19e 100644 --- a/security/manager/ssl/public/moz.build +++ b/security/manager/ssl/public/moz.build @@ -32,7 +32,6 @@ XPIDL_SOURCES += [ 'nsIPKCS11Slot.idl', 'nsIProtectedAuthThread.idl', 'nsIRecentBadCertsService.idl', - 'nsISignatureVerifier.idl', 'nsISSLErrorListener.idl', 'nsISSLStatus.idl', 'nsIStreamCipher.idl', diff --git a/security/manager/ssl/public/nsIDataSignatureVerifier.idl b/security/manager/ssl/public/nsIDataSignatureVerifier.idl index 8e4cb47973de..6ec46849ef5b 100644 --- a/security/manager/ssl/public/nsIDataSignatureVerifier.idl +++ b/security/manager/ssl/public/nsIDataSignatureVerifier.idl @@ -5,11 +5,14 @@ #include "nsISupports.idl" +// NB: This isn't actually a principal at all. The naming is just historical. +interface nsICertificatePrincipal; + /** * An interface for verifying that a given string of data was signed by the * private key matching the given public key. */ -[scriptable, uuid(0a84b3d5-6ba9-432d-89da-4fbd0b0f2aec)] +[scriptable, uuid(577f097f-15e4-4043-bc0e-6d2fadcacae2)] interface nsIDataSignatureVerifier : nsISupports { /** @@ -23,4 +26,16 @@ interface nsIDataSignatureVerifier : nsISupports * @returns true if the signature matches the data, false if not. */ boolean verifyData(in ACString aData, in ACString aSignature, in ACString aPublicKey); + + /* Sig Verification Error Codes */ + const long VERIFY_OK = 0; + const long VERIFY_ERROR_UNKNOWN_ISSUER = 1; + const long VERIFY_ERROR_OTHER = 2; + + nsICertificatePrincipal verifySignature(in string aSignature, + in unsigned long aSignatureLen, + in string plaintext, + in unsigned long plaintextLen, + out long errorCode); + }; diff --git a/security/manager/ssl/public/nsISignatureVerifier.idl b/security/manager/ssl/public/nsISignatureVerifier.idl deleted file mode 100644 index 340522496e40..000000000000 --- a/security/manager/ssl/public/nsISignatureVerifier.idl +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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/. */ - -/* An interface for verifying signatures */ - -#include "nsISupports.idl" - -// NB: This isn't actually a principal at all. The naming is just historical. -interface nsICertificatePrincipal; - -[uuid(22870b07-b5ef-481b-9f7f-d41787d4e617)] -interface nsISignatureVerifier : nsISupports -{ - /* Sig Verification Error Codes */ - const long VERIFY_OK = 0; - const long VERIFY_ERROR_UNKNOWN_CA = -8172; /* -8172 is the error code returned by PSM */ - - nsICertificatePrincipal verifySignature(in string aSignature, - in unsigned long aSignatureLen, - in string plaintext, - in unsigned long plaintextLen, - out long errorCode); -}; - - -%{C++ -#define SIGNATURE_VERIFIER_CONTRACTID "@mozilla.org/psm;1" -%} diff --git a/security/manager/ssl/src/nsDataSignatureVerifier.cpp b/security/manager/ssl/src/nsDataSignatureVerifier.cpp index 5215de24be96..71f9b4070e06 100644 --- a/security/manager/ssl/src/nsDataSignatureVerifier.cpp +++ b/security/manager/ssl/src/nsDataSignatureVerifier.cpp @@ -3,14 +3,22 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsDataSignatureVerifier.h" -#include "nsCOMPtr.h" -#include "nsString.h" -#include "seccomon.h" -#include "nssb64.h" -#include "certt.h" -#include "keyhi.h" +#include "cms.h" #include "cryptohi.h" +#include "keyhi.h" +#include "nsCertificatePrincipal.h" +#include "nsCOMPtr.h" +#include "nsNSSComponent.h" +#include "nssb64.h" +#include "pkix/pkixtypes.h" +#include "ScopedNSSTypes.h" +#include "secerr.h" +#include "SharedCertVerifier.h" + +using namespace mozilla; +using namespace mozilla::pkix; +using namespace mozilla::psm; SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) @@ -104,3 +112,221 @@ nsDataSignatureVerifier::VerifyData(const nsACString & aData, 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) +{ + // 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; + } + + ScopedPtr + cmsMsg(NSS_CMSMessage_CreateFromDER(const_cast(&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; + } + + // signedData is non-owning + NSSCMSSignedData* signedData = + reinterpret_cast(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(&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. + mozilla::pkix::ScopedCERTCertList certs(CERT_NewCertList()); + if (!certs) { + return NS_ERROR_OUT_OF_MEMORY; + } + if (signedData->rawCerts) { + for (size_t i = 0; signedData->rawCerts[i]; ++i) { + mozilla::pkix::ScopedCERTCertificate + cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(), + signedData->rawCerts[i], nullptr, false, + true)); + // Skip certificates that fail to parse + if (cert) { + if (CERT_AddCertToListTail(certs.get(), cert.get()) == SECSuccess) { + cert.release(); // ownership transfered + } else { + return NS_ERROR_OUT_OF_MEMORY; + } + } + } + } + + // 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(&detachedDigest), + &contentTypeOidData->oid)); +} + +} // namespace mozilla + +namespace { + +struct VerifyCertificateContext +{ + nsCOMPtr principal; + mozilla::pkix::ScopedCERTCertList builtChain; +}; + +static nsresult +VerifyCertificate(CERTCertificate* cert, void* voidContext, void* pinArg) +{ + // XXX: missing pinArg is tolerated + if (NS_WARN_IF(!cert) || NS_WARN_IF(!voidContext)) { + return NS_ERROR_INVALID_ARG; + } + + VerifyCertificateContext* context = + reinterpret_cast(voidContext); + + nsCOMPtr xpcomCert(nsNSSCertificate::Create(cert)); + if (!xpcomCert) { + return NS_ERROR_OUT_OF_MEMORY; + } + + nsAutoString fingerprint; + nsresult rv = xpcomCert->GetSha1Fingerprint(fingerprint); + if (NS_FAILED(rv)) { + return rv; + } + nsAutoString orgName; + rv = xpcomCert->GetOrganization(orgName); + if (NS_FAILED(rv)) { + return rv; + } + nsAutoString subjectName; + rv = xpcomCert->GetSubjectName(subjectName); + if (NS_FAILED(rv)) { + return rv; + } + + context->principal = + new nsCertificatePrincipal(NS_ConvertUTF16toUTF8(fingerprint), + NS_ConvertUTF16toUTF8(subjectName), + NS_ConvertUTF16toUTF8(orgName), + xpcomCert); + + RefPtr certVerifier(GetDefaultCertVerifier()); + NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED); + + return MapSECStatus(certVerifier->VerifyCert(cert, + certificateUsageObjectSigner, + PR_Now(), pinArg, + nullptr, // hostname + 0, // flags + nullptr, // stapledOCSPResponse + &context->builtChain)); +} + +} // unnamed namespcae + +NS_IMETHODIMP +nsDataSignatureVerifier::VerifySignature(const char* aRSABuf, + uint32_t aRSABufLen, + const char* aPlaintext, + uint32_t aPlaintextLen, + int32_t* aErrorCode, + nsICertificatePrincipal** aPrincipal) +{ + if (!aPlaintext || !aPrincipal || !aErrorCode) { + return NS_ERROR_INVALID_ARG; + } + + *aErrorCode = VERIFY_ERROR_OTHER; + *aPrincipal = nullptr; + + nsNSSShutDownPreventionLock locker; + + Digest digest; + nsresult rv = digest.DigestBuf(SEC_OID_SHA1, + reinterpret_cast(aPlaintext), + aPlaintextLen); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + SECItem buffer = { + siBuffer, + reinterpret_cast(const_cast(aRSABuf)), + aRSABufLen + }; + + VerifyCertificateContext context; + // XXX: pinArg is missing + rv = VerifyCMSDetachedSignatureIncludingCertificate(buffer, digest.get(), + VerifyCertificate, + &context, nullptr); + if (NS_SUCCEEDED(rv)) { + *aErrorCode = VERIFY_OK; + } else if (NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_SECURITY) { + if (rv == GetXPCOMFromNSSError(SEC_ERROR_UNKNOWN_ISSUER)) { + *aErrorCode = VERIFY_ERROR_UNKNOWN_ISSUER; + } else { + *aErrorCode = VERIFY_ERROR_OTHER; + } + rv = NS_OK; + } + if (rv == NS_OK) { + context.principal.forget(aPrincipal); + } + + return rv; +} diff --git a/security/manager/ssl/src/nsDataSignatureVerifier.h b/security/manager/ssl/src/nsDataSignatureVerifier.h index 109004c65508..f3bfef8c4e0e 100644 --- a/security/manager/ssl/src/nsDataSignatureVerifier.h +++ b/security/manager/ssl/src/nsDataSignatureVerifier.h @@ -10,6 +10,8 @@ #include "keythi.h" +typedef struct CERTCertificateStr CERTCertificate; + // 296d76aa-275b-4f3c-af8a-30a4026c18fc #define NS_DATASIGNATUREVERIFIER_CID \ { 0x296d76aa, 0x275b, 0x4f3c, \ @@ -33,4 +35,14 @@ private: } }; +namespace mozilla { + +nsresult VerifyCMSDetachedSignatureIncludingCertificate( + const SECItem& buffer, const SECItem& detachedDigest, + nsresult (*verifyCertificate)(CERTCertificate* cert, void* context, + void* pinArg), + void* verifyCertificateContext, void* pinArg); + +} // namespace mozilla + #endif // _NS_DATASIGNATUREVERIFIER_H_ diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index 6e7f3357ee5a..31d68109e881 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -33,7 +33,6 @@ #include "nsIDOMSmartCardEvent.h" #include "nsSmartCardMonitor.h" #include "nsIDOMCryptoLegacy.h" -#include "nsIPrincipal.h" #else #include "nsIDOMCrypto.h" #endif @@ -44,7 +43,6 @@ #include "nsIProperties.h" #include "nsIWindowWatcher.h" #include "nsIPrompt.h" -#include "nsCertificatePrincipal.h" #include "nsIBufEntropyCollector.h" #include "nsITokenPasswordDialogs.h" #include "nsServiceManagerUtils.h" @@ -57,7 +55,6 @@ #include "ssl.h" #include "sslproto.h" #include "secmod.h" -#include "secmime.h" #include "secerr.h" #include "sslerr.h" @@ -1357,141 +1354,11 @@ nsNSSComponent::Init() // nsISupports Implementation for the class NS_IMPL_ISUPPORTS(nsNSSComponent, - nsISignatureVerifier, nsIEntropyCollector, nsINSSComponent, nsIObserver, nsISupportsWeakReference) - -// Callback functions for decoder. For now, use empty/default functions. -static void -ContentCallback(void* arg, const char* buf, unsigned long len) -{ -} - -static PK11SymKey* -GetDecryptKeyCallback(void* arg, SECAlgorithmID* algid) -{ - return nullptr; -} - -static PRBool -DecryptionAllowedCallback(SECAlgorithmID* algid, PK11SymKey* bulkkey) -{ - return SECMIME_DecryptionAllowed(algid, bulkkey); -} - -static void* -GetPasswordKeyCallback(void* arg, void* handle) -{ - return nullptr; -} - -NS_IMETHODIMP -nsNSSComponent::VerifySignature(const char* aRSABuf, uint32_t aRSABufLen, - const char* aPlaintext, uint32_t aPlaintextLen, - int32_t* aErrorCode, - nsICertificatePrincipal** aPrincipal) -{ - if (!aPrincipal || !aErrorCode) { - return NS_ERROR_NULL_POINTER; - } - - *aErrorCode = 0; - *aPrincipal = nullptr; - - nsNSSShutDownPreventionLock locker; - ScopedSEC_PKCS7ContentInfo p7_info; - unsigned char hash[SHA1_LENGTH]; - - SECItem item; - item.type = siEncodedCertBuffer; - item.data = (unsigned char*)aRSABuf; - item.len = aRSABufLen; - p7_info = SEC_PKCS7DecodeItem(&item, - ContentCallback, nullptr, - GetPasswordKeyCallback, nullptr, - GetDecryptKeyCallback, nullptr, - DecryptionAllowedCallback); - - if (!p7_info) { - return NS_ERROR_FAILURE; - } - - // Make sure we call SEC_PKCS7DestroyContentInfo after this point; - // otherwise we leak data in p7_info - - //-- If a plaintext was provided, hash it. - SECItem digest; - digest.data = nullptr; - digest.len = 0; - - if (aPlaintext) { - HASHContext* hash_ctxt; - uint32_t hashLen = 0; - - hash_ctxt = HASH_Create(HASH_AlgSHA1); - HASH_Begin(hash_ctxt); - HASH_Update(hash_ctxt,(const unsigned char*)aPlaintext, aPlaintextLen); - HASH_End(hash_ctxt, hash, &hashLen, SHA1_LENGTH); - HASH_Destroy(hash_ctxt); - - digest.data = hash; - digest.len = SHA1_LENGTH; - } - - //-- Verify signature - bool rv = SEC_PKCS7VerifyDetachedSignature(p7_info, certUsageObjectSigner, - &digest, HASH_AlgSHA1, false); - if (!rv) { - *aErrorCode = PR_GetError(); - } - - // Get the signing cert // - CERTCertificate* cert = p7_info->content.signedData->signerInfos[0]->cert; - nsresult rv2 = NS_OK; - if (cert) { - // Use |do { } while (0);| as a "more C++-ish" thing than goto; - // this way we don't have to worry about goto across variable - // declarations. We have no loops in this code, so it's OK. - do { - nsCOMPtr pCert = nsNSSCertificate::Create(cert); - if (!pCert) { - rv2 = NS_ERROR_OUT_OF_MEMORY; - break; - } - - //-- Create a certificate principal with id and organization data - nsAutoString fingerprint; - rv2 = pCert->GetSha1Fingerprint(fingerprint); - if (NS_FAILED(rv2)) { - break; - } - nsAutoString orgName; - rv2 = pCert->GetOrganization(orgName); - if (NS_FAILED(rv2)) { - break; - } - nsAutoString subjectName; - rv2 = pCert->GetSubjectName(subjectName); - if (NS_FAILED(rv2)) { - break; - } - - nsCOMPtr certPrincipal = - new nsCertificatePrincipal(NS_ConvertUTF16toUTF8(fingerprint), - NS_ConvertUTF16toUTF8(subjectName), - NS_ConvertUTF16toUTF8(orgName), - pCert); - - certPrincipal.swap(*aPrincipal); - } while (0); - } - - return rv2; -} - NS_IMETHODIMP nsNSSComponent::RandomUpdate(void* entropy, int32_t bufLen) { diff --git a/security/manager/ssl/src/nsNSSComponent.h b/security/manager/ssl/src/nsNSSComponent.h index 2aa31ded658d..468251aa891d 100644 --- a/security/manager/ssl/src/nsNSSComponent.h +++ b/security/manager/ssl/src/nsNSSComponent.h @@ -10,7 +10,6 @@ #include "mozilla/Mutex.h" #include "mozilla/RefPtr.h" #include "nsCOMPtr.h" -#include "nsISignatureVerifier.h" #include "nsIEntropyCollector.h" #include "nsIStringBundle.h" #include "nsIObserver.h" @@ -113,8 +112,7 @@ class nsNSSShutDownList; class nsCertVerificationThread; // Implementation of the PSM component interface. -class nsNSSComponent : public nsISignatureVerifier, - public nsIEntropyCollector, +class nsNSSComponent : public nsIEntropyCollector, public nsINSSComponent, public nsIObserver, public nsSupportsWeakReference @@ -127,7 +125,6 @@ public: nsNSSComponent(); NS_DECL_THREADSAFE_ISUPPORTS - NS_DECL_NSISIGNATUREVERIFIER NS_DECL_NSIENTROPYCOLLECTOR NS_DECL_NSIOBSERVER