Bug 789224 - Separate certificate principals out from CAPS. r=dveditz
authorBobby Holley <bobbyholley@gmail.com>
Thu, 25 Oct 2012 17:05:00 +0200
changeset 116913 d3453d0161c5860c57a046224ba6acd06aa11f0b
parent 116912 78cc1d3e1d5abf34a5d39d7316979924ea723b3c
child 116914 4d04726fe87b8f7cd6c75ef0bb88202811b02d74
push id239
push userakeybl@mozilla.com
push dateThu, 03 Jan 2013 21:54:43 +0000
treeherdermozilla-release@3a7b66445659 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdveditz
bugs789224
milestone18.0a2
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
caps/idl/nsIPrincipal.idl
caps/idl/nsIScriptSecurityManager.idl
caps/idl/nsISignatureVerifier.idl
caps/include/nsPrincipal.h
caps/include/nsScriptSecurityManager.h
caps/src/nsNullPrincipal.cpp
caps/src/nsPrincipal.cpp
caps/src/nsScriptSecurityManager.cpp
caps/src/nsSystemPrincipal.cpp
ipc/testshell/XPCShellEnvironment.cpp
js/xpconnect/shell/xpcshell.cpp
modules/libjar/nsIZipReader.idl
modules/libjar/nsJAR.cpp
modules/libjar/nsJAR.h
security/manager/ssl/public/Makefile.in
security/manager/ssl/public/nsICertificatePrincipal.idl
security/manager/ssl/public/nsISignatureVerifier.idl
security/manager/ssl/src/Makefile.in
security/manager/ssl/src/nsCertificatePrincipal.cpp
security/manager/ssl/src/nsCertificatePrincipal.h
security/manager/ssl/src/nsNSSComponent.cpp
--- a/caps/idl/Makefile.in
+++ b/caps/idl/Makefile.in
@@ -11,14 +11,13 @@ VPATH		= @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= caps
 GRE_MODULE	= 1
 
 XPIDLSRCS	= \
 		nsIScriptSecurityManager.idl \
 		nsIPrincipal.idl \
-		nsISignatureVerifier.idl \
 		nsISecurityCheckedComponent.idl \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
--- a/caps/idl/nsIPrincipal.idl
+++ b/caps/idl/nsIPrincipal.idl
@@ -21,18 +21,18 @@ interface nsIContentSecurityPolicy;
 [ptr] native JSPrincipals(JSPrincipals);
 [ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
 
 [scriptable, uuid(96a92f0c-adcb-44ac-a034-37627647ec97)]
 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);
 
     /**
      * Like equals, but doesn't take document.domain changes into account.
      */
     boolean equalsIgnoringDomain(in nsIPrincipal other);
 
@@ -74,64 +74,28 @@ interface nsIPrincipal : nsISerializable
      * An origin is defined as: scheme + host + port.
      */
     // XXXcaa this should probably be turned into an nsIURI.
     // The system principal's origin should be some caps namespace
     // 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.
      *
      * The system principal subsumes itself and all other principals.
      *
      * A null principal (corresponding to an unknown, hence assumed minimally
      * 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);
 
     /**
      * Same as the previous method, subsumes(), but for codebase principals
      * ignores changes to document.domain.
      */
     boolean subsumesIgnoringDomain(in nsIPrincipal other);
@@ -165,33 +129,16 @@ interface nsIPrincipal : nsISerializable
      *                                   loadee inherits the principal of the
      *                                   loader.
      * @throws NS_ERROR_DOM_BAD_URI if the load is not allowed.
      */
     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.
      */
     [noscript] attribute nsIContentSecurityPolicy csp;
 
     /**
      * Returns the extended origin of the principal.
      * The extended origin is a string that has more information than the origin
      * and can be used to isolate data or permissions between different
--- a/caps/idl/nsIScriptSecurityManager.idl
+++ b/caps/idl/nsIScriptSecurityManager.idl
@@ -131,31 +131,16 @@ interface nsIScriptSecurityManager : nsI
     [noscript] nsIPrincipal getSubjectPrincipal();
 
     /**
      * Return the all-powerful system principal.
      */
     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
      * have appId = UNKNOWN_APP_ID.
      */
     nsIPrincipal getSimpleCodebasePrincipal(in nsIURI aURI);
 
     /**
      * Returns a principal that has the given information.
--- a/caps/include/nsPrincipal.h
+++ b/caps/include/nsPrincipal.h
@@ -29,72 +29,28 @@ public:
 protected:
   virtual ~nsBasePrincipal();
 
 public:
   NS_IMETHOD_(nsrefcnt) AddRef(void);
   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<nsISupports> 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<Certificate> mCert;
-
   DomainPolicy* mSecurityPolicy;
 
   nsCOMPtr<nsIContentSecurityPolicy> mCSP;
 };
 
 class nsPrincipal : public nsBasePrincipal
 {
 public:
@@ -117,21 +73,17 @@ public:
   NS_IMETHOD GetUnknownAppId(bool* aUnknownAppId);
 #ifdef DEBUG
   virtual void dumpImpl();
 #endif
 
   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);
 
   virtual void GetScriptLocation(nsACString& aStr) MOZ_OVERRIDE;
   void SetURI(nsIURI* aURI);
 
   static bool IsPrincipalInherited(nsIURI* aURI) {
     // return true if the loadee URI has
--- a/caps/include/nsScriptSecurityManager.h
+++ b/caps/include/nsScriptSecurityManager.h
@@ -438,28 +438,16 @@ private:
     GetCodebasePrincipalInternal(nsIURI* aURI, uint32_t aAppId,
                                  bool aInMozBrowser,
                                  nsIPrincipal** result);
 
     nsresult
     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.
     nsIPrincipal*
     GetSubjectPrincipal(JSContext* cx, nsresult* rv);
 
     // 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 frame.
@@ -552,17 +540,16 @@ private:
     inline void
     ScriptSecurityPrefChanged();
 
     nsObjectHashtable* mOriginToPolicyMap;
     DomainPolicy* mDefaultPolicy;
     nsObjectHashtable* mCapabilities;
 
     nsCOMPtr<nsIPrincipal> mSystemPrincipal;
-    nsCOMPtr<nsIPrincipal> mSystemCertificate;
     bool mPrefInitialized;
     bool mIsJavaScriptEnabled;
     bool mIsWritingPrefs;
     bool mPolicyPrefsChanged;
 
     static bool sStrictFileOriginPolicy;
 
     static nsIIOService    *sIOService;
--- a/caps/src/nsNullPrincipal.cpp
+++ b/caps/src/nsNullPrincipal.cpp
@@ -207,35 +207,16 @@ nsNullPrincipal::GetOrigin(char** aOrigi
   NS_ENSURE_SUCCESS(rv, rv);
 
   *aOrigin = ToNewCString(str);
   NS_ENSURE_TRUE(*aOrigin, NS_ERROR_OUT_OF_MEMORY);
 
   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)
 {
   // We don't subsume anything except ourselves.  Note that nsPrincipal::Equals
   // will return false for us, since we're not about:blank and not Equals to
   // reasonable nsPrincipals.
   *aResult = (aOther == this);
   return NS_OK;
@@ -271,29 +252,16 @@ nsNullPrincipal::CheckMayLoad(nsIURI* aU
   if (aReport) {
     nsScriptSecurityManager::ReportError(
       nullptr, NS_LITERAL_STRING("CheckSameOriginError"), mURI, aURI);
   }
 
   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)
 {
   return GetOrigin(getter_Copies(aExtendedOrigin));
 }
 
 NS_IMETHODIMP
 nsNullPrincipal::GetAppStatus(uint16_t* aAppStatus)
--- a/caps/src/nsPrincipal.cpp
+++ b/caps/src/nsPrincipal.cpp
@@ -111,115 +111,16 @@ nsBasePrincipal::SetSecurityPolicy(void*
  
   if (mSecurityPolicy)
     mSecurityPolicy->Drop();
   
   mSecurityPolicy = newPolicy;
   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)
 {
   NS_IF_ADDREF(*aCsp = mCSP);
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -229,34 +130,16 @@ nsBasePrincipal::SetCsp(nsIContentSecuri
   // get set anew when a new principal is created.
   if (mCSP)
     return NS_ERROR_ALREADY_INITIALIZED;
 
   mCSP = 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()
 {
   nsAutoCString str;
   GetScriptLocation(str);
   fprintf(stderr, "nsPrincipal (%p) = %s\n", static_cast<void*>(this), str.get());
 }
 #endif 
@@ -279,49 +162,38 @@ nsPrincipal::nsPrincipal()
   , mDomainImmutable(false)
   , mInitialized(false)
 { }
 
 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;
 
   mCodebase = NS_TryToMakeImmutable(aCodebase);
   mCodebaseImmutable = URIIsImmutable(mCodebase);
 
   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
 nsPrincipal::GetOriginForURI(nsIURI* aURI, char **aOrigin)
 {
   if (!aURI) {
     return NS_ERROR_FAILURE;
   }
@@ -393,39 +265,16 @@ nsPrincipal::Equals(nsIPrincipal *aOther
 {
   if (!aOther) {
     NS_WARNING("Need a principal to compare this to!");
     *aResult = false;
     return NS_OK;
   }
 
   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<nsIURI> 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 =
       NS_SUCCEEDED(nsScriptSecurityManager::CheckSameOriginPrincipal(this,
                                                                      aOther));
     return NS_OK;
   }
 
@@ -437,19 +286,16 @@ NS_IMETHODIMP
 nsPrincipal::EqualsIgnoringDomain(nsIPrincipal *aOther, bool *aResult)
 {
   if (this == aOther) {
     *aResult = true;
     return NS_OK;
   }
 
   *aResult = false;
-  if (!CertificateEquals(aOther)) {
-    return NS_OK;
-  }
 
   nsCOMPtr<nsIURI> otherURI;
   nsresult rv = aOther->GetURI(getter_AddRefs(otherURI));
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   NS_ASSERTION(mCodebase,
@@ -599,26 +445,19 @@ nsPrincipal::SetURI(nsIURI* aURI)
 {
   mCodebase = NS_TryToMakeImmutable(aURI);
   mCodebaseImmutable = URIIsImmutable(mCodebase);
 }
 
 NS_IMETHODIMP
 nsPrincipal::GetHashValue(uint32_t* aValue)
 {
-  NS_PRECONDITION(mCert || mCodebase, "Need a cert or codebase");
+  NS_PRECONDITION(mCodebase, "Need a codebase");
 
-  // If there is a certificate, it takes precendence over the codebase.
-  if (mCert) {
-    *aValue = HashString(mCert->fingerprint);
-  }
-  else {
-    *aValue = nsScriptSecurityManager::HashPrincipalByOrigin(this);
-  }
-
+  *aValue = nsScriptSecurityManager::HashPrincipalByOrigin(this);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPrincipal::GetDomain(nsIURI** aDomain)
 {
   if (!mDomain) {
     *aDomain = nullptr;
@@ -700,50 +539,18 @@ nsPrincipal::GetUnknownAppId(bool* aUnkn
 {
   *aUnknownAppId = mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID;
   return NS_OK;
 }
 
 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<nsISupports> 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<nsIURI> codebase;
-  rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(codebase));
+  nsresult rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(codebase));
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   nsCOMPtr<nsIURI> domain;
   rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(domain));
   if (NS_FAILED(rv)) {
     return rv;
@@ -752,65 +559,35 @@ nsPrincipal::Read(nsIObjectInputStream* 
   uint32_t appId;
   rv = aStream->Read32(&appId);
   NS_ENSURE_SUCCESS(rv, rv);
 
   bool inMozBrowser;
   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);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPrincipal::Write(nsIObjectOutputStream* aStream)
 {
-  NS_ENSURE_STATE(mCert || mCodebase);
-
-  nsresult rv = aStream->WriteBoolean(mCert != nullptr);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
+  NS_ENSURE_STATE(mCodebase);
 
-  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;
   }
 
   rv = NS_WriteOptionalCompoundObject(aStream, mDomain, NS_GET_IID(nsIURI),
                                       true);
   if (NS_FAILED(rv)) {
     return rv;
@@ -1073,22 +850,18 @@ nsExpandedPrincipal::GetUnknownAppId(boo
 {
   *aUnknownAppId = false;
   return NS_OK;
 }
 
 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
 void nsExpandedPrincipal::dumpImpl()
 {
   fprintf(stderr, "nsExpandedPrincipal (%p)\n", static_cast<void*>(this));
 }
 #endif 
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -1861,62 +1861,16 @@ nsScriptSecurityManager::SubjectPrincipa
         // this is the equivalent of system principal code
         *aIsSystem = true;
         return NS_OK;
     }
 
     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<nsPrincipal> 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,
                                                  nsIPrincipal **result)
 {
     // I _think_ it's safe to not create null principals here based on aURI.
     // At least all the callers would do the right thing in those cases, as far
     // as I can tell.  --bz
@@ -1933,19 +1887,17 @@ nsScriptSecurityManager::CreateCodebaseP
 
         return NS_OK;
     }
 
     nsRefPtr<nsPrincipal> codebase = new nsPrincipal();
     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;
 
     NS_ADDREF(*result = codebase);
 
     return NS_OK;
 }
 
--- a/caps/src/nsSystemPrincipal.cpp
+++ b/caps/src/nsSystemPrincipal.cpp
@@ -119,48 +119,16 @@ nsSystemPrincipal::GetURI(nsIURI** aURI)
 
 NS_IMETHODIMP 
 nsSystemPrincipal::GetOrigin(char** aOrigin)
 {
     *aOrigin = ToNewCString(NS_LITERAL_CSTRING(SYSTEM_PRINCIPAL_SPEC));
     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)
 {
   *aCsp = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -738,28 +738,16 @@ FullTrustSecMan::GetSubjectPrincipal(nsI
 NS_IMETHODIMP
 FullTrustSecMan::GetSystemPrincipal(nsIPrincipal **_retval)
 {
     NS_IF_ADDREF(*_retval = mSystemPrincipal);
     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)
 {
     NS_IF_ADDREF(*_retval = mSystemPrincipal);
     return *_retval ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
--- a/js/xpconnect/shell/xpcshell.cpp
+++ b/js/xpconnect/shell/xpcshell.cpp
@@ -1376,28 +1376,16 @@ FullTrustSecMan::GetSubjectPrincipal(nsI
 /* [noscript] nsIPrincipal getSystemPrincipal (); */
 NS_IMETHODIMP
 FullTrustSecMan::GetSystemPrincipal(nsIPrincipal **_retval)
 {
     NS_IF_ADDREF(*_retval = mSystemPrincipal);
     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)
 {
     NS_IF_ADDREF(*_retval = mSystemPrincipal);
     return *_retval ? NS_OK : NS_ERROR_FAILURE;
 }
 
--- a/modules/libjar/nsIZipReader.idl
+++ b/modules/libjar/nsIZipReader.idl
@@ -4,17 +4,17 @@
  * 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"
 
 interface nsIUTF8StringEnumerator;
 interface nsIInputStream;
 interface nsIFile;
-interface nsIPrincipal;
+interface nsICertificatePrincipal;
 
 [scriptable, uuid(e1c028bc-c478-11da-95a8-00e08161165f)]
 interface nsIZipEntry : nsISupports
 {
     /**
      * The type of compression used for the item.  The possible values and
      * their meanings are defined in the zip file specification at
      * http://www.pkware.com/business_and_developers/developer/appnote/
@@ -48,17 +48,17 @@ interface nsIZipEntry : nsISupports
      * directory foo/ in a zip containing exactly one entry for foo/bar.txt
      * is synthetic.  If the zip file contains an actual entry for a directory,
      * this attribute will be false for the nsIZipEntry for that directory.
      * It is impossible for a file to be synthetic.
      */
     readonly attribute boolean          isSynthetic;
 };
 
-[scriptable, uuid(8fbf5023-3827-4fbc-a464-5db546e7f747)]
+[scriptable, uuid(38d6d07a-8a58-4fe7-be8b-ef6472fa83ff)]
 interface nsIZipReader : nsISupports
 {
     /**
      * Opens a zip file for reading.
      * It is allowed to open with another file, 
      * but it needs to be closed first with close().
      */
     void open(in nsIFile zipFile);
@@ -172,17 +172,17 @@ interface nsIZipReader : nsISupports
      /**
      * Returns an object describing the entity which signed 
      * an entry. parseManifest must be called first. If aEntryName is an
      * entry in the jar, getInputStream must be called after parseManifest.
      * If aEntryName is an external file which has meta-information 
      * 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;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIZipReaderCache
 
 [scriptable, uuid(72fc56e5-3e6e-4d11-8967-26ab96071032)]
--- a/modules/libjar/nsJAR.cpp
+++ b/modules/libjar/nsJAR.cpp
@@ -334,17 +334,17 @@ nsJAR::GetInputStreamWithSpec(const nsAC
   }
   if (NS_FAILED(rv)) {
     NS_RELEASE(*result);
   }
   return rv;
 }
 
 NS_IMETHODIMP
-nsJAR::GetCertificatePrincipal(const nsACString &aFilename, nsIPrincipal** aPrincipal)
+nsJAR::GetCertificatePrincipal(const nsACString &aFilename, nsICertificatePrincipal** aPrincipal)
 {
   //-- Parameter check
   if (!aPrincipal)
     return NS_ERROR_NULL_POINTER;
   *aPrincipal = nullptr;
 
   // Don't check signatures in the omnijar - this is only
   // interesting for extensions/XPIs.
--- a/modules/libjar/nsJAR.h
+++ b/modules/libjar/nsJAR.h
@@ -20,17 +20,17 @@
 #include "nsIComponentManager.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsIFile.h"
 #include "nsStringEnumerator.h"
 #include "nsHashtable.h"
 #include "nsIZipReader.h"
 #include "nsZipArchive.h"
-#include "nsIPrincipal.h"
+#include "nsICertificatePrincipal.h"
 #include "nsISignatureVerifier.h"
 #include "nsIObserverService.h"
 #include "nsWeakReference.h"
 #include "nsIObserver.h"
 #include "mozilla/Attributes.h"
 
 class nsIInputStream;
 class nsJARManifestItem;
@@ -96,17 +96,17 @@ class nsJAR : public nsIZipReader
 
   protected:
     //-- Private data members
     nsCOMPtr<nsIFile>        mZipFile;        // The zip/jar file on disk
     nsCString                mOuterZipEntry;  // The entry in the zip this zip is reading from
     nsRefPtr<nsZipArchive>   mZip;            // The underlying zip archive
     nsObjectHashtable        mManifestData;   // Stores metadata for each entry
     bool                     mParsedManifest; // True if manifest has been parsed
-    nsCOMPtr<nsIPrincipal>   mPrincipal;      // The entity which signed this file
+    nsCOMPtr<nsICertificatePrincipal> 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
     mozilla::Mutex           mLock;	
     int64_t                  mMtime;
     int32_t                  mTotalItemsInManifest;
     bool                     mOpened;
 
--- a/security/manager/ssl/public/Makefile.in
+++ b/security/manager/ssl/public/Makefile.in
@@ -62,15 +62,17 @@ XPIDLSRCS = \
     nsIPKCS11ModuleDB.idl \
     nsIPKCS11Module.idl \
     nsICRLManager.idl \
     nsISMimeCert.idl \
     nsIStreamCipher.idl \
     nsIKeyModule.idl \
     nsIProtectedAuthThread.idl \
     nsIDataSignatureVerifier.idl \
+    nsISignatureVerifier.idl \
+    nsICertificatePrincipal.idl \
     $(NULL)
 
 ifdef MOZ_XUL
 XPIDLSRCS += nsICertTree.idl
 endif
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /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);
+};
+
+////////////////////////////////////////////////////////////////////////////////
rename from caps/idl/nsISignatureVerifier.idl
rename to security/manager/ssl/public/nsISignatureVerifier.idl
--- a/caps/idl/nsISignatureVerifier.idl
+++ b/security/manager/ssl/public/nsISignatureVerifier.idl
@@ -1,26 +1,30 @@
 /* -*- 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 "nsIPrincipal.idl"
+
+#include "nsISupports.idl"
 
-[uuid(dea87f65-e91e-4119-aa13-aaa2be80cac2)]
+// 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);
 };
 
 
 %{C++
 #define SIGNATURE_VERIFIER_CONTRACTID "@mozilla.org/psm;1"
 %}
--- a/security/manager/ssl/src/Makefile.in
+++ b/security/manager/ssl/src/Makefile.in
@@ -67,16 +67,17 @@ CPPSRCS = 				\
   nsKeyModule.cpp \
   nsIdentityChecking.cpp \
   nsDataSignatureVerifier.cpp \
   nsRandomGenerator.cpp \
   NSSErrorsService.cpp \
   nsNSSCertificateFakeTransport.cpp \
   PSMRunnable.cpp \
   nsNSSVersion.cpp \
+  nsCertificatePrincipal.cpp \
   $(NULL)
 
 ifdef MOZ_XUL
 CPPSRCS += nsCertTree.cpp
 endif
 
 CSRCS += md4.c
 
new file mode 100644
--- /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<nsISupports> 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;
+}
new file mode 100644
--- /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<nsISupports> mCert;
+};
+
+#endif /* __NS_CERTIFICATEPRINCIPAL_H */
--- a/security/manager/ssl/src/nsNSSComponent.cpp
+++ b/security/manager/ssl/src/nsNSSComponent.cpp
@@ -38,17 +38,17 @@
 #include "nsThreadUtils.h"
 #include "nsAutoPtr.h"
 #include "nsCRT.h"
 #include "nsCRLInfo.h"
 #include "nsCertOverrideService.h"
 
 #include "nsIWindowWatcher.h"
 #include "nsIPrompt.h"
-#include "nsIPrincipal.h"
+#include "nsCertificatePrincipal.h"
 #include "nsReadableUtils.h"
 #include "nsIDateTimeFormat.h"
 #include "prtypes.h"
 #include "nsIEntropyCollector.h"
 #include "nsIBufEntropyCollector.h"
 #include "nsIServiceManager.h"
 #include "nsIFile.h"
 #include "nsITokenPasswordDialogs.h"
@@ -2068,17 +2068,17 @@ static void * GetPasswordKeyCallback(voi
 {
   return NULL;
 }
 
 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;
   }
 
   *aErrorCode = 0;
   *aPrincipal = nullptr;
 
@@ -2167,26 +2167,22 @@ nsNSSComponent::VerifySignature(const ch
         break;
       }
       nsAutoString subjectName;
       rv2 = pCert->GetSubjectName(subjectName);
       if (NS_FAILED(rv2)) {
         break;
       }
     
-      nsCOMPtr<nsIPrincipal> 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<nsICertificatePrincipal> certPrincipal =
+        new nsCertificatePrincipal(NS_ConvertUTF16toUTF8(fingerprint),
+                                   NS_ConvertUTF16toUTF8(subjectName),
+                                   NS_ConvertUTF16toUTF8(orgName),
+                                   pCert);
+
       certPrincipal.swap(*aPrincipal);
     } while (0);
   }
 
   SEC_PKCS7DestroyContentInfo(p7_info);
 
   return rv2;
 }