Bug 1935611 - Fix libyuv/libpng link failed for loongarch64. r=glandium,tnikkel,ng
[gecko.git] / security / manager / ssl / NSSSocketControl.h
blobc215b4131e30d17aa5539d3ec42fc8178b5503f5
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 #ifndef NSSSocketControl_h
8 #define NSSSocketControl_h
10 #include "CommonSocketControl.h"
11 #include "TLSClientAuthCertSelection.h"
12 #include "mozilla/Casting.h"
13 #include "nsNSSIOLayer.h"
14 #include "nsThreadUtils.h"
16 extern mozilla::LazyLogModule gPIPNSSLog;
18 class SelectClientAuthCertificate;
20 class NSSSocketControl final : public CommonSocketControl {
21 public:
22 NSSSocketControl(const nsCString& aHostName, int32_t aPort,
23 already_AddRefed<nsSSLIOLayerHelpers> aSSLIOLayerHelpers,
24 uint32_t providerFlags, uint32_t providerTlsFlags);
26 NS_INLINE_DECL_REFCOUNTING_INHERITED(NSSSocketControl, CommonSocketControl);
28 void SetForSTARTTLS(bool aForSTARTTLS);
29 bool GetForSTARTTLS();
31 nsresult GetFileDescPtr(PRFileDesc** aFilePtr);
32 nsresult SetFileDescPtr(PRFileDesc* aFilePtr);
34 bool IsHandshakePending() const {
35 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
36 return mHandshakePending;
38 void SetHandshakeNotPending() {
39 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
40 mHandshakePending = false;
43 void SetTLSVersionRange(SSLVersionRange range) {
44 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
45 mTLSVersionRange = range;
47 SSLVersionRange GetTLSVersionRange() const {
48 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
49 return mTLSVersionRange;
52 void RememberTLSTolerant() {
53 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
54 mSSLIOLayerHelpers->rememberTolerantAtVersion(
55 GetHostName(), mozilla::AssertedCast<uint16_t>(GetPort()),
56 mTLSVersionRange.max);
59 void RemoveInsecureTLSFallback() {
60 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
61 mSSLIOLayerHelpers->removeInsecureFallbackSite(
62 GetHostName(), mozilla::AssertedCast<uint16_t>(GetPort()));
65 PRErrorCode GetTLSIntoleranceReason() {
66 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
67 return mSSLIOLayerHelpers->getIntoleranceReason(
68 GetHostName(), mozilla::AssertedCast<uint16_t>(GetPort()));
71 void ForgetTLSIntolerance() {
72 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
73 mSSLIOLayerHelpers->forgetIntolerance(
74 GetHostName(), mozilla::AssertedCast<uint16_t>(GetPort()));
77 bool RememberTLSIntolerant(PRErrorCode err) {
78 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
79 return mSSLIOLayerHelpers->rememberIntolerantAtVersion(
80 GetHostName(), mozilla::AssertedCast<uint16_t>(GetPort()),
81 mTLSVersionRange.min, mTLSVersionRange.max, err);
84 void AdjustForTLSIntolerance(SSLVersionRange& range) {
85 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
86 mSSLIOLayerHelpers->adjustForTLSIntolerance(
87 GetHostName(), mozilla::AssertedCast<uint16_t>(GetPort()), range);
90 // From nsITLSSocketControl.
91 NS_IMETHOD ProxyStartSSL(void) override;
92 NS_IMETHOD StartTLS(void) override;
93 NS_IMETHOD AsyncStartTLS(JSContext* aCx,
94 mozilla::dom::Promise** aPromise) override;
95 NS_IMETHOD SetNPNList(nsTArray<nsCString>& aNPNList) override;
96 NS_IMETHOD GetAlpnEarlySelection(nsACString& _retval) override;
97 NS_IMETHOD GetEarlyDataAccepted(bool* aEarlyDataAccepted) override;
98 NS_IMETHOD DriveHandshake(void) override;
99 NS_IMETHOD GetKEAUsed(int16_t* aKEAUsed) override;
100 NS_IMETHOD GetKEAKeyBits(uint32_t* aKEAKeyBits) override;
101 NS_IMETHOD GetSSLVersionOffered(int16_t* aSSLVersionOffered) override;
102 NS_IMETHOD GetMACAlgorithmUsed(int16_t* aMACAlgorithmUsed) override;
103 bool GetDenyClientCert() override;
104 void SetDenyClientCert(bool aDenyClientCert) override;
105 NS_IMETHOD GetEsniTxt(nsACString& aEsniTxt) override;
106 NS_IMETHOD SetEsniTxt(const nsACString& aEsniTxt) override;
107 NS_IMETHOD GetEchConfig(nsACString& aEchConfig) override;
108 NS_IMETHOD SetEchConfig(const nsACString& aEchConfig) override;
109 NS_IMETHOD GetPeerId(nsACString& aResult) override;
110 NS_IMETHOD GetRetryEchConfig(nsACString& aEchConfig) override;
111 NS_IMETHOD DisableEarlyData(void) override;
112 NS_IMETHOD SetHandshakeCallbackListener(
113 nsITlsHandshakeCallbackListener* callback) override;
114 NS_IMETHOD Claim() override;
115 NS_IMETHOD SetBrowserId(uint64_t browserId) override;
116 NS_IMETHOD GetBrowserId(uint64_t* browserId) override;
118 PRStatus CloseSocketAndDestroy();
120 void SetNegotiatedNPN(const char* value, uint32_t length);
121 void SetEarlyDataAccepted(bool aAccepted);
123 void SetHandshakeCompleted();
124 bool IsHandshakeCompleted() const {
125 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
126 return mHandshakeCompleted;
128 void NoteTimeUntilReady();
130 void SetFalseStartCallbackCalled() {
131 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
132 mFalseStartCallbackCalled = true;
134 void SetFalseStarted() {
135 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
136 mFalseStarted = true;
139 // Note that this is only valid *during* a handshake; at the end of the
140 // handshake, it gets reset back to false.
141 void SetFullHandshake() {
142 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
143 mIsFullHandshake = true;
145 bool IsFullHandshake() const {
146 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
147 return mIsFullHandshake;
150 void UpdateEchExtensionStatus(EchExtensionStatus aEchExtensionStatus) {
151 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
152 mEchExtensionStatus = std::max(aEchExtensionStatus, mEchExtensionStatus);
154 EchExtensionStatus GetEchExtensionStatus() const {
155 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
156 return mEchExtensionStatus;
159 void WillSendMlkemShare() {
160 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
161 mSentMlkemShare = true;
164 bool SentMlkemShare() {
165 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
166 return mSentMlkemShare;
169 void SetHasTls13HandshakeSecrets() {
170 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
171 mHasTls13HandshakeSecrets = true;
174 bool HasTls13HandshakeSecrets() {
175 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
176 return mHasTls13HandshakeSecrets;
179 bool GetJoined() {
180 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
181 return mJoined;
184 uint32_t GetProviderTlsFlags() const {
185 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
186 return mProviderTlsFlags;
189 enum CertVerificationState {
190 BeforeCertVerification,
191 WaitingForCertVerification,
192 AfterCertVerification
195 void SetCertVerificationWaiting();
197 // Use errorCode == 0 to indicate success;
198 void SetCertVerificationResult(PRErrorCode errorCode) override;
200 void ClientAuthCertificateSelected(
201 nsTArray<uint8_t>& certBytes,
202 nsTArray<nsTArray<uint8_t>>& certChainBytes);
204 bool IsWaitingForCertVerification() const {
205 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
206 return mCertVerificationState == WaitingForCertVerification;
208 void AddPlaintextBytesRead(uint64_t val) {
209 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
210 mPlaintextBytesRead += val;
213 bool IsPreliminaryHandshakeDone() const {
214 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
215 return mPreliminaryHandshakeDone;
217 void SetPreliminaryHandshakeDone() {
218 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
219 mPreliminaryHandshakeDone = true;
222 void SetKEAUsed(int16_t kea) {
223 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
224 mKEAUsed = kea;
227 void SetKEAKeyBits(uint32_t keaBits) {
228 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
229 mKEAKeyBits = keaBits;
232 void SetMACAlgorithmUsed(int16_t mac) {
233 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
234 mMACAlgorithmUsed = mac;
237 void SetShortWritePending(int32_t amount, unsigned char data) {
238 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
239 mIsShortWritePending = true;
240 mShortWriteOriginalAmount = amount;
241 mShortWritePendingByte = data;
244 bool IsShortWritePending() {
245 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
246 return mIsShortWritePending;
249 unsigned char const* GetShortWritePendingByteRef() {
250 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
251 return &mShortWritePendingByte;
254 int32_t ResetShortWritePending() {
255 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
256 mIsShortWritePending = false;
257 return mShortWriteOriginalAmount;
260 #ifdef DEBUG
261 // These helpers assert that the caller does try to send the same data
262 // as it was previously when we hit the short-write. This is a measure
263 // to make sure we communicate correctly to the consumer.
264 void RememberShortWrittenBuffer(const unsigned char* data) {
265 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
266 mShortWriteBufferCheck =
267 mozilla::MakeUnique<char[]>(mShortWriteOriginalAmount);
268 memcpy(mShortWriteBufferCheck.get(), data, mShortWriteOriginalAmount);
270 void CheckShortWrittenBuffer(const unsigned char* data, int32_t amount) {
271 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
272 if (!mShortWriteBufferCheck) return;
273 MOZ_ASSERT(amount >= mShortWriteOriginalAmount,
274 "unexpected amount length after short write");
275 MOZ_ASSERT(
276 !memcmp(mShortWriteBufferCheck.get(), data, mShortWriteOriginalAmount),
277 "unexpected buffer content after short write");
278 mShortWriteBufferCheck = nullptr;
280 #endif
282 nsresult SetResumptionTokenFromExternalCache(PRFileDesc* fd);
284 void SetPreliminaryHandshakeInfo(const SSLChannelInfo& channelInfo,
285 const SSLCipherSuiteInfo& cipherInfo);
287 void SetPendingSelectClientAuthCertificate(
288 nsCOMPtr<nsIRunnable>&& selectClientAuthCertificate) {
289 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
290 MOZ_LOG(
291 gPIPNSSLog, mozilla::LogLevel::Debug,
292 ("[%p] setting pending select client auth certificate", (void*)mFd));
293 // If the connection corresponding to this socket hasn't been claimed, it
294 // is a speculative connection. The connection will block until the "choose
295 // a client auth certificate" dialog has been shown. The dialog will only
296 // be shown when this connection gets claimed. However, necko will never
297 // claim the connection as long as it is blocking. Thus, this connection
298 // can't proceed, so it's best to cancel it. Necko will create a new,
299 // non-speculative connection instead.
300 if (!mClaimed) {
301 SetCanceled(PR_CONNECT_RESET_ERROR);
302 } else {
303 mPendingSelectClientAuthCertificate =
304 std::move(selectClientAuthCertificate);
308 void MaybeDispatchSelectClientAuthCertificate() {
309 COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
310 if (!IsWaitingForCertVerification() && mClaimed &&
311 mPendingSelectClientAuthCertificate) {
312 MOZ_LOG(gPIPNSSLog, mozilla::LogLevel::Debug,
313 ("[%p] dispatching pending select client auth certificate",
314 (void*)mFd));
315 mozilla::Unused << NS_DispatchToMainThread(
316 mPendingSelectClientAuthCertificate);
317 mPendingSelectClientAuthCertificate = nullptr;
321 private:
322 ~NSSSocketControl() = default;
324 PRFileDesc* mFd;
326 CertVerificationState mCertVerificationState;
328 RefPtr<nsSSLIOLayerHelpers> mSSLIOLayerHelpers;
329 bool mForSTARTTLS;
330 SSLVersionRange mTLSVersionRange;
331 bool mHandshakePending;
332 bool mPreliminaryHandshakeDone; // after false start items are complete
334 nsresult ActivateSSL();
336 nsCString mEsniTxt;
337 nsCString mEchConfig;
338 bool mEarlyDataAccepted;
339 bool mDenyClientCert;
340 bool mFalseStartCallbackCalled;
341 bool mFalseStarted;
342 bool mIsFullHandshake;
343 bool mNotedTimeUntilReady;
344 EchExtensionStatus mEchExtensionStatus; // Currently only used for telemetry.
345 bool mSentMlkemShare;
346 bool mHasTls13HandshakeSecrets;
348 // True when SSL layer has indicated an "SSL short write", i.e. need
349 // to call on send one or more times to push all pending data to write.
350 bool mIsShortWritePending;
352 // These are only valid if mIsShortWritePending is true.
354 // Value of the last byte pending from the SSL short write that needs
355 // to be passed to subsequent calls to send to perform the flush.
356 unsigned char mShortWritePendingByte;
358 // Original amount of data the upper layer has requested to write to
359 // return after the successful flush.
360 int32_t mShortWriteOriginalAmount;
362 #ifdef DEBUG
363 mozilla::UniquePtr<char[]> mShortWriteBufferCheck;
364 #endif
366 // mKEA* are used in false start and http/2 detetermination
367 // Values are from nsITLSSocketControl
368 int16_t mKEAUsed;
369 uint32_t mKEAKeyBits;
370 int16_t mMACAlgorithmUsed;
372 uint32_t mProviderTlsFlags;
373 mozilla::TimeStamp mSocketCreationTimestamp;
374 uint64_t mPlaintextBytesRead;
376 bool mClaimed;
377 nsCOMPtr<nsIRunnable> mPendingSelectClientAuthCertificate;
379 // Regarding the client certificate message in the TLS handshake, RFC 5246
380 // (TLS 1.2) says:
381 // If the certificate_authorities list in the certificate request
382 // message was non-empty, one of the certificates in the certificate
383 // chain SHOULD be issued by one of the listed CAs.
384 // (RFC 8446 (TLS 1.3) has a similar provision)
385 // These certificates may be known to gecko but not NSS (e.g. enterprise
386 // intermediates). In order to make these certificates discoverable to NSS
387 // so it can include them in the message, we cache them here as temporary
388 // certificates.
389 mozilla::UniqueCERTCertList mClientCertChain;
391 nsCOMPtr<nsITlsHandshakeCallbackListener> mTlsHandshakeCallback;
393 uint64_t mBrowserId;
396 #endif // NSSSocketControl_h