|
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 "nsISSLSocketControl.h" |
|
12 #include "nsIClientAuthDialogs.h" |
|
13 #include "nsIProxyInfo.h" |
|
14 #include "nsNSSCertificate.h" |
|
15 #include "nsDataHashtable.h" |
|
16 #include "nsTHashtable.h" |
|
17 #include "mozilla/TimeStamp.h" |
|
18 #include "sslt.h" |
|
19 |
|
20 namespace mozilla { |
|
21 namespace psm { |
|
22 class SharedSSLState; |
|
23 } |
|
24 } |
|
25 |
|
26 class nsIObserver; |
|
27 |
|
28 class nsNSSSocketInfo : public mozilla::psm::TransportSecurityInfo, |
|
29 public nsISSLSocketControl, |
|
30 public nsIClientAuthUserDecision |
|
31 { |
|
32 public: |
|
33 nsNSSSocketInfo(mozilla::psm::SharedSSLState& aState, uint32_t providerFlags); |
|
34 |
|
35 NS_DECL_ISUPPORTS_INHERITED |
|
36 NS_DECL_NSISSLSOCKETCONTROL |
|
37 NS_DECL_NSICLIENTAUTHUSERDECISION |
|
38 |
|
39 void SetForSTARTTLS(bool aForSTARTTLS); |
|
40 bool GetForSTARTTLS(); |
|
41 |
|
42 nsresult GetFileDescPtr(PRFileDesc** aFilePtr); |
|
43 nsresult SetFileDescPtr(PRFileDesc* aFilePtr); |
|
44 |
|
45 bool IsHandshakePending() const { return mHandshakePending; } |
|
46 void SetHandshakeNotPending() { mHandshakePending = false; } |
|
47 |
|
48 void GetPreviousCert(nsIX509Cert** _result); |
|
49 |
|
50 void SetTLSVersionRange(SSLVersionRange range) { mTLSVersionRange = range; } |
|
51 SSLVersionRange GetTLSVersionRange() const { return mTLSVersionRange; }; |
|
52 |
|
53 PRStatus CloseSocketAndDestroy( |
|
54 const nsNSSShutDownPreventionLock& proofOfLock); |
|
55 |
|
56 void SetNegotiatedNPN(const char* value, uint32_t length); |
|
57 |
|
58 void SetHandshakeCompleted(); |
|
59 void NoteTimeUntilReady(); |
|
60 |
|
61 |
|
62 void SetFalseStartCallbackCalled() { mFalseStartCallbackCalled = true; } |
|
63 void SetFalseStarted() { mFalseStarted = true; } |
|
64 |
|
65 // Note that this is only valid *during* a handshake; at the end of the handshake, |
|
66 // it gets reset back to false. |
|
67 void SetFullHandshake() { mIsFullHandshake = true; } |
|
68 bool IsFullHandshake() const { return mIsFullHandshake; } |
|
69 |
|
70 bool GetJoined() { return mJoined; } |
|
71 void SetSentClientCert() { mSentClientCert = true; } |
|
72 |
|
73 uint32_t GetProviderFlags() const { return mProviderFlags; } |
|
74 |
|
75 mozilla::psm::SharedSSLState& SharedState(); |
|
76 |
|
77 // XXX: These are only used on for diagnostic purposes |
|
78 enum CertVerificationState { |
|
79 before_cert_verification, |
|
80 waiting_for_cert_verification, |
|
81 after_cert_verification |
|
82 }; |
|
83 void SetCertVerificationWaiting(); |
|
84 // Use errorCode == 0 to indicate success; in that case, errorMessageType is |
|
85 // ignored. |
|
86 void SetCertVerificationResult(PRErrorCode errorCode, |
|
87 ::mozilla::psm::SSLErrorMessageType errorMessageType); |
|
88 |
|
89 // for logging only |
|
90 PRBool IsWaitingForCertVerification() const |
|
91 { |
|
92 return mCertVerificationState == waiting_for_cert_verification; |
|
93 } |
|
94 void AddPlaintextBytesRead(uint64_t val) { mPlaintextBytesRead += val; } |
|
95 |
|
96 bool IsPreliminaryHandshakeDone() const { return mPreliminaryHandshakeDone; } |
|
97 void SetPreliminaryHandshakeDone() { mPreliminaryHandshakeDone = true; } |
|
98 |
|
99 void SetKEAUsed(uint16_t kea) { mKEAUsed = kea; } |
|
100 inline int16_t GetKEAExpected() // infallible in nsISSLSocketControl |
|
101 { |
|
102 int16_t result; |
|
103 mozilla::DebugOnly<nsresult> rv = GetKEAExpected(&result); |
|
104 MOZ_ASSERT(NS_SUCCEEDED(rv)); |
|
105 return result; |
|
106 } |
|
107 |
|
108 void SetSSLVersionUsed(int16_t version) |
|
109 { |
|
110 mSSLVersionUsed = version; |
|
111 } |
|
112 |
|
113 private: |
|
114 PRFileDesc* mFd; |
|
115 |
|
116 CertVerificationState mCertVerificationState; |
|
117 |
|
118 mozilla::psm::SharedSSLState& mSharedState; |
|
119 bool mForSTARTTLS; |
|
120 SSLVersionRange mTLSVersionRange; |
|
121 bool mHandshakePending; |
|
122 bool mRememberClientAuthCertificate; |
|
123 bool mPreliminaryHandshakeDone; // after false start items are complete |
|
124 |
|
125 nsresult ActivateSSL(); |
|
126 |
|
127 nsCString mNegotiatedNPN; |
|
128 bool mNPNCompleted; |
|
129 bool mFalseStartCallbackCalled; |
|
130 bool mFalseStarted; |
|
131 bool mIsFullHandshake; |
|
132 bool mHandshakeCompleted; |
|
133 bool mJoined; |
|
134 bool mSentClientCert; |
|
135 bool mNotedTimeUntilReady; |
|
136 |
|
137 // mKEA* are used in false start detetermination |
|
138 // Values are from nsISSLSocketControl |
|
139 int16_t mKEAUsed; |
|
140 int16_t mKEAExpected; |
|
141 int16_t mSSLVersionUsed; |
|
142 |
|
143 uint32_t mProviderFlags; |
|
144 mozilla::TimeStamp mSocketCreationTimestamp; |
|
145 uint64_t mPlaintextBytesRead; |
|
146 }; |
|
147 |
|
148 class nsSSLIOLayerHelpers |
|
149 { |
|
150 public: |
|
151 nsSSLIOLayerHelpers(); |
|
152 ~nsSSLIOLayerHelpers(); |
|
153 |
|
154 nsresult Init(); |
|
155 void Cleanup(); |
|
156 |
|
157 static bool nsSSLIOLayerInitialized; |
|
158 static PRDescIdentity nsSSLIOLayerIdentity; |
|
159 static PRDescIdentity nsSSLPlaintextLayerIdentity; |
|
160 static PRIOMethods nsSSLIOLayerMethods; |
|
161 static PRIOMethods nsSSLPlaintextLayerMethods; |
|
162 |
|
163 nsTHashtable<nsCStringHashKey>* mRenegoUnrestrictedSites; |
|
164 bool mTreatUnsafeNegotiationAsBroken; |
|
165 int32_t mWarnLevelMissingRFC5746; |
|
166 |
|
167 void setTreatUnsafeNegotiationAsBroken(bool broken); |
|
168 bool treatUnsafeNegotiationAsBroken(); |
|
169 void setWarnLevelMissingRFC5746(int32_t level); |
|
170 int32_t getWarnLevelMissingRFC5746(); |
|
171 |
|
172 private: |
|
173 struct IntoleranceEntry |
|
174 { |
|
175 uint16_t tolerant; |
|
176 uint16_t intolerant; |
|
177 |
|
178 void AssertInvariant() const |
|
179 { |
|
180 MOZ_ASSERT(intolerant == 0 || tolerant < intolerant); |
|
181 } |
|
182 }; |
|
183 nsDataHashtable<nsCStringHashKey, IntoleranceEntry> mTLSIntoleranceInfo; |
|
184 public: |
|
185 void rememberTolerantAtVersion(const nsACString& hostname, int16_t port, |
|
186 uint16_t tolerant); |
|
187 bool rememberIntolerantAtVersion(const nsACString& hostname, int16_t port, |
|
188 uint16_t intolerant, uint16_t minVersion); |
|
189 void adjustForTLSIntolerance(const nsACString& hostname, int16_t port, |
|
190 /*in/out*/ SSLVersionRange& range); |
|
191 |
|
192 void setRenegoUnrestrictedSites(const nsCString& str); |
|
193 bool isRenegoUnrestrictedSite(const nsCString& str); |
|
194 void clearStoredData(); |
|
195 |
|
196 bool mFalseStartRequireNPN; |
|
197 bool mFalseStartRequireForwardSecrecy; |
|
198 private: |
|
199 mozilla::Mutex mutex; |
|
200 nsCOMPtr<nsIObserver> mPrefObserver; |
|
201 }; |
|
202 |
|
203 nsresult nsSSLIOLayerNewSocket(int32_t family, |
|
204 const char* host, |
|
205 int32_t port, |
|
206 nsIProxyInfo *proxy, |
|
207 PRFileDesc** fd, |
|
208 nsISupports** securityInfo, |
|
209 bool forSTARTTLS, |
|
210 uint32_t flags); |
|
211 |
|
212 nsresult nsSSLIOLayerAddToSocket(int32_t family, |
|
213 const char* host, |
|
214 int32_t port, |
|
215 nsIProxyInfo *proxy, |
|
216 PRFileDesc* fd, |
|
217 nsISupports** securityInfo, |
|
218 bool forSTARTTLS, |
|
219 uint32_t flags); |
|
220 |
|
221 nsresult nsSSLIOLayerFreeTLSIntolerantSites(); |
|
222 nsresult displayUnknownCertErrorAlert(nsNSSSocketInfo* infoObject, int error); |
|
223 |
|
224 #endif /* _NSNSSIOLAYER_H */ |