nsNSSIOLayer.h 8.4 KB

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