CertVerifier.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef CertVerifier_h
  6. #define CertVerifier_h
  7. #include "BRNameMatchingPolicy.h"
  8. #include "CTVerifyResult.h"
  9. #include "OCSPCache.h"
  10. #include "ScopedNSSTypes.h"
  11. #include "mozilla/UniquePtr.h"
  12. #include "pkix/pkixtypes.h"
  13. #if defined(_MSC_VER)
  14. #pragma warning(push)
  15. // Silence "RootingAPI.h(718): warning C4324: 'js::DispatchWrapper<T>':
  16. // structure was padded due to alignment specifier with [ T=void * ]"
  17. #pragma warning(disable:4324)
  18. // Silence "Value.h(448): warning C4365: 'return': conversion from 'const
  19. // int32_t' to 'JS::Value::PayloadType', signed/unsigned mismatch"
  20. #pragma warning(disable:4365)
  21. // Silence "warning C5031: #pragma warning(pop): likely mismatch, popping
  22. // warning state pushed in different file
  23. #pragma warning(disable:5031)
  24. #endif /* defined(_MSC_VER) */
  25. #include "mozilla/BasePrincipal.h"
  26. #if defined(_MSC_VER)
  27. #pragma warning(pop) /* popping the pragma in Vector.h */
  28. #pragma warning(pop) /* popping the pragma in this file */
  29. #endif /* defined(_MSC_VER) */
  30. namespace mozilla { namespace ct {
  31. // Including MultiLogCTVerifier.h would bring along all of its dependent
  32. // headers and force us to export them in moz.build. Just forward-declare
  33. // the class here instead.
  34. class MultiLogCTVerifier;
  35. } } // namespace mozilla::ct
  36. namespace mozilla { namespace psm {
  37. typedef mozilla::pkix::Result Result;
  38. // These values correspond to the CERT_CHAIN_KEY_SIZE_STATUS telemetry.
  39. enum class KeySizeStatus {
  40. NeverChecked = 0,
  41. LargeMinimumSucceeded = 1,
  42. CompatibilityRisk = 2,
  43. AlreadyBad = 3,
  44. };
  45. // These values correspond to the CERT_CHAIN_SHA1_POLICY_STATUS telemetry.
  46. enum class SHA1ModeResult {
  47. NeverChecked = 0,
  48. SucceededWithoutSHA1 = 1,
  49. SucceededWithImportedRoot = 2,
  50. SucceededWithImportedRootOrSHA1Before2016 = 3,
  51. SucceededWithSHA1 = 4,
  52. Failed = 5,
  53. };
  54. enum class NetscapeStepUpPolicy : uint32_t;
  55. class CertificateTransparencyInfo
  56. {
  57. public:
  58. CertificateTransparencyInfo() { Reset(); }
  59. // Was CT enabled?
  60. bool enabled;
  61. // Did we receive and process any binary SCT data from the supported sources?
  62. bool processedSCTs;
  63. // Verification result of the processed SCTs.
  64. mozilla::ct::CTVerifyResult verifyResult;
  65. void Reset() { enabled = false; processedSCTs = false; verifyResult.Reset(); }
  66. };
  67. class NSSCertDBTrustDomain;
  68. class CertVerifier
  69. {
  70. public:
  71. typedef unsigned int Flags;
  72. // XXX: FLAG_LOCAL_ONLY is ignored in the classic verification case
  73. static const Flags FLAG_LOCAL_ONLY;
  74. // Don't perform fallback DV validation on EV validation failure.
  75. static const Flags FLAG_MUST_BE_EV;
  76. // TLS feature request_status should be ignored
  77. static const Flags FLAG_TLS_IGNORE_STATUS_REQUEST;
  78. // These values correspond to the SSL_OCSP_STAPLING telemetry.
  79. enum OCSPStaplingStatus {
  80. OCSP_STAPLING_NEVER_CHECKED = 0,
  81. OCSP_STAPLING_GOOD = 1,
  82. OCSP_STAPLING_NONE = 2,
  83. OCSP_STAPLING_EXPIRED = 3,
  84. OCSP_STAPLING_INVALID = 4,
  85. };
  86. // *evOidPolicy == SEC_OID_UNKNOWN means the cert is NOT EV
  87. // Only one usage per verification is supported.
  88. mozilla::pkix::Result VerifyCert(
  89. CERTCertificate* cert,
  90. SECCertificateUsage usage,
  91. mozilla::pkix::Time time,
  92. void* pinArg,
  93. const char* hostname,
  94. /*out*/ UniqueCERTCertList& builtChain,
  95. Flags flags = 0,
  96. /*optional in*/ const SECItem* stapledOCSPResponse = nullptr,
  97. /*optional in*/ const SECItem* sctsFromTLS = nullptr,
  98. /*optional in*/ const NeckoOriginAttributes& originAttributes =
  99. NeckoOriginAttributes(),
  100. /*optional out*/ SECOidTag* evOidPolicy = nullptr,
  101. /*optional out*/ OCSPStaplingStatus* ocspStaplingStatus = nullptr,
  102. /*optional out*/ KeySizeStatus* keySizeStatus = nullptr,
  103. /*optional out*/ SHA1ModeResult* sha1ModeResult = nullptr,
  104. /*optional out*/ CertificateTransparencyInfo* ctInfo = nullptr);
  105. mozilla::pkix::Result VerifySSLServerCert(
  106. const UniqueCERTCertificate& peerCert,
  107. /*optional*/ const SECItem* stapledOCSPResponse,
  108. /*optional*/ const SECItem* sctsFromTLS,
  109. mozilla::pkix::Time time,
  110. /*optional*/ void* pinarg,
  111. const char* hostname,
  112. /*out*/ UniqueCERTCertList& builtChain,
  113. /*optional*/ bool saveIntermediatesInPermanentDatabase = false,
  114. /*optional*/ Flags flags = 0,
  115. /*optional*/ const NeckoOriginAttributes& originAttributes =
  116. NeckoOriginAttributes(),
  117. /*optional out*/ SECOidTag* evOidPolicy = nullptr,
  118. /*optional out*/ OCSPStaplingStatus* ocspStaplingStatus = nullptr,
  119. /*optional out*/ KeySizeStatus* keySizeStatus = nullptr,
  120. /*optional out*/ SHA1ModeResult* sha1ModeResult = nullptr,
  121. /*optional out*/ CertificateTransparencyInfo* ctInfo = nullptr);
  122. enum class SHA1Mode {
  123. Allowed = 0,
  124. Forbidden = 1,
  125. // There used to be a policy that only allowed SHA1 for certificates issued
  126. // before 2016. This is no longer available. If a user has selected this
  127. // policy in about:config, it now maps to Forbidden.
  128. UsedToBeBefore2016ButNowIsForbidden = 2,
  129. ImportedRoot = 3,
  130. ImportedRootOrBefore2016 = 4,
  131. };
  132. enum OcspDownloadConfig {
  133. ocspOff = 0,
  134. ocspOn = 1,
  135. ocspEVOnly = 2
  136. };
  137. enum OcspStrictConfig { ocspRelaxed = 0, ocspStrict };
  138. enum OcspGetConfig { ocspGetDisabled = 0, ocspGetEnabled = 1 };
  139. enum class CertificateTransparencyMode {
  140. Disabled = 0,
  141. TelemetryOnly = 1,
  142. };
  143. CertVerifier(OcspDownloadConfig odc, OcspStrictConfig osc,
  144. OcspGetConfig ogc, uint32_t certShortLifetimeInDays,
  145. SHA1Mode sha1Mode,
  146. BRNameMatchingPolicy::Mode nameMatchingMode,
  147. NetscapeStepUpPolicy netscapeStepUpPolicy,
  148. CertificateTransparencyMode ctMode);
  149. ~CertVerifier();
  150. void ClearOCSPCache() { mOCSPCache.Clear(); }
  151. const OcspDownloadConfig mOCSPDownloadConfig;
  152. const bool mOCSPStrict;
  153. const bool mOCSPGETEnabled;
  154. const uint32_t mCertShortLifetimeInDays;
  155. const SHA1Mode mSHA1Mode;
  156. const BRNameMatchingPolicy::Mode mNameMatchingMode;
  157. const NetscapeStepUpPolicy mNetscapeStepUpPolicy;
  158. const CertificateTransparencyMode mCTMode;
  159. private:
  160. OCSPCache mOCSPCache;
  161. // We only have a forward declaration of MultiLogCTVerifier (see above),
  162. // so we keep a pointer to it and allocate dynamically.
  163. UniquePtr<mozilla::ct::MultiLogCTVerifier> mCTVerifier;
  164. void LoadKnownCTLogs();
  165. mozilla::pkix::Result VerifySignedCertificateTimestamps(
  166. NSSCertDBTrustDomain& trustDomain,
  167. const UniqueCERTCertList& builtChain,
  168. mozilla::pkix::Input sctsFromTLS,
  169. mozilla::pkix::Time time,
  170. /*optional out*/ CertificateTransparencyInfo* ctInfo);
  171. // Returns true if the configured SHA1 mode is more restrictive than the given
  172. // mode. SHA1Mode::Forbidden is more restrictive than any other mode except
  173. // Forbidden. Next is ImportedRoot, then ImportedRootOrBefore2016, then
  174. // Allowed. (A mode is never more restrictive than itself.)
  175. bool SHA1ModeMoreRestrictiveThanGivenMode(SHA1Mode mode);
  176. };
  177. mozilla::pkix::Result IsCertBuiltInRoot(CERTCertificate* cert, bool& result);
  178. mozilla::pkix::Result CertListContainsExpectedKeys(
  179. const CERTCertList* certList, const char* hostname, mozilla::pkix::Time time);
  180. } } // namespace mozilla::psm
  181. #endif // CertVerifier_h