1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : *
3 : * ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is mozilla.org code.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Netscape Communications Corporation.
20 : * Portions created by the Initial Developer are Copyright (C) 1998
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Brian Ryner <bryner@brianryner.com>
25 : * Kai Engert <kengert@redhat.com>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either the GNU General Public License Version 2 or later (the "GPL"), or
29 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #ifndef _NSNSSIOLAYER_H
42 : #define _NSNSSIOLAYER_H
43 :
44 : #include "prtypes.h"
45 : #include "prio.h"
46 : #include "certt.h"
47 : #include "mozilla/Mutex.h"
48 : #include "nsString.h"
49 : #include "nsIInterfaceRequestor.h"
50 : #include "nsIInterfaceRequestorUtils.h"
51 : #include "nsITransportSecurityInfo.h"
52 : #include "nsISSLSocketControl.h"
53 : #include "nsSSLStatus.h"
54 : #include "nsISSLStatusProvider.h"
55 : #include "nsIAssociatedContentSecurity.h"
56 : #include "nsXPIDLString.h"
57 : #include "nsNSSShutDown.h"
58 : #include "nsIClientAuthDialogs.h"
59 : #include "nsAutoPtr.h"
60 : #include "nsNSSCertificate.h"
61 : #include "nsDataHashtable.h"
62 : #include "nsTHashtable.h"
63 :
64 : namespace mozilla {
65 :
66 : namespace psm {
67 :
68 : enum SSLErrorMessageType {
69 : OverridableCertErrorMessage = 1, // for *overridable* certificate errors
70 : PlainErrorMessage = 2 // all other errors (or "no error")
71 : };
72 :
73 : } // namespace psm
74 :
75 : } // namespace mozilla
76 :
77 : class nsNSSSocketInfo : public nsITransportSecurityInfo,
78 : public nsISSLSocketControl,
79 : public nsIInterfaceRequestor,
80 : public nsISSLStatusProvider,
81 : public nsIAssociatedContentSecurity,
82 : public nsISerializable,
83 : public nsIClassInfo,
84 : public nsIClientAuthUserDecision,
85 : public nsNSSShutDownObject,
86 : public nsOnPK11LogoutCancelObject
87 : {
88 : public:
89 : nsNSSSocketInfo();
90 : virtual ~nsNSSSocketInfo();
91 :
92 : NS_DECL_ISUPPORTS
93 : NS_DECL_NSITRANSPORTSECURITYINFO
94 : NS_DECL_NSISSLSOCKETCONTROL
95 : NS_DECL_NSIINTERFACEREQUESTOR
96 : NS_DECL_NSISSLSTATUSPROVIDER
97 : NS_DECL_NSIASSOCIATEDCONTENTSECURITY
98 : NS_DECL_NSISERIALIZABLE
99 : NS_DECL_NSICLASSINFO
100 : NS_DECL_NSICLIENTAUTHUSERDECISION
101 :
102 : nsresult SetSecurityState(PRUint32 aState);
103 : nsresult SetShortSecurityDescription(const PRUnichar *aText);
104 :
105 : nsresult SetForSTARTTLS(bool aForSTARTTLS);
106 : nsresult GetForSTARTTLS(bool *aForSTARTTLS);
107 :
108 : nsresult GetFileDescPtr(PRFileDesc** aFilePtr);
109 : nsresult SetFileDescPtr(PRFileDesc* aFilePtr);
110 :
111 : nsresult GetHandshakePending(bool *aHandshakePending);
112 : nsresult SetHandshakePending(bool aHandshakePending);
113 :
114 4 : const char * GetHostName() const {
115 4 : return mHostName.get();
116 : }
117 : nsresult GetHostName(char **aHostName);
118 : nsresult SetHostName(const char *aHostName);
119 :
120 : nsresult GetPort(PRInt32 *aPort);
121 : nsresult SetPort(PRInt32 aPort);
122 :
123 : void GetPreviousCert(nsIX509Cert** _result);
124 :
125 : PRErrorCode GetErrorCode() const;
126 : void SetCanceled(PRErrorCode errorCode,
127 : ::mozilla::psm::SSLErrorMessageType errorMessageType);
128 :
129 : void SetHasCleartextPhase(bool aHasCleartextPhase);
130 : bool GetHasCleartextPhase();
131 :
132 : void SetHandshakeInProgress(bool aIsIn);
133 : bool GetHandshakeInProgress() { return mHandshakeInProgress; }
134 : bool HandshakeTimeout();
135 :
136 : void SetAllowTLSIntoleranceTimeout(bool aAllow);
137 :
138 : nsresult RememberCAChain(CERTCertList *aCertList);
139 :
140 : /* Set SSL Status values */
141 : nsresult SetSSLStatus(nsSSLStatus *aSSLStatus);
142 12 : nsSSLStatus* SSLStatus() { return mSSLStatus; }
143 : void SetStatusErrorBits(nsIX509Cert & cert, PRUint32 collected_errors);
144 :
145 : PRStatus CloseSocketAndDestroy(
146 : const nsNSSShutDownPreventionLock & proofOfLock);
147 :
148 0 : bool IsCertIssuerBlacklisted() const {
149 0 : return mIsCertIssuerBlacklisted;
150 : }
151 0 : void SetCertIssuerBlacklisted() {
152 0 : mIsCertIssuerBlacklisted = true;
153 0 : }
154 :
155 : void SetNegotiatedNPN(const char *value, PRUint32 length);
156 4 : void SetHandshakeCompleted() { mHandshakeCompleted = true; }
157 :
158 0 : bool GetJoined() { return mJoined; }
159 0 : void SetSentClientCert() { mSentClientCert = true; }
160 :
161 : // XXX: These are only used on for diagnostic purposes
162 : enum CertVerificationState {
163 : before_cert_verification,
164 : waiting_for_cert_verification,
165 : after_cert_verification
166 : };
167 : void SetCertVerificationWaiting();
168 : // Use errorCode == 0 to indicate success; in that case, errorMessageType is
169 : // ignored.
170 : void SetCertVerificationResult(PRErrorCode errorCode,
171 : ::mozilla::psm::SSLErrorMessageType errorMessageType);
172 :
173 : // for logging only
174 0 : PRBool IsWaitingForCertVerification() const
175 : {
176 0 : return mCertVerificationState == waiting_for_cert_verification;
177 : }
178 :
179 0 : bool IsSSL3Enabled() const { return mSSL3Enabled; }
180 4 : void SetSSL3Enabled(bool enabled) { mSSL3Enabled = enabled; }
181 4 : bool IsTLSEnabled() const { return mTLSEnabled; }
182 4 : void SetTLSEnabled(bool enabled) { mTLSEnabled = enabled; }
183 : protected:
184 : mutable ::mozilla::Mutex mMutex;
185 :
186 : nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
187 : PRFileDesc* mFd;
188 : CertVerificationState mCertVerificationState;
189 : PRIntervalTime mCertVerificationStarted;
190 : PRIntervalTime mCertVerificationEnded;
191 : PRUint32 mSecurityState;
192 : PRInt32 mSubRequestsHighSecurity;
193 : PRInt32 mSubRequestsLowSecurity;
194 : PRInt32 mSubRequestsBrokenSecurity;
195 : PRInt32 mSubRequestsNoSecurity;
196 : nsString mShortDesc;
197 :
198 : PRErrorCode mErrorCode;
199 : ::mozilla::psm::SSLErrorMessageType mErrorMessageType;
200 : nsString mErrorMessageCached;
201 : nsresult formatErrorMessage(::mozilla::MutexAutoLock const & proofOfLock);
202 :
203 : bool mDocShellDependentStuffKnown;
204 : bool mExternalErrorReporting; // DocShellDependent
205 : bool mForSTARTTLS;
206 : bool mSSL3Enabled;
207 : bool mTLSEnabled;
208 : bool mHandshakePending;
209 : bool mHasCleartextPhase;
210 : bool mHandshakeInProgress;
211 : bool mAllowTLSIntoleranceTimeout;
212 : bool mRememberClientAuthCertificate;
213 : PRIntervalTime mHandshakeStartTime;
214 : PRInt32 mPort;
215 : nsXPIDLCString mHostName;
216 : PRErrorCode mIsCertIssuerBlacklisted;
217 :
218 : /* SSL Status */
219 : nsRefPtr<nsSSLStatus> mSSLStatus;
220 :
221 : nsresult ActivateSSL();
222 :
223 : nsCString mNegotiatedNPN;
224 : bool mNPNCompleted;
225 : bool mHandshakeCompleted;
226 : bool mJoined;
227 : bool mSentClientCert;
228 :
229 : private:
230 : virtual void virtualDestroyNSSReference();
231 : void destructorSafeDestroyNSSReference();
232 : };
233 :
234 : class nsSSLStatus;
235 : class nsNSSSocketInfo;
236 :
237 : class nsPSMRememberCertErrorsTable
238 328 : {
239 : private:
240 : struct CertStateBits
241 : {
242 : bool mIsDomainMismatch;
243 : bool mIsNotValidAtThisTime;
244 : bool mIsUntrusted;
245 : };
246 : nsDataHashtableMT<nsCStringHashKey, CertStateBits> mErrorHosts;
247 : nsresult GetHostPortKey(nsNSSSocketInfo* infoObject, nsCAutoString& result);
248 :
249 : public:
250 : friend class nsSSLIOLayerHelpers;
251 : nsPSMRememberCertErrorsTable();
252 : void RememberCertHasError(nsNSSSocketInfo* infoObject,
253 : nsSSLStatus* status,
254 : SECStatus certVerificationResult);
255 : void LookupCertErrorBits(nsNSSSocketInfo* infoObject,
256 : nsSSLStatus* status);
257 : };
258 :
259 : class nsSSLIOLayerHelpers
260 : {
261 : public:
262 : static nsresult Init();
263 : static void Cleanup();
264 :
265 : static bool nsSSLIOLayerInitialized;
266 : static PRDescIdentity nsSSLIOLayerIdentity;
267 : static PRIOMethods nsSSLIOLayerMethods;
268 :
269 : static mozilla::Mutex *mutex;
270 : static nsTHashtable<nsCStringHashKey> *mTLSIntolerantSites;
271 : static nsTHashtable<nsCStringHashKey> *mTLSTolerantSites;
272 : static nsPSMRememberCertErrorsTable* mHostsWithCertErrors;
273 :
274 : static nsTHashtable<nsCStringHashKey> *mRenegoUnrestrictedSites;
275 : static bool mTreatUnsafeNegotiationAsBroken;
276 : static PRInt32 mWarnLevelMissingRFC5746;
277 :
278 : static void setTreatUnsafeNegotiationAsBroken(bool broken);
279 : static bool treatUnsafeNegotiationAsBroken();
280 :
281 : static void setWarnLevelMissingRFC5746(PRInt32 level);
282 : static PRInt32 getWarnLevelMissingRFC5746();
283 :
284 : static void getSiteKey(nsNSSSocketInfo *socketInfo, nsCSubstring &key);
285 : static bool rememberPossibleTLSProblemSite(nsNSSSocketInfo *socketInfo);
286 : static void rememberTolerantSite(nsNSSSocketInfo *socketInfo);
287 :
288 : static void addIntolerantSite(const nsCString &str);
289 : static void removeIntolerantSite(const nsCString &str);
290 : static bool isKnownAsIntolerantSite(const nsCString &str);
291 :
292 : static void setRenegoUnrestrictedSites(const nsCString &str);
293 : static bool isRenegoUnrestrictedSite(const nsCString &str);
294 : };
295 :
296 : nsresult nsSSLIOLayerNewSocket(PRInt32 family,
297 : const char *host,
298 : PRInt32 port,
299 : const char *proxyHost,
300 : PRInt32 proxyPort,
301 : PRFileDesc **fd,
302 : nsISupports **securityInfo,
303 : bool forSTARTTLS,
304 : bool anonymousLoad);
305 :
306 : nsresult nsSSLIOLayerAddToSocket(PRInt32 family,
307 : const char *host,
308 : PRInt32 port,
309 : const char *proxyHost,
310 : PRInt32 proxyPort,
311 : PRFileDesc *fd,
312 : nsISupports **securityInfo,
313 : bool forSTARTTLS,
314 : bool anonymousLoad);
315 :
316 : nsresult nsSSLIOLayerFreeTLSIntolerantSites();
317 : nsresult displayUnknownCertErrorAlert(nsNSSSocketInfo *infoObject, int error);
318 :
319 : // 16786594-0296-4471-8096-8f84497ca428
320 : #define NS_NSSSOCKETINFO_CID \
321 : { 0x16786594, 0x0296, 0x4471, \
322 : { 0x80, 0x96, 0x8f, 0x84, 0x49, 0x7c, 0xa4, 0x28 } }
323 :
324 :
325 : #endif /* _NSNSSIOLAYER_H */
|