summaryrefslogtreecommitdiffstats
path: root/security/manager/ssl/CommonSocketControl.h
blob: 4ff8bd40943e44c4f294ba065531cecefb795837 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/* -*- 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 CommonSocketControl_h
#define CommonSocketControl_h

#include "CertVerifier.h"
#include "TransportSecurityInfo.h"
#include "mozilla/Maybe.h"
#include "mozilla/net/SSLTokensCache.h"
#include "nsIInterfaceRequestor.h"
#include "nsITLSSocketControl.h"
#include "nsSocketTransportService2.h"

#ifdef DEBUG
#  include "prthread.h"
#  define COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD() \
    MOZ_ASSERT(mOwningThread == PR_GetCurrentThread())
#else
#  define COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD() \
    do {                                                  \
    } while (false)
#endif

// CommonSocketControl is the base class that implements nsITLSSocketControl.
// Various concrete TLS socket control implementations inherit from this class.
// Currently these implementations consist of NSSSocketControl (a socket
// control for NSS) and QuicSocketControl (a socket control for quic).
// NB: these classes must only be used on the socket thread (the one exception
// being tests that incidentally use CommonSocketControl on the main thread
// (and only the main thread)). This is enforced via the macro
// COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD() that should be called at the
// beginning of every function in this class and all subclasses.
class CommonSocketControl : public nsITLSSocketControl {
 public:
  NS_DECL_THREADSAFE_ISUPPORTS
  NS_DECL_NSITLSSOCKETCONTROL

  CommonSocketControl(const nsCString& aHostName, int32_t aPort,
                      uint32_t aProviderFlags);

  // Use "errorCode" 0 to indicate success.
  virtual void SetCertVerificationResult(PRErrorCode errorCode) {
    MOZ_ASSERT_UNREACHABLE("Subclasses must override this.");
  }

  const nsACString& GetHostName() {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    return mHostName;
  }
  int32_t GetPort() {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    return mPort;
  }
  void SetMadeOCSPRequests(bool aMadeOCSPRequests) {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    mMadeOCSPRequests = aMadeOCSPRequests;
  }
  bool GetMadeOCSPRequests() {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    return mMadeOCSPRequests;
  }
  void SetUsedPrivateDNS(bool aUsedPrivateDNS) {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    mUsedPrivateDNS = aUsedPrivateDNS;
  }
  bool GetUsedPrivateDNS() {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    return mUsedPrivateDNS;
  }

  void SetServerCert(const nsCOMPtr<nsIX509Cert>& aServerCert,
                     mozilla::psm::EVStatus aEVStatus);
  already_AddRefed<nsIX509Cert> GetServerCert() {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    return do_AddRef(mServerCert);
  }
  bool HasServerCert() {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    return mServerCert != nullptr;
  }
  void SetStatusErrorBits(const nsCOMPtr<nsIX509Cert>& cert,
                          nsITransportSecurityInfo::OverridableErrorCategory
                              overridableErrorCategory);
  bool HasUserOverriddenCertificateError() {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    return mOverridableErrorCategory.isSome() &&
           *mOverridableErrorCategory !=
               nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET;
  }
  void SetSucceededCertChain(nsTArray<nsTArray<uint8_t>>&& certList);
  void SetFailedCertChain(nsTArray<nsTArray<uint8_t>>&& certList);
  void SetIsBuiltCertChainRootBuiltInRoot(
      bool aIsBuiltCertChainRootBuiltInRoot) {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    mIsBuiltCertChainRootBuiltInRoot = aIsBuiltCertChainRootBuiltInRoot;
  }
  void SetCertificateTransparencyStatus(
      uint16_t aCertificateTransparencyStatus) {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    mCertificateTransparencyStatus = aCertificateTransparencyStatus;
  }
  void SetOriginAttributes(const mozilla::OriginAttributes& aOriginAttributes) {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    mOriginAttributes = aOriginAttributes;
  }
  mozilla::OriginAttributes& GetOriginAttributes() {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    return mOriginAttributes;
  }

  void SetSecurityState(uint32_t aSecurityState) {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    mSecurityState = aSecurityState;
  }
  void SetResumed(bool aResumed) {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    mResumed = aResumed;
  }

  uint32_t GetProviderFlags() const {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    return mProviderFlags;
  }
  void SetSSLVersionUsed(uint16_t version) {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    mSSLVersionUsed = version;
  }
  void SetSessionCacheInfo(mozilla::net::SessionCacheInfo&& aInfo) {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    mSessionCacheInfo.reset();
    mSessionCacheInfo.emplace(std::move(aInfo));
  }
  void RebuildCertificateInfoFromSSLTokenCache();
  void SetCanceled(PRErrorCode errorCode);
  bool IsCanceled() {
    COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();
    return mCanceled;
  }
  int32_t GetErrorCode();

 protected:
  virtual ~CommonSocketControl() = default;

  nsCString mHostName;
  int32_t mPort;
  mozilla::OriginAttributes mOriginAttributes;

  bool mCanceled;
  mozilla::Maybe<mozilla::net::SessionCacheInfo> mSessionCacheInfo;
  bool mHandshakeCompleted;
  bool mJoined;
  bool mSentClientCert;
  bool mFailedVerification;
  uint16_t mSSLVersionUsed;
  uint32_t mProviderFlags;

  // Fields used to build a TransportSecurityInfo
  uint32_t mSecurityState;
  PRErrorCode mErrorCode;
  // Peer cert chain for failed connections.
  nsTArray<RefPtr<nsIX509Cert>> mFailedCertChain;
  nsCOMPtr<nsIX509Cert> mServerCert;
  nsTArray<RefPtr<nsIX509Cert>> mSucceededCertChain;
  mozilla::Maybe<uint16_t> mCipherSuite;
  mozilla::Maybe<nsCString> mKeaGroupName;
  mozilla::Maybe<nsCString> mSignatureSchemeName;
  mozilla::Maybe<uint16_t> mProtocolVersion;
  uint16_t mCertificateTransparencyStatus;
  mozilla::Maybe<bool> mIsAcceptedEch;
  mozilla::Maybe<bool> mIsDelegatedCredential;
  mozilla::Maybe<nsITransportSecurityInfo::OverridableErrorCategory>
      mOverridableErrorCategory;
  bool mMadeOCSPRequests;
  bool mUsedPrivateDNS;
  mozilla::Maybe<bool> mIsEV;
  bool mNPNCompleted;
  nsCString mNegotiatedNPN;
  bool mResumed;
  bool mIsBuiltCertChainRootBuiltInRoot;
  nsCString mPeerId;

#ifdef DEBUG
  const PRThread* mOwningThread;
#endif
};

#endif  // CommonSocketControl_h