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 TransportSecurityInfo_h 8 #define TransportSecurityInfo_h 9 10 #include "CertVerifier.h" // For CertificateTransparencyInfo, EVStatus 11 #include "ScopedNSSTypes.h" 12 #include "certt.h" 13 #include "mozilla/Assertions.h" 14 #include "mozilla/BasePrincipal.h" 15 #include "mozilla/Mutex.h" 16 #include "mozilla/RefPtr.h" 17 #include "mozilla/ipc/TransportSecurityInfoUtils.h" 18 #include "mozpkix/pkixtypes.h" 19 #include "nsTHashMap.h" 20 #include "nsIClassInfo.h" 21 #include "nsIObjectInputStream.h" 22 #include "nsIInterfaceRequestor.h" 23 #include "nsITransportSecurityInfo.h" 24 #include "nsNSSCertificate.h" 25 #include "nsString.h" 26 27 namespace mozilla { 28 namespace psm { 29 30 class TransportSecurityInfo : public nsITransportSecurityInfo, 31 public nsIInterfaceRequestor, 32 public nsISerializable, 33 public nsIClassInfo { 34 protected: 35 virtual ~TransportSecurityInfo() = default; 36 37 public: 38 TransportSecurityInfo(); 39 40 NS_DECL_THREADSAFE_ISUPPORTS 41 NS_DECL_NSITRANSPORTSECURITYINFO 42 NS_DECL_NSIINTERFACEREQUESTOR 43 NS_DECL_NSISERIALIZABLE 44 NS_DECL_NSICLASSINFO 45 46 void SetPreliminaryHandshakeInfo(const SSLChannelInfo& channelInfo, 47 const SSLCipherSuiteInfo& cipherInfo); 48 49 void SetSecurityState(uint32_t aState); 50 GetErrorCode()51 inline int32_t GetErrorCode() { 52 int32_t result; 53 mozilla::DebugOnly<nsresult> rv = GetErrorCode(&result); 54 MOZ_ASSERT(NS_SUCCEEDED(rv)); 55 return result; 56 } 57 GetHostName()58 const nsACString& GetHostName() const { 59 MutexAutoLock lock(mMutex); 60 return mHostName; 61 } 62 63 void SetHostName(const char* host); 64 GetPort()65 int32_t GetPort() const { return mPort; } 66 void SetPort(int32_t aPort); 67 GetOriginAttributes()68 const OriginAttributes& GetOriginAttributes() const { 69 MutexAutoLock lock(mMutex); 70 return mOriginAttributes; 71 } GetOriginAttributes(MutexAutoLock & aProofOfLock)72 const OriginAttributes& GetOriginAttributes( 73 MutexAutoLock& aProofOfLock) const { 74 return mOriginAttributes; 75 } 76 void SetOriginAttributes(const OriginAttributes& aOriginAttributes); 77 78 void SetCanceled(PRErrorCode errorCode); 79 bool IsCanceled(); 80 81 void SetStatusErrorBits(const nsCOMPtr<nsIX509Cert>& cert, 82 uint32_t collected_errors); 83 84 nsresult SetFailedCertChain(nsTArray<nsTArray<uint8_t>>&& certList); 85 86 void SetServerCert(const nsCOMPtr<nsIX509Cert>& aServerCert, 87 EVStatus aEVStatus); 88 89 nsresult SetSucceededCertChain(nsTArray<nsTArray<uint8_t>>&& certList); 90 HasServerCert()91 bool HasServerCert() { 92 MutexAutoLock lock(mMutex); 93 return mServerCert != nullptr; 94 } 95 96 static uint16_t ConvertCertificateTransparencyInfoToStatus( 97 const mozilla::psm::CertificateTransparencyInfo& info); 98 99 // Use errorCode == 0 to indicate success; SetCertVerificationResult(PRErrorCode errorCode)100 virtual void SetCertVerificationResult(PRErrorCode errorCode){}; 101 SetCertificateTransparencyStatus(uint16_t aCertificateTransparencyStatus)102 void SetCertificateTransparencyStatus( 103 uint16_t aCertificateTransparencyStatus) { 104 MutexAutoLock lock(mMutex); 105 mCertificateTransparencyStatus = aCertificateTransparencyStatus; 106 } 107 108 void SetResumed(bool aResumed); 109 110 Atomic<bool> mIsDomainMismatch; 111 Atomic<bool> mIsNotValidAtThisTime; 112 Atomic<bool> mIsUntrusted; 113 Atomic<bool> mIsEV; 114 115 Atomic<bool> mHasIsEVStatus; 116 Atomic<bool> mHaveCipherSuiteAndProtocol; 117 118 /* mHaveCertErrrorBits is relied on to determine whether or not a SPDY 119 connection is eligible for joining in nsNSSSocketInfo::JoinConnection() */ 120 Atomic<bool> mHaveCertErrorBits; 121 122 private: 123 // True if SetCanceled has been called (or if this was deserialized with a 124 // non-zero mErrorCode, which can only be the case if SetCanceled was called 125 // on the original TransportSecurityInfo). 126 Atomic<bool> mCanceled; 127 128 protected: 129 mutable ::mozilla::Mutex mMutex; 130 131 uint16_t mCipherSuite; 132 uint16_t mProtocolVersion; 133 uint16_t mCertificateTransparencyStatus; 134 nsCString mKeaGroup; 135 nsCString mSignatureSchemeName; 136 137 bool mIsAcceptedEch; 138 bool mIsDelegatedCredential; 139 140 nsCOMPtr<nsIInterfaceRequestor> mCallbacks; 141 nsTArray<RefPtr<nsIX509Cert>> mSucceededCertChain; 142 bool mNPNCompleted; 143 nsCString mNegotiatedNPN; 144 bool mResumed; 145 bool mIsBuiltCertChainRootBuiltInRoot; 146 nsCString mPeerId; 147 148 private: ReadBoolAndSetAtomicFieldHelper(nsIObjectInputStream * stream,Atomic<bool> & atomic)149 static nsresult ReadBoolAndSetAtomicFieldHelper(nsIObjectInputStream* stream, 150 Atomic<bool>& atomic) { 151 bool tmpBool; 152 nsresult rv = stream->ReadBoolean(&tmpBool); 153 if (NS_FAILED(rv)) { 154 return rv; 155 } 156 atomic = tmpBool; 157 return rv; 158 } 159 ReadUint32AndSetAtomicFieldHelper(nsIObjectInputStream * stream,Atomic<uint32_t> & atomic)160 static nsresult ReadUint32AndSetAtomicFieldHelper( 161 nsIObjectInputStream* stream, Atomic<uint32_t>& atomic) { 162 uint32_t tmpInt; 163 nsresult rv = stream->Read32(&tmpInt); 164 if (NS_FAILED(rv)) { 165 return rv; 166 } 167 atomic = tmpInt; 168 return rv; 169 } 170 171 template <typename P> ReadParamAtomicHelper(IPC::MessageReader * aReader,Atomic<P> & atomic)172 static bool ReadParamAtomicHelper(IPC::MessageReader* aReader, 173 Atomic<P>& atomic) { 174 P tmpStore; 175 bool result = ReadParam(aReader, &tmpStore); 176 if (result == false) { 177 return result; 178 } 179 atomic = tmpStore; 180 return result; 181 } 182 183 Atomic<uint32_t> mSecurityState; 184 185 Atomic<PRErrorCode> mErrorCode; 186 187 Atomic<int32_t> mPort; 188 nsCString mHostName; 189 OriginAttributes mOriginAttributes; 190 191 nsCOMPtr<nsIX509Cert> mServerCert; 192 193 /* Peer cert chain for failed connections (for error reporting) */ 194 nsTArray<RefPtr<nsIX509Cert>> mFailedCertChain; 195 196 nsresult ReadSSLStatus(nsIObjectInputStream* aStream, 197 MutexAutoLock& aProofOfLock); 198 199 // This function is used to read the binary that are serialized 200 // by using nsIX509CertList 201 nsresult ReadCertList(nsIObjectInputStream* aStream, 202 nsTArray<RefPtr<nsIX509Cert>>& aCertList, 203 MutexAutoLock& aProofOfLock); 204 nsresult ReadCertificatesFromStream(nsIObjectInputStream* aStream, 205 uint32_t aSize, 206 nsTArray<RefPtr<nsIX509Cert>>& aCertList, 207 MutexAutoLock& aProofOfLock); 208 }; 209 210 class RememberCertErrorsTable { 211 private: 212 RememberCertErrorsTable(); 213 214 struct CertStateBits { 215 bool mIsDomainMismatch; 216 bool mIsNotValidAtThisTime; 217 bool mIsUntrusted; 218 }; 219 nsTHashMap<nsCStringHashKey, CertStateBits> mErrorHosts; 220 221 public: 222 void RememberCertHasError(TransportSecurityInfo* infoObject, 223 SECStatus certVerificationResult); 224 void LookupCertErrorBits(TransportSecurityInfo* infoObject); 225 Init()226 static void Init() { sInstance = new RememberCertErrorsTable(); } 227 GetInstance()228 static RememberCertErrorsTable& GetInstance() { 229 MOZ_ASSERT(sInstance); 230 return *sInstance; 231 } 232 Cleanup()233 static void Cleanup() { 234 delete sInstance; 235 sInstance = nullptr; 236 } 237 238 private: 239 Mutex mMutex; 240 241 static RememberCertErrorsTable* sInstance; 242 }; 243 244 } // namespace psm 245 } // namespace mozilla 246 247 // 16786594-0296-4471-8096-8f84497ca428 248 #define TRANSPORTSECURITYINFO_CID \ 249 { \ 250 0x16786594, 0x0296, 0x4471, { \ 251 0x80, 0x96, 0x8f, 0x84, 0x49, 0x7c, 0xa4, 0x28 \ 252 } \ 253 } 254 255 #endif // TransportSecurityInfo_h 256