Bug 783551 - Get tooltool running on the b2g on OS X builds. r=respindola
[gecko.git] / security / manager / ssl / src / nsRecentBadCerts.cpp
blob24e51ea266c15b8073061ccf853a52b7d5335f19
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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"
8 #include "nsIX509Cert.h"
9 #include "nsSSLStatus.h"
10 #include "nsCOMPtr.h"
11 #include "nsAutoPtr.h"
12 #include "nsNSSCertificate.h"
13 #include "nsCRT.h"
14 #include "nsPromiseFlatString.h"
15 #include "nsStringBuffer.h"
16 #include "nsAutoPtr.h"
17 #include "nspr.h"
18 #include "pk11pub.h"
19 #include "certdb.h"
20 #include "sechash.h"
22 #include "nsNSSCleaner.h"
24 using namespace mozilla;
26 NSSCleanupAutoPtrClass(CERTCertificate, CERT_DestroyCertificate)
28 NS_IMPL_THREADSAFE_ISUPPORTS1(nsRecentBadCertsService,
29 nsIRecentBadCertsService)
31 nsRecentBadCertsService::nsRecentBadCertsService()
32 :monitor("nsRecentBadCertsService.monitor")
33 ,mNextStorePosition(0)
37 nsRecentBadCertsService::~nsRecentBadCertsService()
41 nsresult
42 nsRecentBadCertsService::Init()
44 return NS_OK;
47 NS_IMETHODIMP
48 nsRecentBadCertsService::GetRecentBadCert(const nsAString & aHostNameWithPort,
49 nsISSLStatus **aStatus)
51 NS_ENSURE_ARG_POINTER(aStatus);
52 if (!aHostNameWithPort.Length())
53 return NS_ERROR_INVALID_ARG;
55 *aStatus = nullptr;
56 nsRefPtr<nsSSLStatus> status = new nsSSLStatus();
57 if (!status)
58 return NS_ERROR_OUT_OF_MEMORY;
60 SECItem foundDER;
61 foundDER.len = 0;
62 foundDER.data = nullptr;
64 bool isDomainMismatch = false;
65 bool isNotValidAtThisTime = false;
66 bool isUntrusted = false;
69 ReentrantMonitorAutoEnter lock(monitor);
70 for (size_t i=0; i<const_recently_seen_list_size; ++i) {
71 if (mCerts[i].mHostWithPort.Equals(aHostNameWithPort)) {
72 SECStatus srv = SECITEM_CopyItem(nullptr, &foundDER, &mCerts[i].mDERCert);
73 if (srv != SECSuccess)
74 return NS_ERROR_OUT_OF_MEMORY;
76 isDomainMismatch = mCerts[i].isDomainMismatch;
77 isNotValidAtThisTime = mCerts[i].isNotValidAtThisTime;
78 isUntrusted = mCerts[i].isUntrusted;
83 if (foundDER.len) {
84 CERTCertificate *nssCert;
85 CERTCertDBHandle *certdb = CERT_GetDefaultCertDB();
86 nssCert = CERT_FindCertByDERCert(certdb, &foundDER);
87 if (!nssCert)
88 nssCert = CERT_NewTempCertificate(certdb, &foundDER,
89 nullptr, // no nickname
90 false, // not perm
91 true); // copy der
93 SECITEM_FreeItem(&foundDER, false);
95 if (!nssCert)
96 return NS_ERROR_FAILURE;
98 status->mServerCert = nsNSSCertificate::Create(nssCert);
99 CERT_DestroyCertificate(nssCert);
101 status->mHaveCertErrorBits = true;
102 status->mIsDomainMismatch = isDomainMismatch;
103 status->mIsNotValidAtThisTime = isNotValidAtThisTime;
104 status->mIsUntrusted = isUntrusted;
106 *aStatus = status;
107 NS_IF_ADDREF(*aStatus);
110 return NS_OK;
113 NS_IMETHODIMP
114 nsRecentBadCertsService::AddBadCert(const nsAString &hostWithPort,
115 nsISSLStatus *aStatus)
117 NS_ENSURE_ARG(aStatus);
119 nsCOMPtr<nsIX509Cert> cert;
120 nsresult rv;
121 rv = aStatus->GetServerCert(getter_AddRefs(cert));
122 NS_ENSURE_SUCCESS(rv, rv);
124 bool isDomainMismatch;
125 bool isNotValidAtThisTime;
126 bool isUntrusted;
128 rv = aStatus->GetIsDomainMismatch(&isDomainMismatch);
129 NS_ENSURE_SUCCESS(rv, rv);
131 rv = aStatus->GetIsNotValidAtThisTime(&isNotValidAtThisTime);
132 NS_ENSURE_SUCCESS(rv, rv);
134 rv = aStatus->GetIsUntrusted(&isUntrusted);
135 NS_ENSURE_SUCCESS(rv, rv);
137 SECItem tempItem;
138 rv = cert->GetRawDER(&tempItem.len, (PRUint8 **)&tempItem.data);
139 NS_ENSURE_SUCCESS(rv, rv);
142 ReentrantMonitorAutoEnter lock(monitor);
143 RecentBadCert &updatedEntry = mCerts[mNextStorePosition];
145 ++mNextStorePosition;
146 if (mNextStorePosition == const_recently_seen_list_size)
147 mNextStorePosition = 0;
149 updatedEntry.Clear();
150 updatedEntry.mHostWithPort = hostWithPort;
151 updatedEntry.mDERCert = tempItem; // consume
152 updatedEntry.isDomainMismatch = isDomainMismatch;
153 updatedEntry.isNotValidAtThisTime = isNotValidAtThisTime;
154 updatedEntry.isUntrusted = isUntrusted;
157 return NS_OK;