From 10241f928cd6f00eba012e511450e37347c898e0 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Mon, 22 Oct 2012 08:29:56 +0200 Subject: [PATCH] Bug 789224 - Separate certificate principals out from CAPS. r=dveditz There's no longer any reason why "certificate principals" need to be principals at all. I tried to rip them out entirely, but it looks like they're still used vestigially at XPI install time to display author information. But there's no reason that they have to be porkbarreled into the security-critical objects that we pass around all over the place. So let's make them their own deal. I was tempted to call them "certificate holders", but that would involve renaming methods and cause more compat fuss than necessary. --HG-- rename : caps/idl/nsISignatureVerifier.idl => security/manager/ssl/public/nsISignatureVerifier.idl --- caps/idl/Makefile.in | 1 - caps/idl/nsIPrincipal.idl | 61 +---- caps/idl/nsIScriptSecurityManager.idl | 15 -- caps/include/nsPrincipal.h | 50 +--- caps/include/nsScriptSecurityManager.h | 13 - caps/src/nsNullPrincipal.cpp | 32 --- caps/src/nsPrincipal.cpp | 253 +----------------- caps/src/nsScriptSecurityManager.cpp | 50 +--- caps/src/nsSystemPrincipal.cpp | 32 --- ipc/testshell/XPCShellEnvironment.cpp | 12 - js/xpconnect/shell/xpcshell.cpp | 12 - modules/libjar/nsIZipReader.idl | 6 +- modules/libjar/nsJAR.cpp | 2 +- modules/libjar/nsJAR.h | 4 +- security/manager/ssl/public/Makefile.in | 2 + .../ssl/public/nsICertificatePrincipal.idl | 33 +++ .../ssl/public}/nsISignatureVerifier.idl | 18 +- security/manager/ssl/src/Makefile.in | 1 + .../ssl/src/nsCertificatePrincipal.cpp | 67 +++++ .../manager/ssl/src/nsCertificatePrincipal.h | 38 +++ security/manager/ssl/src/nsNSSComponent.cpp | 20 +- 21 files changed, 185 insertions(+), 537 deletions(-) create mode 100644 security/manager/ssl/public/nsICertificatePrincipal.idl rename {caps/idl => security/manager/ssl/public}/nsISignatureVerifier.idl (53%) create mode 100644 security/manager/ssl/src/nsCertificatePrincipal.cpp create mode 100644 security/manager/ssl/src/nsCertificatePrincipal.h diff --git a/caps/idl/Makefile.in b/caps/idl/Makefile.in index f29091516f71..055ed0131e07 100644 --- a/caps/idl/Makefile.in +++ b/caps/idl/Makefile.in @@ -16,7 +16,6 @@ GRE_MODULE = 1 XPIDLSRCS = \ nsIScriptSecurityManager.idl \ nsIPrincipal.idl \ - nsISignatureVerifier.idl \ nsISecurityCheckedComponent.idl \ $(NULL) diff --git a/caps/idl/nsIPrincipal.idl b/caps/idl/nsIPrincipal.idl index 20a2aaf60b87..538b5be18a2e 100644 --- a/caps/idl/nsIPrincipal.idl +++ b/caps/idl/nsIPrincipal.idl @@ -26,8 +26,8 @@ interface nsIPrincipal : nsISerializable { /** * Returns whether the other principal is equivalent to this principal. - * Principals are considered equal if they are the same principal, - * they have the same origin, or have the same certificate fingerprint ID + * Principals are considered equal if they are the same principal, or + * they have the same origin. */ boolean equals(in nsIPrincipal other); @@ -78,34 +78,10 @@ interface nsIPrincipal : nsISerializable // with a chrome URI. All of chrome should probably be the same. readonly attribute string origin; - /** - * Whether this principal is associated with a certificate. - */ - readonly attribute boolean hasCertificate; - - /** - * The fingerprint ID of this principal's certificate. - * Throws if there is no certificate associated with this principal. - */ - // XXXcaa kaie says this may not be unique. We should probably - // consider using something else for this.... - readonly attribute AUTF8String fingerprint; - - /** - * The pretty name for the certificate. This sort of (but not really) - * identifies the subject of the certificate (the entity that stands behind - * the certificate). Note that this may be empty; prefer to get the - * certificate itself and get this information from it, since that may - * provide more information. - * - * Throws if there is no certificate associated with this principal. - */ - readonly attribute AUTF8String prettyName; - /** * Returns whether the other principal is equal to or weaker than this - * principal. Principals are equal if they are the same object, they - * have the same origin, or they have the same certificate ID. + * principal. Principals are equal if they are the same object or they + * have the same origin. * * Thus a principal always subsumes itself. * @@ -115,18 +91,6 @@ interface nsIPrincipal : nsISerializable * privileged, security context) is not equal to any other principal * (including other null principals), and therefore does not subsume * anything but itself. - * - * Both codebase and certificate principals are subsumed by the system - * principal, but no codebase or certificate principal yet subsumes any - * other codebase or certificate principal. This may change in a future - * release; note that nsIPrincipal is unfrozen, not slated to be frozen. - * - * XXXbz except see bug 147145! - * - * Note for the future: Perhaps we should consider a certificate principal - * for a given URI subsuming a codebase principal for the same URI? Not - * sure what the immediate benefit would be, but I think the setup could - * make some code (e.g. MaybeDowngradeToCodebase) clearer. */ boolean subsumes(in nsIPrincipal other); @@ -169,23 +133,6 @@ interface nsIPrincipal : nsISerializable void checkMayLoad(in nsIURI uri, in boolean report, in boolean allowIfInheritsPrincipal); - /** - * The subject name for the certificate. This actually identifies the - * subject of the certificate. This may well not be a string that would - * mean much to a typical user on its own (e.g. it may have a number of - * different names all concatenated together with some information on what - * they mean in between). - * - * Throws if there is no certificate associated with this principal. - */ - readonly attribute AUTF8String subjectName; - - /** - * The certificate associated with this principal, if any. If there isn't - * one, this will return null. Getting this attribute never throws. - */ - readonly attribute nsISupports certificate; - /** * A Content Security Policy associated with this principal. */ diff --git a/caps/idl/nsIScriptSecurityManager.idl b/caps/idl/nsIScriptSecurityManager.idl index a00f9f56139d..fa80fbce9a63 100644 --- a/caps/idl/nsIScriptSecurityManager.idl +++ b/caps/idl/nsIScriptSecurityManager.idl @@ -135,21 +135,6 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager */ nsIPrincipal getSystemPrincipal(); - /** - * Return a principal with the specified certificate fingerprint, subject - * name (the full name or concatenated set of names of the entity - * represented by the certificate), pretty name, certificate, and - * codebase URI. The certificate fingerprint and subject name MUST be - * nonempty; otherwise an error will be thrown. Similarly, aCert must - * not be null. - */ - [noscript] nsIPrincipal - getCertificatePrincipal(in AUTF8String aCertFingerprint, - in AUTF8String aSubjectName, - in AUTF8String aPrettyName, - in nsISupports aCert, - in nsIURI aURI); - /** * Return a principal that has the same origin as aURI. * This principals should not be used for any data/permission check, it will diff --git a/caps/include/nsPrincipal.h b/caps/include/nsPrincipal.h index ef4dbf0922fa..46023cdd8a15 100644 --- a/caps/include/nsPrincipal.h +++ b/caps/include/nsPrincipal.h @@ -34,62 +34,18 @@ public: NS_IMETHOD_(nsrefcnt) Release(void); NS_IMETHOD GetSecurityPolicy(void** aSecurityPolicy); NS_IMETHOD SetSecurityPolicy(void* aSecurityPolicy); - NS_IMETHOD GetHasCertificate(bool* aHasCertificate); - NS_IMETHOD GetFingerprint(nsACString& aFingerprint); - NS_IMETHOD GetPrettyName(nsACString& aPrettyName); - NS_IMETHOD GetSubjectName(nsACString& aSubjectName); - NS_IMETHOD GetCertificate(nsISupports** aCertificate); NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp); NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp); public: - // Call this to ensure that this principal has a subject name, a pretty name, - // and a cert pointer. This method will throw if there is already a - // different subject name or if this principal has no certificate. - nsresult EnsureCertData(const nsACString& aSubjectName, - const nsACString& aPrettyName, - nsISupports* aCert); - static const char sInvalid[]; protected: - // XXXcaa This is a semi-hack. The best solution here is to keep - // a reference to an interface here, except there is no interface - // that we can use yet. - struct Certificate - { - Certificate(const nsACString& aFingerprint, const nsACString& aSubjectName, - const nsACString& aPrettyName, nsISupports* aCert) - : fingerprint(aFingerprint), - subjectName(aSubjectName), - prettyName(aPrettyName), - cert(aCert) - { - } - nsCString fingerprint; - nsCString subjectName; - nsCString prettyName; - nsCOMPtr cert; - }; - - nsresult SetCertificate(const nsACString& aFingerprint, - const nsACString& aSubjectName, - const nsACString& aPrettyName, - nsISupports* aCert); - - // Checks whether this principal's certificate equals aOther's. - bool CertificateEquals(nsIPrincipal *aOther); - #ifdef DEBUG virtual void dumpImpl() = 0; #endif - // Keep this is a pointer, even though it may slightly increase the - // cost of keeping a certificate, this is a good tradeoff though since - // it is very rare that we actually have a certificate. - nsAutoPtr mCert; - DomainPolicy* mSecurityPolicy; nsCOMPtr mCSP; @@ -122,11 +78,7 @@ public: nsPrincipal(); // Init() must be called before the principal is in a usable state. - nsresult Init(const nsACString& aCertFingerprint, - const nsACString& aSubjectName, - const nsACString& aPrettyName, - nsISupports* aCert, - nsIURI* aCodebase, + nsresult Init(nsIURI* aCodebase, uint32_t aAppId, bool aInMozBrowser); diff --git a/caps/include/nsScriptSecurityManager.h b/caps/include/nsScriptSecurityManager.h index b8cb0ef9ba66..97ef38400339 100644 --- a/caps/include/nsScriptSecurityManager.h +++ b/caps/include/nsScriptSecurityManager.h @@ -443,18 +443,6 @@ private: CreateCodebasePrincipal(nsIURI* aURI, uint32_t aAppId, bool aInMozBrowser, nsIPrincipal** result); - // This is just like the API method, but it doesn't check that the subject - // name is non-empty or aCertificate is non-null, and it doesn't change the - // certificate in the table (if any) in any way if aModifyTable is false. - nsresult - DoGetCertificatePrincipal(const nsACString& aCertFingerprint, - const nsACString& aSubjectName, - const nsACString& aPrettyName, - nsISupports* aCertificate, - nsIURI* aURI, - bool aModifyTable, - nsIPrincipal **result); - // Returns null if a principal cannot be found. Note that rv can be NS_OK // when this happens -- this means that there was no script for the // context. Callers MUST pass in a non-null rv here. @@ -557,7 +545,6 @@ private: nsObjectHashtable* mCapabilities; nsCOMPtr mSystemPrincipal; - nsCOMPtr mSystemCertificate; bool mPrefInitialized; bool mIsJavaScriptEnabled; bool mIsWritingPrefs; diff --git a/caps/src/nsNullPrincipal.cpp b/caps/src/nsNullPrincipal.cpp index faff3bc73132..1064e92718e4 100644 --- a/caps/src/nsNullPrincipal.cpp +++ b/caps/src/nsNullPrincipal.cpp @@ -212,25 +212,6 @@ nsNullPrincipal::GetOrigin(char** aOrigin) return NS_OK; } -NS_IMETHODIMP -nsNullPrincipal::GetHasCertificate(bool* aResult) -{ - *aResult = false; - return NS_OK; -} - -NS_IMETHODIMP -nsNullPrincipal::GetFingerprint(nsACString& aID) -{ - return NS_ERROR_NOT_AVAILABLE; -} - -NS_IMETHODIMP -nsNullPrincipal::GetPrettyName(nsACString& aName) -{ - return NS_ERROR_NOT_AVAILABLE; -} - NS_IMETHODIMP nsNullPrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult) { @@ -276,19 +257,6 @@ nsNullPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsP return NS_ERROR_DOM_BAD_URI; } -NS_IMETHODIMP -nsNullPrincipal::GetSubjectName(nsACString& aName) -{ - return NS_ERROR_NOT_AVAILABLE; -} - -NS_IMETHODIMP -nsNullPrincipal::GetCertificate(nsISupports** aCertificate) -{ - *aCertificate = nullptr; - return NS_OK; -} - NS_IMETHODIMP nsNullPrincipal::GetExtendedOrigin(nsACString& aExtendedOrigin) { diff --git a/caps/src/nsPrincipal.cpp b/caps/src/nsPrincipal.cpp index 827bba79b34b..b6df185609ba 100644 --- a/caps/src/nsPrincipal.cpp +++ b/caps/src/nsPrincipal.cpp @@ -116,105 +116,6 @@ nsBasePrincipal::SetSecurityPolicy(void* aSecurityPolicy) return NS_OK; } -bool -nsBasePrincipal::CertificateEquals(nsIPrincipal *aOther) -{ - bool otherHasCert; - aOther->GetHasCertificate(&otherHasCert); - if (otherHasCert != (mCert != nullptr)) { - // One has a cert while the other doesn't. Not equal. - return false; - } - - if (!mCert) - return true; - - nsAutoCString str; - aOther->GetFingerprint(str); - if (!str.Equals(mCert->fingerprint)) - return false; - - // If either subject name is empty, just let the result stand, but if they're - // both non-empty, only claim equality if they're equal. - if (!mCert->subjectName.IsEmpty()) { - // Check the other principal's subject name - aOther->GetSubjectName(str); - return str.Equals(mCert->subjectName) || str.IsEmpty(); - } - - return true; -} - -NS_IMETHODIMP -nsBasePrincipal::GetHasCertificate(bool* aResult) -{ - *aResult = (mCert != nullptr); - - return NS_OK; -} - -nsresult -nsBasePrincipal::SetCertificate(const nsACString& aFingerprint, - const nsACString& aSubjectName, - const nsACString& aPrettyName, - nsISupports* aCert) -{ - NS_ENSURE_STATE(!mCert); - - if (aFingerprint.IsEmpty()) { - return NS_ERROR_INVALID_ARG; - } - - mCert = new Certificate(aFingerprint, aSubjectName, aPrettyName, aCert); - if (!mCert) { - return NS_ERROR_OUT_OF_MEMORY; - } - - return NS_OK; -} - -NS_IMETHODIMP -nsBasePrincipal::GetFingerprint(nsACString& aFingerprint) -{ - NS_ENSURE_STATE(mCert); - - aFingerprint = mCert->fingerprint; - - return NS_OK; -} - -NS_IMETHODIMP -nsBasePrincipal::GetPrettyName(nsACString& aName) -{ - NS_ENSURE_STATE(mCert); - - aName = mCert->prettyName; - - return NS_OK; -} - -NS_IMETHODIMP -nsBasePrincipal::GetSubjectName(nsACString& aName) -{ - NS_ENSURE_STATE(mCert); - - aName = mCert->subjectName; - - return NS_OK; -} - -NS_IMETHODIMP -nsBasePrincipal::GetCertificate(nsISupports** aCertificate) -{ - if (mCert) { - NS_IF_ADDREF(*aCertificate = mCert->cert); - } - else { - *aCertificate = nullptr; - } - return NS_OK; -} - NS_IMETHODIMP nsBasePrincipal::GetCsp(nsIContentSecurityPolicy** aCsp) { @@ -234,24 +135,6 @@ nsBasePrincipal::SetCsp(nsIContentSecurityPolicy* aCsp) return NS_OK; } -nsresult -nsBasePrincipal::EnsureCertData(const nsACString& aSubjectName, - const nsACString& aPrettyName, - nsISupports* aCert) -{ - NS_ENSURE_STATE(mCert); - - if (!mCert->subjectName.IsEmpty() && - !mCert->subjectName.Equals(aSubjectName)) { - return NS_ERROR_INVALID_ARG; - } - - mCert->subjectName = aSubjectName; - mCert->prettyName = aPrettyName; - mCert->cert = aCert; - return NS_OK; -} - #ifdef DEBUG void nsPrincipal::dumpImpl() { @@ -284,16 +167,12 @@ nsPrincipal::~nsPrincipal() { } nsresult -nsPrincipal::Init(const nsACString& aCertFingerprint, - const nsACString& aSubjectName, - const nsACString& aPrettyName, - nsISupports* aCert, - nsIURI *aCodebase, +nsPrincipal::Init(nsIURI *aCodebase, uint32_t aAppId, bool aInMozBrowser) { NS_ENSURE_STATE(!mInitialized); - NS_ENSURE_ARG(!aCertFingerprint.IsEmpty() || aCodebase); // better have one of these. + NS_ENSURE_ARG(aCodebase); mInitialized = true; @@ -303,20 +182,13 @@ nsPrincipal::Init(const nsACString& aCertFingerprint, mAppId = aAppId; mInMozBrowser = aInMozBrowser; - if (aCertFingerprint.IsEmpty()) - return NS_OK; - - return SetCertificate(aCertFingerprint, aSubjectName, aPrettyName, aCert); + return NS_OK; } void nsPrincipal::GetScriptLocation(nsACString &aStr) { - if (mCert) { - aStr.Assign(mCert->fingerprint); - } else { - mCodebase->GetSpec(aStr); - } + mCodebase->GetSpec(aStr); } /* static */ nsresult @@ -398,29 +270,6 @@ nsPrincipal::Equals(nsIPrincipal *aOther, bool *aResult) } if (this != aOther) { - if (!CertificateEquals(aOther)) { - *aResult = false; - return NS_OK; - } - - if (mCert) { - // If either principal has no URI, it's the saved principal from - // preferences; in that case, test true. Do NOT test true if the two - // principals have URIs with different codebases. - nsCOMPtr otherURI; - nsresult rv = aOther->GetURI(getter_AddRefs(otherURI)); - if (NS_FAILED(rv)) { - *aResult = false; - return rv; - } - - if (!otherURI || !mCodebase) { - *aResult = true; - return NS_OK; - } - - // Fall through to the codebase comparison. - } // Codebases are equal if they have the same origin. *aResult = @@ -442,9 +291,6 @@ nsPrincipal::EqualsIgnoringDomain(nsIPrincipal *aOther, bool *aResult) } *aResult = false; - if (!CertificateEquals(aOther)) { - return NS_OK; - } nsCOMPtr otherURI; nsresult rv = aOther->GetURI(getter_AddRefs(otherURI)); @@ -604,16 +450,9 @@ nsPrincipal::SetURI(nsIURI* aURI) NS_IMETHODIMP nsPrincipal::GetHashValue(uint32_t* aValue) { - NS_PRECONDITION(mCert || mCodebase, "Need a cert or codebase"); - - // If there is a certificate, it takes precendence over the codebase. - if (mCert) { - *aValue = HashString(mCert->fingerprint); - } - else { - *aValue = nsScriptSecurityManager::HashPrincipalByOrigin(this); - } + NS_PRECONDITION(mCodebase, "Need a codebase"); + *aValue = nsScriptSecurityManager::HashPrincipalByOrigin(this); return NS_OK; } @@ -705,40 +544,8 @@ nsPrincipal::GetUnknownAppId(bool* aUnknownAppId) NS_IMETHODIMP nsPrincipal::Read(nsIObjectInputStream* aStream) { - bool haveCert; - nsresult rv = aStream->ReadBoolean(&haveCert); - if (NS_FAILED(rv)) { - return rv; - } - - nsCString fingerprint; - nsCString subjectName; - nsCString prettyName; - nsCOMPtr cert; - if (haveCert) { - rv = NS_ReadOptionalCString(aStream, fingerprint); - if (NS_FAILED(rv)) { - return rv; - } - - rv = NS_ReadOptionalCString(aStream, subjectName); - if (NS_FAILED(rv)) { - return rv; - } - - rv = NS_ReadOptionalCString(aStream, prettyName); - if (NS_FAILED(rv)) { - return rv; - } - - rv = aStream->ReadObject(true, getter_AddRefs(cert)); - if (NS_FAILED(rv)) { - return rv; - } - } - nsCOMPtr codebase; - rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(codebase)); + nsresult rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(codebase)); if (NS_FAILED(rv)) { return rv; } @@ -757,7 +564,7 @@ nsPrincipal::Read(nsIObjectInputStream* aStream) rv = aStream->ReadBoolean(&inMozBrowser); NS_ENSURE_SUCCESS(rv, rv); - rv = Init(fingerprint, subjectName, prettyName, cert, codebase, appId, inMozBrowser); + rv = Init(codebase, appId, inMozBrowser); NS_ENSURE_SUCCESS(rv, rv); SetDomain(domain); @@ -768,44 +575,14 @@ nsPrincipal::Read(nsIObjectInputStream* aStream) NS_IMETHODIMP nsPrincipal::Write(nsIObjectOutputStream* aStream) { - NS_ENSURE_STATE(mCert || mCodebase); + NS_ENSURE_STATE(mCodebase); - nsresult rv = aStream->WriteBoolean(mCert != nullptr); - if (NS_FAILED(rv)) { - return rv; - } - - if (mCert) { - NS_ENSURE_STATE(mCert->cert); - - rv = NS_WriteOptionalStringZ(aStream, mCert->fingerprint.get()); - if (NS_FAILED(rv)) { - return rv; - } - - rv = NS_WriteOptionalStringZ(aStream, mCert->subjectName.get()); - if (NS_FAILED(rv)) { - return rv; - } - - rv = NS_WriteOptionalStringZ(aStream, mCert->prettyName.get()); - if (NS_FAILED(rv)) { - return rv; - } - - rv = aStream->WriteCompoundObject(mCert->cert, NS_GET_IID(nsISupports), - true); - if (NS_FAILED(rv)) { - return rv; - } - } - // mSecurityPolicy is an optimization; it'll get looked up again as needed. // Don't bother saving and restoring it, esp. since it might change if // preferences change. - rv = NS_WriteOptionalCompoundObject(aStream, mCodebase, NS_GET_IID(nsIURI), - true); + nsresult rv = NS_WriteOptionalCompoundObject(aStream, mCodebase, NS_GET_IID(nsIURI), + true); if (NS_FAILED(rv)) { return rv; } @@ -1078,12 +855,8 @@ nsExpandedPrincipal::GetUnknownAppId(bool* aUnknownAppId) void nsExpandedPrincipal::GetScriptLocation(nsACString& aStr) { - if (mCert) { - aStr.Assign(mCert->fingerprint); - } else { - // Is that a good idea to list it's principals? - aStr.Assign(EXPANDED_PRINCIPAL_SPEC); - } + // Is that a good idea to list it's principals? + aStr.Assign(EXPANDED_PRINCIPAL_SPEC); } #ifdef DEBUG diff --git a/caps/src/nsScriptSecurityManager.cpp b/caps/src/nsScriptSecurityManager.cpp index ff12342dd01a..3bff9ca04598 100644 --- a/caps/src/nsScriptSecurityManager.cpp +++ b/caps/src/nsScriptSecurityManager.cpp @@ -1852,52 +1852,6 @@ nsScriptSecurityManager::SubjectPrincipalIsSystem(bool* aIsSystem) return mSystemPrincipal->Equals(subject, aIsSystem); } -NS_IMETHODIMP -nsScriptSecurityManager::GetCertificatePrincipal(const nsACString& aCertFingerprint, - const nsACString& aSubjectName, - const nsACString& aPrettyName, - nsISupports* aCertificate, - nsIURI* aURI, - nsIPrincipal **result) -{ - *result = nullptr; - - NS_ENSURE_ARG(!aCertFingerprint.IsEmpty() && - !aSubjectName.IsEmpty() && - aCertificate); - - return DoGetCertificatePrincipal(aCertFingerprint, aSubjectName, - aPrettyName, aCertificate, aURI, true, - result); -} - -nsresult -nsScriptSecurityManager::DoGetCertificatePrincipal(const nsACString& aCertFingerprint, - const nsACString& aSubjectName, - const nsACString& aPrettyName, - nsISupports* aCertificate, - nsIURI* aURI, - bool aModifyTable, - nsIPrincipal **result) -{ - NS_ENSURE_ARG(!aCertFingerprint.IsEmpty()); - - // Create a certificate principal out of the certificate ID - // and URI given to us. We will use this principal to test - // equality when doing our hashtable lookups below. - nsRefPtr certificate = new nsPrincipal(); - if (!certificate) - return NS_ERROR_OUT_OF_MEMORY; - - nsresult rv = certificate->Init(aCertFingerprint, aSubjectName, - aPrettyName, aCertificate, aURI, - UNKNOWN_APP_ID, false); - NS_ENSURE_SUCCESS(rv, rv); - NS_ADDREF(*result = certificate); - - return rv; -} - nsresult nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, uint32_t aAppId, bool aInMozBrowser, @@ -1924,9 +1878,7 @@ nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, uint32_t aAppId, if (!codebase) return NS_ERROR_OUT_OF_MEMORY; - nsresult rv = codebase->Init(EmptyCString(), EmptyCString(), - EmptyCString(), nullptr, aURI, aAppId, - aInMozBrowser); + nsresult rv = codebase->Init(aURI, aAppId, aInMozBrowser); if (NS_FAILED(rv)) return rv; diff --git a/caps/src/nsSystemPrincipal.cpp b/caps/src/nsSystemPrincipal.cpp index 62822af74a15..ab095e4c6b81 100644 --- a/caps/src/nsSystemPrincipal.cpp +++ b/caps/src/nsSystemPrincipal.cpp @@ -124,38 +124,6 @@ nsSystemPrincipal::GetOrigin(char** aOrigin) return *aOrigin ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } -NS_IMETHODIMP -nsSystemPrincipal::GetFingerprint(nsACString& aID) -{ - return NS_ERROR_NOT_AVAILABLE; -} - -NS_IMETHODIMP -nsSystemPrincipal::GetPrettyName(nsACString& aName) -{ - return NS_ERROR_NOT_AVAILABLE; -} - -NS_IMETHODIMP -nsSystemPrincipal::GetSubjectName(nsACString& aName) -{ - return NS_ERROR_NOT_AVAILABLE; -} - -NS_IMETHODIMP -nsSystemPrincipal::GetCertificate(nsISupports** aCertificate) -{ - *aCertificate = nullptr; - return NS_OK; -} - -NS_IMETHODIMP -nsSystemPrincipal::GetHasCertificate(bool* aResult) -{ - *aResult = false; - return NS_OK; -} - NS_IMETHODIMP nsSystemPrincipal::GetCsp(nsIContentSecurityPolicy** aCsp) { diff --git a/ipc/testshell/XPCShellEnvironment.cpp b/ipc/testshell/XPCShellEnvironment.cpp index 784076031068..e05847c054ed 100644 --- a/ipc/testshell/XPCShellEnvironment.cpp +++ b/ipc/testshell/XPCShellEnvironment.cpp @@ -742,18 +742,6 @@ FullTrustSecMan::GetSystemPrincipal(nsIPrincipal **_retval) return *_retval ? NS_OK : NS_ERROR_FAILURE; } -NS_IMETHODIMP -FullTrustSecMan::GetCertificatePrincipal(const nsACString & aCertFingerprint, - const nsACString & aSubjectName, - const nsACString & aPrettyName, - nsISupports *aCert, - nsIURI *aURI, - nsIPrincipal **_retval) -{ - NS_IF_ADDREF(*_retval = mSystemPrincipal); - return *_retval ? NS_OK : NS_ERROR_FAILURE; -} - NS_IMETHODIMP FullTrustSecMan::GetSimpleCodebasePrincipal(nsIURI *aURI, nsIPrincipal **_retval) diff --git a/js/xpconnect/shell/xpcshell.cpp b/js/xpconnect/shell/xpcshell.cpp index 1e74624d8547..fc4e171ad524 100644 --- a/js/xpconnect/shell/xpcshell.cpp +++ b/js/xpconnect/shell/xpcshell.cpp @@ -1380,18 +1380,6 @@ FullTrustSecMan::GetSystemPrincipal(nsIPrincipal **_retval) return *_retval ? NS_OK : NS_ERROR_FAILURE; } -/* [noscript] nsIPrincipal getCertificatePrincipal (in AUTF8String aCertFingerprint, in AUTF8String aSubjectName, in AUTF8String aPrettyName, in nsISupports aCert, in nsIURI aURI); */ -NS_IMETHODIMP -FullTrustSecMan::GetCertificatePrincipal(const nsACString & aCertFingerprint, - const nsACString & aSubjectName, - const nsACString & aPrettyName, - nsISupports *aCert, nsIURI *aURI, - nsIPrincipal **_retval) -{ - NS_IF_ADDREF(*_retval = mSystemPrincipal); - return *_retval ? NS_OK : NS_ERROR_FAILURE; -} - /* [noscript] nsIPrincipal getSimpleCodebasePrincipal (in nsIURI aURI); */ NS_IMETHODIMP FullTrustSecMan::GetSimpleCodebasePrincipal(nsIURI *aURI, nsIPrincipal **_retval) diff --git a/modules/libjar/nsIZipReader.idl b/modules/libjar/nsIZipReader.idl index d2048a266470..2aa89eddf5e5 100644 --- a/modules/libjar/nsIZipReader.idl +++ b/modules/libjar/nsIZipReader.idl @@ -9,7 +9,7 @@ interface nsIUTF8StringEnumerator; interface nsIInputStream; interface nsIFile; -interface nsIPrincipal; +interface nsICertificatePrincipal; [scriptable, uuid(e1c028bc-c478-11da-95a8-00e08161165f)] interface nsIZipEntry : nsISupports @@ -53,7 +53,7 @@ interface nsIZipEntry : nsISupports readonly attribute boolean isSynthetic; }; -[scriptable, uuid(8fbf5023-3827-4fbc-a464-5db546e7f747)] +[scriptable, uuid(38d6d07a-8a58-4fe7-be8b-ef6472fa83ff)] interface nsIZipReader : nsISupports { /** @@ -177,7 +177,7 @@ interface nsIZipReader : nsISupports * stored in the jar, verifyExternalFile (not yet implemented) must * be called before getPrincipal. */ - nsIPrincipal getCertificatePrincipal(in AUTF8String aEntryName); + nsICertificatePrincipal getCertificatePrincipal(in AUTF8String aEntryName); readonly attribute uint32_t manifestEntriesCount; }; diff --git a/modules/libjar/nsJAR.cpp b/modules/libjar/nsJAR.cpp index b6c7c8a5701b..97c5f347c1d7 100644 --- a/modules/libjar/nsJAR.cpp +++ b/modules/libjar/nsJAR.cpp @@ -339,7 +339,7 @@ nsJAR::GetInputStreamWithSpec(const nsACString& aJarDirSpec, } NS_IMETHODIMP -nsJAR::GetCertificatePrincipal(const nsACString &aFilename, nsIPrincipal** aPrincipal) +nsJAR::GetCertificatePrincipal(const nsACString &aFilename, nsICertificatePrincipal** aPrincipal) { //-- Parameter check if (!aPrincipal) diff --git a/modules/libjar/nsJAR.h b/modules/libjar/nsJAR.h index 5d7024a93d1d..80c9c48687ca 100644 --- a/modules/libjar/nsJAR.h +++ b/modules/libjar/nsJAR.h @@ -24,7 +24,7 @@ #include "nsHashtable.h" #include "nsIZipReader.h" #include "nsZipArchive.h" -#include "nsIPrincipal.h" +#include "nsICertificatePrincipal.h" #include "nsISignatureVerifier.h" #include "nsIObserverService.h" #include "nsWeakReference.h" @@ -100,7 +100,7 @@ class nsJAR : public nsIZipReader nsRefPtr mZip; // The underlying zip archive nsObjectHashtable mManifestData; // Stores metadata for each entry bool mParsedManifest; // True if manifest has been parsed - nsCOMPtr mPrincipal; // The entity which signed this file + nsCOMPtr mPrincipal; // The entity which signed this file int16_t mGlobalStatus; // Global signature verification status PRIntervalTime mReleaseTime; // used by nsZipReaderCache for flushing entries nsZipReaderCache* mCache; // if cached, this points to the cache it's contained in diff --git a/security/manager/ssl/public/Makefile.in b/security/manager/ssl/public/Makefile.in index 36b561111d42..30c43010d48e 100644 --- a/security/manager/ssl/public/Makefile.in +++ b/security/manager/ssl/public/Makefile.in @@ -67,6 +67,8 @@ XPIDLSRCS = \ nsIKeyModule.idl \ nsIProtectedAuthThread.idl \ nsIDataSignatureVerifier.idl \ + nsISignatureVerifier.idl \ + nsICertificatePrincipal.idl \ $(NULL) ifdef MOZ_XUL diff --git a/security/manager/ssl/public/nsICertificatePrincipal.idl b/security/manager/ssl/public/nsICertificatePrincipal.idl new file mode 100644 index 000000000000..a1e709d8eca4 --- /dev/null +++ b/security/manager/ssl/public/nsICertificatePrincipal.idl @@ -0,0 +1,33 @@ +/* -*- 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/. */ + +#include "nsISupports.idl" + +/* + * Historically, principals, certificates, and signed JARs were all linked + * together in one big mess. When that mess was cleaned up, it turned out that + * the principals used to store certificate information didn't overlap at all + * with the principals used for security policy. So this interface was created + * so that real principals wouldn't have to carry around all that baggage. + * + * The name here is totally a misnomer. This isn't a principal at all, and would + * better be called nsICertificateHolder or something. But that would require + * renaming some APIs, so let's just let this be for now. + */ + +[scriptable, uuid(7cd4af5a-64d3-44a8-9700-804a42a6109a)] +interface nsICertificatePrincipal : nsISupports +{ + readonly attribute AUTF8String fingerprint; + readonly attribute AUTF8String prettyName; + readonly attribute AUTF8String subjectName; + readonly attribute nsISupports certificate; + readonly attribute boolean hasCertificate; // For compat; always true. + + bool equals(in nsICertificatePrincipal aOther); +}; + +//////////////////////////////////////////////////////////////////////////////// diff --git a/caps/idl/nsISignatureVerifier.idl b/security/manager/ssl/public/nsISignatureVerifier.idl similarity index 53% rename from caps/idl/nsISignatureVerifier.idl rename to security/manager/ssl/public/nsISignatureVerifier.idl index 0cc3584f157e..340522496e40 100644 --- a/caps/idl/nsISignatureVerifier.idl +++ b/security/manager/ssl/public/nsISignatureVerifier.idl @@ -4,20 +4,24 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* An interface for verifying signatures */ -#include "nsIPrincipal.idl" -[uuid(dea87f65-e91e-4119-aa13-aaa2be80cac2)] +#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 */ - nsIPrincipal verifySignature(in string aSignature, - in unsigned long aSignatureLen, - in string plaintext, - in unsigned long plaintextLen, - out long errorCode); + 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/src/Makefile.in b/security/manager/ssl/src/Makefile.in index abc4bd70dfb2..ad2312f1ff87 100644 --- a/security/manager/ssl/src/Makefile.in +++ b/security/manager/ssl/src/Makefile.in @@ -72,6 +72,7 @@ CPPSRCS = \ nsNSSCertificateFakeTransport.cpp \ PSMRunnable.cpp \ nsNSSVersion.cpp \ + nsCertificatePrincipal.cpp \ $(NULL) ifdef MOZ_XUL diff --git a/security/manager/ssl/src/nsCertificatePrincipal.cpp b/security/manager/ssl/src/nsCertificatePrincipal.cpp new file mode 100644 index 000000000000..7080a636d354 --- /dev/null +++ b/security/manager/ssl/src/nsCertificatePrincipal.cpp @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "nsCertificatePrincipal.h" + +NS_IMPL_ISUPPORTS1(nsCertificatePrincipal, nsICertificatePrincipal) + +NS_IMETHODIMP +nsCertificatePrincipal::GetFingerprint(nsACString& aFingerprint) +{ + aFingerprint = mFingerprint; + return NS_OK; +} + +NS_IMETHODIMP +nsCertificatePrincipal::GetSubjectName(nsACString& aSubjectName) +{ + aSubjectName = mSubjectName; + return NS_OK; +} + +NS_IMETHODIMP +nsCertificatePrincipal::GetPrettyName(nsACString& aPrettyName) +{ + aPrettyName = mPrettyName; + return NS_OK; +} + +NS_IMETHODIMP +nsCertificatePrincipal::GetCertificate(nsISupports** aCert) +{ + nsCOMPtr cert = mCert; + cert.forget(aCert); + return NS_OK; +} + +NS_IMETHODIMP +nsCertificatePrincipal::GetHasCertificate(bool* rv) +{ + *rv = true; + return NS_OK; +} + +NS_IMETHODIMP +nsCertificatePrincipal::Equals(nsICertificatePrincipal* aOther, bool* rv) +{ + nsAutoCString str; + aOther->GetFingerprint(str); + if (!str.Equals(mFingerprint)) { + *rv = false; + return NS_OK; + } + + // If either subject name is empty, just let the result stand, but if they're + // both non-empty, only claim equality if they're equal. + if (!mSubjectName.IsEmpty()) { + // Check the other principal's subject name + aOther->GetSubjectName(str); + *rv = str.Equals(mSubjectName) || str.IsEmpty(); + return NS_OK; + } + + *rv = true; + return NS_OK; +} diff --git a/security/manager/ssl/src/nsCertificatePrincipal.h b/security/manager/ssl/src/nsCertificatePrincipal.h new file mode 100644 index 000000000000..182731e1859c --- /dev/null +++ b/security/manager/ssl/src/nsCertificatePrincipal.h @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 __NS_CERTIFICATEPRINCIPAL_H +#define __NS_CERTIFICATEPRINCIPAL_H + +#include "nsICertificatePrincipal.h" +#include "nsString.h" +#include "nsCOMPtr.h" + +class nsCertificatePrincipal : public nsICertificatePrincipal +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSICERTIFICATEPRINCIPAL + + nsCertificatePrincipal(const nsACString& aFingerprint, + const nsACString& aSubjectName, + const nsACString& aPrettyName, + nsISupports* aCert) + : mFingerprint(aFingerprint) + , mSubjectName(aSubjectName) + , mPrettyName(aPrettyName) + , mCert(aCert) + {} + + virtual ~nsCertificatePrincipal() {}; + +private: + nsCString mFingerprint; + nsCString mSubjectName; + nsCString mPrettyName; + nsCOMPtr mCert; +}; + +#endif /* __NS_CERTIFICATEPRINCIPAL_H */ diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index f12b518dbb0f..e0aad9715c49 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -42,7 +42,7 @@ #include "nsIWindowWatcher.h" #include "nsIPrompt.h" -#include "nsIPrincipal.h" +#include "nsCertificatePrincipal.h" #include "nsReadableUtils.h" #include "nsIDateTimeFormat.h" #include "prtypes.h" @@ -2053,7 +2053,7 @@ NS_IMETHODIMP nsNSSComponent::VerifySignature(const char* aRSABuf, uint32_t aRSABufLen, const char* aPlaintext, uint32_t aPlaintextLen, int32_t* aErrorCode, - nsIPrincipal** aPrincipal) + nsICertificatePrincipal** aPrincipal) { if (!aPrincipal || !aErrorCode) { return NS_ERROR_NULL_POINTER; @@ -2152,16 +2152,12 @@ nsNSSComponent::VerifySignature(const char* aRSABuf, uint32_t aRSABufLen, break; } - nsCOMPtr certPrincipal; - rv2 = mScriptSecurityManager-> - GetCertificatePrincipal(NS_ConvertUTF16toUTF8(fingerprint), - NS_ConvertUTF16toUTF8(subjectName), - NS_ConvertUTF16toUTF8(orgName), - pCert, nullptr, getter_AddRefs(certPrincipal)); - if (NS_FAILED(rv2) || !certPrincipal) { - break; - } - + nsCOMPtr certPrincipal = + new nsCertificatePrincipal(NS_ConvertUTF16toUTF8(fingerprint), + NS_ConvertUTF16toUTF8(subjectName), + NS_ConvertUTF16toUTF8(orgName), + pCert); + certPrincipal.swap(*aPrincipal); } while (0); }