security/manager/ssl/src/nsCertPicker.cpp

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsCertPicker.h"
     7 #include "pkix/pkixtypes.h"
     8 #include "nsMemory.h"
     9 #include "nsCOMPtr.h"
    10 #include "nsXPIDLString.h"
    11 #include "nsIServiceManager.h"
    12 #include "nsNSSComponent.h"
    13 #include "nsNSSCertificate.h"
    14 #include "nsReadableUtils.h"
    15 #include "nsICertPickDialogs.h"
    16 #include "nsNSSShutDown.h"
    17 #include "nsNSSCertHelper.h"
    18 #include "ScopedNSSTypes.h"
    20 #include "cert.h"
    22 using namespace mozilla;
    24 NS_IMPL_ISUPPORTS(nsCertPicker, nsIUserCertPicker)
    26 nsCertPicker::nsCertPicker()
    27 {
    28 }
    30 nsCertPicker::~nsCertPicker()
    31 {
    32 }
    34 NS_IMETHODIMP nsCertPicker::PickByUsage(nsIInterfaceRequestor *ctx, 
    35                                         const char16_t *selectedNickname, 
    36                                         int32_t certUsage, 
    37                                         bool allowInvalid, 
    38                                         bool allowDuplicateNicknames, 
    39                                         bool *canceled, 
    40                                         nsIX509Cert **_retval)
    41 {
    42   nsNSSShutDownPreventionLock locker;
    43   int32_t selectedIndex = -1;
    44   bool selectionFound = false;
    45   char16_t **certNicknameList = nullptr;
    46   char16_t **certDetailsList = nullptr;
    47   CERTCertListNode* node = nullptr;
    48   nsresult rv = NS_OK;
    50   {
    51     // Iterate over all certs. This assures that user is logged in to all hardware tokens.
    52     nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
    53     mozilla::pkix::ScopedCERTCertList allcerts(
    54       PK11_ListCerts(PK11CertListUnique, ctx));
    55   }
    57   /* find all user certs that are valid and for SSL */
    58   /* note that we are allowing expired certs in this list */
    60   mozilla::pkix::ScopedCERTCertList certList(
    61     CERT_FindUserCertsByUsage(CERT_GetDefaultCertDB(), 
    62                               (SECCertUsage)certUsage,
    63                               !allowDuplicateNicknames,
    64                               !allowInvalid,
    65                               ctx));
    66   if (!certList) {
    67     return NS_ERROR_NOT_AVAILABLE;
    68   }
    70   ScopedCERTCertNicknames nicknames(getNSSCertNicknamesFromCertList(certList.get()));
    71   if (!nicknames) {
    72     return NS_ERROR_NOT_AVAILABLE;
    73   }
    75   certNicknameList = (char16_t **)nsMemory::Alloc(sizeof(char16_t *) * nicknames->numnicknames);
    76   certDetailsList = (char16_t **)nsMemory::Alloc(sizeof(char16_t *) * nicknames->numnicknames);
    78   if (!certNicknameList || !certDetailsList) {
    79     nsMemory::Free(certNicknameList);
    80     nsMemory::Free(certDetailsList);
    81     return NS_ERROR_OUT_OF_MEMORY;
    82   }
    84   int32_t CertsToUse;
    86   for (CertsToUse = 0, node = CERT_LIST_HEAD(certList.get());
    87        !CERT_LIST_END(node, certList.get()) &&
    88          CertsToUse < nicknames->numnicknames;
    89        node = CERT_LIST_NEXT(node)
    90       )
    91   {
    92     nsNSSCertificate *tempCert = nsNSSCertificate::Create(node->cert);
    94     if (tempCert) {
    96       // XXX we really should be using an nsCOMPtr instead of manually add-refing,
    97       // but nsNSSCertificate does not have a default constructor.
    99       NS_ADDREF(tempCert);
   101       nsAutoString i_nickname(NS_ConvertUTF8toUTF16(nicknames->nicknames[CertsToUse]));
   102       nsAutoString nickWithSerial;
   103       nsAutoString details;
   105       if (!selectionFound) {
   106         if (i_nickname == nsDependentString(selectedNickname)) {
   107           selectedIndex = CertsToUse;
   108           selectionFound = true;
   109         }
   110       }
   112       if (NS_SUCCEEDED(tempCert->FormatUIStrings(i_nickname, nickWithSerial, details))) {
   113         certNicknameList[CertsToUse] = ToNewUnicode(nickWithSerial);
   114         certDetailsList[CertsToUse] = ToNewUnicode(details);
   115       }
   116       else {
   117         certNicknameList[CertsToUse] = nullptr;
   118         certDetailsList[CertsToUse] = nullptr;
   119       }
   121       NS_RELEASE(tempCert);
   123       ++CertsToUse;
   124     }
   125   }
   127   if (CertsToUse) {
   128     nsICertPickDialogs *dialogs = nullptr;
   129     rv = getNSSDialogs((void**)&dialogs, 
   130       NS_GET_IID(nsICertPickDialogs), 
   131       NS_CERTPICKDIALOGS_CONTRACTID);
   133     if (NS_SUCCEEDED(rv)) {
   134       nsPSMUITracker tracker;
   135       if (tracker.isUIForbidden()) {
   136         rv = NS_ERROR_NOT_AVAILABLE;
   137       }
   138       else {
   139         /* Throw up the cert picker dialog and get back the index of the selected cert */
   140         rv = dialogs->PickCertificate(ctx,
   141           (const char16_t**)certNicknameList, (const char16_t**)certDetailsList,
   142           CertsToUse, &selectedIndex, canceled);
   143       }
   145       NS_RELEASE(dialogs);
   146     }
   147   }
   149   int32_t i;
   150   for (i = 0; i < CertsToUse; ++i) {
   151     nsMemory::Free(certNicknameList[i]);
   152     nsMemory::Free(certDetailsList[i]);
   153   }
   154   nsMemory::Free(certNicknameList);
   155   nsMemory::Free(certDetailsList);
   157   if (!CertsToUse) {
   158     return NS_ERROR_NOT_AVAILABLE;
   159   }
   161   if (NS_SUCCEEDED(rv) && !*canceled) {
   162     for (i = 0, node = CERT_LIST_HEAD(certList);
   163          !CERT_LIST_END(node, certList);
   164          ++i, node = CERT_LIST_NEXT(node)) {
   166       if (i == selectedIndex) {
   167         nsNSSCertificate *cert = nsNSSCertificate::Create(node->cert);
   168         if (!cert) {
   169           rv = NS_ERROR_OUT_OF_MEMORY;
   170           break;
   171         }
   173         nsIX509Cert *x509 = 0;
   174         nsresult rv = cert->QueryInterface(NS_GET_IID(nsIX509Cert), (void**)&x509);
   175         if (NS_FAILED(rv)) {
   176           break;
   177         }
   179         NS_ADDREF(x509);
   180         *_retval = x509;
   181         NS_RELEASE(cert);
   182         break;
   183       }
   184     }
   185   }
   187   return rv;
   188 }

mercurial