1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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/. */
10 #include "CTPolicyEnforcer.h"
11 #include "CTVerifyResult.h"
12 #include "EnterpriseRoots.h"
13 #include "OCSPCache.h"
14 #include "RootCertificateTelemetryUtils.h"
15 #include "ScopedNSSTypes.h"
16 #include "mozilla/Telemetry.h"
17 #include "mozilla/TimeStamp.h"
18 #include "mozilla/UniquePtr.h"
20 #include "mozpkix/pkixtypes.h"
24 # pragma warning(push)
25 // Silence "RootingAPI.h(718): warning C4324: 'js::DispatchWrapper<T>':
26 // structure was padded due to alignment specifier with [ T=void * ]"
27 # pragma warning(disable : 4324)
28 #endif /* defined(_MSC_VER) */
29 #include "mozilla/BasePrincipal.h"
31 # pragma warning(pop) /* popping the pragma in this file */
32 #endif /* defined(_MSC_VER) */
37 // Including the headers of the classes below would bring along all of their
38 // dependent headers and force us to export them in moz.build.
39 // Just forward-declare the classes here instead.
40 class MultiLogCTVerifier
;
41 class CTDiversityPolicy
;
44 } // namespace mozilla
49 typedef mozilla::pkix::Result Result
;
51 enum class EVStatus
: uint8_t {
56 // These values correspond to the CERT_CHAIN_KEY_SIZE_STATUS telemetry.
57 enum class KeySizeStatus
{
59 LargeMinimumSucceeded
= 1,
60 CompatibilityRisk
= 2,
64 enum class CRLiteMode
{
68 ConfirmRevocations
= 3,
71 enum class NetscapeStepUpPolicy
: uint32_t;
73 class PinningTelemetryInfo
{
75 PinningTelemetryInfo()
76 : certPinningResultBucket(0), rootBucket(ROOT_CERTIFICATE_UNKNOWN
) {
80 // Should we accumulate pinning telemetry for the result?
81 bool accumulateResult
;
82 Maybe
<Telemetry::HistogramID
> certPinningResultHistogram
;
83 int32_t certPinningResultBucket
;
84 // Should we accumulate telemetry for the root?
85 bool accumulateForRoot
;
89 accumulateForRoot
= false;
90 accumulateResult
= false;
94 class CertificateTransparencyInfo
{
96 CertificateTransparencyInfo()
98 policyCompliance(mozilla::ct::CTPolicyCompliance::Unknown
) {
104 // Verification result of the processed SCTs.
105 mozilla::ct::CTVerifyResult verifyResult
;
106 // Connection compliance to the CT Policy.
107 mozilla::ct::CTPolicyCompliance policyCompliance
;
112 class DelegatedCredentialInfo
{
114 DelegatedCredentialInfo() : scheme(ssl_sig_none
), authKeyBits(0) {}
115 DelegatedCredentialInfo(SSLSignatureScheme scheme
, uint32_t authKeyBits
)
116 : scheme(scheme
), authKeyBits(authKeyBits
) {}
118 // The signature scheme to be used in CertVerify. This tells us
119 // whether to interpret |authKeyBits| in an RSA or ECDSA context.
120 SSLSignatureScheme scheme
;
122 // The size of the key, in bits.
123 uint32_t authKeyBits
;
126 class NSSCertDBTrustDomain
;
130 typedef unsigned int Flags
;
131 // XXX: FLAG_LOCAL_ONLY is ignored in the classic verification case
132 static const Flags FLAG_LOCAL_ONLY
;
133 // Don't perform fallback DV validation on EV validation failure.
134 static const Flags FLAG_MUST_BE_EV
;
135 // TLS feature request_status should be ignored
136 static const Flags FLAG_TLS_IGNORE_STATUS_REQUEST
;
138 // These values correspond to the SSL_OCSP_STAPLING telemetry.
139 enum OCSPStaplingStatus
{
140 OCSP_STAPLING_NEVER_CHECKED
= 0,
141 OCSP_STAPLING_GOOD
= 1,
142 OCSP_STAPLING_NONE
= 2,
143 OCSP_STAPLING_EXPIRED
= 3,
144 OCSP_STAPLING_INVALID
= 4,
147 // *evOidPolicy == SEC_OID_UNKNOWN means the cert is NOT EV
148 // Only one usage per verification is supported.
149 mozilla::pkix::Result
VerifyCert(
150 const nsTArray
<uint8_t>& certBytes
, SECCertificateUsage usage
,
151 mozilla::pkix::Time time
, void* pinArg
, const char* hostname
,
152 /*out*/ nsTArray
<nsTArray
<uint8_t>>& builtChain
, Flags flags
= 0,
154 const Maybe
<nsTArray
<nsTArray
<uint8_t>>>& extraCertificates
= Nothing(),
155 /*optional in*/ const Maybe
<nsTArray
<uint8_t>>& stapledOCSPResponseArg
=
157 /*optional in*/ const Maybe
<nsTArray
<uint8_t>>& sctsFromTLS
= Nothing(),
158 /*optional in*/ const OriginAttributes
& originAttributes
=
160 /*optional out*/ EVStatus
* evStatus
= nullptr,
161 /*optional out*/ OCSPStaplingStatus
* ocspStaplingStatus
= nullptr,
162 /*optional out*/ KeySizeStatus
* keySizeStatus
= nullptr,
163 /*optional out*/ PinningTelemetryInfo
* pinningTelemetryInfo
= nullptr,
164 /*optional out*/ CertificateTransparencyInfo
* ctInfo
= nullptr,
165 /*optional out*/ bool* isBuiltChainRootBuiltInRoot
= nullptr,
166 /*optional out*/ bool* madeOCSPRequests
= nullptr);
168 mozilla::pkix::Result
VerifySSLServerCert(
169 const nsTArray
<uint8_t>& peerCert
, mozilla::pkix::Time time
, void* pinarg
,
170 const nsACString
& hostname
,
171 /*out*/ nsTArray
<nsTArray
<uint8_t>>& builtChain
,
172 /*optional*/ Flags flags
= 0,
173 /*optional*/ const Maybe
<nsTArray
<nsTArray
<uint8_t>>>& extraCertificates
=
175 /*optional*/ const Maybe
<nsTArray
<uint8_t>>& stapledOCSPResponse
=
177 /*optional*/ const Maybe
<nsTArray
<uint8_t>>& sctsFromTLS
= Nothing(),
178 /*optional*/ const Maybe
<DelegatedCredentialInfo
>& dcInfo
= Nothing(),
179 /*optional*/ const OriginAttributes
& originAttributes
=
181 /*optional out*/ EVStatus
* evStatus
= nullptr,
182 /*optional out*/ OCSPStaplingStatus
* ocspStaplingStatus
= nullptr,
183 /*optional out*/ KeySizeStatus
* keySizeStatus
= nullptr,
184 /*optional out*/ PinningTelemetryInfo
* pinningTelemetryInfo
= nullptr,
185 /*optional out*/ CertificateTransparencyInfo
* ctInfo
= nullptr,
186 /*optional out*/ bool* isBuiltChainRootBuiltInRoot
= nullptr,
187 /*optional out*/ bool* madeOCSPRequests
= nullptr);
189 enum OcspDownloadConfig
{ ocspOff
= 0, ocspOn
= 1, ocspEVOnly
= 2 };
190 enum OcspStrictConfig
{ ocspRelaxed
= 0, ocspStrict
};
192 enum class CertificateTransparencyMode
{
197 CertVerifier(OcspDownloadConfig odc
, OcspStrictConfig osc
,
198 mozilla::TimeDuration ocspTimeoutSoft
,
199 mozilla::TimeDuration ocspTimeoutHard
,
200 uint32_t certShortLifetimeInDays
,
201 NetscapeStepUpPolicy netscapeStepUpPolicy
,
202 CertificateTransparencyMode ctMode
, CRLiteMode crliteMode
,
203 const nsTArray
<EnterpriseCert
>& thirdPartyCerts
);
206 void ClearOCSPCache() { mOCSPCache
.Clear(); }
208 const OcspDownloadConfig mOCSPDownloadConfig
;
209 const bool mOCSPStrict
;
210 const mozilla::TimeDuration mOCSPTimeoutSoft
;
211 const mozilla::TimeDuration mOCSPTimeoutHard
;
212 const uint32_t mCertShortLifetimeInDays
;
213 const NetscapeStepUpPolicy mNetscapeStepUpPolicy
;
214 const CertificateTransparencyMode mCTMode
;
215 const CRLiteMode mCRLiteMode
;
218 OCSPCache mOCSPCache
;
219 // We keep a copy of the bytes of each third party root to own.
220 nsTArray
<EnterpriseCert
> mThirdPartyCerts
;
221 // This is a reusable, precomputed list of Inputs corresponding to each root
222 // in mThirdPartyCerts that wasn't too long to make an Input out of.
223 nsTArray
<mozilla::pkix::Input
> mThirdPartyRootInputs
;
224 // Similarly, but with intermediates.
225 nsTArray
<mozilla::pkix::Input
> mThirdPartyIntermediateInputs
;
227 // We only have a forward declarations of these classes (see above)
228 // so we must allocate dynamically.
229 UniquePtr
<mozilla::ct::MultiLogCTVerifier
> mCTVerifier
;
230 UniquePtr
<mozilla::ct::CTDiversityPolicy
> mCTDiversityPolicy
;
232 void LoadKnownCTLogs();
233 mozilla::pkix::Result
VerifyCertificateTransparencyPolicy(
234 NSSCertDBTrustDomain
& trustDomain
,
235 const nsTArray
<nsTArray
<uint8_t>>& builtChain
,
236 mozilla::pkix::Input sctsFromTLS
, mozilla::pkix::Time time
,
237 /*optional out*/ CertificateTransparencyInfo
* ctInfo
);
240 mozilla::pkix::Result
IsCertBuiltInRoot(pkix::Input certInput
, bool& result
);
241 mozilla::pkix::Result
CertListContainsExpectedKeys(const CERTCertList
* certList
,
242 const char* hostname
,
243 mozilla::pkix::Time time
);
246 } // namespace mozilla
248 #endif // CertVerifier_h