summaryrefslogtreecommitdiffstats
path: root/security/certverifier/NSSCertDBTrustDomain.h
blob: 438e9bec10d94093873c9bc776810a686a396088 (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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
/* -*- 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 NSSCertDBTrustDomain_h
#define NSSCertDBTrustDomain_h

#include "CertVerifier.h"
#include "CRLiteTimestamp.h"
#include "ScopedNSSTypes.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/TimeStamp.h"
#include "mozpkix/pkixtypes.h"
#include "nsICertStorage.h"
#include "nsString.h"
#include "secmodt.h"

namespace mozilla {
namespace psm {

enum class ValidityCheckingMode {
  CheckingOff = 0,
  CheckForEV = 1,
};

enum class NSSDBConfig {
  ReadWrite = 0,
  ReadOnly = 1,
};

enum class PKCS11DBConfig {
  DoNotLoadModules = 0,
  LoadModules = 1,
};

// Policy options for matching id-Netscape-stepUp with id-kp-serverAuth (for CA
// certificates only):
// * Always match: the step-up OID is considered equivalent to serverAuth
// * Match before 23 August 2016: the OID is considered equivalent if the
//   certificate's notBefore is before 23 August 2016
// * Match before 23 August 2015: similarly, but for 23 August 2015
// * Never match: the OID is never considered equivalent to serverAuth
enum class NetscapeStepUpPolicy : uint32_t {
  AlwaysMatch = 0,
  MatchBefore23August2016 = 1,
  MatchBefore23August2015 = 2,
  NeverMatch = 3,
};

enum class OCSPFetchStatus : uint16_t {
  NotFetched = 0,
  Fetched = 1,
};

SECStatus InitializeNSS(const nsACString& dir, NSSDBConfig nssDbConfig,
                        PKCS11DBConfig pkcs11DbConfig);

void DisableMD5();

/**
 * Loads root certificates from a module.
 *
 * @param dir
 *        The path to the directory containing the NSS builtin roots module.
 *        Usually the same as the path to the other NSS shared libraries.
 *        If empty, the (library) path will be searched.
 * @return true if the roots were successfully loaded, false otherwise.
 */
bool LoadLoadableRoots(const nsCString& dir);

/**
 * Loads the OS client certs module.
 *
 * @param dir
 *        The path to the directory containing the module. This should be the
 *        same as where all of the other gecko libraries live.
 * @return true if the module was successfully loaded, false otherwise.
 */
bool LoadOSClientCertsModule(const nsCString& dir);

extern const char* kOSClientCertsModuleName;

/**
 * Loads the IPC client certs module.
 *
 * @param dir
 *        The path to the directory containing the module. This should be the
 *        same as where all of the other gecko libraries live.
 * @return true if the module was successfully loaded, false otherwise.
 */
bool LoadIPCClientCertsModule(const nsCString& dir);

extern const char* kIPCClientCertsModuleName;

/**
 * Unloads the loadable roots module and os client certs module, if loaded.
 */
void UnloadUserModules();

nsresult DefaultServerNicknameForCert(const CERTCertificate* cert,
                                      /*out*/ nsCString& nickname);

/**
 * Build nsTArray<uint8_t>s out of the issuer, serial, subject and public key
 * data from the supplied certificate for use in revocation checks.
 *
 * @param certDER
 *        The Input that references the encoded bytes of the certificate.
 * @param endEntityOrCA
 *        Whether the certificate is an end-entity or CA.
 * @param out encIssuer
 *        The array to populate with issuer data.
 * @param out encSerial
 *        The array to populate with serial number data.
 * @param out encSubject
 *        The array to populate with subject data.
 * @param out encPubKey
 *        The array to populate with public key data.
 * @return
 *        Result::Success, unless there's a problem decoding the certificate.
 */
pkix::Result BuildRevocationCheckArrays(pkix::Input certDER,
                                        pkix::EndEntityOrCA endEntityOrCA,
                                        /*out*/ nsTArray<uint8_t>& issuerBytes,
                                        /*out*/ nsTArray<uint8_t>& serialBytes,
                                        /*out*/ nsTArray<uint8_t>& subjectBytes,
                                        /*out*/ nsTArray<uint8_t>& pubKeyBytes);

void SaveIntermediateCerts(const nsTArray<nsTArray<uint8_t>>& certList);

class NSSCertDBTrustDomain : public mozilla::pkix::TrustDomain {
 public:
  typedef mozilla::pkix::Result Result;

  enum OCSPFetching {
    NeverFetchOCSP = 0,
    FetchOCSPForDVSoftFail = 1,
    FetchOCSPForDVHardFail = 2,
    FetchOCSPForEV = 3,
    LocalOnlyOCSPForEV = 4,
  };

  NSSCertDBTrustDomain(
      SECTrustType certDBTrustType, OCSPFetching ocspFetching,
      OCSPCache& ocspCache, void* pinArg, mozilla::TimeDuration ocspTimeoutSoft,
      mozilla::TimeDuration ocspTimeoutHard, uint32_t certShortLifetimeInDays,
      unsigned int minRSABits, ValidityCheckingMode validityCheckingMode,
      NetscapeStepUpPolicy netscapeStepUpPolicy, CRLiteMode crliteMode,
      const OriginAttributes& originAttributes,
      const Vector<mozilla::pkix::Input>& thirdPartyRootInputs,
      const Vector<mozilla::pkix::Input>& thirdPartyIntermediateInputs,
      const Maybe<nsTArray<nsTArray<uint8_t>>>& extraCertificates,
      /*out*/ nsTArray<nsTArray<uint8_t>>& builtChain,
      /*optional*/ PinningTelemetryInfo* pinningTelemetryInfo = nullptr,
      /*optional*/ const char* hostname = nullptr);

  virtual Result FindIssuer(mozilla::pkix::Input encodedIssuerName,
                            IssuerChecker& checker,
                            mozilla::pkix::Time time) override;

  virtual Result GetCertTrust(
      mozilla::pkix::EndEntityOrCA endEntityOrCA,
      const mozilla::pkix::CertPolicyId& policy,
      mozilla::pkix::Input candidateCertDER,
      /*out*/ mozilla::pkix::TrustLevel& trustLevel) override;

  virtual Result CheckSignatureDigestAlgorithm(
      mozilla::pkix::DigestAlgorithm digestAlg,
      mozilla::pkix::EndEntityOrCA endEntityOrCA,
      mozilla::pkix::Time notBefore) override;

  virtual Result CheckRSAPublicKeyModulusSizeInBits(
      mozilla::pkix::EndEntityOrCA endEntityOrCA,
      unsigned int modulusSizeInBits) override;

  virtual Result VerifyRSAPKCS1SignedData(
      mozilla::pkix::Input data, mozilla::pkix::DigestAlgorithm digestAlgorithm,
      mozilla::pkix::Input signature,
      mozilla::pkix::Input subjectPublicKeyInfo) override;

  virtual Result VerifyRSAPSSSignedData(
      mozilla::pkix::Input data, mozilla::pkix::DigestAlgorithm digestAlgorithm,
      mozilla::pkix::Input signature,
      mozilla::pkix::Input subjectPublicKeyInfo) override;

  virtual Result CheckECDSACurveIsAcceptable(
      mozilla::pkix::EndEntityOrCA endEntityOrCA,
      mozilla::pkix::NamedCurve curve) override;

  virtual Result VerifyECDSASignedData(
      mozilla::pkix::Input data, mozilla::pkix::DigestAlgorithm digestAlgorithm,
      mozilla::pkix::Input signature,
      mozilla::pkix::Input subjectPublicKeyInfo) override;

  virtual Result DigestBuf(mozilla::pkix::Input item,
                           mozilla::pkix::DigestAlgorithm digestAlg,
                           /*out*/ uint8_t* digestBuf,
                           size_t digestBufLen) override;

  virtual Result CheckValidityIsAcceptable(
      mozilla::pkix::Time notBefore, mozilla::pkix::Time notAfter,
      mozilla::pkix::EndEntityOrCA endEntityOrCA,
      mozilla::pkix::KeyPurposeId keyPurpose) override;

  virtual Result NetscapeStepUpMatchesServerAuth(
      mozilla::pkix::Time notBefore,
      /*out*/ bool& matches) override;

  virtual Result CheckRevocation(
      mozilla::pkix::EndEntityOrCA endEntityOrCA,
      const mozilla::pkix::CertID& certID, mozilla::pkix::Time time,
      mozilla::pkix::Duration validityDuration,
      /*optional*/ const mozilla::pkix::Input* stapledOCSPResponse,
      /*optional*/ const mozilla::pkix::Input* aiaExtension,
      /*optional*/ const mozilla::pkix::Input* sctExtension) override;

  virtual Result IsChainValid(
      const mozilla::pkix::DERArray& certChain, mozilla::pkix::Time time,
      const mozilla::pkix::CertPolicyId& requiredPolicy) override;

  virtual void NoteAuxiliaryExtension(
      mozilla::pkix::AuxiliaryExtension extension,
      mozilla::pkix::Input extensionData) override;

  // Resets the OCSP stapling status and SCT lists accumulated during
  // the chain building.
  void ResetAccumulatedState();

  CertVerifier::OCSPStaplingStatus GetOCSPStaplingStatus() const {
    return mOCSPStaplingStatus;
  }

  // SCT lists (see Certificate Transparency) extracted during
  // certificate verification. Note that the returned Inputs are invalidated
  // the next time a chain is built and by ResetAccumulatedState method
  // (and when the TrustDomain object is destroyed).

  mozilla::pkix::Input GetSCTListFromCertificate() const;
  mozilla::pkix::Input GetSCTListFromOCSPStapling() const;

  bool GetIsBuiltChainRootBuiltInRoot() const;

  bool GetIsErrorDueToDistrustedCAPolicy() const;

  OCSPFetchStatus GetOCSPFetchStatus() { return mOCSPFetchStatus; }

 private:
  Result CheckCRLiteStash(
      const nsTArray<uint8_t>& issuerSubjectPublicKeyInfoBytes,
      const nsTArray<uint8_t>& serialNumberBytes);
  Result CheckCRLite(
      const nsTArray<uint8_t>& issuerBytes,
      const nsTArray<uint8_t>& issuerSubjectPublicKeyInfoBytes,
      const nsTArray<uint8_t>& serialNumberBytes,
      const nsTArray<RefPtr<nsICRLiteTimestamp>>& crliteTimestamps,
      bool& filterCoversCertificate);

  enum EncodedResponseSource {
    ResponseIsFromNetwork = 1,
    ResponseWasStapled = 2
  };
  Result VerifyAndMaybeCacheEncodedOCSPResponse(
      const mozilla::pkix::CertID& certID, mozilla::pkix::Time time,
      uint16_t maxLifetimeInDays, mozilla::pkix::Input encodedResponse,
      EncodedResponseSource responseSource, /*out*/ bool& expired,
      /*out*/ uint32_t& ageInHours);
  TimeDuration GetOCSPTimeout() const;

  Result CheckRevocationByCRLite(const mozilla::pkix::CertID& certID,
                                 const mozilla::pkix::Input& sctExtension,
                                 /*out*/ bool& crliteCoversCertificate);

  Result CheckRevocationByOCSP(
      const mozilla::pkix::CertID& certID, mozilla::pkix::Time time,
      mozilla::pkix::Duration validityDuration, const nsCString& aiaLocation,
      const bool crliteCoversCertificate, const Result crliteResult,
      /*optional*/ const mozilla::pkix::Input* stapledOCSPResponse,
      /*out*/ bool& softFailure);

  Result SynchronousCheckRevocationWithServer(
      const mozilla::pkix::CertID& certID, const nsCString& aiaLocation,
      mozilla::pkix::Time time, uint16_t maxOCSPLifetimeInDays,
      const Result cachedResponseResult, const Result stapledOCSPResponseResult,
      const bool crliteFilterCoversCertificate, const Result crliteResult,
      /*out*/ bool& softFailure);
  Result HandleOCSPFailure(const Result cachedResponseResult,
                           const Result stapledOCSPResponseResult,
                           const Result error,
                           /*out*/ bool& softFailure);

  const SECTrustType mCertDBTrustType;
  const OCSPFetching mOCSPFetching;
  OCSPCache& mOCSPCache;  // non-owning!
  void* mPinArg;          // non-owning!
  const mozilla::TimeDuration mOCSPTimeoutSoft;
  const mozilla::TimeDuration mOCSPTimeoutHard;
  const uint32_t mCertShortLifetimeInDays;
  const unsigned int mMinRSABits;
  ValidityCheckingMode mValidityCheckingMode;
  NetscapeStepUpPolicy mNetscapeStepUpPolicy;
  CRLiteMode mCRLiteMode;
  bool mSawDistrustedCAByPolicyError;
  const OriginAttributes& mOriginAttributes;
  const Vector<mozilla::pkix::Input>& mThirdPartyRootInputs;  // non-owning
  const Vector<mozilla::pkix::Input>&
      mThirdPartyIntermediateInputs;                             // non-owning
  const Maybe<nsTArray<nsTArray<uint8_t>>>& mExtraCertificates;  // non-owning
  nsTArray<nsTArray<uint8_t>>& mBuiltChain;                      // non-owning
  bool mIsBuiltChainRootBuiltInRoot;
  PinningTelemetryInfo* mPinningTelemetryInfo;
  const char* mHostname;  // non-owning - only used for pinning checks
  nsCOMPtr<nsICertStorage> mCertStorage;
  CertVerifier::OCSPStaplingStatus mOCSPStaplingStatus;
  // Certificate Transparency data extracted during certificate verification
  UniqueSECItem mSCTListFromCertificate;
  UniqueSECItem mSCTListFromOCSPStapling;

  // The built-in roots module, if available.
  UniqueSECMODModule mBuiltInRootsModule;

  OCSPFetchStatus mOCSPFetchStatus;
};

}  // namespace psm
}  // namespace mozilla

#endif  // NSSCertDBTrustDomain_h