security/manager/ssl/src/nsRecentBadCerts.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  *
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "nsRecentBadCerts.h"
     9 #include "pkix/pkixtypes.h"
    10 #include "nsIX509Cert.h"
    11 #include "nsIObserverService.h"
    12 #include "mozilla/RefPtr.h"
    13 #include "mozilla/Services.h"
    14 #include "nsSSLStatus.h"
    15 #include "nsCOMPtr.h"
    16 #include "nsNSSCertificate.h"
    17 #include "nsCRT.h"
    18 #include "nsPromiseFlatString.h"
    19 #include "nsStringBuffer.h"
    20 #include "nspr.h"
    21 #include "pk11pub.h"
    22 #include "certdb.h"
    23 #include "sechash.h"
    25 using namespace mozilla;
    27 NS_IMPL_ISUPPORTS(nsRecentBadCerts, nsIRecentBadCerts)
    29 nsRecentBadCerts::nsRecentBadCerts()
    30 :monitor("nsRecentBadCerts.monitor")
    31 ,mNextStorePosition(0)
    32 {
    33 }
    35 nsRecentBadCerts::~nsRecentBadCerts()
    36 {
    37 }
    39 NS_IMETHODIMP
    40 nsRecentBadCerts::GetRecentBadCert(const nsAString & aHostNameWithPort, 
    41                                    nsISSLStatus **aStatus)
    42 {
    43   NS_ENSURE_ARG_POINTER(aStatus);
    44   if (!aHostNameWithPort.Length())
    45     return NS_ERROR_INVALID_ARG;
    47   *aStatus = nullptr;
    48   RefPtr<nsSSLStatus> status(new nsSSLStatus());
    50   SECItem foundDER;
    51   foundDER.len = 0;
    52   foundDER.data = nullptr;
    54   bool isDomainMismatch = false;
    55   bool isNotValidAtThisTime = false;
    56   bool isUntrusted = false;
    58   {
    59     ReentrantMonitorAutoEnter lock(monitor);
    60     for (size_t i=0; i<const_recently_seen_list_size; ++i) {
    61       if (mCerts[i].mHostWithPort.Equals(aHostNameWithPort)) {
    62         SECStatus srv = SECITEM_CopyItem(nullptr, &foundDER, &mCerts[i].mDERCert);
    63         if (srv != SECSuccess)
    64           return NS_ERROR_OUT_OF_MEMORY;
    66         isDomainMismatch = mCerts[i].isDomainMismatch;
    67         isNotValidAtThisTime = mCerts[i].isNotValidAtThisTime;
    68         isUntrusted = mCerts[i].isUntrusted;
    69       }
    70     }
    71   }
    73   if (foundDER.len) {
    74     CERTCertDBHandle *certdb = CERT_GetDefaultCertDB();
    75     mozilla::pkix::ScopedCERTCertificate nssCert(
    76       CERT_FindCertByDERCert(certdb, &foundDER));
    77     if (!nssCert) 
    78       nssCert = CERT_NewTempCertificate(certdb, &foundDER,
    79                                         nullptr, // no nickname
    80                                         false, // not perm
    81                                         true); // copy der
    83     SECITEM_FreeItem(&foundDER, false);
    85     if (!nssCert)
    86       return NS_ERROR_FAILURE;
    88     status->mServerCert = nsNSSCertificate::Create(nssCert.get());
    89     status->mHaveCertErrorBits = true;
    90     status->mIsDomainMismatch = isDomainMismatch;
    91     status->mIsNotValidAtThisTime = isNotValidAtThisTime;
    92     status->mIsUntrusted = isUntrusted;
    94     *aStatus = status;
    95     NS_IF_ADDREF(*aStatus);
    96   }
    98   return NS_OK;
    99 }
   101 NS_IMETHODIMP
   102 nsRecentBadCerts::AddBadCert(const nsAString &hostWithPort, 
   103                                     nsISSLStatus *aStatus)
   104 {
   105   NS_ENSURE_ARG(aStatus);
   107   nsCOMPtr<nsIX509Cert> cert;
   108   nsresult rv;
   109   rv = aStatus->GetServerCert(getter_AddRefs(cert));
   110   NS_ENSURE_SUCCESS(rv, rv);
   112   bool isDomainMismatch;
   113   bool isNotValidAtThisTime;
   114   bool isUntrusted;
   116   rv = aStatus->GetIsDomainMismatch(&isDomainMismatch);
   117   NS_ENSURE_SUCCESS(rv, rv);
   119   rv = aStatus->GetIsNotValidAtThisTime(&isNotValidAtThisTime);
   120   NS_ENSURE_SUCCESS(rv, rv);
   122   rv = aStatus->GetIsUntrusted(&isUntrusted);
   123   NS_ENSURE_SUCCESS(rv, rv);
   125   SECItem tempItem;
   126   rv = cert->GetRawDER(&tempItem.len, (uint8_t **)&tempItem.data);
   127   NS_ENSURE_SUCCESS(rv, rv);
   129   {
   130     ReentrantMonitorAutoEnter lock(monitor);
   131     RecentBadCert &updatedEntry = mCerts[mNextStorePosition];
   133     ++mNextStorePosition;
   134     if (mNextStorePosition == const_recently_seen_list_size)
   135       mNextStorePosition = 0;
   137     updatedEntry.Clear();
   138     updatedEntry.mHostWithPort = hostWithPort;
   139     updatedEntry.mDERCert = tempItem; // consume
   140     updatedEntry.isDomainMismatch = isDomainMismatch;
   141     updatedEntry.isNotValidAtThisTime = isNotValidAtThisTime;
   142     updatedEntry.isUntrusted = isUntrusted;
   143   }
   145   return NS_OK;
   146 }
   148 NS_IMETHODIMP
   149 nsRecentBadCerts::ResetStoredCerts()
   150 {
   151   for (size_t i = 0; i < const_recently_seen_list_size; ++i) {
   152     RecentBadCert &entry = mCerts[i];
   153     entry.Clear();
   154   }
   155   return NS_OK;
   156 }

mercurial