LCOV - code coverage report
Current view: directory - security/manager/ssl/src - nsNSSCertificate.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 925 63 6.8 %
Date: 2012-06-02 Functions: 94 13 13.8 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is the Netscape security libraries.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2000
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Ian McGreer <mcgreer@netscape.com>
      24                 :  *   Javier Delgadillo <javi@netscape.com>
      25                 :  *   Kai Engert <kengert@redhat.com>
      26                 :  *   Jesper Kristensen <mail@jesperkristensen.dk>
      27                 :  *
      28                 :  * Alternatively, the contents of this file may be used under the terms of
      29                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      30                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      31                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      32                 :  * of those above. If you wish to allow use of your version of this file only
      33                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      34                 :  * use your version of this file under the terms of the MPL, indicate your
      35                 :  * decision by deleting the provisions above and replace them with the notice
      36                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      37                 :  * the provisions above, a recipient may use your version of this file under
      38                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      39                 :  *
      40                 :  * ***** END LICENSE BLOCK ***** */
      41                 : 
      42                 : #include "prmem.h"
      43                 : #include "prerror.h"
      44                 : #include "prprf.h"
      45                 : 
      46                 : #include "nsNSSComponent.h" // for PIPNSS string bundle calls.
      47                 : #include "nsNSSCleaner.h"
      48                 : #include "nsCOMPtr.h"
      49                 : #include "nsIMutableArray.h"
      50                 : #include "nsNSSCertificate.h"
      51                 : #include "nsNSSCertValidity.h"
      52                 : #include "nsPKCS12Blob.h"
      53                 : #include "nsPK11TokenDB.h"
      54                 : #include "nsIX509Cert.h"
      55                 : #include "nsIX509Cert3.h"
      56                 : #include "nsISMimeCert.h"
      57                 : #include "nsNSSASN1Object.h"
      58                 : #include "nsString.h"
      59                 : #include "nsXPIDLString.h"
      60                 : #include "nsReadableUtils.h"
      61                 : #include "nsIURI.h"
      62                 : #include "nsCRT.h"
      63                 : #include "nsUsageArrayHelper.h"
      64                 : #include "nsICertificateDialogs.h"
      65                 : #include "nsNSSCertHelper.h"
      66                 : #include "nsISupportsPrimitives.h"
      67                 : #include "nsUnicharUtils.h"
      68                 : #include "nsThreadUtils.h"
      69                 : #include "nsCertVerificationThread.h"
      70                 : #include "nsIObjectOutputStream.h"
      71                 : #include "nsIObjectInputStream.h"
      72                 : #include "nsIProgrammingLanguage.h"
      73                 : 
      74                 : #include "nsXULAppAPI.h"
      75                 : 
      76                 : #include "nspr.h"
      77                 : extern "C" {
      78                 : #include "pk11func.h"
      79                 : #include "certdb.h"
      80                 : #include "cert.h"
      81                 : #include "secerr.h"
      82                 : #include "nssb64.h"
      83                 : #include "secasn1.h"
      84                 : #include "secder.h"
      85                 : }
      86                 : #include "ssl.h"
      87                 : #include "ocsp.h"
      88                 : #include "plbase64.h"
      89                 : #include "cms.h"
      90                 : #include "cert.h"
      91                 : 
      92                 : #ifdef PR_LOGGING
      93                 : extern PRLogModuleInfo* gPIPNSSLog;
      94                 : #endif
      95                 : 
      96                 : static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
      97                 : 
      98               0 : NSSCleanupAutoPtrClass(CERTCertificateList, CERT_DestroyCertificateList)
      99               0 : NSSCleanupAutoPtrClass(CERTCertificate, CERT_DestroyCertificate)
     100               0 : NSSCleanupAutoPtrClass(NSSCMSMessage, NSS_CMSMessage_Destroy)
     101               0 : NSSCleanupAutoPtrClass_WithParam(PLArenaPool, PORT_FreeArena, FalseParam, false)
     102               0 : NSSCleanupAutoPtrClass(NSSCMSSignedData, NSS_CMSSignedData_Destroy)
     103               0 : NSSCleanupAutoPtrClass(PK11SlotList, PK11_FreeSlotList)
     104                 : 
     105                 : // This is being stored in an PRUint32 that can otherwise
     106                 : // only take values from nsIX509Cert's list of cert types.
     107                 : // As nsIX509Cert is frozen, we choose a value not contained
     108                 : // in the list to mean not yet initialized.
     109                 : #define CERT_TYPE_NOT_YET_INITIALIZED (1 << 30)
     110                 : 
     111                 : /* nsNSSCertificate */
     112                 : 
     113              80 : NS_IMPL_THREADSAFE_ISUPPORTS7(nsNSSCertificate, nsIX509Cert,
     114                 :                                                 nsIX509Cert2,
     115                 :                                                 nsIX509Cert3,
     116                 :                                                 nsIIdentityInfo,
     117                 :                                                 nsISMimeCert,
     118                 :                                                 nsISerializable,
     119                 :                                                 nsIClassInfo)
     120                 : 
     121                 : /* static */
     122                 : nsNSSCertificate*
     123               8 : nsNSSCertificate::Create(CERTCertificate *cert)
     124                 : {
     125               8 :   if (GeckoProcessType_Default != XRE_GetProcessType()) {
     126               0 :     NS_ERROR("Trying to initialize nsNSSCertificate in a non-chrome process!");
     127               0 :     return nsnull;
     128                 :   }
     129               8 :   if (cert)
     130               8 :     return new nsNSSCertificate(cert);
     131                 :   else
     132               0 :     return new nsNSSCertificate();
     133                 : }
     134                 : 
     135                 : nsNSSCertificate*
     136               0 : nsNSSCertificate::ConstructFromDER(char *certDER, int derLen)
     137                 : {
     138                 :   // On non-chrome process prevent instantiation
     139               0 :   if (GeckoProcessType_Default != XRE_GetProcessType())
     140               0 :     return nsnull;
     141                 : 
     142               0 :   nsNSSCertificate* newObject = nsNSSCertificate::Create();
     143               0 :   if (newObject && !newObject->InitFromDER(certDER, derLen)) {
     144               0 :     delete newObject;
     145               0 :     newObject = nsnull;
     146                 :   }
     147                 : 
     148               0 :   return newObject;
     149                 : }
     150                 : 
     151                 : bool
     152               0 : nsNSSCertificate::InitFromDER(char *certDER, int derLen)
     153                 : {
     154               0 :   nsNSSShutDownPreventionLock locker;
     155               0 :   if (isAlreadyShutDown())
     156               0 :     return false;
     157                 : 
     158               0 :   if (!certDER || !derLen)
     159               0 :     return false;
     160                 : 
     161               0 :   CERTCertificate *aCert = CERT_DecodeCertFromPackage(certDER, derLen);
     162                 :   
     163               0 :   if (!aCert)
     164               0 :     return false;
     165                 : 
     166               0 :   if(aCert->dbhandle == nsnull)
     167                 :   {
     168               0 :     aCert->dbhandle = CERT_GetDefaultCertDB();
     169                 :   }
     170                 : 
     171               0 :   mCert = aCert;
     172               0 :   return true;
     173                 : }
     174                 : 
     175             176 : nsNSSCertificate::nsNSSCertificate(CERTCertificate *cert) : 
     176                 :                                            mCert(nsnull),
     177                 :                                            mPermDelete(false),
     178                 :                                            mCertType(CERT_TYPE_NOT_YET_INITIALIZED),
     179             176 :                                            mCachedEVStatus(ev_status_unknown)
     180                 : {
     181                 : #if defined(DEBUG)
     182             176 :   if (GeckoProcessType_Default != XRE_GetProcessType())
     183               0 :     NS_ERROR("Trying to initialize nsNSSCertificate in a non-chrome process!");
     184                 : #endif
     185                 : 
     186             352 :   nsNSSShutDownPreventionLock locker;
     187             176 :   if (isAlreadyShutDown())
     188                 :     return;
     189                 : 
     190             176 :   if (cert) 
     191             176 :     mCert = CERT_DupCertificate(cert);
     192                 : }
     193                 : 
     194               0 : nsNSSCertificate::nsNSSCertificate() : 
     195                 :   mCert(nsnull),
     196                 :   mPermDelete(false),
     197                 :   mCertType(CERT_TYPE_NOT_YET_INITIALIZED),
     198               0 :   mCachedEVStatus(ev_status_unknown)
     199                 : {
     200               0 :   if (GeckoProcessType_Default != XRE_GetProcessType())
     201               0 :     NS_ERROR("Trying to initialize nsNSSCertificate in a non-chrome process!");
     202               0 : }
     203                 : 
     204             360 : nsNSSCertificate::~nsNSSCertificate()
     205                 : {
     206             352 :   nsNSSShutDownPreventionLock locker;
     207             176 :   if (isAlreadyShutDown())
     208                 :     return;
     209                 : 
     210             172 :   destructorSafeDestroyNSSReference();
     211             348 :   shutdown(calledFromObject);
     212             368 : }
     213                 : 
     214               4 : void nsNSSCertificate::virtualDestroyNSSReference()
     215                 : {
     216               4 :   destructorSafeDestroyNSSReference();
     217               4 : }
     218                 : 
     219             176 : void nsNSSCertificate::destructorSafeDestroyNSSReference()
     220                 : {
     221             176 :   if (isAlreadyShutDown())
     222               0 :     return;
     223                 : 
     224             176 :   if (mPermDelete) {
     225               0 :     if (mCertType == nsNSSCertificate::USER_CERT) {
     226               0 :       nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext();
     227               0 :       PK11_DeleteTokenCertAndKey(mCert, cxt);
     228               0 :     } else if (!PK11_IsReadOnly(mCert->slot)) {
     229                 :       // If the list of built-ins does contain a non-removable
     230                 :       // copy of this certificate, our call will not remove
     231                 :       // the certificate permanently, but rather remove all trust.
     232               0 :       SEC_DeletePermCertificate(mCert);
     233                 :     }
     234                 :   }
     235                 : 
     236             176 :   if (mCert) {
     237             176 :     CERT_DestroyCertificate(mCert);
     238             176 :     mCert = nsnull;
     239                 :   }
     240                 : }
     241                 : 
     242                 : nsresult
     243               0 : nsNSSCertificate::GetCertType(PRUint32 *aCertType)
     244                 : {
     245               0 :   if (mCertType == CERT_TYPE_NOT_YET_INITIALIZED) {
     246                 :      // only determine cert type once and cache it
     247               0 :      mCertType = getCertType(mCert);
     248                 :   }
     249               0 :   *aCertType = mCertType;
     250               0 :   return NS_OK;
     251                 : }
     252                 : 
     253                 : NS_IMETHODIMP
     254               0 : nsNSSCertificate::GetIsSelfSigned(bool *aIsSelfSigned)
     255                 : {
     256               0 :   NS_ENSURE_ARG(aIsSelfSigned);
     257                 : 
     258               0 :   nsNSSShutDownPreventionLock locker;
     259               0 :   if (isAlreadyShutDown())
     260               0 :     return NS_ERROR_NOT_AVAILABLE;
     261                 : 
     262               0 :   *aIsSelfSigned = mCert->isRoot;
     263               0 :   return NS_OK;
     264                 : }
     265                 : 
     266                 : nsresult
     267               0 : nsNSSCertificate::MarkForPermDeletion()
     268                 : {
     269               0 :   nsNSSShutDownPreventionLock locker;
     270               0 :   if (isAlreadyShutDown())
     271               0 :     return NS_ERROR_NOT_AVAILABLE;
     272                 : 
     273                 :   // make sure user is logged in to the token
     274               0 :   nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
     275                 : 
     276               0 :   if (PK11_NeedLogin(mCert->slot)
     277               0 :       && !PK11_NeedUserInit(mCert->slot)
     278               0 :       && !PK11_IsInternal(mCert->slot))
     279                 :   {
     280               0 :     if (SECSuccess != PK11_Authenticate(mCert->slot, true, ctx))
     281                 :     {
     282               0 :       return NS_ERROR_FAILURE;
     283                 :     }
     284                 :   }
     285                 : 
     286               0 :   mPermDelete = true;
     287               0 :   return NS_OK;
     288                 : }
     289                 : 
     290                 : nsresult
     291               0 : GetKeyUsagesString(CERTCertificate *cert, nsINSSComponent *nssComponent, 
     292                 :                    nsString &text)
     293                 : {
     294               0 :   text.Truncate();
     295                 : 
     296                 :   SECItem keyUsageItem;
     297               0 :   keyUsageItem.data = NULL;
     298                 : 
     299                 :   SECStatus srv;
     300                 : 
     301                 :   /* There is no extension, v1 or v2 certificate */
     302               0 :   if (!cert->extensions)
     303               0 :     return NS_OK;
     304                 : 
     305                 : 
     306               0 :   srv = CERT_FindKeyUsageExtension(cert, &keyUsageItem);
     307               0 :   if (srv == SECFailure) {
     308               0 :     if (PORT_GetError () == SEC_ERROR_EXTENSION_NOT_FOUND)
     309               0 :       return NS_OK;
     310                 :     else
     311               0 :       return NS_ERROR_FAILURE;
     312                 :   }
     313                 : 
     314               0 :   unsigned char keyUsage = keyUsageItem.data[0];
     315               0 :   nsAutoString local;
     316                 :   nsresult rv;
     317               0 :   const PRUnichar *comma = NS_LITERAL_STRING(",").get();
     318                 : 
     319               0 :   if (keyUsage & KU_DIGITAL_SIGNATURE) {
     320               0 :     rv = nssComponent->GetPIPNSSBundleString("CertDumpKUSign", local);
     321               0 :     if (NS_SUCCEEDED(rv)) {
     322               0 :       if (!text.IsEmpty()) text.Append(comma);
     323               0 :       text.Append(local.get());
     324                 :     }
     325                 :   }
     326               0 :   if (keyUsage & KU_NON_REPUDIATION) {
     327               0 :     rv = nssComponent->GetPIPNSSBundleString("CertDumpKUNonRep", local);
     328               0 :     if (NS_SUCCEEDED(rv)) {
     329               0 :       if (!text.IsEmpty()) text.Append(comma);
     330               0 :       text.Append(local.get());
     331                 :     }
     332                 :   }
     333               0 :   if (keyUsage & KU_KEY_ENCIPHERMENT) {
     334               0 :     rv = nssComponent->GetPIPNSSBundleString("CertDumpKUEnc", local);
     335               0 :     if (NS_SUCCEEDED(rv)) {
     336               0 :       if (!text.IsEmpty()) text.Append(comma);
     337               0 :       text.Append(local.get());
     338                 :     }
     339                 :   }
     340               0 :   if (keyUsage & KU_DATA_ENCIPHERMENT) {
     341               0 :     rv = nssComponent->GetPIPNSSBundleString("CertDumpKUDEnc", local);
     342               0 :     if (NS_SUCCEEDED(rv)) {
     343               0 :       if (!text.IsEmpty()) text.Append(comma);
     344               0 :       text.Append(local.get());
     345                 :     }
     346                 :   }
     347               0 :   if (keyUsage & KU_KEY_AGREEMENT) {
     348               0 :     rv = nssComponent->GetPIPNSSBundleString("CertDumpKUKA", local);
     349               0 :     if (NS_SUCCEEDED(rv)) {
     350               0 :       if (!text.IsEmpty()) text.Append(comma);
     351               0 :       text.Append(local.get());
     352                 :     }
     353                 :   }
     354               0 :   if (keyUsage & KU_KEY_CERT_SIGN) {
     355               0 :     rv = nssComponent->GetPIPNSSBundleString("CertDumpKUCertSign", local);
     356               0 :     if (NS_SUCCEEDED(rv)) {
     357               0 :       if (!text.IsEmpty()) text.Append(comma);
     358               0 :       text.Append(local.get());
     359                 :     }
     360                 :   }
     361               0 :   if (keyUsage & KU_CRL_SIGN) {
     362               0 :     rv = nssComponent->GetPIPNSSBundleString("CertDumpKUCRLSign", local);
     363               0 :     if (NS_SUCCEEDED(rv)) {
     364               0 :       if (!text.IsEmpty()) text.Append(comma);
     365               0 :       text.Append(local.get());
     366                 :     }
     367                 :   }
     368                 : 
     369               0 :   PORT_Free (keyUsageItem.data);
     370               0 :   return NS_OK;
     371                 : }
     372                 : 
     373                 : nsresult
     374               0 : nsNSSCertificate::FormatUIStrings(const nsAutoString &nickname, nsAutoString &nickWithSerial, nsAutoString &details)
     375                 : {
     376               0 :   if (!NS_IsMainThread()) {
     377               0 :     NS_ERROR("nsNSSCertificate::FormatUIStrings called off the main thread");
     378               0 :     return NS_ERROR_NOT_SAME_THREAD;
     379                 :   }
     380                 :   
     381               0 :   nsresult rv = NS_OK;
     382                 : 
     383               0 :   nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
     384                 : 
     385               0 :   if (NS_FAILED(rv) || !nssComponent) {
     386               0 :     return NS_ERROR_FAILURE;
     387                 :   }
     388                 :   
     389               0 :   nsAutoString info;
     390               0 :   nsAutoString temp1;
     391                 : 
     392               0 :   nickWithSerial.Append(nickname);
     393                 : 
     394               0 :   if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertInfoIssuedFor", info))) {
     395               0 :     details.Append(info);
     396               0 :     details.Append(PRUnichar(' '));
     397               0 :     if (NS_SUCCEEDED(GetSubjectName(temp1)) && !temp1.IsEmpty()) {
     398               0 :       details.Append(temp1);
     399                 :     }
     400               0 :     details.Append(PRUnichar('\n'));
     401                 :   }
     402                 : 
     403               0 :   if (NS_SUCCEEDED(GetSerialNumber(temp1)) && !temp1.IsEmpty()) {
     404               0 :     details.AppendLiteral("  ");
     405               0 :     if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertDumpSerialNo", info))) {
     406               0 :       details.Append(info);
     407               0 :       details.AppendLiteral(": ");
     408                 :     }
     409               0 :     details.Append(temp1);
     410                 : 
     411               0 :     nickWithSerial.AppendLiteral(" [");
     412               0 :     nickWithSerial.Append(temp1);
     413               0 :     nickWithSerial.Append(PRUnichar(']'));
     414                 : 
     415               0 :     details.Append(PRUnichar('\n'));
     416                 :   }
     417                 : 
     418               0 :   nsCOMPtr<nsIX509CertValidity> validity;
     419               0 :   rv = GetValidity(getter_AddRefs(validity));
     420               0 :   if (NS_SUCCEEDED(rv) && validity) {
     421               0 :     details.AppendLiteral("  ");
     422               0 :     if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertInfoValid", info))) {
     423               0 :       details.Append(info);
     424                 :     }
     425                 : 
     426               0 :     if (NS_SUCCEEDED(validity->GetNotBeforeLocalTime(temp1)) && !temp1.IsEmpty()) {
     427               0 :       details.Append(PRUnichar(' '));
     428               0 :       if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertInfoFrom", info))) {
     429               0 :         details.Append(info);
     430               0 :         details.Append(PRUnichar(' '));
     431                 :       }
     432               0 :       details.Append(temp1);
     433                 :     }
     434                 : 
     435               0 :     if (NS_SUCCEEDED(validity->GetNotAfterLocalTime(temp1)) && !temp1.IsEmpty()) {
     436               0 :       details.Append(PRUnichar(' '));
     437               0 :       if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertInfoTo", info))) {
     438               0 :         details.Append(info);
     439               0 :         details.Append(PRUnichar(' '));
     440                 :       }
     441               0 :       details.Append(temp1);
     442                 :     }
     443                 : 
     444               0 :     details.Append(PRUnichar('\n'));
     445                 :   }
     446                 : 
     447               0 :   if (NS_SUCCEEDED(GetKeyUsagesString(mCert, nssComponent, temp1)) && !temp1.IsEmpty()) {
     448               0 :     details.AppendLiteral("  ");
     449               0 :     if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertDumpKeyUsage", info))) {
     450               0 :       details.Append(info);
     451               0 :       details.AppendLiteral(": ");
     452                 :     }
     453               0 :     details.Append(temp1);
     454               0 :     details.Append(PRUnichar('\n'));
     455                 :   }
     456                 : 
     457               0 :   nsAutoString firstEmail;
     458                 :   const char *aWalkAddr;
     459               0 :   for (aWalkAddr = CERT_GetFirstEmailAddress(mCert)
     460               0 :         ;
     461                 :         aWalkAddr
     462                 :         ;
     463               0 :         aWalkAddr = CERT_GetNextEmailAddress(mCert, aWalkAddr))
     464                 :   {
     465               0 :     NS_ConvertUTF8toUTF16 email(aWalkAddr);
     466               0 :     if (email.IsEmpty())
     467               0 :       continue;
     468                 : 
     469               0 :     if (firstEmail.IsEmpty()) {
     470                 :       /*
     471                 :         * If the first email address from the subject DN is also present
     472                 :         * in the subjectAltName extension, GetEmailAddresses() will return
     473                 :         * it twice (as received from NSS). Remember the first address so that
     474                 :         * we can filter out duplicates later on.
     475                 :         */
     476               0 :       firstEmail = email;
     477                 : 
     478               0 :       details.AppendLiteral("  ");
     479               0 :       if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertInfoEmail", info))) {
     480               0 :         details.Append(info);
     481               0 :         details.AppendLiteral(": ");
     482                 :       }
     483               0 :       details.Append(email);
     484                 :     }
     485                 :     else {
     486                 :       // Append current address if it's different from the first one.
     487               0 :       if (!firstEmail.Equals(email)) {
     488               0 :         details.AppendLiteral(", ");
     489               0 :         details.Append(email);
     490                 :       }
     491                 :     }
     492                 :   }
     493                 : 
     494               0 :   if (!firstEmail.IsEmpty()) {
     495                 :     // We got at least one email address, so we want a newline
     496               0 :     details.Append(PRUnichar('\n'));
     497                 :   }
     498                 : 
     499               0 :   if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertInfoIssuedBy", info))) {
     500               0 :     details.Append(info);
     501               0 :     details.Append(PRUnichar(' '));
     502                 : 
     503               0 :     if (NS_SUCCEEDED(GetIssuerName(temp1)) && !temp1.IsEmpty()) {
     504               0 :       details.Append(temp1);
     505                 :     }
     506                 : 
     507               0 :     details.Append(PRUnichar('\n'));
     508                 :   }
     509                 : 
     510               0 :   if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertInfoStoredIn", info))) {
     511               0 :     details.Append(info);
     512               0 :     details.Append(PRUnichar(' '));
     513                 : 
     514               0 :     if (NS_SUCCEEDED(GetTokenName(temp1)) && !temp1.IsEmpty()) {
     515               0 :       details.Append(temp1);
     516                 :     }
     517                 :   }
     518                 : 
     519                 :   /*
     520                 :     the above produces the following output:
     521                 : 
     522                 :     Issued to: $subjectName
     523                 :     Serial number: $serialNumber
     524                 :     Valid from: $starting_date to $expiration_date
     525                 :     Certificate Key usage: $usages
     526                 :     Email: $address(es)
     527                 :     Issued by: $issuerName
     528                 :     Stored in: $token
     529                 :   */
     530                 :   
     531               0 :   return rv;
     532                 : }
     533                 : 
     534                 : 
     535                 : /* readonly attribute string dbKey; */
     536                 : NS_IMETHODIMP 
     537               0 : nsNSSCertificate::GetDbKey(char * *aDbKey)
     538                 : {
     539               0 :   nsNSSShutDownPreventionLock locker;
     540               0 :   if (isAlreadyShutDown())
     541               0 :     return NS_ERROR_NOT_AVAILABLE;
     542                 : 
     543                 :   SECItem key;
     544                 : 
     545               0 :   NS_ENSURE_ARG(aDbKey);
     546               0 :   *aDbKey = nsnull;
     547               0 :   key.len = NS_NSS_LONG*4+mCert->serialNumber.len+mCert->derIssuer.len;
     548               0 :   key.data = (unsigned char *)nsMemory::Alloc(key.len);
     549               0 :   if (!key.data)
     550               0 :     return NS_ERROR_OUT_OF_MEMORY;
     551               0 :   NS_NSS_PUT_LONG(0,key.data); // later put moduleID
     552               0 :   NS_NSS_PUT_LONG(0,&key.data[NS_NSS_LONG]); // later put slotID
     553               0 :   NS_NSS_PUT_LONG(mCert->serialNumber.len,&key.data[NS_NSS_LONG*2]);
     554               0 :   NS_NSS_PUT_LONG(mCert->derIssuer.len,&key.data[NS_NSS_LONG*3]);
     555               0 :   memcpy(&key.data[NS_NSS_LONG*4], mCert->serialNumber.data,
     556               0 :          mCert->serialNumber.len);
     557               0 :   memcpy(&key.data[NS_NSS_LONG*4+mCert->serialNumber.len],
     558               0 :          mCert->derIssuer.data, mCert->derIssuer.len);
     559                 :   
     560               0 :   *aDbKey = NSSBase64_EncodeItem(nsnull, nsnull, 0, &key);
     561               0 :   nsMemory::Free(key.data); // SECItem is a 'c' type without a destrutor
     562               0 :   return (*aDbKey) ? NS_OK : NS_ERROR_FAILURE;
     563                 : }
     564                 : 
     565                 : /* readonly attribute string windowTitle; */
     566                 : NS_IMETHODIMP 
     567               0 : nsNSSCertificate::GetWindowTitle(char * *aWindowTitle)
     568                 : {
     569               0 :   nsNSSShutDownPreventionLock locker;
     570               0 :   if (isAlreadyShutDown())
     571               0 :     return NS_ERROR_NOT_AVAILABLE;
     572                 : 
     573               0 :   NS_ENSURE_ARG(aWindowTitle);
     574               0 :   if (mCert) {
     575               0 :     if (mCert->nickname) {
     576               0 :       *aWindowTitle = PL_strdup(mCert->nickname);
     577                 :     } else {
     578               0 :       *aWindowTitle = CERT_GetCommonName(&mCert->subject);
     579               0 :       if (!*aWindowTitle) {
     580               0 :         if (mCert->subjectName) {
     581               0 :           *aWindowTitle = PL_strdup(mCert->subjectName);
     582               0 :         } else if (mCert->emailAddr) {
     583               0 :           *aWindowTitle = PL_strdup(mCert->emailAddr);
     584                 :         } else {
     585               0 :           *aWindowTitle = PL_strdup("");
     586                 :         }
     587                 :       }
     588                 :     }
     589                 :   } else {
     590               0 :     NS_ERROR("Somehow got nsnull for mCertificate in nsNSSCertificate.");
     591               0 :     *aWindowTitle = nsnull;
     592                 :   }
     593               0 :   return NS_OK;
     594                 : }
     595                 : 
     596                 : NS_IMETHODIMP
     597               0 : nsNSSCertificate::GetNickname(nsAString &aNickname)
     598                 : {
     599               0 :   nsNSSShutDownPreventionLock locker;
     600               0 :   if (isAlreadyShutDown())
     601               0 :     return NS_ERROR_NOT_AVAILABLE;
     602                 : 
     603               0 :   if (mCert->nickname) {
     604               0 :     CopyUTF8toUTF16(mCert->nickname, aNickname);
     605                 :   } else {
     606                 :     nsresult rv;
     607               0 :     nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
     608               0 :     if (NS_FAILED(rv) || !nssComponent) {
     609               0 :       return NS_ERROR_FAILURE;
     610                 :     }
     611               0 :     nssComponent->GetPIPNSSBundleString("CertNoNickname", aNickname);
     612                 :   }
     613               0 :   return NS_OK;
     614                 : }
     615                 : 
     616                 : NS_IMETHODIMP
     617               0 : nsNSSCertificate::GetEmailAddress(nsAString &aEmailAddress)
     618                 : {
     619               0 :   nsNSSShutDownPreventionLock locker;
     620               0 :   if (isAlreadyShutDown())
     621               0 :     return NS_ERROR_NOT_AVAILABLE;
     622                 : 
     623               0 :   if (mCert->emailAddr) {
     624               0 :     CopyUTF8toUTF16(mCert->emailAddr, aEmailAddress);
     625                 :   } else {
     626                 :     nsresult rv;
     627               0 :     nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
     628               0 :     if (NS_FAILED(rv) || !nssComponent) {
     629               0 :       return NS_ERROR_FAILURE;
     630                 :     }
     631               0 :     nssComponent->GetPIPNSSBundleString("CertNoEmailAddress", aEmailAddress);
     632                 :   }
     633               0 :   return NS_OK;
     634                 : }
     635                 : 
     636                 : NS_IMETHODIMP
     637               0 : nsNSSCertificate::GetEmailAddresses(PRUint32 *aLength, PRUnichar*** aAddresses)
     638                 : {
     639               0 :   nsNSSShutDownPreventionLock locker;
     640               0 :   if (isAlreadyShutDown())
     641               0 :     return NS_ERROR_NOT_AVAILABLE;
     642                 : 
     643               0 :   NS_ENSURE_ARG(aLength);
     644               0 :   NS_ENSURE_ARG(aAddresses);
     645                 : 
     646               0 :   *aLength = 0;
     647                 : 
     648                 :   const char *aAddr;
     649               0 :   for (aAddr = CERT_GetFirstEmailAddress(mCert)
     650               0 :        ;
     651                 :        aAddr
     652                 :        ;
     653               0 :        aAddr = CERT_GetNextEmailAddress(mCert, aAddr))
     654                 :   {
     655               0 :     ++(*aLength);
     656                 :   }
     657                 : 
     658               0 :   *aAddresses = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * (*aLength));
     659               0 :   if (!*aAddresses)
     660               0 :     return NS_ERROR_OUT_OF_MEMORY;
     661                 : 
     662                 :   PRUint32 iAddr;
     663               0 :   for (aAddr = CERT_GetFirstEmailAddress(mCert), iAddr = 0
     664               0 :        ;
     665                 :        aAddr
     666                 :        ;
     667               0 :        aAddr = CERT_GetNextEmailAddress(mCert, aAddr), ++iAddr)
     668                 :   {
     669               0 :     (*aAddresses)[iAddr] = ToNewUnicode(NS_ConvertUTF8toUTF16(aAddr));
     670                 :   }
     671                 : 
     672               0 :   return NS_OK;
     673                 : }
     674                 : 
     675                 : NS_IMETHODIMP
     676               0 : nsNSSCertificate::ContainsEmailAddress(const nsAString &aEmailAddress, bool *result)
     677                 : {
     678               0 :   nsNSSShutDownPreventionLock locker;
     679               0 :   if (isAlreadyShutDown())
     680               0 :     return NS_ERROR_NOT_AVAILABLE;
     681                 : 
     682               0 :   NS_ENSURE_ARG(result);
     683               0 :   *result = false;
     684                 : 
     685               0 :   const char *aAddr = nsnull;
     686               0 :   for (aAddr = CERT_GetFirstEmailAddress(mCert)
     687               0 :        ;
     688                 :        aAddr
     689                 :        ;
     690               0 :        aAddr = CERT_GetNextEmailAddress(mCert, aAddr))
     691                 :   {
     692               0 :     NS_ConvertUTF8toUTF16 certAddr(aAddr);
     693               0 :     ToLowerCase(certAddr);
     694                 : 
     695               0 :     nsAutoString testAddr(aEmailAddress);
     696               0 :     ToLowerCase(testAddr);
     697                 :     
     698               0 :     if (certAddr == testAddr)
     699                 :     {
     700               0 :       *result = true;
     701                 :       break;
     702                 :     }
     703                 : 
     704                 :   }
     705                 :   
     706               0 :   return NS_OK;
     707                 : }
     708                 : 
     709                 : NS_IMETHODIMP
     710               0 : nsNSSCertificate::GetCommonName(nsAString &aCommonName)
     711                 : {
     712               0 :   nsNSSShutDownPreventionLock locker;
     713               0 :   if (isAlreadyShutDown())
     714               0 :     return NS_ERROR_NOT_AVAILABLE;
     715                 : 
     716               0 :   aCommonName.Truncate();
     717               0 :   if (mCert) {
     718               0 :     char *commonName = CERT_GetCommonName(&mCert->subject);
     719               0 :     if (commonName) {
     720               0 :       aCommonName = NS_ConvertUTF8toUTF16(commonName);
     721               0 :       PORT_Free(commonName);
     722                 :     } /*else {
     723                 :       *aCommonName = ToNewUnicode(NS_LITERAL_STRING("<not set>")), 
     724                 :     }*/
     725                 :   }
     726               0 :   return NS_OK;
     727                 : }
     728                 : 
     729                 : NS_IMETHODIMP
     730               0 : nsNSSCertificate::GetOrganization(nsAString &aOrganization)
     731                 : {
     732               0 :   nsNSSShutDownPreventionLock locker;
     733               0 :   if (isAlreadyShutDown())
     734               0 :     return NS_ERROR_NOT_AVAILABLE;
     735                 : 
     736               0 :   aOrganization.Truncate();
     737               0 :   if (mCert) {
     738               0 :     char *organization = CERT_GetOrgName(&mCert->subject);
     739               0 :     if (organization) {
     740               0 :       aOrganization = NS_ConvertUTF8toUTF16(organization);
     741               0 :       PORT_Free(organization);
     742                 :     } /*else {
     743                 :       *aOrganization = ToNewUnicode(NS_LITERAL_STRING("<not set>")), 
     744                 :     }*/
     745                 :   }
     746               0 :   return NS_OK;
     747                 : }
     748                 : 
     749                 : NS_IMETHODIMP
     750               0 : nsNSSCertificate::GetIssuerCommonName(nsAString &aCommonName)
     751                 : {
     752               0 :   nsNSSShutDownPreventionLock locker;
     753               0 :   if (isAlreadyShutDown())
     754               0 :     return NS_ERROR_NOT_AVAILABLE;
     755                 : 
     756               0 :   aCommonName.Truncate();
     757               0 :   if (mCert) {
     758               0 :     char *commonName = CERT_GetCommonName(&mCert->issuer);
     759               0 :     if (commonName) {
     760               0 :       aCommonName = NS_ConvertUTF8toUTF16(commonName);
     761               0 :       PORT_Free(commonName);
     762                 :     }
     763                 :   }
     764               0 :   return NS_OK;
     765                 : }
     766                 : 
     767                 : NS_IMETHODIMP
     768               0 : nsNSSCertificate::GetIssuerOrganization(nsAString &aOrganization)
     769                 : {
     770               0 :   nsNSSShutDownPreventionLock locker;
     771               0 :   if (isAlreadyShutDown())
     772               0 :     return NS_ERROR_NOT_AVAILABLE;
     773                 : 
     774               0 :   aOrganization.Truncate();
     775               0 :   if (mCert) {
     776               0 :     char *organization = CERT_GetOrgName(&mCert->issuer);
     777               0 :     if (organization) {
     778               0 :       aOrganization = NS_ConvertUTF8toUTF16(organization);
     779               0 :       PORT_Free(organization);
     780                 :     } else {
     781               0 :       return GetIssuerCommonName(aOrganization);
     782                 :     }
     783                 :   }
     784               0 :   return NS_OK;
     785                 : }
     786                 : 
     787                 : NS_IMETHODIMP
     788               0 : nsNSSCertificate::GetIssuerOrganizationUnit(nsAString &aOrganizationUnit)
     789                 : {
     790               0 :   nsNSSShutDownPreventionLock locker;
     791               0 :   if (isAlreadyShutDown())
     792               0 :     return NS_ERROR_NOT_AVAILABLE;
     793                 : 
     794               0 :   aOrganizationUnit.Truncate();
     795               0 :   if (mCert) {
     796               0 :     char *organizationUnit = CERT_GetOrgUnitName(&mCert->issuer);
     797               0 :     if (organizationUnit) {
     798               0 :       aOrganizationUnit = NS_ConvertUTF8toUTF16(organizationUnit);
     799               0 :       PORT_Free(organizationUnit);
     800                 :     }
     801                 :   }
     802               0 :   return NS_OK;
     803                 : }
     804                 : 
     805                 : /* readonly attribute nsIX509Cert issuer; */
     806                 : NS_IMETHODIMP 
     807               0 : nsNSSCertificate::GetIssuer(nsIX509Cert * *aIssuer)
     808                 : {
     809               0 :   nsNSSShutDownPreventionLock locker;
     810               0 :   if (isAlreadyShutDown())
     811               0 :     return NS_ERROR_NOT_AVAILABLE;
     812                 : 
     813               0 :   NS_ENSURE_ARG(aIssuer);
     814               0 :   *aIssuer = nsnull;
     815                 :   CERTCertificate *issuer;
     816               0 :   issuer = CERT_FindCertIssuer(mCert, PR_Now(), certUsageSSLClient);
     817               0 :   if (issuer) {
     818               0 :     nsCOMPtr<nsIX509Cert> cert = nsNSSCertificate::Create(issuer);
     819               0 :     if (cert) {
     820               0 :       *aIssuer = cert;
     821               0 :       NS_ADDREF(*aIssuer);
     822                 :     }
     823               0 :     CERT_DestroyCertificate(issuer);
     824                 :   }
     825               0 :   return NS_OK;
     826                 : }
     827                 : 
     828                 : NS_IMETHODIMP
     829               0 : nsNSSCertificate::GetOrganizationalUnit(nsAString &aOrganizationalUnit)
     830                 : {
     831               0 :   nsNSSShutDownPreventionLock locker;
     832               0 :   if (isAlreadyShutDown())
     833               0 :     return NS_ERROR_NOT_AVAILABLE;
     834                 : 
     835               0 :   aOrganizationalUnit.Truncate();
     836               0 :   if (mCert) {
     837               0 :     char *orgunit = CERT_GetOrgUnitName(&mCert->subject);
     838               0 :     if (orgunit) {
     839               0 :       aOrganizationalUnit = NS_ConvertUTF8toUTF16(orgunit);
     840               0 :       PORT_Free(orgunit);
     841                 :     } /*else {
     842                 :       *aOrganizationalUnit = ToNewUnicode(NS_LITERAL_STRING("<not set>")), 
     843                 :     }*/
     844                 :   }
     845               0 :   return NS_OK;
     846                 : }
     847                 : 
     848                 : /* 
     849                 :  * nsIEnumerator getChain(); 
     850                 :  */
     851                 : NS_IMETHODIMP
     852               0 : nsNSSCertificate::GetChain(nsIArray **_rvChain)
     853                 : {
     854               0 :   nsNSSShutDownPreventionLock locker;
     855               0 :   if (isAlreadyShutDown())
     856               0 :     return NS_ERROR_NOT_AVAILABLE;
     857                 : 
     858               0 :   NS_ENSURE_ARG(_rvChain);
     859                 :   nsresult rv;
     860                 :   /* Get the cert chain from NSS */
     861               0 :   CERTCertList *nssChain = NULL;
     862               0 :   PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Getting chain for \"%s\"\n", mCert->nickname));
     863               0 :   nssChain = CERT_GetCertChainFromCert(mCert, PR_Now(), certUsageSSLClient);
     864               0 :   if (!nssChain)
     865               0 :     return NS_ERROR_FAILURE;
     866                 :   /* enumerate the chain for scripting purposes */
     867                 :   nsCOMPtr<nsIMutableArray> array =
     868               0 :     do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
     869               0 :   if (NS_FAILED(rv)) { 
     870               0 :     goto done; 
     871                 :   }
     872                 :   CERTCertListNode *node;
     873               0 :   for (node = CERT_LIST_HEAD(nssChain);
     874               0 :        !CERT_LIST_END(node, nssChain);
     875                 :        node = CERT_LIST_NEXT(node)) {
     876               0 :     PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("adding %s to chain\n", node->cert->nickname));
     877               0 :     nsCOMPtr<nsIX509Cert> cert = nsNSSCertificate::Create(node->cert);
     878               0 :     array->AppendElement(cert, false);
     879                 :   }
     880               0 :   *_rvChain = array;
     881               0 :   NS_IF_ADDREF(*_rvChain);
     882               0 :   rv = NS_OK;
     883                 : done:
     884               0 :   if (nssChain)
     885               0 :     CERT_DestroyCertList(nssChain);
     886               0 :   return rv;
     887                 : }
     888                 : 
     889                 : NS_IMETHODIMP
     890               0 : nsNSSCertificate::GetAllTokenNames(PRUint32 *aLength, PRUnichar*** aTokenNames)
     891                 : {
     892               0 :   nsNSSShutDownPreventionLock locker;
     893               0 :   if (isAlreadyShutDown())
     894               0 :     return NS_ERROR_NOT_AVAILABLE;
     895                 : 
     896               0 :   NS_ENSURE_ARG(aLength);
     897               0 :   NS_ENSURE_ARG(aTokenNames);
     898               0 :   *aLength = 0;
     899               0 :   *aTokenNames = NULL;
     900                 : 
     901                 :   /* Get the slots from NSS */
     902               0 :   PK11SlotList *slots = NULL;
     903               0 :   PK11SlotListCleaner slotCleaner(slots);
     904               0 :   PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Getting slots for \"%s\"\n", mCert->nickname));
     905               0 :   slots = PK11_GetAllSlotsForCert(mCert, NULL);
     906               0 :   if (!slots) {
     907               0 :     if (PORT_GetError() == SEC_ERROR_NO_TOKEN)
     908               0 :       return NS_OK; // List of slots is empty, return empty array
     909                 :     else
     910               0 :       return NS_ERROR_FAILURE;
     911                 :   }
     912                 : 
     913                 :   /* read the token names from slots */
     914                 :   PK11SlotListElement *le;
     915                 : 
     916               0 :   for (le = slots->head; le; le = le->next) {
     917               0 :     ++(*aLength);
     918                 :   }
     919                 : 
     920               0 :   *aTokenNames = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * (*aLength));
     921               0 :   if (!*aTokenNames) {
     922               0 :     *aLength = 0;
     923               0 :     return NS_ERROR_OUT_OF_MEMORY;
     924                 :   }
     925                 : 
     926                 :   PRUint32 iToken;
     927               0 :   for (le = slots->head, iToken = 0; le; le = le->next, ++iToken) {
     928               0 :     char *token = PK11_GetTokenName(le->slot);
     929               0 :     (*aTokenNames)[iToken] = ToNewUnicode(NS_ConvertUTF8toUTF16(token));
     930               0 :     if (!(*aTokenNames)[iToken]) {
     931               0 :       NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(iToken, *aTokenNames);
     932               0 :       *aLength = 0;
     933               0 :       *aTokenNames = NULL;
     934               0 :       return NS_ERROR_OUT_OF_MEMORY;
     935                 :     }
     936                 :   }
     937                 : 
     938               0 :   return NS_OK;
     939                 : }
     940                 : 
     941                 : NS_IMETHODIMP
     942               0 : nsNSSCertificate::GetSubjectName(nsAString &_subjectName)
     943                 : {
     944               0 :   nsNSSShutDownPreventionLock locker;
     945               0 :   if (isAlreadyShutDown())
     946               0 :     return NS_ERROR_NOT_AVAILABLE;
     947                 : 
     948               0 :   _subjectName.Truncate();
     949               0 :   if (mCert->subjectName) {
     950               0 :     _subjectName = NS_ConvertUTF8toUTF16(mCert->subjectName);
     951               0 :     return NS_OK;
     952                 :   }
     953               0 :   return NS_ERROR_FAILURE;
     954                 : }
     955                 : 
     956                 : NS_IMETHODIMP
     957               0 : nsNSSCertificate::GetIssuerName(nsAString &_issuerName)
     958                 : {
     959               0 :   nsNSSShutDownPreventionLock locker;
     960               0 :   if (isAlreadyShutDown())
     961               0 :     return NS_ERROR_NOT_AVAILABLE;
     962                 : 
     963               0 :   _issuerName.Truncate();
     964               0 :   if (mCert->issuerName) {
     965               0 :     _issuerName = NS_ConvertUTF8toUTF16(mCert->issuerName);
     966               0 :     return NS_OK;
     967                 :   }
     968               0 :   return NS_ERROR_FAILURE;
     969                 : }
     970                 : 
     971                 : NS_IMETHODIMP
     972               0 : nsNSSCertificate::GetSerialNumber(nsAString &_serialNumber)
     973                 : {
     974               0 :   nsNSSShutDownPreventionLock locker;
     975               0 :   if (isAlreadyShutDown())
     976               0 :     return NS_ERROR_NOT_AVAILABLE;
     977                 : 
     978               0 :   _serialNumber.Truncate();
     979               0 :   char *tmpstr = CERT_Hexify(&mCert->serialNumber, 1);
     980               0 :   if (tmpstr) {
     981               0 :     _serialNumber = NS_ConvertASCIItoUTF16(tmpstr);
     982               0 :     PORT_Free(tmpstr);
     983               0 :     return NS_OK;
     984                 :   }
     985               0 :   return NS_ERROR_FAILURE;
     986                 : }
     987                 : 
     988                 : NS_IMETHODIMP
     989             168 : nsNSSCertificate::GetSha1Fingerprint(nsAString &_sha1Fingerprint)
     990                 : {
     991             336 :   nsNSSShutDownPreventionLock locker;
     992             168 :   if (isAlreadyShutDown())
     993               0 :     return NS_ERROR_NOT_AVAILABLE;
     994                 : 
     995             168 :   _sha1Fingerprint.Truncate();
     996                 :   unsigned char fingerprint[20];
     997                 :   SECItem fpItem;
     998             168 :   memset(fingerprint, 0, sizeof fingerprint);
     999                 :   PK11_HashBuf(SEC_OID_SHA1, fingerprint, 
    1000             168 :                mCert->derCert.data, mCert->derCert.len);
    1001             168 :   fpItem.data = fingerprint;
    1002             168 :   fpItem.len = SHA1_LENGTH;
    1003             168 :   char *fpStr = CERT_Hexify(&fpItem, 1);
    1004             168 :   if (fpStr) {
    1005             168 :     _sha1Fingerprint = NS_ConvertASCIItoUTF16(fpStr);
    1006             168 :     PORT_Free(fpStr);
    1007             168 :     return NS_OK;
    1008                 :   }
    1009               0 :   return NS_ERROR_FAILURE;
    1010                 : }
    1011                 : 
    1012                 : NS_IMETHODIMP
    1013               0 : nsNSSCertificate::GetMd5Fingerprint(nsAString &_md5Fingerprint)
    1014                 : {
    1015               0 :   nsNSSShutDownPreventionLock locker;
    1016               0 :   if (isAlreadyShutDown())
    1017               0 :     return NS_ERROR_NOT_AVAILABLE;
    1018                 : 
    1019               0 :   _md5Fingerprint.Truncate();
    1020                 :   unsigned char fingerprint[20];
    1021                 :   SECItem fpItem;
    1022               0 :   memset(fingerprint, 0, sizeof fingerprint);
    1023                 :   PK11_HashBuf(SEC_OID_MD5, fingerprint, 
    1024               0 :                mCert->derCert.data, mCert->derCert.len);
    1025               0 :   fpItem.data = fingerprint;
    1026               0 :   fpItem.len = MD5_LENGTH;
    1027               0 :   char *fpStr = CERT_Hexify(&fpItem, 1);
    1028               0 :   if (fpStr) {
    1029               0 :     _md5Fingerprint = NS_ConvertASCIItoUTF16(fpStr);
    1030               0 :     PORT_Free(fpStr);
    1031               0 :     return NS_OK;
    1032                 :   }
    1033               0 :   return NS_ERROR_FAILURE;
    1034                 : }
    1035                 : 
    1036                 : NS_IMETHODIMP
    1037               0 : nsNSSCertificate::GetTokenName(nsAString &aTokenName)
    1038                 : {
    1039               0 :   nsNSSShutDownPreventionLock locker;
    1040               0 :   if (isAlreadyShutDown())
    1041               0 :     return NS_ERROR_NOT_AVAILABLE;
    1042                 : 
    1043               0 :   aTokenName.Truncate();
    1044               0 :   if (mCert) {
    1045                 :     // HACK alert
    1046                 :     // When the trust of a builtin cert is modified, NSS copies it into the
    1047                 :     // cert db.  At this point, it is now "managed" by the user, and should
    1048                 :     // not be listed with the builtins.  However, in the collection code
    1049                 :     // used by PK11_ListCerts, the cert is found in the temp db, where it
    1050                 :     // has been loaded from the token.  Though the trust is correct (grabbed
    1051                 :     // from the cert db), the source is wrong.  I believe this is a safe
    1052                 :     // way to work around this.
    1053               0 :     if (mCert->slot) {
    1054               0 :       char *token = PK11_GetTokenName(mCert->slot);
    1055               0 :       if (token) {
    1056               0 :         aTokenName = NS_ConvertUTF8toUTF16(token);
    1057                 :       }
    1058                 :     } else {
    1059                 :       nsresult rv;
    1060               0 :       nsAutoString tok;
    1061               0 :       nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
    1062               0 :       if (NS_FAILED(rv)) return rv;
    1063               0 :       rv = nssComponent->GetPIPNSSBundleString("InternalToken", tok);
    1064               0 :       if (NS_SUCCEEDED(rv))
    1065               0 :         aTokenName = tok;
    1066                 :     }
    1067                 :   }
    1068               0 :   return NS_OK;
    1069                 : }
    1070                 : 
    1071                 : NS_IMETHODIMP
    1072               0 : nsNSSCertificate::GetRawDER(PRUint32 *aLength, PRUint8 **aArray)
    1073                 : {
    1074               0 :   nsNSSShutDownPreventionLock locker;
    1075               0 :   if (isAlreadyShutDown())
    1076               0 :     return NS_ERROR_NOT_AVAILABLE;
    1077                 : 
    1078               0 :   if (mCert) {
    1079               0 :     *aArray = (PRUint8*)nsMemory::Alloc(mCert->derCert.len);
    1080               0 :     if (*aArray) {
    1081               0 :       memcpy(*aArray, mCert->derCert.data, mCert->derCert.len);
    1082               0 :       *aLength = mCert->derCert.len;
    1083               0 :       return NS_OK;
    1084                 :     }
    1085                 :   }
    1086               0 :   *aLength = 0;
    1087               0 :   return NS_ERROR_FAILURE;
    1088                 : }
    1089                 : 
    1090                 : NS_IMETHODIMP
    1091               0 : nsNSSCertificate::ExportAsCMS(PRUint32 chainMode,
    1092                 :                               PRUint32 *aLength, PRUint8 **aArray)
    1093                 : {
    1094               0 :   NS_ENSURE_ARG(aLength);
    1095               0 :   NS_ENSURE_ARG(aArray);
    1096                 : 
    1097               0 :   nsNSSShutDownPreventionLock locker;
    1098               0 :   if (isAlreadyShutDown())
    1099               0 :     return NS_ERROR_NOT_AVAILABLE;
    1100                 : 
    1101               0 :   if (!mCert)
    1102               0 :     return NS_ERROR_FAILURE;
    1103                 : 
    1104               0 :   switch (chainMode) {
    1105                 :     case nsIX509Cert3::CMS_CHAIN_MODE_CertOnly:
    1106                 :     case nsIX509Cert3::CMS_CHAIN_MODE_CertChain:
    1107                 :     case nsIX509Cert3::CMS_CHAIN_MODE_CertChainWithRoot:
    1108                 :       break;
    1109                 :     default:
    1110               0 :       return NS_ERROR_INVALID_ARG;
    1111                 :   };
    1112                 : 
    1113               0 :   PLArenaPool *arena = PORT_NewArena(1024);
    1114               0 :   PLArenaPoolCleanerFalseParam arenaCleaner(arena);
    1115               0 :   if (!arena) {
    1116               0 :     PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
    1117                 :            ("nsNSSCertificate::ExportAsCMS - out of memory\n"));
    1118               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1119                 :   }
    1120                 : 
    1121               0 :   NSSCMSMessage *cmsg = NSS_CMSMessage_Create(nsnull);
    1122               0 :   NSSCMSMessageCleaner cmsgCleaner(cmsg);
    1123               0 :   if (!cmsg) {
    1124               0 :     PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
    1125                 :            ("nsNSSCertificate::ExportAsCMS - can't create CMS message\n"));
    1126               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1127                 :   }
    1128                 : 
    1129                 :   /*
    1130                 :    * first, create SignedData with the certificate only (no chain)
    1131                 :    */
    1132               0 :   NSSCMSSignedData *sigd = NSS_CMSSignedData_CreateCertsOnly(cmsg, mCert, false);
    1133               0 :   NSSCMSSignedDataCleaner sigdCleaner(sigd);
    1134               0 :   if (!sigd) {
    1135               0 :     PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
    1136                 :            ("nsNSSCertificate::ExportAsCMS - can't create SignedData\n"));
    1137               0 :     return NS_ERROR_FAILURE;
    1138                 :   }
    1139                 : 
    1140                 :   /*
    1141                 :    * Calling NSS_CMSSignedData_CreateCertsOnly() will not allow us
    1142                 :    * to specify the inclusion of the root, but CERT_CertChainFromCert() does.
    1143                 :    * Since CERT_CertChainFromCert() also includes the certificate itself,
    1144                 :    * we have to start at the issuing cert (to avoid duplicate certs
    1145                 :    * in the SignedData).
    1146                 :    */
    1147               0 :   if (chainMode == nsIX509Cert3::CMS_CHAIN_MODE_CertChain ||
    1148                 :       chainMode == nsIX509Cert3::CMS_CHAIN_MODE_CertChainWithRoot) {
    1149               0 :     CERTCertificate *issuerCert = CERT_FindCertIssuer(mCert, PR_Now(), certUsageAnyCA);
    1150               0 :     CERTCertificateCleaner issuerCertCleaner(issuerCert);
    1151                 :     /*
    1152                 :      * the issuerCert of a self signed root is the cert itself,
    1153                 :      * so make sure we're not adding duplicates, again
    1154                 :      */
    1155               0 :     if (issuerCert && issuerCert != mCert) {
    1156                 :       bool includeRoot = 
    1157               0 :         (chainMode == nsIX509Cert3::CMS_CHAIN_MODE_CertChainWithRoot);
    1158               0 :       CERTCertificateList *certChain = CERT_CertChainFromCert(issuerCert, certUsageAnyCA, includeRoot);
    1159               0 :       CERTCertificateListCleaner certChainCleaner(certChain);
    1160               0 :       if (certChain) {
    1161               0 :         if (NSS_CMSSignedData_AddCertList(sigd, certChain) == SECSuccess) {
    1162               0 :           certChainCleaner.detach();
    1163                 :         }
    1164                 :         else {
    1165               0 :           PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
    1166                 :                  ("nsNSSCertificate::ExportAsCMS - can't add chain\n"));
    1167               0 :           return NS_ERROR_FAILURE;
    1168                 :         }
    1169                 :       }
    1170                 :       else { 
    1171                 :         /* try to add the issuerCert, at least */
    1172               0 :         if (NSS_CMSSignedData_AddCertificate(sigd, issuerCert)
    1173                 :             == SECSuccess) {
    1174               0 :           issuerCertCleaner.detach();
    1175                 :         }
    1176                 :         else {
    1177               0 :           PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
    1178                 :                  ("nsNSSCertificate::ExportAsCMS - can't add issuer cert\n"));
    1179               0 :           return NS_ERROR_FAILURE;
    1180                 :         }
    1181                 :       }
    1182                 :     }
    1183                 :   }
    1184                 : 
    1185               0 :   NSSCMSContentInfo *cinfo = NSS_CMSMessage_GetContentInfo(cmsg);
    1186               0 :   if (NSS_CMSContentInfo_SetContent_SignedData(cmsg, cinfo, sigd)
    1187                 :        == SECSuccess) {
    1188               0 :     sigdCleaner.detach();
    1189                 :   }
    1190                 :   else {
    1191               0 :     PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
    1192                 :            ("nsNSSCertificate::ExportAsCMS - can't attach SignedData\n"));
    1193               0 :     return NS_ERROR_FAILURE;
    1194                 :   }
    1195                 : 
    1196               0 :   SECItem certP7 = { siBuffer, nsnull, 0 };
    1197                 :   NSSCMSEncoderContext *ecx = NSS_CMSEncoder_Start(cmsg, nsnull, nsnull, &certP7, arena,
    1198                 :                                                    nsnull, nsnull, nsnull, nsnull, nsnull,
    1199               0 :                                                    nsnull);
    1200               0 :   if (!ecx) {
    1201               0 :     PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
    1202                 :            ("nsNSSCertificate::ExportAsCMS - can't create encoder context\n"));
    1203               0 :     return NS_ERROR_FAILURE;
    1204                 :   }
    1205                 : 
    1206               0 :   if (NSS_CMSEncoder_Finish(ecx) != SECSuccess) {
    1207               0 :     PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
    1208                 :            ("nsNSSCertificate::ExportAsCMS - failed to add encoded data\n"));
    1209               0 :     return NS_ERROR_FAILURE;
    1210                 :   }
    1211                 : 
    1212               0 :   *aArray = (PRUint8*)nsMemory::Alloc(certP7.len);
    1213               0 :   if (!*aArray)
    1214               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1215                 : 
    1216               0 :   memcpy(*aArray, certP7.data, certP7.len);
    1217               0 :   *aLength = certP7.len;
    1218               0 :   return NS_OK;
    1219                 : }
    1220                 : 
    1221                 : CERTCertificate *
    1222               0 : nsNSSCertificate::GetCert()
    1223                 : {
    1224               0 :   nsNSSShutDownPreventionLock locker;
    1225               0 :   if (isAlreadyShutDown())
    1226               0 :     return nsnull;
    1227                 : 
    1228               0 :   return (mCert) ? CERT_DupCertificate(mCert) : nsnull;
    1229                 : }
    1230                 : 
    1231                 : NS_IMETHODIMP
    1232               0 : nsNSSCertificate::GetValidity(nsIX509CertValidity **aValidity)
    1233                 : {
    1234               0 :   nsNSSShutDownPreventionLock locker;
    1235               0 :   if (isAlreadyShutDown())
    1236               0 :     return NS_ERROR_NOT_AVAILABLE;
    1237                 : 
    1238               0 :   NS_ENSURE_ARG(aValidity);
    1239               0 :   nsX509CertValidity *validity = new nsX509CertValidity(mCert);
    1240               0 :   if (nsnull == validity)
    1241               0 :    return  NS_ERROR_OUT_OF_MEMORY; 
    1242                 : 
    1243               0 :   NS_ADDREF(validity);
    1244               0 :   *aValidity = static_cast<nsIX509CertValidity*>(validity);
    1245               0 :   return NS_OK;
    1246                 : }
    1247                 : 
    1248                 : NS_IMETHODIMP
    1249               0 : nsNSSCertificate::VerifyForUsage(PRUint32 usage, PRUint32 *verificationResult)
    1250                 : {
    1251               0 :   nsNSSShutDownPreventionLock locker;
    1252               0 :   if (isAlreadyShutDown())
    1253               0 :     return NS_ERROR_NOT_AVAILABLE;
    1254                 : 
    1255               0 :   NS_ENSURE_ARG(verificationResult);
    1256                 : 
    1257                 :   nsresult nsrv;
    1258               0 :   nsCOMPtr<nsINSSComponent> inss = do_GetService(kNSSComponentCID, &nsrv);
    1259               0 :   if (!inss)
    1260               0 :     return nsrv;
    1261               0 :   nsRefPtr<nsCERTValInParamWrapper> survivingParams;
    1262               0 :   nsrv = inss->GetDefaultCERTValInParam(survivingParams);
    1263               0 :   if (NS_FAILED(nsrv))
    1264               0 :     return nsrv;
    1265                 :   
    1266                 :   SECCertificateUsage nss_usage;
    1267                 :   
    1268               0 :   switch (usage)
    1269                 :   {
    1270                 :     case CERT_USAGE_SSLClient:
    1271               0 :       nss_usage = certificateUsageSSLClient;
    1272               0 :       break;
    1273                 : 
    1274                 :     case CERT_USAGE_SSLServer:
    1275               0 :       nss_usage = certificateUsageSSLServer;
    1276               0 :       break;
    1277                 : 
    1278                 :     case CERT_USAGE_SSLServerWithStepUp:
    1279               0 :       nss_usage = certificateUsageSSLServerWithStepUp;
    1280               0 :       break;
    1281                 : 
    1282                 :     case CERT_USAGE_SSLCA:
    1283               0 :       nss_usage = certificateUsageSSLCA;
    1284               0 :       break;
    1285                 : 
    1286                 :     case CERT_USAGE_EmailSigner:
    1287               0 :       nss_usage = certificateUsageEmailSigner;
    1288               0 :       break;
    1289                 : 
    1290                 :     case CERT_USAGE_EmailRecipient:
    1291               0 :       nss_usage = certificateUsageEmailRecipient;
    1292               0 :       break;
    1293                 : 
    1294                 :     case CERT_USAGE_ObjectSigner:
    1295               0 :       nss_usage = certificateUsageObjectSigner;
    1296               0 :       break;
    1297                 : 
    1298                 :     case CERT_USAGE_UserCertImport:
    1299               0 :       nss_usage = certificateUsageUserCertImport;
    1300               0 :       break;
    1301                 : 
    1302                 :     case CERT_USAGE_VerifyCA:
    1303               0 :       nss_usage = certificateUsageVerifyCA;
    1304               0 :       break;
    1305                 : 
    1306                 :     case CERT_USAGE_ProtectedObjectSigner:
    1307               0 :       nss_usage = certificateUsageProtectedObjectSigner;
    1308               0 :       break;
    1309                 : 
    1310                 :     case CERT_USAGE_StatusResponder:
    1311               0 :       nss_usage = certificateUsageStatusResponder;
    1312               0 :       break;
    1313                 : 
    1314                 :     case CERT_USAGE_AnyCA:
    1315               0 :       nss_usage = certificateUsageAnyCA;
    1316               0 :       break;
    1317                 : 
    1318                 :     default:
    1319               0 :       return NS_ERROR_FAILURE;
    1320                 :   }
    1321                 : 
    1322                 :   SECStatus verify_result;
    1323               0 :   if (!nsNSSComponent::globalConstFlagUsePKIXVerification) {
    1324               0 :     CERTCertDBHandle *defaultcertdb = CERT_GetDefaultCertDB();
    1325                 :     verify_result = CERT_VerifyCertificateNow(defaultcertdb, mCert, true, 
    1326               0 :                                               nss_usage, NULL, NULL);
    1327                 :   }
    1328                 :   else {
    1329                 :     CERTValOutParam cvout[1];
    1330               0 :     cvout[0].type = cert_po_end;
    1331                 :     verify_result = CERT_PKIXVerifyCert(mCert, nss_usage,
    1332                 :                                         survivingParams->GetRawPointerForNSS(),
    1333               0 :                                         cvout, NULL);
    1334                 :   }
    1335                 :   
    1336               0 :   if (verify_result == SECSuccess)
    1337                 :   {
    1338               0 :     *verificationResult = VERIFIED_OK;
    1339                 :   }
    1340                 :   else
    1341                 :   {
    1342               0 :     int err = PR_GetError();
    1343                 : 
    1344                 :     // this list was cloned from verifyFailed
    1345                 : 
    1346               0 :     switch (err)
    1347                 :     {
    1348                 :       case SEC_ERROR_INADEQUATE_KEY_USAGE:
    1349                 :       case SEC_ERROR_INADEQUATE_CERT_TYPE:
    1350               0 :         *verificationResult = USAGE_NOT_ALLOWED;
    1351               0 :         break;
    1352                 : 
    1353                 :       case SEC_ERROR_REVOKED_CERTIFICATE:
    1354               0 :         *verificationResult = CERT_REVOKED;
    1355               0 :         break;
    1356                 : 
    1357                 :       case SEC_ERROR_EXPIRED_CERTIFICATE:
    1358               0 :         *verificationResult = CERT_EXPIRED;
    1359               0 :         break;
    1360                 :         
    1361                 :       case SEC_ERROR_UNTRUSTED_CERT:
    1362               0 :         *verificationResult = CERT_NOT_TRUSTED;
    1363               0 :         break;
    1364                 :         
    1365                 :       case SEC_ERROR_UNTRUSTED_ISSUER:
    1366               0 :         *verificationResult = ISSUER_NOT_TRUSTED;
    1367               0 :         break;
    1368                 :         
    1369                 :       case SEC_ERROR_UNKNOWN_ISSUER:
    1370               0 :         *verificationResult = ISSUER_UNKNOWN;
    1371               0 :         break;
    1372                 :         
    1373                 :       case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
    1374               0 :         *verificationResult = INVALID_CA;
    1375               0 :         break;
    1376                 :         
    1377                 :       case SEC_ERROR_CERT_USAGES_INVALID:
    1378                 :       default:
    1379               0 :         *verificationResult = NOT_VERIFIED_UNKNOWN; 
    1380               0 :         break;
    1381                 :     }
    1382                 :   }
    1383                 :   
    1384               0 :   return NS_OK;  
    1385                 : }
    1386                 : 
    1387                 : 
    1388                 : NS_IMETHODIMP
    1389               0 : nsNSSCertificate::GetUsagesArray(bool localOnly,
    1390                 :                                  PRUint32 *_verified,
    1391                 :                                  PRUint32 *_count,
    1392                 :                                  PRUnichar ***_usages)
    1393                 : {
    1394               0 :   nsNSSShutDownPreventionLock locker;
    1395               0 :   if (isAlreadyShutDown())
    1396               0 :     return NS_ERROR_NOT_AVAILABLE;
    1397                 : 
    1398                 :   nsresult rv;
    1399               0 :   const int max_usages = 13;
    1400                 :   PRUnichar *tmpUsages[max_usages];
    1401               0 :   const char *suffix = "";
    1402                 :   PRUint32 tmpCount;
    1403               0 :   nsUsageArrayHelper uah(mCert);
    1404               0 :   rv = uah.GetUsagesArray(suffix, localOnly, max_usages, _verified, &tmpCount, tmpUsages);
    1405               0 :   NS_ENSURE_SUCCESS(rv,rv);
    1406               0 :   if (tmpCount > 0) {
    1407               0 :     *_usages = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * tmpCount);
    1408               0 :     if (!*_usages)
    1409               0 :       return NS_ERROR_OUT_OF_MEMORY;
    1410               0 :     for (PRUint32 i=0; i<tmpCount; i++) {
    1411               0 :       (*_usages)[i] = tmpUsages[i];
    1412                 :     }
    1413               0 :     *_count = tmpCount;
    1414               0 :     return NS_OK;
    1415                 :   }
    1416               0 :   *_usages = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *));
    1417               0 :   if (!*_usages)
    1418               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1419               0 :   *_count = 0;
    1420               0 :   return NS_OK;
    1421                 : }
    1422                 : 
    1423                 : NS_IMETHODIMP
    1424               0 : nsNSSCertificate::RequestUsagesArrayAsync(nsICertVerificationListener *aResultListener)
    1425                 : {
    1426               0 :   if (!aResultListener)
    1427               0 :     return NS_ERROR_FAILURE;
    1428                 :   
    1429               0 :   nsCertVerificationJob *job = new nsCertVerificationJob;
    1430               0 :   if (!job)
    1431               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1432                 : 
    1433               0 :   job->mCert = this;
    1434               0 :   job->mListener = aResultListener;
    1435                 : 
    1436               0 :   nsresult rv = nsCertVerificationThread::addJob(job);
    1437               0 :   if (NS_FAILED(rv))
    1438               0 :     delete job;
    1439                 : 
    1440               0 :   return rv;
    1441                 : }
    1442                 : 
    1443                 : NS_IMETHODIMP
    1444               0 : nsNSSCertificate::GetUsagesString(bool localOnly,
    1445                 :                                   PRUint32   *_verified,
    1446                 :                                   nsAString &_usages)
    1447                 : {
    1448               0 :   nsNSSShutDownPreventionLock locker;
    1449               0 :   if (isAlreadyShutDown())
    1450               0 :     return NS_ERROR_NOT_AVAILABLE;
    1451                 : 
    1452                 :   nsresult rv;
    1453               0 :   const int max_usages = 13;
    1454                 :   PRUnichar *tmpUsages[max_usages];
    1455               0 :   const char *suffix = "_p";
    1456                 :   PRUint32 tmpCount;
    1457               0 :   nsUsageArrayHelper uah(mCert);
    1458               0 :   rv = uah.GetUsagesArray(suffix, localOnly, max_usages, _verified, &tmpCount, tmpUsages);
    1459               0 :   NS_ENSURE_SUCCESS(rv,rv);
    1460               0 :   _usages.Truncate();
    1461               0 :   for (PRUint32 i=0; i<tmpCount; i++) {
    1462               0 :     if (i>0) _usages.AppendLiteral(",");
    1463               0 :     _usages.Append(tmpUsages[i]);
    1464               0 :     nsMemory::Free(tmpUsages[i]);
    1465                 :   }
    1466               0 :   return NS_OK;
    1467                 : }
    1468                 : 
    1469                 : #if defined(DEBUG_javi) || defined(DEBUG_jgmyers)
    1470                 : void
    1471                 : DumpASN1Object(nsIASN1Object *object, unsigned int level)
    1472                 : {
    1473                 :   nsAutoString dispNameU, dispValU;
    1474                 :   unsigned int i;
    1475                 :   nsCOMPtr<nsIMutableArray> asn1Objects;
    1476                 :   nsCOMPtr<nsISupports> isupports;
    1477                 :   nsCOMPtr<nsIASN1Object> currObject;
    1478                 :   bool processObjects;
    1479                 :   PRUint32 numObjects;
    1480                 : 
    1481                 :   for (i=0; i<level; i++)
    1482                 :     printf ("  ");
    1483                 : 
    1484                 :   object->GetDisplayName(dispNameU);
    1485                 :   nsCOMPtr<nsIASN1Sequence> sequence(do_QueryInterface(object));
    1486                 :   if (sequence) {
    1487                 :     printf ("%s ", NS_ConvertUTF16toUTF8(dispNameU).get());
    1488                 :     sequence->GetIsValidContainer(&processObjects);
    1489                 :     if (processObjects) {
    1490                 :       printf("\n");
    1491                 :       sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
    1492                 :       asn1Objects->GetLength(&numObjects);
    1493                 :       for (i=0; i<numObjects;i++) {
    1494                 :         asn1Objects->QueryElementAt(i, NS_GET_IID(nsISupports), getter_AddRefs(currObject));
    1495                 :         DumpASN1Object(currObject, level+1);    
    1496                 :       }
    1497                 :     } else { 
    1498                 :       object->GetDisplayValue(dispValU);
    1499                 :       printf("= %s\n", NS_ConvertUTF16toUTF8(dispValU).get()); 
    1500                 :     }
    1501                 :   } else { 
    1502                 :     object->GetDisplayValue(dispValU);
    1503                 :     printf("%s = %s\n",NS_ConvertUTF16toUTF8(dispNameU).get(), 
    1504                 :                        NS_ConvertUTF16toUTF8(dispValU).get()); 
    1505                 :   }
    1506                 : }
    1507                 : #endif
    1508                 : 
    1509                 : /* readonly attribute nsIASN1Object ASN1Structure; */
    1510                 : NS_IMETHODIMP 
    1511               0 : nsNSSCertificate::GetASN1Structure(nsIASN1Object * *aASN1Structure)
    1512                 : {
    1513               0 :   nsNSSShutDownPreventionLock locker;
    1514               0 :   nsresult rv = NS_OK;
    1515               0 :   NS_ENSURE_ARG_POINTER(aASN1Structure);
    1516               0 :   if (mASN1Structure == nsnull) {
    1517                 :     // First create the recursive structure os ASN1Objects
    1518                 :     // which tells us the layout of the cert.
    1519               0 :     rv = CreateASN1Struct();
    1520               0 :     if (NS_FAILED(rv)) {
    1521               0 :       return rv;
    1522                 :     }
    1523                 : #ifdef DEBUG_javi
    1524                 :     DumpASN1Object(mASN1Structure, 0);
    1525                 : #endif
    1526                 :   }
    1527               0 :   *aASN1Structure = mASN1Structure;
    1528               0 :   NS_IF_ADDREF(*aASN1Structure);
    1529               0 :   return rv;
    1530                 : }
    1531                 : 
    1532                 : NS_IMETHODIMP
    1533               0 : nsNSSCertificate::Equals(nsIX509Cert *other, bool *result)
    1534                 : {
    1535               0 :   nsNSSShutDownPreventionLock locker;
    1536               0 :   if (isAlreadyShutDown())
    1537               0 :     return NS_ERROR_NOT_AVAILABLE;
    1538                 : 
    1539               0 :   NS_ENSURE_ARG(other);
    1540               0 :   NS_ENSURE_ARG(result);
    1541                 : 
    1542               0 :   nsCOMPtr<nsIX509Cert2> other2 = do_QueryInterface(other);
    1543               0 :   if (!other2)
    1544               0 :     return NS_ERROR_FAILURE;
    1545                 :  
    1546               0 :   CERTCertificate *cert = other2->GetCert();
    1547               0 :   *result = (mCert == cert);
    1548               0 :   if (cert) {
    1549               0 :     CERT_DestroyCertificate(cert);
    1550                 :   }
    1551               0 :   return NS_OK;
    1552                 : }
    1553                 : 
    1554                 : NS_IMETHODIMP
    1555               0 : nsNSSCertificate::SaveSMimeProfile()
    1556                 : {
    1557               0 :   nsNSSShutDownPreventionLock locker;
    1558               0 :   if (isAlreadyShutDown())
    1559               0 :     return NS_ERROR_NOT_AVAILABLE;
    1560                 : 
    1561               0 :   if (SECSuccess != CERT_SaveSMimeProfile(mCert, nsnull, nsnull))
    1562               0 :     return NS_ERROR_FAILURE;
    1563                 :   else
    1564               0 :     return NS_OK;
    1565                 : }
    1566                 : 
    1567                 : 
    1568               4 : char* nsNSSCertificate::defaultServerNickname(CERTCertificate* cert)
    1569                 : {
    1570               8 :   nsNSSShutDownPreventionLock locker;
    1571               4 :   char* nickname = nsnull;
    1572                 :   int count;
    1573                 :   bool conflict;
    1574               4 :   char* servername = nsnull;
    1575                 :   
    1576               4 :   servername = CERT_GetCommonName(&cert->subject);
    1577               4 :   if (!servername) {
    1578                 :     // Certs without common names are strange, but they do exist...
    1579                 :     // Let's try to use another string for the nickname
    1580               0 :     servername = CERT_GetOrgUnitName(&cert->subject);
    1581               0 :     if (!servername) {
    1582               0 :       servername = CERT_GetOrgName(&cert->subject);
    1583               0 :       if (!servername) {
    1584               0 :         servername = CERT_GetLocalityName(&cert->subject);
    1585               0 :         if (!servername) {
    1586               0 :           servername = CERT_GetStateName(&cert->subject);
    1587               0 :           if (!servername) {
    1588               0 :             servername = CERT_GetCountryName(&cert->subject);
    1589               0 :             if (!servername) {
    1590                 :               // We tried hard, there is nothing more we can do.
    1591                 :               // A cert without any names doesn't really make sense.
    1592               0 :               return nsnull;
    1593                 :             }
    1594                 :           }
    1595                 :         }
    1596                 :       }
    1597                 :     }
    1598                 :   }
    1599                 :    
    1600               4 :   count = 1;
    1601               0 :   while (1) {
    1602               4 :     if (count == 1) {
    1603               4 :       nickname = PR_smprintf("%s", servername);
    1604                 :     }
    1605                 :     else {
    1606               0 :       nickname = PR_smprintf("%s #%d", servername, count);
    1607                 :     }
    1608               4 :     if (nickname == NULL) {
    1609               0 :       break;
    1610                 :     }
    1611                 : 
    1612                 :     conflict = SEC_CertNicknameConflict(nickname, &cert->derSubject,
    1613               4 :                                         cert->dbhandle);
    1614               4 :     if (!conflict) {
    1615               4 :       break;
    1616                 :     }
    1617               0 :     PR_Free(nickname);
    1618               0 :     count++;
    1619                 :   }
    1620               4 :   PR_FREEIF(servername);
    1621               4 :   return nickname;
    1622                 : }
    1623                 : 
    1624               0 : NS_IMPL_THREADSAFE_ISUPPORTS1(nsNSSCertList, nsIX509CertList)
    1625                 : 
    1626               0 : nsNSSCertList::nsNSSCertList(CERTCertList *certList, bool adopt)
    1627                 : {
    1628               0 :   if (certList) {
    1629               0 :     if (adopt) {
    1630               0 :       mCertList = certList;
    1631                 :     } else {
    1632               0 :       mCertList = DupCertList(certList);
    1633                 :     }
    1634                 :   } else {
    1635               0 :     mCertList = CERT_NewCertList();
    1636                 :   }
    1637               0 : }
    1638                 : 
    1639               0 : nsNSSCertList::~nsNSSCertList()
    1640                 : {
    1641               0 :   if (mCertList) {
    1642               0 :     CERT_DestroyCertList(mCertList);
    1643                 :   }
    1644               0 : }
    1645                 : 
    1646                 : /* void addCert (in nsIX509Cert cert); */
    1647                 : NS_IMETHODIMP
    1648               0 : nsNSSCertList::AddCert(nsIX509Cert *aCert) 
    1649                 : {
    1650                 :   /* This should be a query interface, but currently this his how the
    1651                 :    * rest of PSM is working */
    1652               0 :   nsCOMPtr<nsIX509Cert2> nssCert = do_QueryInterface(aCert);
    1653                 :   CERTCertificate *cert;
    1654                 : 
    1655               0 :   cert = nssCert->GetCert();
    1656               0 :   if (cert == nsnull) {
    1657               0 :     NS_ERROR("Somehow got nsnull for mCertificate in nsNSSCertificate.");
    1658               0 :     return NS_ERROR_FAILURE;
    1659                 :   }
    1660                 : 
    1661               0 :   if (mCertList == nsnull) {
    1662               0 :     NS_ERROR("Somehow got nsnull for mCertList in nsNSSCertList.");
    1663               0 :     return NS_ERROR_FAILURE;
    1664                 :   }
    1665               0 :   CERT_AddCertToListTail(mCertList,cert);
    1666               0 :   return NS_OK;
    1667                 : }
    1668                 : 
    1669                 : /* void deleteCert (in nsIX509Cert cert); */
    1670                 : NS_IMETHODIMP
    1671               0 : nsNSSCertList::DeleteCert(nsIX509Cert *aCert)
    1672                 : {
    1673                 :   /* This should be a query interface, but currently this his how the
    1674                 :    * rest of PSM is working */
    1675               0 :   nsCOMPtr<nsIX509Cert2> nssCert = do_QueryInterface(aCert);
    1676               0 :   CERTCertificate *cert = nssCert->GetCert();
    1677                 :   CERTCertListNode *node;
    1678                 : 
    1679               0 :   if (cert == nsnull) {
    1680               0 :     NS_ERROR("Somehow got nsnull for mCertificate in nsNSSCertificate.");
    1681               0 :     return NS_ERROR_FAILURE;
    1682                 :   }
    1683                 : 
    1684               0 :   if (mCertList == nsnull) {
    1685               0 :     NS_ERROR("Somehow got nsnull for mCertList in nsNSSCertList.");
    1686               0 :     return NS_ERROR_FAILURE;
    1687                 :   }
    1688                 : 
    1689               0 :   for (node = CERT_LIST_HEAD(mCertList); !CERT_LIST_END(node,mCertList);
    1690                 :                                              node = CERT_LIST_NEXT(node)) {
    1691               0 :     if (node->cert == cert) {
    1692               0 :         CERT_RemoveCertListNode(node);
    1693               0 :         return NS_OK;
    1694                 :     }
    1695                 :   }
    1696               0 :   return NS_OK; /* should we fail if we couldn't find it? */
    1697                 : }
    1698                 : 
    1699                 : CERTCertList *
    1700               0 : nsNSSCertList::DupCertList(CERTCertList *aCertList)
    1701                 : {
    1702               0 :   if (!aCertList)
    1703               0 :     return nsnull;
    1704                 : 
    1705               0 :   CERTCertList *newList = CERT_NewCertList();
    1706                 : 
    1707               0 :   if (newList == nsnull) {
    1708               0 :     return nsnull;
    1709                 :   }
    1710                 : 
    1711                 :   CERTCertListNode *node;
    1712               0 :   for (node = CERT_LIST_HEAD(aCertList); !CERT_LIST_END(node, aCertList);
    1713                 :                                               node = CERT_LIST_NEXT(node)) {
    1714               0 :     CERTCertificate *cert = CERT_DupCertificate(node->cert);
    1715               0 :     CERT_AddCertToListTail(newList, cert);
    1716                 :   }
    1717               0 :   return newList;
    1718                 : }
    1719                 : 
    1720                 : void *
    1721               0 : nsNSSCertList::GetRawCertList()
    1722                 : {
    1723               0 :   return mCertList;
    1724                 : }
    1725                 : 
    1726                 : /* nsISimpleEnumerator getEnumerator (); */
    1727                 : NS_IMETHODIMP
    1728               0 : nsNSSCertList::GetEnumerator(nsISimpleEnumerator **_retval) 
    1729                 : {
    1730               0 :   nsCOMPtr<nsISimpleEnumerator> enumerator = new nsNSSCertListEnumerator(mCertList);
    1731               0 :   if (!enumerator) { 
    1732               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1733                 :   }
    1734                 : 
    1735               0 :   *_retval = enumerator;
    1736               0 :   NS_ADDREF(*_retval);
    1737               0 :   return NS_OK;
    1738                 : }
    1739                 : 
    1740               0 : NS_IMPL_THREADSAFE_ISUPPORTS1(nsNSSCertListEnumerator, 
    1741                 :                               nsISimpleEnumerator)
    1742                 : 
    1743               0 : nsNSSCertListEnumerator::nsNSSCertListEnumerator(CERTCertList *certList)
    1744                 : {
    1745               0 :   mCertList = nsNSSCertList::DupCertList(certList);
    1746               0 : }
    1747                 : 
    1748               0 : nsNSSCertListEnumerator::~nsNSSCertListEnumerator()
    1749                 : {
    1750               0 :   if (mCertList) {
    1751               0 :     CERT_DestroyCertList(mCertList);
    1752                 :   }
    1753               0 : }
    1754                 : 
    1755                 : /* boolean hasMoreElements (); */
    1756                 : NS_IMETHODIMP
    1757               0 : nsNSSCertListEnumerator::HasMoreElements(bool *_retval)
    1758                 : { 
    1759               0 :   NS_ENSURE_TRUE(mCertList, NS_ERROR_FAILURE);
    1760                 : 
    1761               0 :   *_retval = !CERT_LIST_EMPTY(mCertList);
    1762               0 :   return NS_OK;
    1763                 : }
    1764                 : 
    1765                 : /* nsISupports getNext(); */
    1766                 : NS_IMETHODIMP
    1767               0 : nsNSSCertListEnumerator::GetNext(nsISupports **_retval) 
    1768                 : {
    1769               0 :   NS_ENSURE_TRUE(mCertList, NS_ERROR_FAILURE);
    1770                 : 
    1771               0 :   CERTCertListNode *node = CERT_LIST_HEAD(mCertList);
    1772               0 :   if (CERT_LIST_END(node, mCertList)) {
    1773               0 :     return NS_ERROR_FAILURE;
    1774                 :   }
    1775                 : 
    1776               0 :   nsCOMPtr<nsIX509Cert> nssCert = nsNSSCertificate::Create(node->cert);
    1777               0 :   if (!nssCert) { 
    1778               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1779                 :   }
    1780                 : 
    1781               0 :   *_retval = nssCert;
    1782               0 :   NS_ADDREF(*_retval);
    1783                 : 
    1784               0 :   CERT_RemoveCertListNode(node);
    1785               0 :   return NS_OK;
    1786                 : }
    1787                 : 
    1788                 : NS_IMETHODIMP
    1789               8 : nsNSSCertificate::Write(nsIObjectOutputStream* aStream)
    1790                 : {
    1791               8 :   NS_ENSURE_STATE(mCert);
    1792               8 :   nsresult rv = aStream->Write32(mCert->derCert.len);
    1793               8 :   if (NS_FAILED(rv)) {
    1794               0 :     return rv;
    1795                 :   }
    1796                 :   
    1797               8 :   return aStream->WriteByteArray(mCert->derCert.data, mCert->derCert.len);
    1798                 : }
    1799                 : 
    1800                 : NS_IMETHODIMP
    1801               0 : nsNSSCertificate::Read(nsIObjectInputStream* aStream)
    1802                 : {
    1803               0 :   NS_ENSURE_STATE(!mCert);
    1804                 :   
    1805                 :   PRUint32 len;
    1806               0 :   nsresult rv = aStream->Read32(&len);
    1807               0 :   if (NS_FAILED(rv)) {
    1808               0 :     return rv;
    1809                 :   }
    1810                 : 
    1811               0 :   nsXPIDLCString str;
    1812               0 :   rv = aStream->ReadBytes(len, getter_Copies(str));
    1813               0 :   if (NS_FAILED(rv)) {
    1814               0 :     return rv;
    1815                 :   }
    1816                 : 
    1817               0 :   if (!InitFromDER(const_cast<char*>(str.get()), len)) {
    1818               0 :     return NS_ERROR_UNEXPECTED;
    1819                 :   }
    1820                 : 
    1821               0 :   return NS_OK;
    1822                 : }
    1823                 : 
    1824                 : NS_IMETHODIMP 
    1825               0 : nsNSSCertificate::GetInterfaces(PRUint32 *count, nsIID * **array)
    1826                 : {
    1827               0 :   *count = 0;
    1828               0 :   *array = nsnull;
    1829               0 :   return NS_OK;
    1830                 : }
    1831                 : 
    1832                 : NS_IMETHODIMP 
    1833               0 : nsNSSCertificate::GetHelperForLanguage(PRUint32 language, nsISupports **_retval)
    1834                 : {
    1835               0 :   *_retval = nsnull;
    1836               0 :   return NS_OK;
    1837                 : }
    1838                 : 
    1839                 : NS_IMETHODIMP 
    1840               0 : nsNSSCertificate::GetContractID(char * *aContractID)
    1841                 : {
    1842               0 :   *aContractID = nsnull;
    1843               0 :   return NS_OK;
    1844                 : }
    1845                 : 
    1846                 : NS_IMETHODIMP 
    1847               0 : nsNSSCertificate::GetClassDescription(char * *aClassDescription)
    1848                 : {
    1849               0 :   *aClassDescription = nsnull;
    1850               0 :   return NS_OK;
    1851                 : }
    1852                 : 
    1853                 : NS_IMETHODIMP 
    1854               0 : nsNSSCertificate::GetClassID(nsCID * *aClassID)
    1855                 : {
    1856               0 :   *aClassID = (nsCID*) nsMemory::Alloc(sizeof(nsCID));
    1857               0 :   if (!*aClassID)
    1858               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1859               0 :   return GetClassIDNoAlloc(*aClassID);
    1860                 : }
    1861                 : 
    1862                 : NS_IMETHODIMP 
    1863               0 : nsNSSCertificate::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
    1864                 : {
    1865               0 :   *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
    1866               0 :   return NS_OK;
    1867                 : }
    1868                 : 
    1869                 : NS_IMETHODIMP 
    1870               0 : nsNSSCertificate::GetFlags(PRUint32 *aFlags)
    1871                 : {
    1872               0 :   *aFlags = nsIClassInfo::THREADSAFE;
    1873               0 :   return NS_OK;
    1874                 : }
    1875                 : 
    1876                 : static NS_DEFINE_CID(kNSSCertificateCID, NS_X509CERT_CID);
    1877                 : 
    1878                 : NS_IMETHODIMP 
    1879               4 : nsNSSCertificate::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
    1880                 : {
    1881               4 :   *aClassIDNoAlloc = kNSSCertificateCID;
    1882               4 :   return NS_OK;
    1883                 : }

Generated by: LCOV version 1.7