security/manager/ssl/src/nsRecentBadCerts.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:caf1a029c879
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/. */
6
7 #include "nsRecentBadCerts.h"
8
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"
24
25 using namespace mozilla;
26
27 NS_IMPL_ISUPPORTS(nsRecentBadCerts, nsIRecentBadCerts)
28
29 nsRecentBadCerts::nsRecentBadCerts()
30 :monitor("nsRecentBadCerts.monitor")
31 ,mNextStorePosition(0)
32 {
33 }
34
35 nsRecentBadCerts::~nsRecentBadCerts()
36 {
37 }
38
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;
46
47 *aStatus = nullptr;
48 RefPtr<nsSSLStatus> status(new nsSSLStatus());
49
50 SECItem foundDER;
51 foundDER.len = 0;
52 foundDER.data = nullptr;
53
54 bool isDomainMismatch = false;
55 bool isNotValidAtThisTime = false;
56 bool isUntrusted = false;
57
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;
65
66 isDomainMismatch = mCerts[i].isDomainMismatch;
67 isNotValidAtThisTime = mCerts[i].isNotValidAtThisTime;
68 isUntrusted = mCerts[i].isUntrusted;
69 }
70 }
71 }
72
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
82
83 SECITEM_FreeItem(&foundDER, false);
84
85 if (!nssCert)
86 return NS_ERROR_FAILURE;
87
88 status->mServerCert = nsNSSCertificate::Create(nssCert.get());
89 status->mHaveCertErrorBits = true;
90 status->mIsDomainMismatch = isDomainMismatch;
91 status->mIsNotValidAtThisTime = isNotValidAtThisTime;
92 status->mIsUntrusted = isUntrusted;
93
94 *aStatus = status;
95 NS_IF_ADDREF(*aStatus);
96 }
97
98 return NS_OK;
99 }
100
101 NS_IMETHODIMP
102 nsRecentBadCerts::AddBadCert(const nsAString &hostWithPort,
103 nsISSLStatus *aStatus)
104 {
105 NS_ENSURE_ARG(aStatus);
106
107 nsCOMPtr<nsIX509Cert> cert;
108 nsresult rv;
109 rv = aStatus->GetServerCert(getter_AddRefs(cert));
110 NS_ENSURE_SUCCESS(rv, rv);
111
112 bool isDomainMismatch;
113 bool isNotValidAtThisTime;
114 bool isUntrusted;
115
116 rv = aStatus->GetIsDomainMismatch(&isDomainMismatch);
117 NS_ENSURE_SUCCESS(rv, rv);
118
119 rv = aStatus->GetIsNotValidAtThisTime(&isNotValidAtThisTime);
120 NS_ENSURE_SUCCESS(rv, rv);
121
122 rv = aStatus->GetIsUntrusted(&isUntrusted);
123 NS_ENSURE_SUCCESS(rv, rv);
124
125 SECItem tempItem;
126 rv = cert->GetRawDER(&tempItem.len, (uint8_t **)&tempItem.data);
127 NS_ENSURE_SUCCESS(rv, rv);
128
129 {
130 ReentrantMonitorAutoEnter lock(monitor);
131 RecentBadCert &updatedEntry = mCerts[mNextStorePosition];
132
133 ++mNextStorePosition;
134 if (mNextStorePosition == const_recently_seen_list_size)
135 mNextStorePosition = 0;
136
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 }
144
145 return NS_OK;
146 }
147
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