summaryrefslogtreecommitdiffstats
path: root/security/manager/ssl/SSLServerCertVerification.h
blob: 694563152d91aaa2a40f565e6b7b20ba2959422b (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
/* -*- 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 _SSLSERVERCERTVERIFICATION_H
#define _SSLSERVERCERTVERIFICATION_H

#include "CertVerifier.h"
#include "CommonSocketControl.h"
#include "ScopedNSSTypes.h"
#include "mozilla/Maybe.h"
#include "mozpkix/pkix.h"
#include "nsITransportSecurityInfo.h"
#include "nsIX509Cert.h"
#include "nsTArray.h"
#include "nsThreadUtils.h"
#include "prerror.h"
#include "prio.h"
#include "seccomon.h"
#include "secoidt.h"

using namespace mozilla::pkix;

namespace mozilla {
namespace psm {

enum class EVStatus : uint8_t;

SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig,
                              PRBool isServer);

// This function triggers the certificate verification. The verification is
// asynchronous and the info object will be notified when the verification has
// completed via SetCertVerificationResult.
SECStatus AuthCertificateHookWithInfo(
    CommonSocketControl* socketControl, const nsACString& aHostName,
    const void* aPtrForLogging, nsTArray<nsTArray<uint8_t>>&& peerCertChain,
    Maybe<nsTArray<nsTArray<uint8_t>>>& stapledOCSPResponses,
    Maybe<nsTArray<uint8_t>>& sctsFromTLSExtension, uint32_t providerFlags);

// Base class for dispatching the certificate verification result.
class BaseSSLServerCertVerificationResult {
 public:
  NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING

  virtual void Dispatch(nsTArray<nsTArray<uint8_t>>&& aBuiltChain,
                        nsTArray<nsTArray<uint8_t>>&& aPeerCertChain,
                        uint16_t aCertificateTransparencyStatus,
                        EVStatus aEVStatus, bool aSucceeded,
                        PRErrorCode aFinalError,
                        nsITransportSecurityInfo::OverridableErrorCategory
                            aOverridableErrorCategory,
                        bool aIsBuiltCertChainRootBuiltInRoot,
                        uint32_t aProviderFlags, bool aMadeOCSPRequests) = 0;
};

// Dispatched to the STS thread to notify the infoObject of the verification
// result.
//
// This will cause the PR_Poll in the STS thread to return, so things work
// correctly even if the STS thread is blocked polling (only) on the file
// descriptor that is waiting for this result.
class SSLServerCertVerificationResult final
    : public BaseSSLServerCertVerificationResult,
      public Runnable {
 public:
  NS_DECL_ISUPPORTS_INHERITED
  NS_DECL_NSIRUNNABLE

  explicit SSLServerCertVerificationResult(CommonSocketControl* socketControl);

  void Dispatch(nsTArray<nsTArray<uint8_t>>&& aBuiltChain,
                nsTArray<nsTArray<uint8_t>>&& aPeerCertChain,
                uint16_t aCertificateTransparencyStatus, EVStatus aEVStatus,
                bool aSucceeded, PRErrorCode aFinalError,
                nsITransportSecurityInfo::OverridableErrorCategory
                    aOverridableErrorCategory,
                bool aIsBuiltCertChainRootBuiltInRoot, uint32_t aProviderFlags,
                bool aMadeOCSPRequests) override;

 private:
  ~SSLServerCertVerificationResult() = default;

  const RefPtr<CommonSocketControl> mSocketControl;
  nsTArray<nsTArray<uint8_t>> mBuiltChain;
  nsTArray<nsTArray<uint8_t>> mPeerCertChain;
  uint16_t mCertificateTransparencyStatus;
  EVStatus mEVStatus;
  bool mSucceeded;
  PRErrorCode mFinalError;
  nsITransportSecurityInfo::OverridableErrorCategory mOverridableErrorCategory;
  bool mIsBuiltCertChainRootBuiltInRoot;
  uint32_t mProviderFlags;
  bool mMadeOCSPRequests;
};

class SSLServerCertVerificationJob : public Runnable {
 public:
  SSLServerCertVerificationJob(const SSLServerCertVerificationJob&) = delete;

  // Must be called only on the socket transport thread
  static SECStatus Dispatch(uint64_t addrForLogging, void* aPinArg,
                            nsTArray<nsTArray<uint8_t>>&& peerCertChain,
                            const nsACString& aHostName, int32_t aPort,
                            const OriginAttributes& aOriginAttributes,
                            Maybe<nsTArray<uint8_t>>& stapledOCSPResponse,
                            Maybe<nsTArray<uint8_t>>& sctsFromTLSExtension,
                            Maybe<DelegatedCredentialInfo>& dcInfo,
                            uint32_t providerFlags, Time time,
                            uint32_t certVerifierFlags,
                            BaseSSLServerCertVerificationResult* aResultTask);

 private:
  NS_DECL_NSIRUNNABLE

  // Must be called only on the socket transport thread
  SSLServerCertVerificationJob(uint64_t addrForLogging, void* aPinArg,
                               nsTArray<nsTArray<uint8_t>>&& peerCertChain,
                               const nsACString& aHostName, int32_t aPort,
                               const OriginAttributes& aOriginAttributes,
                               Maybe<nsTArray<uint8_t>>& stapledOCSPResponse,
                               Maybe<nsTArray<uint8_t>>& sctsFromTLSExtension,
                               Maybe<DelegatedCredentialInfo>& dcInfo,
                               uint32_t providerFlags, Time time,
                               uint32_t certVerifierFlags,
                               BaseSSLServerCertVerificationResult* aResultTask)
      : Runnable("psm::SSLServerCertVerificationJob"),
        mAddrForLogging(addrForLogging),
        mPinArg(aPinArg),
        mPeerCertChain(std::move(peerCertChain)),
        mHostName(aHostName),
        mPort(aPort),
        mOriginAttributes(aOriginAttributes),
        mProviderFlags(providerFlags),
        mCertVerifierFlags(certVerifierFlags),
        mTime(time),
        mStapledOCSPResponse(std::move(stapledOCSPResponse)),
        mSCTsFromTLSExtension(std::move(sctsFromTLSExtension)),
        mDCInfo(std::move(dcInfo)),
        mResultTask(aResultTask) {}

  uint64_t mAddrForLogging;
  void* mPinArg;
  nsTArray<nsTArray<uint8_t>> mPeerCertChain;
  nsCString mHostName;
  int32_t mPort;
  OriginAttributes mOriginAttributes;
  const uint32_t mProviderFlags;
  const uint32_t mCertVerifierFlags;
  const Time mTime;
  Maybe<nsTArray<uint8_t>> mStapledOCSPResponse;
  Maybe<nsTArray<uint8_t>> mSCTsFromTLSExtension;
  Maybe<DelegatedCredentialInfo> mDCInfo;
  RefPtr<BaseSSLServerCertVerificationResult> mResultTask;
};

}  // namespace psm
}  // namespace mozilla

#endif