summaryrefslogtreecommitdiffstats
path: root/security/certverifier/CertVerifier.h
diff options
context:
space:
mode:
Diffstat (limited to 'security/certverifier/CertVerifier.h')
-rw-r--r--security/certverifier/CertVerifier.h242
1 files changed, 242 insertions, 0 deletions
diff --git a/security/certverifier/CertVerifier.h b/security/certverifier/CertVerifier.h
new file mode 100644
index 000000000..d88c3f33c
--- /dev/null
+++ b/security/certverifier/CertVerifier.h
@@ -0,0 +1,242 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 CertVerifier_h
+#define CertVerifier_h
+
+#include "BRNameMatchingPolicy.h"
+#include "CTVerifyResult.h"
+#include "OCSPCache.h"
+#include "ScopedNSSTypes.h"
+#include "mozilla/Telemetry.h"
+#include "mozilla/UniquePtr.h"
+#include "pkix/pkixtypes.h"
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+// Silence "RootingAPI.h(718): warning C4324: 'js::DispatchWrapper<T>':
+// structure was padded due to alignment specifier with [ T=void * ]"
+#pragma warning(disable:4324)
+// Silence "Value.h(448): warning C4365: 'return': conversion from 'const
+// int32_t' to 'JS::Value::PayloadType', signed/unsigned mismatch"
+#pragma warning(disable:4365)
+// Silence "warning C5031: #pragma warning(pop): likely mismatch, popping
+// warning state pushed in different file
+#pragma warning(disable:5031)
+#endif /* defined(_MSC_VER) */
+#include "mozilla/BasePrincipal.h"
+#if defined(_MSC_VER)
+#pragma warning(pop) /* popping the pragma in Vector.h */
+#pragma warning(pop) /* popping the pragma in this file */
+#endif /* defined(_MSC_VER) */
+
+namespace mozilla { namespace ct {
+
+// Including MultiLogCTVerifier.h would bring along all of its dependent
+// headers and force us to export them in moz.build. Just forward-declare
+// the class here instead.
+class MultiLogCTVerifier;
+
+} } // namespace mozilla::ct
+
+namespace mozilla { namespace psm {
+
+typedef mozilla::pkix::Result Result;
+
+// These values correspond to the CERT_CHAIN_KEY_SIZE_STATUS telemetry.
+enum class KeySizeStatus {
+ NeverChecked = 0,
+ LargeMinimumSucceeded = 1,
+ CompatibilityRisk = 2,
+ AlreadyBad = 3,
+};
+
+// These values correspond to the CERT_CHAIN_SHA1_POLICY_STATUS telemetry.
+enum class SHA1ModeResult {
+ NeverChecked = 0,
+ SucceededWithoutSHA1 = 1,
+ SucceededWithImportedRoot = 2,
+ SucceededWithImportedRootOrSHA1Before2016 = 3,
+ SucceededWithSHA1 = 4,
+ Failed = 5,
+};
+
+enum class NetscapeStepUpPolicy : uint32_t;
+
+class PinningTelemetryInfo
+{
+public:
+ PinningTelemetryInfo() { Reset(); }
+
+ // Should we accumulate pinning telemetry for the result?
+ bool accumulateResult;
+ Telemetry::ID certPinningResultHistogram;
+ int32_t certPinningResultBucket;
+ // Should we accumulate telemetry for the root?
+ bool accumulateForRoot;
+ int32_t rootBucket;
+
+ void Reset() { accumulateForRoot = false; accumulateResult = false; }
+};
+
+class CertificateTransparencyInfo
+{
+public:
+ CertificateTransparencyInfo() { Reset(); }
+
+ // Was CT enabled?
+ bool enabled;
+ // Did we receive and process any binary SCT data from the supported sources?
+ bool processedSCTs;
+ // Verification result of the processed SCTs.
+ mozilla::ct::CTVerifyResult verifyResult;
+
+ void Reset() { enabled = false; processedSCTs = false; verifyResult.Reset(); }
+};
+
+class NSSCertDBTrustDomain;
+
+class CertVerifier
+{
+public:
+ typedef unsigned int Flags;
+ // XXX: FLAG_LOCAL_ONLY is ignored in the classic verification case
+ static const Flags FLAG_LOCAL_ONLY;
+ // Don't perform fallback DV validation on EV validation failure.
+ static const Flags FLAG_MUST_BE_EV;
+ // TLS feature request_status should be ignored
+ static const Flags FLAG_TLS_IGNORE_STATUS_REQUEST;
+
+ // These values correspond to the SSL_OCSP_STAPLING telemetry.
+ enum OCSPStaplingStatus {
+ OCSP_STAPLING_NEVER_CHECKED = 0,
+ OCSP_STAPLING_GOOD = 1,
+ OCSP_STAPLING_NONE = 2,
+ OCSP_STAPLING_EXPIRED = 3,
+ OCSP_STAPLING_INVALID = 4,
+ };
+
+ // *evOidPolicy == SEC_OID_UNKNOWN means the cert is NOT EV
+ // Only one usage per verification is supported.
+ mozilla::pkix::Result VerifyCert(
+ CERTCertificate* cert,
+ SECCertificateUsage usage,
+ mozilla::pkix::Time time,
+ void* pinArg,
+ const char* hostname,
+ /*out*/ UniqueCERTCertList& builtChain,
+ Flags flags = 0,
+ /*optional in*/ const SECItem* stapledOCSPResponse = nullptr,
+ /*optional in*/ const SECItem* sctsFromTLS = nullptr,
+ /*optional in*/ const NeckoOriginAttributes& originAttributes =
+ NeckoOriginAttributes(),
+ /*optional out*/ SECOidTag* evOidPolicy = nullptr,
+ /*optional out*/ OCSPStaplingStatus* ocspStaplingStatus = nullptr,
+ /*optional out*/ KeySizeStatus* keySizeStatus = nullptr,
+ /*optional out*/ SHA1ModeResult* sha1ModeResult = nullptr,
+ /*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo = nullptr,
+ /*optional out*/ CertificateTransparencyInfo* ctInfo = nullptr);
+
+ mozilla::pkix::Result VerifySSLServerCert(
+ const UniqueCERTCertificate& peerCert,
+ /*optional*/ const SECItem* stapledOCSPResponse,
+ /*optional*/ const SECItem* sctsFromTLS,
+ mozilla::pkix::Time time,
+ /*optional*/ void* pinarg,
+ const char* hostname,
+ /*out*/ UniqueCERTCertList& builtChain,
+ /*optional*/ bool saveIntermediatesInPermanentDatabase = false,
+ /*optional*/ Flags flags = 0,
+ /*optional*/ const NeckoOriginAttributes& originAttributes =
+ NeckoOriginAttributes(),
+ /*optional out*/ SECOidTag* evOidPolicy = nullptr,
+ /*optional out*/ OCSPStaplingStatus* ocspStaplingStatus = nullptr,
+ /*optional out*/ KeySizeStatus* keySizeStatus = nullptr,
+ /*optional out*/ SHA1ModeResult* sha1ModeResult = nullptr,
+ /*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo = nullptr,
+ /*optional out*/ CertificateTransparencyInfo* ctInfo = nullptr);
+
+ enum PinningMode {
+ pinningDisabled = 0,
+ pinningAllowUserCAMITM = 1,
+ pinningStrict = 2,
+ pinningEnforceTestMode = 3
+ };
+
+ enum class SHA1Mode {
+ Allowed = 0,
+ Forbidden = 1,
+ // There used to be a policy that only allowed SHA1 for certificates issued
+ // before 2016. This is no longer available. If a user has selected this
+ // policy in about:config, it now maps to Forbidden.
+ UsedToBeBefore2016ButNowIsForbidden = 2,
+ ImportedRoot = 3,
+ ImportedRootOrBefore2016 = 4,
+ };
+
+ enum OcspDownloadConfig {
+ ocspOff = 0,
+ ocspOn = 1,
+ ocspEVOnly = 2
+ };
+ enum OcspStrictConfig { ocspRelaxed = 0, ocspStrict };
+ enum OcspGetConfig { ocspGetDisabled = 0, ocspGetEnabled = 1 };
+
+ enum class CertificateTransparencyMode {
+ Disabled = 0,
+ TelemetryOnly = 1,
+ };
+
+ CertVerifier(OcspDownloadConfig odc, OcspStrictConfig osc,
+ OcspGetConfig ogc, uint32_t certShortLifetimeInDays,
+ PinningMode pinningMode, SHA1Mode sha1Mode,
+ BRNameMatchingPolicy::Mode nameMatchingMode,
+ NetscapeStepUpPolicy netscapeStepUpPolicy,
+ CertificateTransparencyMode ctMode);
+ ~CertVerifier();
+
+ void ClearOCSPCache() { mOCSPCache.Clear(); }
+
+ const OcspDownloadConfig mOCSPDownloadConfig;
+ const bool mOCSPStrict;
+ const bool mOCSPGETEnabled;
+ const uint32_t mCertShortLifetimeInDays;
+ const PinningMode mPinningMode;
+ const SHA1Mode mSHA1Mode;
+ const BRNameMatchingPolicy::Mode mNameMatchingMode;
+ const NetscapeStepUpPolicy mNetscapeStepUpPolicy;
+ const CertificateTransparencyMode mCTMode;
+
+private:
+ OCSPCache mOCSPCache;
+
+ // We only have a forward declaration of MultiLogCTVerifier (see above),
+ // so we keep a pointer to it and allocate dynamically.
+ UniquePtr<mozilla::ct::MultiLogCTVerifier> mCTVerifier;
+
+ void LoadKnownCTLogs();
+ mozilla::pkix::Result VerifySignedCertificateTimestamps(
+ NSSCertDBTrustDomain& trustDomain,
+ const UniqueCERTCertList& builtChain,
+ mozilla::pkix::Input sctsFromTLS,
+ mozilla::pkix::Time time,
+ /*optional out*/ CertificateTransparencyInfo* ctInfo);
+
+ // Returns true if the configured SHA1 mode is more restrictive than the given
+ // mode. SHA1Mode::Forbidden is more restrictive than any other mode except
+ // Forbidden. Next is ImportedRoot, then ImportedRootOrBefore2016, then
+ // Allowed. (A mode is never more restrictive than itself.)
+ bool SHA1ModeMoreRestrictiveThanGivenMode(SHA1Mode mode);
+};
+
+mozilla::pkix::Result IsCertBuiltInRoot(CERTCertificate* cert, bool& result);
+mozilla::pkix::Result CertListContainsExpectedKeys(
+ const CERTCertList* certList, const char* hostname, mozilla::pkix::Time time,
+ CertVerifier::PinningMode pinningMode);
+
+} } // namespace mozilla::psm
+
+#endif // CertVerifier_h