1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/manager/ssl/src/nsNSSIOLayer.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,224 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef _NSNSSIOLAYER_H 1.11 +#define _NSNSSIOLAYER_H 1.12 + 1.13 +#include "TransportSecurityInfo.h" 1.14 +#include "nsISSLSocketControl.h" 1.15 +#include "nsIClientAuthDialogs.h" 1.16 +#include "nsIProxyInfo.h" 1.17 +#include "nsNSSCertificate.h" 1.18 +#include "nsDataHashtable.h" 1.19 +#include "nsTHashtable.h" 1.20 +#include "mozilla/TimeStamp.h" 1.21 +#include "sslt.h" 1.22 + 1.23 +namespace mozilla { 1.24 +namespace psm { 1.25 +class SharedSSLState; 1.26 +} 1.27 +} 1.28 + 1.29 +class nsIObserver; 1.30 + 1.31 +class nsNSSSocketInfo : public mozilla::psm::TransportSecurityInfo, 1.32 + public nsISSLSocketControl, 1.33 + public nsIClientAuthUserDecision 1.34 +{ 1.35 +public: 1.36 + nsNSSSocketInfo(mozilla::psm::SharedSSLState& aState, uint32_t providerFlags); 1.37 + 1.38 + NS_DECL_ISUPPORTS_INHERITED 1.39 + NS_DECL_NSISSLSOCKETCONTROL 1.40 + NS_DECL_NSICLIENTAUTHUSERDECISION 1.41 + 1.42 + void SetForSTARTTLS(bool aForSTARTTLS); 1.43 + bool GetForSTARTTLS(); 1.44 + 1.45 + nsresult GetFileDescPtr(PRFileDesc** aFilePtr); 1.46 + nsresult SetFileDescPtr(PRFileDesc* aFilePtr); 1.47 + 1.48 + bool IsHandshakePending() const { return mHandshakePending; } 1.49 + void SetHandshakeNotPending() { mHandshakePending = false; } 1.50 + 1.51 + void GetPreviousCert(nsIX509Cert** _result); 1.52 + 1.53 + void SetTLSVersionRange(SSLVersionRange range) { mTLSVersionRange = range; } 1.54 + SSLVersionRange GetTLSVersionRange() const { return mTLSVersionRange; }; 1.55 + 1.56 + PRStatus CloseSocketAndDestroy( 1.57 + const nsNSSShutDownPreventionLock& proofOfLock); 1.58 + 1.59 + void SetNegotiatedNPN(const char* value, uint32_t length); 1.60 + 1.61 + void SetHandshakeCompleted(); 1.62 + void NoteTimeUntilReady(); 1.63 + 1.64 + 1.65 + void SetFalseStartCallbackCalled() { mFalseStartCallbackCalled = true; } 1.66 + void SetFalseStarted() { mFalseStarted = true; } 1.67 + 1.68 + // Note that this is only valid *during* a handshake; at the end of the handshake, 1.69 + // it gets reset back to false. 1.70 + void SetFullHandshake() { mIsFullHandshake = true; } 1.71 + bool IsFullHandshake() const { return mIsFullHandshake; } 1.72 + 1.73 + bool GetJoined() { return mJoined; } 1.74 + void SetSentClientCert() { mSentClientCert = true; } 1.75 + 1.76 + uint32_t GetProviderFlags() const { return mProviderFlags; } 1.77 + 1.78 + mozilla::psm::SharedSSLState& SharedState(); 1.79 + 1.80 + // XXX: These are only used on for diagnostic purposes 1.81 + enum CertVerificationState { 1.82 + before_cert_verification, 1.83 + waiting_for_cert_verification, 1.84 + after_cert_verification 1.85 + }; 1.86 + void SetCertVerificationWaiting(); 1.87 + // Use errorCode == 0 to indicate success; in that case, errorMessageType is 1.88 + // ignored. 1.89 + void SetCertVerificationResult(PRErrorCode errorCode, 1.90 + ::mozilla::psm::SSLErrorMessageType errorMessageType); 1.91 + 1.92 + // for logging only 1.93 + PRBool IsWaitingForCertVerification() const 1.94 + { 1.95 + return mCertVerificationState == waiting_for_cert_verification; 1.96 + } 1.97 + void AddPlaintextBytesRead(uint64_t val) { mPlaintextBytesRead += val; } 1.98 + 1.99 + bool IsPreliminaryHandshakeDone() const { return mPreliminaryHandshakeDone; } 1.100 + void SetPreliminaryHandshakeDone() { mPreliminaryHandshakeDone = true; } 1.101 + 1.102 + void SetKEAUsed(uint16_t kea) { mKEAUsed = kea; } 1.103 + inline int16_t GetKEAExpected() // infallible in nsISSLSocketControl 1.104 + { 1.105 + int16_t result; 1.106 + mozilla::DebugOnly<nsresult> rv = GetKEAExpected(&result); 1.107 + MOZ_ASSERT(NS_SUCCEEDED(rv)); 1.108 + return result; 1.109 + } 1.110 + 1.111 + void SetSSLVersionUsed(int16_t version) 1.112 + { 1.113 + mSSLVersionUsed = version; 1.114 + } 1.115 + 1.116 +private: 1.117 + PRFileDesc* mFd; 1.118 + 1.119 + CertVerificationState mCertVerificationState; 1.120 + 1.121 + mozilla::psm::SharedSSLState& mSharedState; 1.122 + bool mForSTARTTLS; 1.123 + SSLVersionRange mTLSVersionRange; 1.124 + bool mHandshakePending; 1.125 + bool mRememberClientAuthCertificate; 1.126 + bool mPreliminaryHandshakeDone; // after false start items are complete 1.127 + 1.128 + nsresult ActivateSSL(); 1.129 + 1.130 + nsCString mNegotiatedNPN; 1.131 + bool mNPNCompleted; 1.132 + bool mFalseStartCallbackCalled; 1.133 + bool mFalseStarted; 1.134 + bool mIsFullHandshake; 1.135 + bool mHandshakeCompleted; 1.136 + bool mJoined; 1.137 + bool mSentClientCert; 1.138 + bool mNotedTimeUntilReady; 1.139 + 1.140 + // mKEA* are used in false start detetermination 1.141 + // Values are from nsISSLSocketControl 1.142 + int16_t mKEAUsed; 1.143 + int16_t mKEAExpected; 1.144 + int16_t mSSLVersionUsed; 1.145 + 1.146 + uint32_t mProviderFlags; 1.147 + mozilla::TimeStamp mSocketCreationTimestamp; 1.148 + uint64_t mPlaintextBytesRead; 1.149 +}; 1.150 + 1.151 +class nsSSLIOLayerHelpers 1.152 +{ 1.153 +public: 1.154 + nsSSLIOLayerHelpers(); 1.155 + ~nsSSLIOLayerHelpers(); 1.156 + 1.157 + nsresult Init(); 1.158 + void Cleanup(); 1.159 + 1.160 + static bool nsSSLIOLayerInitialized; 1.161 + static PRDescIdentity nsSSLIOLayerIdentity; 1.162 + static PRDescIdentity nsSSLPlaintextLayerIdentity; 1.163 + static PRIOMethods nsSSLIOLayerMethods; 1.164 + static PRIOMethods nsSSLPlaintextLayerMethods; 1.165 + 1.166 + nsTHashtable<nsCStringHashKey>* mRenegoUnrestrictedSites; 1.167 + bool mTreatUnsafeNegotiationAsBroken; 1.168 + int32_t mWarnLevelMissingRFC5746; 1.169 + 1.170 + void setTreatUnsafeNegotiationAsBroken(bool broken); 1.171 + bool treatUnsafeNegotiationAsBroken(); 1.172 + void setWarnLevelMissingRFC5746(int32_t level); 1.173 + int32_t getWarnLevelMissingRFC5746(); 1.174 + 1.175 +private: 1.176 + struct IntoleranceEntry 1.177 + { 1.178 + uint16_t tolerant; 1.179 + uint16_t intolerant; 1.180 + 1.181 + void AssertInvariant() const 1.182 + { 1.183 + MOZ_ASSERT(intolerant == 0 || tolerant < intolerant); 1.184 + } 1.185 + }; 1.186 + nsDataHashtable<nsCStringHashKey, IntoleranceEntry> mTLSIntoleranceInfo; 1.187 +public: 1.188 + void rememberTolerantAtVersion(const nsACString& hostname, int16_t port, 1.189 + uint16_t tolerant); 1.190 + bool rememberIntolerantAtVersion(const nsACString& hostname, int16_t port, 1.191 + uint16_t intolerant, uint16_t minVersion); 1.192 + void adjustForTLSIntolerance(const nsACString& hostname, int16_t port, 1.193 + /*in/out*/ SSLVersionRange& range); 1.194 + 1.195 + void setRenegoUnrestrictedSites(const nsCString& str); 1.196 + bool isRenegoUnrestrictedSite(const nsCString& str); 1.197 + void clearStoredData(); 1.198 + 1.199 + bool mFalseStartRequireNPN; 1.200 + bool mFalseStartRequireForwardSecrecy; 1.201 +private: 1.202 + mozilla::Mutex mutex; 1.203 + nsCOMPtr<nsIObserver> mPrefObserver; 1.204 +}; 1.205 + 1.206 +nsresult nsSSLIOLayerNewSocket(int32_t family, 1.207 + const char* host, 1.208 + int32_t port, 1.209 + nsIProxyInfo *proxy, 1.210 + PRFileDesc** fd, 1.211 + nsISupports** securityInfo, 1.212 + bool forSTARTTLS, 1.213 + uint32_t flags); 1.214 + 1.215 +nsresult nsSSLIOLayerAddToSocket(int32_t family, 1.216 + const char* host, 1.217 + int32_t port, 1.218 + nsIProxyInfo *proxy, 1.219 + PRFileDesc* fd, 1.220 + nsISupports** securityInfo, 1.221 + bool forSTARTTLS, 1.222 + uint32_t flags); 1.223 + 1.224 +nsresult nsSSLIOLayerFreeTLSIntolerantSites(); 1.225 +nsresult displayUnknownCertErrorAlert(nsNSSSocketInfo* infoObject, int error); 1.226 + 1.227 +#endif /* _NSNSSIOLAYER_H */