summaryrefslogtreecommitdiffstats
path: root/security/manager/ssl/nsNSSIOLayer.h
diff options
context:
space:
mode:
Diffstat (limited to 'security/manager/ssl/nsNSSIOLayer.h')
-rw-r--r--security/manager/ssl/nsNSSIOLayer.h263
1 files changed, 263 insertions, 0 deletions
diff --git a/security/manager/ssl/nsNSSIOLayer.h b/security/manager/ssl/nsNSSIOLayer.h
new file mode 100644
index 000000000..b0b6281a8
--- /dev/null
+++ b/security/manager/ssl/nsNSSIOLayer.h
@@ -0,0 +1,263 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsNSSIOLayer_h
+#define nsNSSIOLayer_h
+
+#include "TransportSecurityInfo.h"
+#include "mozilla/TimeStamp.h"
+#include "nsCOMPtr.h"
+#include "nsDataHashtable.h"
+#include "nsIClientAuthDialogs.h"
+#include "nsIProxyInfo.h"
+#include "nsISSLSocketControl.h"
+#include "nsNSSCertificate.h"
+#include "nsTHashtable.h"
+#include "sslt.h"
+
+namespace mozilla {
+class NeckoOriginAttributes;
+namespace psm {
+class SharedSSLState;
+} // namespace psm
+} // namespace mozilla
+
+using mozilla::NeckoOriginAttributes;
+
+class nsIObserver;
+
+class nsNSSSocketInfo final : public mozilla::psm::TransportSecurityInfo,
+ public nsISSLSocketControl,
+ public nsIClientAuthUserDecision
+{
+public:
+ nsNSSSocketInfo(mozilla::psm::SharedSSLState& aState, uint32_t providerFlags);
+
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_NSISSLSOCKETCONTROL
+ NS_DECL_NSICLIENTAUTHUSERDECISION
+
+ void SetForSTARTTLS(bool aForSTARTTLS);
+ bool GetForSTARTTLS();
+
+ nsresult GetFileDescPtr(PRFileDesc** aFilePtr);
+ nsresult SetFileDescPtr(PRFileDesc* aFilePtr);
+
+ bool IsHandshakePending() const { return mHandshakePending; }
+ void SetHandshakeNotPending() { mHandshakePending = false; }
+
+ void SetTLSVersionRange(SSLVersionRange range) { mTLSVersionRange = range; }
+ SSLVersionRange GetTLSVersionRange() const { return mTLSVersionRange; };
+
+ PRStatus CloseSocketAndDestroy(
+ const nsNSSShutDownPreventionLock& proofOfLock);
+
+ void SetNegotiatedNPN(const char* value, uint32_t length);
+ void SetEarlyDataAccepted(bool aAccepted);
+
+ void SetHandshakeCompleted();
+ void NoteTimeUntilReady();
+
+
+ void SetFalseStartCallbackCalled() { mFalseStartCallbackCalled = true; }
+ void SetFalseStarted() { mFalseStarted = true; }
+
+ // Note that this is only valid *during* a handshake; at the end of the handshake,
+ // it gets reset back to false.
+ void SetFullHandshake() { mIsFullHandshake = true; }
+ bool IsFullHandshake() const { return mIsFullHandshake; }
+
+ bool GetJoined() { return mJoined; }
+ void SetSentClientCert() { mSentClientCert = true; }
+
+ uint32_t GetProviderFlags() const { return mProviderFlags; }
+
+ mozilla::psm::SharedSSLState& SharedState();
+
+ // XXX: These are only used on for diagnostic purposes
+ enum CertVerificationState {
+ before_cert_verification,
+ waiting_for_cert_verification,
+ after_cert_verification
+ };
+ void SetCertVerificationWaiting();
+ // Use errorCode == 0 to indicate success; in that case, errorMessageType is
+ // ignored.
+ void SetCertVerificationResult(PRErrorCode errorCode,
+ ::mozilla::psm::SSLErrorMessageType errorMessageType);
+
+ // for logging only
+ PRBool IsWaitingForCertVerification() const
+ {
+ return mCertVerificationState == waiting_for_cert_verification;
+ }
+ void AddPlaintextBytesRead(uint64_t val) { mPlaintextBytesRead += val; }
+
+ bool IsPreliminaryHandshakeDone() const { return mPreliminaryHandshakeDone; }
+ void SetPreliminaryHandshakeDone() { mPreliminaryHandshakeDone = true; }
+
+ void SetKEAUsed(uint16_t kea) { mKEAUsed = kea; }
+
+ void SetKEAKeyBits(uint32_t keaBits) { mKEAKeyBits = keaBits; }
+
+ void SetBypassAuthentication(bool val)
+ {
+ if (!mHandshakeCompleted) {
+ mBypassAuthentication = val;
+ }
+ }
+
+ void SetSSLVersionUsed(int16_t version)
+ {
+ mSSLVersionUsed = version;
+ }
+
+ void SetMACAlgorithmUsed(int16_t mac) { mMACAlgorithmUsed = mac; }
+
+protected:
+ virtual ~nsNSSSocketInfo();
+
+private:
+ PRFileDesc* mFd;
+
+ CertVerificationState mCertVerificationState;
+
+ mozilla::psm::SharedSSLState& mSharedState;
+ bool mForSTARTTLS;
+ SSLVersionRange mTLSVersionRange;
+ bool mHandshakePending;
+ bool mRememberClientAuthCertificate;
+ bool mPreliminaryHandshakeDone; // after false start items are complete
+
+ nsresult ActivateSSL();
+
+ nsCString mNegotiatedNPN;
+ bool mNPNCompleted;
+ bool mEarlyDataAccepted;
+ bool mFalseStartCallbackCalled;
+ bool mFalseStarted;
+ bool mIsFullHandshake;
+ bool mHandshakeCompleted;
+ bool mJoined;
+ bool mSentClientCert;
+ bool mNotedTimeUntilReady;
+ bool mFailedVerification;
+
+ // mKEA* are used in false start and http/2 detetermination
+ // Values are from nsISSLSocketControl
+ int16_t mKEAUsed;
+ uint32_t mKEAKeyBits;
+ int16_t mSSLVersionUsed;
+ int16_t mMACAlgorithmUsed;
+ bool mBypassAuthentication;
+
+ uint32_t mProviderFlags;
+ mozilla::TimeStamp mSocketCreationTimestamp;
+ uint64_t mPlaintextBytesRead;
+
+ nsCOMPtr<nsIX509Cert> mClientCert;
+};
+
+enum StrongCipherStatus {
+ StrongCipherStatusUnknown,
+ StrongCiphersWorked,
+ StrongCiphersFailed
+};
+
+class nsSSLIOLayerHelpers
+{
+public:
+ nsSSLIOLayerHelpers();
+ ~nsSSLIOLayerHelpers();
+
+ nsresult Init();
+ void Cleanup();
+
+ static bool nsSSLIOLayerInitialized;
+ static PRDescIdentity nsSSLIOLayerIdentity;
+ static PRDescIdentity nsSSLPlaintextLayerIdentity;
+ static PRIOMethods nsSSLIOLayerMethods;
+ static PRIOMethods nsSSLPlaintextLayerMethods;
+
+ bool mTreatUnsafeNegotiationAsBroken;
+
+ void setTreatUnsafeNegotiationAsBroken(bool broken);
+ bool treatUnsafeNegotiationAsBroken();
+
+private:
+ struct IntoleranceEntry
+ {
+ uint16_t tolerant;
+ uint16_t intolerant;
+ PRErrorCode intoleranceReason;
+ StrongCipherStatus strongCipherStatus;
+
+ void AssertInvariant() const
+ {
+ MOZ_ASSERT(intolerant == 0 || tolerant < intolerant);
+ }
+ };
+ nsDataHashtable<nsCStringHashKey, IntoleranceEntry> mTLSIntoleranceInfo;
+ // Sites that require insecure fallback to TLS 1.0, set by the pref
+ // security.tls.insecure_fallback_hosts, which is a comma-delimited
+ // list of domain names.
+ nsTHashtable<nsCStringHashKey> mInsecureFallbackSites;
+public:
+ void rememberTolerantAtVersion(const nsACString& hostname, int16_t port,
+ uint16_t tolerant);
+ bool fallbackLimitReached(const nsACString& hostname, uint16_t intolerant);
+ bool rememberIntolerantAtVersion(const nsACString& hostname, int16_t port,
+ uint16_t intolerant, uint16_t minVersion,
+ PRErrorCode intoleranceReason);
+ bool rememberStrongCiphersFailed(const nsACString& hostName, int16_t port,
+ PRErrorCode intoleranceReason);
+ void forgetIntolerance(const nsACString& hostname, int16_t port);
+ void adjustForTLSIntolerance(const nsACString& hostname, int16_t port,
+ /*in/out*/ SSLVersionRange& range,
+ /*out*/ StrongCipherStatus& strongCipherStatus);
+ PRErrorCode getIntoleranceReason(const nsACString& hostname, int16_t port);
+
+ void clearStoredData();
+ void loadVersionFallbackLimit();
+ void setInsecureFallbackSites(const nsCString& str);
+ void initInsecureFallbackSites();
+ bool isPublic() const;
+ void addInsecureFallbackSite(const nsCString& hostname, bool temporary);
+ void removeInsecureFallbackSite(const nsACString& hostname, uint16_t port);
+ bool isInsecureFallbackSite(const nsACString& hostname);
+
+ bool mFalseStartRequireNPN;
+ bool mUnrestrictedRC4Fallback;
+ uint16_t mVersionFallbackLimit;
+private:
+ mozilla::Mutex mutex;
+ nsCOMPtr<nsIObserver> mPrefObserver;
+};
+
+nsresult nsSSLIOLayerNewSocket(int32_t family,
+ const char* host,
+ int32_t port,
+ nsIProxyInfo *proxy,
+ const NeckoOriginAttributes& originAttributes,
+ PRFileDesc** fd,
+ nsISupports** securityInfo,
+ bool forSTARTTLS,
+ uint32_t flags);
+
+nsresult nsSSLIOLayerAddToSocket(int32_t family,
+ const char* host,
+ int32_t port,
+ nsIProxyInfo *proxy,
+ const NeckoOriginAttributes& originAttributes,
+ PRFileDesc* fd,
+ nsISupports** securityInfo,
+ bool forSTARTTLS,
+ uint32_t flags);
+
+nsresult nsSSLIOLayerFreeTLSIntolerantSites();
+nsresult displayUnknownCertErrorAlert(nsNSSSocketInfo* infoObject, int error);
+
+#endif // nsNSSIOLayer_h