Line data Source code
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 : #ifndef nsNSSIOLayer_h
8 : #define nsNSSIOLayer_h
9 :
10 : #include "TransportSecurityInfo.h"
11 : #include "mozilla/Assertions.h"
12 : #include "mozilla/TimeStamp.h"
13 : #include "nsCOMPtr.h"
14 : #include "nsDataHashtable.h"
15 : #include "nsIClientAuthDialogs.h"
16 : #include "nsIProxyInfo.h"
17 : #include "nsISSLSocketControl.h"
18 : #include "nsNSSCertificate.h"
19 : #include "nsTHashtable.h"
20 : #include "sslt.h"
21 :
22 : namespace mozilla {
23 : class OriginAttributes;
24 : namespace psm {
25 : class SharedSSLState;
26 : } // namespace psm
27 : } // namespace mozilla
28 :
29 : using mozilla::OriginAttributes;
30 :
31 : class nsIObserver;
32 :
33 : class nsNSSSocketInfo final : public mozilla::psm::TransportSecurityInfo,
34 : public nsISSLSocketControl,
35 : public nsIClientAuthUserDecision
36 : {
37 : public:
38 : nsNSSSocketInfo(mozilla::psm::SharedSSLState& aState, uint32_t providerFlags);
39 :
40 : NS_DECL_ISUPPORTS_INHERITED
41 : NS_DECL_NSISSLSOCKETCONTROL
42 : NS_DECL_NSICLIENTAUTHUSERDECISION
43 :
44 : void SetForSTARTTLS(bool aForSTARTTLS);
45 : bool GetForSTARTTLS();
46 :
47 : nsresult GetFileDescPtr(PRFileDesc** aFilePtr);
48 : nsresult SetFileDescPtr(PRFileDesc* aFilePtr);
49 :
50 0 : bool IsHandshakePending() const { return mHandshakePending; }
51 0 : void SetHandshakeNotPending() { mHandshakePending = false; }
52 :
53 0 : void SetTLSVersionRange(SSLVersionRange range) { mTLSVersionRange = range; }
54 0 : SSLVersionRange GetTLSVersionRange() const { return mTLSVersionRange; };
55 :
56 : PRStatus CloseSocketAndDestroy(
57 : const nsNSSShutDownPreventionLock& proofOfLock);
58 :
59 : void SetNegotiatedNPN(const char* value, uint32_t length);
60 : void SetEarlyDataAccepted(bool aAccepted);
61 :
62 : void SetHandshakeCompleted();
63 : void NoteTimeUntilReady();
64 :
65 :
66 0 : void SetFalseStartCallbackCalled() { mFalseStartCallbackCalled = true; }
67 0 : void SetFalseStarted() { mFalseStarted = true; }
68 :
69 : // Note that this is only valid *during* a handshake; at the end of the handshake,
70 : // it gets reset back to false.
71 0 : void SetFullHandshake() { mIsFullHandshake = true; }
72 0 : bool IsFullHandshake() const { return mIsFullHandshake; }
73 :
74 0 : bool GetJoined() { return mJoined; }
75 0 : void SetSentClientCert() { mSentClientCert = true; }
76 :
77 0 : uint32_t GetProviderFlags() const { return mProviderFlags; }
78 :
79 : mozilla::psm::SharedSSLState& SharedState();
80 :
81 : // XXX: These are only used on for diagnostic purposes
82 : enum CertVerificationState {
83 : before_cert_verification,
84 : waiting_for_cert_verification,
85 : after_cert_verification
86 : };
87 : void SetCertVerificationWaiting();
88 : // Use errorCode == 0 to indicate success; in that case, errorMessageType is
89 : // ignored.
90 : void SetCertVerificationResult(PRErrorCode errorCode,
91 : ::mozilla::psm::SSLErrorMessageType errorMessageType);
92 :
93 : // for logging only
94 0 : PRBool IsWaitingForCertVerification() const
95 : {
96 0 : return mCertVerificationState == waiting_for_cert_verification;
97 : }
98 0 : void AddPlaintextBytesRead(uint64_t val) { mPlaintextBytesRead += val; }
99 :
100 0 : bool IsPreliminaryHandshakeDone() const { return mPreliminaryHandshakeDone; }
101 0 : void SetPreliminaryHandshakeDone() { mPreliminaryHandshakeDone = true; }
102 :
103 0 : void SetKEAUsed(uint16_t kea) { mKEAUsed = kea; }
104 :
105 0 : void SetKEAKeyBits(uint32_t keaBits) { mKEAKeyBits = keaBits; }
106 :
107 0 : void SetBypassAuthentication(bool val)
108 : {
109 0 : if (!mHandshakeCompleted) {
110 0 : mBypassAuthentication = val;
111 : }
112 0 : }
113 :
114 0 : void SetSSLVersionUsed(int16_t version)
115 : {
116 0 : mSSLVersionUsed = version;
117 0 : }
118 :
119 0 : void SetMACAlgorithmUsed(int16_t mac) { mMACAlgorithmUsed = mac; }
120 :
121 : protected:
122 : virtual ~nsNSSSocketInfo();
123 :
124 : private:
125 : PRFileDesc* mFd;
126 :
127 : CertVerificationState mCertVerificationState;
128 :
129 : mozilla::psm::SharedSSLState& mSharedState;
130 : bool mForSTARTTLS;
131 : SSLVersionRange mTLSVersionRange;
132 : bool mHandshakePending;
133 : bool mRememberClientAuthCertificate;
134 : bool mPreliminaryHandshakeDone; // after false start items are complete
135 :
136 : nsresult ActivateSSL();
137 :
138 : nsCString mNegotiatedNPN;
139 : bool mNPNCompleted;
140 : bool mEarlyDataAccepted;
141 : bool mFalseStartCallbackCalled;
142 : bool mFalseStarted;
143 : bool mIsFullHandshake;
144 : bool mHandshakeCompleted;
145 : bool mJoined;
146 : bool mSentClientCert;
147 : bool mNotedTimeUntilReady;
148 : bool mFailedVerification;
149 :
150 : // mKEA* are used in false start and http/2 detetermination
151 : // Values are from nsISSLSocketControl
152 : int16_t mKEAUsed;
153 : uint32_t mKEAKeyBits;
154 : int16_t mSSLVersionUsed;
155 : int16_t mMACAlgorithmUsed;
156 : bool mBypassAuthentication;
157 :
158 : uint32_t mProviderFlags;
159 : mozilla::TimeStamp mSocketCreationTimestamp;
160 : uint64_t mPlaintextBytesRead;
161 :
162 : nsCOMPtr<nsIX509Cert> mClientCert;
163 : };
164 :
165 : class nsSSLIOLayerHelpers
166 : {
167 : public:
168 : nsSSLIOLayerHelpers();
169 : ~nsSSLIOLayerHelpers();
170 :
171 : nsresult Init();
172 : void Cleanup();
173 :
174 : static bool nsSSLIOLayerInitialized;
175 : static PRDescIdentity nsSSLIOLayerIdentity;
176 : static PRDescIdentity nsSSLPlaintextLayerIdentity;
177 : static PRIOMethods nsSSLIOLayerMethods;
178 : static PRIOMethods nsSSLPlaintextLayerMethods;
179 :
180 : bool mTreatUnsafeNegotiationAsBroken;
181 :
182 : void setTreatUnsafeNegotiationAsBroken(bool broken);
183 : bool treatUnsafeNegotiationAsBroken();
184 :
185 : private:
186 : struct IntoleranceEntry
187 : {
188 : uint16_t tolerant;
189 : uint16_t intolerant;
190 : PRErrorCode intoleranceReason;
191 :
192 0 : void AssertInvariant() const
193 : {
194 0 : MOZ_ASSERT(intolerant == 0 || tolerant < intolerant);
195 0 : }
196 : };
197 : nsDataHashtable<nsCStringHashKey, IntoleranceEntry> mTLSIntoleranceInfo;
198 : // Sites that require insecure fallback to TLS 1.0, set by the pref
199 : // security.tls.insecure_fallback_hosts, which is a comma-delimited
200 : // list of domain names.
201 : nsTHashtable<nsCStringHashKey> mInsecureFallbackSites;
202 : public:
203 : void rememberTolerantAtVersion(const nsACString& hostname, int16_t port,
204 : uint16_t tolerant);
205 : bool fallbackLimitReached(const nsACString& hostname, uint16_t intolerant);
206 : bool rememberIntolerantAtVersion(const nsACString& hostname, int16_t port,
207 : uint16_t intolerant, uint16_t minVersion,
208 : PRErrorCode intoleranceReason);
209 : void forgetIntolerance(const nsACString& hostname, int16_t port);
210 : void adjustForTLSIntolerance(const nsACString& hostname, int16_t port,
211 : /*in/out*/ SSLVersionRange& range);
212 : PRErrorCode getIntoleranceReason(const nsACString& hostname, int16_t port);
213 :
214 : void clearStoredData();
215 : void loadVersionFallbackLimit();
216 : void setInsecureFallbackSites(const nsCString& str);
217 : void initInsecureFallbackSites();
218 : bool isPublic() const;
219 : void removeInsecureFallbackSite(const nsACString& hostname, uint16_t port);
220 : bool isInsecureFallbackSite(const nsACString& hostname);
221 :
222 : uint16_t mVersionFallbackLimit;
223 : private:
224 : mozilla::Mutex mutex;
225 : nsCOMPtr<nsIObserver> mPrefObserver;
226 : };
227 :
228 : nsresult nsSSLIOLayerNewSocket(int32_t family,
229 : const char* host,
230 : int32_t port,
231 : nsIProxyInfo *proxy,
232 : const OriginAttributes& originAttributes,
233 : PRFileDesc** fd,
234 : nsISupports** securityInfo,
235 : bool forSTARTTLS,
236 : uint32_t flags);
237 :
238 : nsresult nsSSLIOLayerAddToSocket(int32_t family,
239 : const char* host,
240 : int32_t port,
241 : nsIProxyInfo *proxy,
242 : const OriginAttributes& originAttributes,
243 : PRFileDesc* fd,
244 : nsISupports** securityInfo,
245 : bool forSTARTTLS,
246 : uint32_t flags);
247 :
248 : nsresult nsSSLIOLayerFreeTLSIntolerantSites();
249 : nsresult displayUnknownCertErrorAlert(nsNSSSocketInfo* infoObject, int error);
250 :
251 : #endif // nsNSSIOLayer_h
|