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"
11 #include "nsAutoPtr.h"
12 #include "nsNSSCertificate.h"
14 #include "nsPromiseFlatString.h"
15 #include "nsStringBuffer.h"
16 #include "nsAutoPtr.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()
42 nsRecentBadCertsService::Init()
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
;
56 nsRefPtr
<nsSSLStatus
> status
= new nsSSLStatus();
58 return NS_ERROR_OUT_OF_MEMORY
;
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
;
84 CERTCertificate
*nssCert
;
85 CERTCertDBHandle
*certdb
= CERT_GetDefaultCertDB();
86 nssCert
= CERT_FindCertByDERCert(certdb
, &foundDER
);
88 nssCert
= CERT_NewTempCertificate(certdb
, &foundDER
,
89 nullptr, // no nickname
93 SECITEM_FreeItem(&foundDER
, false);
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
;
107 NS_IF_ADDREF(*aStatus
);
114 nsRecentBadCertsService::AddBadCert(const nsAString
&hostWithPort
,
115 nsISSLStatus
*aStatus
)
117 NS_ENSURE_ARG(aStatus
);
119 nsCOMPtr
<nsIX509Cert
> cert
;
121 rv
= aStatus
->GetServerCert(getter_AddRefs(cert
));
122 NS_ENSURE_SUCCESS(rv
, rv
);
124 bool isDomainMismatch
;
125 bool isNotValidAtThisTime
;
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
);
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
;