Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/security/pkix/lib/pkixcheck.cpp
Line
Count
Source (jump to first uncovered line)
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 code is made available to you under your choice of the following sets
4
 * of licensing terms:
5
 */
6
/* This Source Code Form is subject to the terms of the Mozilla Public
7
 * License, v. 2.0. If a copy of the MPL was not distributed with this
8
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
 */
10
/* Copyright 2013 Mozilla Contributors
11
 *
12
 * Licensed under the Apache License, Version 2.0 (the "License");
13
 * you may not use this file except in compliance with the License.
14
 * You may obtain a copy of the License at
15
 *
16
 *     http://www.apache.org/licenses/LICENSE-2.0
17
 *
18
 * Unless required by applicable law or agreed to in writing, software
19
 * distributed under the License is distributed on an "AS IS" BASIS,
20
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
 * See the License for the specific language governing permissions and
22
 * limitations under the License.
23
 */
24
25
#include "pkixcheck.h"
26
27
#include "pkixder.h"
28
#include "pkixutil.h"
29
30
namespace mozilla { namespace pkix {
31
32
// 4.1.1.2 signatureAlgorithm
33
// 4.1.2.3 signature
34
35
Result
36
CheckSignatureAlgorithm(TrustDomain& trustDomain,
37
                        EndEntityOrCA endEntityOrCA,
38
                        Time notBefore,
39
                        const der::SignedDataWithSignature& signedData,
40
                        Input signatureValue)
41
0
{
42
0
  // 4.1.1.2. signatureAlgorithm
43
0
  der::PublicKeyAlgorithm publicKeyAlg;
44
0
  DigestAlgorithm digestAlg;
45
0
  Reader signatureAlgorithmReader(signedData.algorithm);
46
0
  Result rv = der::SignatureAlgorithmIdentifierValue(signatureAlgorithmReader,
47
0
                                                     publicKeyAlg, digestAlg);
48
0
  if (rv != Success) {
49
0
    return rv;
50
0
  }
51
0
  rv = der::End(signatureAlgorithmReader);
52
0
  if (rv != Success) {
53
0
    return rv;
54
0
  }
55
0
56
0
  // 4.1.2.3. Signature
57
0
  der::PublicKeyAlgorithm signedPublicKeyAlg;
58
0
  DigestAlgorithm signedDigestAlg;
59
0
  Reader signedSignatureAlgorithmReader(signatureValue);
60
0
  rv = der::SignatureAlgorithmIdentifierValue(signedSignatureAlgorithmReader,
61
0
                                              signedPublicKeyAlg,
62
0
                                              signedDigestAlg);
63
0
  if (rv != Success) {
64
0
    return rv;
65
0
  }
66
0
  rv = der::End(signedSignatureAlgorithmReader);
67
0
  if (rv != Success) {
68
0
    return rv;
69
0
  }
70
0
71
0
  // "This field MUST contain the same algorithm identifier as the
72
0
  // signatureAlgorithm field in the sequence Certificate." However, it may
73
0
  // be encoded differently. In particular, one of the fields may have a NULL
74
0
  // parameter while the other one may omit the parameter field altogether, and
75
0
  // these are considered equivalent. Some certificates generation software
76
0
  // actually generates certificates like that, so we compare the parsed values
77
0
  // instead of comparing the encoded values byte-for-byte.
78
0
  //
79
0
  // Along the same lines, we accept two different OIDs for RSA-with-SHA1, and
80
0
  // we consider those OIDs to be equivalent here.
81
0
  if (publicKeyAlg != signedPublicKeyAlg || digestAlg != signedDigestAlg) {
82
0
    return Result::ERROR_SIGNATURE_ALGORITHM_MISMATCH;
83
0
  }
84
0
85
0
  // During the time of the deprecation of SHA-1 and the deprecation of RSA
86
0
  // keys of less than 2048 bits, we will encounter many certs signed using
87
0
  // SHA-1 and/or too-small RSA keys. With this in mind, we ask the trust
88
0
  // domain early on if it knows it will reject the signature purely based on
89
0
  // the digest algorithm and/or the RSA key size (if an RSA signature). This
90
0
  // is a good optimization because it completely avoids calling
91
0
  // trustDomain.FindIssuers (which may be slow) for such rejected certs, and
92
0
  // more generally it short-circuits any path building with them (which, of
93
0
  // course, is even slower).
94
0
95
0
  rv = trustDomain.CheckSignatureDigestAlgorithm(digestAlg, endEntityOrCA,
96
0
                                                 notBefore);
97
0
  if (rv != Success) {
98
0
    return rv;
99
0
  }
100
0
101
0
  switch (publicKeyAlg) {
102
0
    case der::PublicKeyAlgorithm::RSA_PKCS1:
103
0
    {
104
0
      // The RSA computation may give a result that requires fewer bytes to
105
0
      // encode than the public key (since it is modular arithmetic). However,
106
0
      // the last step of generating a PKCS#1.5 signature is the I2OSP
107
0
      // procedure, which pads any such shorter result with zeros so that it
108
0
      // is exactly the same length as the public key.
109
0
      unsigned int signatureSizeInBits = signedData.signature.GetLength() * 8u;
110
0
      return trustDomain.CheckRSAPublicKeyModulusSizeInBits(
111
0
               endEntityOrCA, signatureSizeInBits);
112
0
    }
113
0
114
0
    case der::PublicKeyAlgorithm::ECDSA:
115
0
      // In theory, we could implement a similar early-pruning optimization for
116
0
      // ECDSA curves. However, since there has been no similar deprecation for
117
0
      // for any curve that we support, the chances of us encountering a curve
118
0
      // during path building is too low to be worth bothering with.
119
0
      break;
120
0
    case der::PublicKeyAlgorithm::Uninitialized:
121
0
    {
122
0
      assert(false);
123
0
      return Result::FATAL_ERROR_LIBRARY_FAILURE;
124
0
    }
125
0
    MOZILLA_PKIX_UNREACHABLE_DEFAULT_ENUM
126
0
  }
127
0
128
0
  return Success;
129
0
}
130
131
// 4.1.2.4 Issuer
132
133
Result
134
CheckIssuer(Input encodedIssuer)
135
0
{
136
0
  // "The issuer field MUST contain a non-empty distinguished name (DN)."
137
0
  Reader issuer(encodedIssuer);
138
0
  Input encodedRDNs;
139
0
  ExpectTagAndGetValue(issuer, der::SEQUENCE, encodedRDNs);
140
0
  Reader rdns(encodedRDNs);
141
0
  // Check that the issuer name contains at least one RDN
142
0
  // (Note: this does not check related grammar rules, such as there being one
143
0
  // or more AVAs in each RDN, or the values in AVAs not being empty strings)
144
0
  if (rdns.AtEnd()) {
145
0
    return Result::ERROR_EMPTY_ISSUER_NAME;
146
0
  }
147
0
  return Success;
148
0
}
149
150
// 4.1.2.5 Validity
151
152
Result
153
ParseValidity(Input encodedValidity,
154
              /*optional out*/ Time* notBeforeOut,
155
              /*optional out*/ Time* notAfterOut)
156
0
{
157
0
  Reader validity(encodedValidity);
158
0
  Time notBefore(Time::uninitialized);
159
0
  if (der::TimeChoice(validity, notBefore) != Success) {
160
0
    return Result::ERROR_INVALID_DER_TIME;
161
0
  }
162
0
163
0
  Time notAfter(Time::uninitialized);
164
0
  if (der::TimeChoice(validity, notAfter) != Success) {
165
0
    return Result::ERROR_INVALID_DER_TIME;
166
0
  }
167
0
168
0
  if (der::End(validity) != Success) {
169
0
    return Result::ERROR_INVALID_DER_TIME;
170
0
  }
171
0
172
0
  if (notBefore > notAfter) {
173
0
    return Result::ERROR_INVALID_DER_TIME;
174
0
  }
175
0
176
0
  if (notBeforeOut) {
177
0
    *notBeforeOut = notBefore;
178
0
  }
179
0
  if (notAfterOut) {
180
0
    *notAfterOut = notAfter;
181
0
  }
182
0
183
0
  return Success;
184
0
}
185
186
Result
187
CheckValidity(Time time, Time notBefore, Time notAfter)
188
0
{
189
0
  if (time < notBefore) {
190
0
    return Result::ERROR_NOT_YET_VALID_CERTIFICATE;
191
0
  }
192
0
193
0
  if (time > notAfter) {
194
0
    return Result::ERROR_EXPIRED_CERTIFICATE;
195
0
  }
196
0
197
0
  return Success;
198
0
}
199
200
// 4.1.2.7 Subject Public Key Info
201
202
Result
203
CheckSubjectPublicKeyInfoContents(Reader& input, TrustDomain& trustDomain,
204
                                  EndEntityOrCA endEntityOrCA)
205
0
{
206
0
  // Here, we validate the syntax and do very basic semantic validation of the
207
0
  // public key of the certificate. The intention here is to filter out the
208
0
  // types of bad inputs that are most likely to trigger non-mathematical
209
0
  // security vulnerabilities in the TrustDomain, like buffer overflows or the
210
0
  // use of unsafe elliptic curves.
211
0
  //
212
0
  // We don't check (all of) the mathematical properties of the public key here
213
0
  // because it is more efficient for the TrustDomain to do it during signature
214
0
  // verification and/or other use of the public key. In particular, we
215
0
  // delegate the arithmetic validation of the public key, as specified in
216
0
  // NIST SP800-56A section 5.6.2, to the TrustDomain, at least for now.
217
0
218
0
  Reader algorithm;
219
0
  Input subjectPublicKey;
220
0
  Result rv = der::ExpectTagAndGetValue(input, der::SEQUENCE, algorithm);
221
0
  if (rv != Success) {
222
0
    return rv;
223
0
  }
224
0
  rv = der::BitStringWithNoUnusedBits(input, subjectPublicKey);
225
0
  if (rv != Success) {
226
0
    return rv;
227
0
  }
228
0
  rv = der::End(input);
229
0
  if (rv != Success) {
230
0
    return rv;
231
0
  }
232
0
233
0
  Reader subjectPublicKeyReader(subjectPublicKey);
234
0
235
0
  Reader algorithmOID;
236
0
  rv = der::ExpectTagAndGetValue(algorithm, der::OIDTag, algorithmOID);
237
0
  if (rv != Success) {
238
0
    return rv;
239
0
  }
240
0
241
0
  // RFC 3279 Section 2.3.1
242
0
  // python DottedOIDToCode.py rsaEncryption 1.2.840.113549.1.1.1
243
0
  static const uint8_t rsaEncryption[] = {
244
0
    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01
245
0
  };
246
0
247
0
  // RFC 3279 Section 2.3.5 and RFC 5480 Section 2.1.1
248
0
  // python DottedOIDToCode.py id-ecPublicKey 1.2.840.10045.2.1
249
0
  static const uint8_t id_ecPublicKey[] = {
250
0
    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01
251
0
  };
252
0
253
0
  if (algorithmOID.MatchRest(id_ecPublicKey)) {
254
0
    // An id-ecPublicKey AlgorithmIdentifier has a parameter that identifes
255
0
    // the curve being used. Although RFC 5480 specifies multiple forms, we
256
0
    // only supported the NamedCurve form, where the curve is identified by an
257
0
    // OID.
258
0
259
0
    Reader namedCurveOIDValue;
260
0
    rv = der::ExpectTagAndGetValue(algorithm, der::OIDTag,
261
0
                                   namedCurveOIDValue);
262
0
    if (rv != Success) {
263
0
      return rv;
264
0
    }
265
0
266
0
    // RFC 5480
267
0
    // python DottedOIDToCode.py secp256r1 1.2.840.10045.3.1.7
268
0
    static const uint8_t secp256r1[] = {
269
0
      0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
270
0
    };
271
0
272
0
    // RFC 5480
273
0
    // python DottedOIDToCode.py secp384r1 1.3.132.0.34
274
0
    static const uint8_t secp384r1[] = {
275
0
      0x2b, 0x81, 0x04, 0x00, 0x22
276
0
    };
277
0
278
0
    // RFC 5480
279
0
    // python DottedOIDToCode.py secp521r1 1.3.132.0.35
280
0
    static const uint8_t secp521r1[] = {
281
0
      0x2b, 0x81, 0x04, 0x00, 0x23
282
0
    };
283
0
284
0
    // Matching is attempted based on a rough estimate of the commonality of the
285
0
    // elliptic curve, to minimize the number of MatchRest calls.
286
0
    NamedCurve curve;
287
0
    unsigned int bits;
288
0
    if (namedCurveOIDValue.MatchRest(secp256r1)) {
289
0
      curve = NamedCurve::secp256r1;
290
0
      bits = 256;
291
0
    } else if (namedCurveOIDValue.MatchRest(secp384r1)) {
292
0
      curve = NamedCurve::secp384r1;
293
0
      bits = 384;
294
0
    } else if (namedCurveOIDValue.MatchRest(secp521r1)) {
295
0
      curve = NamedCurve::secp521r1;
296
0
      bits = 521;
297
0
    } else {
298
0
      return Result::ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
299
0
    }
300
0
301
0
    rv = trustDomain.CheckECDSACurveIsAcceptable(endEntityOrCA, curve);
302
0
    if (rv != Success) {
303
0
      return rv;
304
0
    }
305
0
306
0
    // RFC 5480 Section 2.2 says that the first octet will be 0x04 to indicate
307
0
    // an uncompressed point, which is the only encoding we support.
308
0
    uint8_t compressedOrUncompressed;
309
0
    rv = subjectPublicKeyReader.Read(compressedOrUncompressed);
310
0
    if (rv != Success) {
311
0
      return rv;
312
0
    }
313
0
    if (compressedOrUncompressed != 0x04) {
314
0
      return Result::ERROR_UNSUPPORTED_EC_POINT_FORM;
315
0
    }
316
0
317
0
    // The point is encoded as two raw (not DER-encoded) integers, each padded
318
0
    // to the bit length (rounded up to the nearest byte).
319
0
    Input point;
320
0
    rv = subjectPublicKeyReader.SkipToEnd(point);
321
0
    if (rv != Success) {
322
0
      return rv;
323
0
    }
324
0
    if (point.GetLength() != ((bits + 7) / 8u) * 2u) {
325
0
      return Result::ERROR_BAD_DER;
326
0
    }
327
0
328
0
    // XXX: We defer the mathematical verification of the validity of the point
329
0
    // until signature verification. This means that if we never verify a
330
0
    // signature, we'll never fully check whether the public key is valid.
331
0
  } else if (algorithmOID.MatchRest(rsaEncryption)) {
332
0
    // RFC 3279 Section 2.3.1 says "The parameters field MUST have ASN.1 type
333
0
    // NULL for this algorithm identifier."
334
0
    rv = der::ExpectTagAndEmptyValue(algorithm, der::NULLTag);
335
0
    if (rv != Success) {
336
0
      return rv;
337
0
    }
338
0
339
0
    // RSAPublicKey :: = SEQUENCE{
340
0
    //    modulus            INTEGER,    --n
341
0
    //    publicExponent     INTEGER  }  --e
342
0
    rv = der::Nested(subjectPublicKeyReader, der::SEQUENCE,
343
0
                     [&trustDomain, endEntityOrCA](Reader& r) {
344
0
      Input modulus;
345
0
      Input::size_type modulusSignificantBytes;
346
0
      Result nestedRv =
347
0
        der::PositiveInteger(r, modulus, &modulusSignificantBytes);
348
0
      if (nestedRv != Success) {
349
0
        return nestedRv;
350
0
      }
351
0
      // XXX: Should we do additional checks of the modulus?
352
0
      nestedRv = trustDomain.CheckRSAPublicKeyModulusSizeInBits(
353
0
        endEntityOrCA, modulusSignificantBytes * 8u);
354
0
      if (nestedRv != Success) {
355
0
        return nestedRv;
356
0
      }
357
0
358
0
      // XXX: We don't allow the TrustDomain to validate the exponent.
359
0
      // XXX: We don't do our own sanity checking of the exponent.
360
0
      Input exponent;
361
0
      return der::PositiveInteger(r, exponent);
362
0
    });
363
0
    if (rv != Success) {
364
0
      return rv;
365
0
    }
366
0
  } else {
367
0
    return Result::ERROR_UNSUPPORTED_KEYALG;
368
0
  }
369
0
370
0
  rv = der::End(algorithm);
371
0
  if (rv != Success) {
372
0
    return rv;
373
0
  }
374
0
  rv = der::End(subjectPublicKeyReader);
375
0
  if (rv != Success) {
376
0
    return rv;
377
0
  }
378
0
379
0
  return Success;
380
0
}
381
382
Result
383
CheckSubjectPublicKeyInfo(Input subjectPublicKeyInfo, TrustDomain& trustDomain,
384
                          EndEntityOrCA endEntityOrCA)
385
0
{
386
0
  Reader spkiReader(subjectPublicKeyInfo);
387
0
  Result rv = der::Nested(spkiReader, der::SEQUENCE, [&](Reader& r) {
388
0
    return CheckSubjectPublicKeyInfoContents(r, trustDomain, endEntityOrCA);
389
0
  });
390
0
  if (rv != Success) {
391
0
    return rv;
392
0
  }
393
0
  return der::End(spkiReader);
394
0
}
395
396
// 4.2.1.3. Key Usage (id-ce-keyUsage)
397
398
// As explained in the comment in CheckKeyUsage, bit 0 is the most significant
399
// bit and bit 7 is the least significant bit.
400
inline uint8_t KeyUsageToBitMask(KeyUsage keyUsage)
401
0
{
402
0
  assert(keyUsage != KeyUsage::noParticularKeyUsageRequired);
403
0
  return 0x80u >> static_cast<uint8_t>(keyUsage);
404
0
}
405
406
Result
407
CheckKeyUsage(EndEntityOrCA endEntityOrCA, const Input* encodedKeyUsage,
408
              KeyUsage requiredKeyUsageIfPresent)
409
0
{
410
0
  if (!encodedKeyUsage) {
411
0
    // TODO(bug 970196): Reject certificates that are being used to verify
412
0
    // certificate signatures unless the certificate is a trust anchor, to
413
0
    // reduce the chances of an end-entity certificate being abused as a CA
414
0
    // certificate.
415
0
    // if (endEntityOrCA == EndEntityOrCA::MustBeCA && !isTrustAnchor) {
416
0
    //   return Result::ERROR_INADEQUATE_KEY_USAGE;
417
0
    // }
418
0
    //
419
0
    // TODO: Users may configure arbitrary certificates as trust anchors, not
420
0
    // just roots. We should only allow a certificate without a key usage to be
421
0
    // used as a CA when it is self-issued and self-signed.
422
0
    return Success;
423
0
  }
424
0
425
0
  Reader input(*encodedKeyUsage);
426
0
  Reader value;
427
0
  if (der::ExpectTagAndGetValue(input, der::BIT_STRING, value) != Success) {
428
0
    return Result::ERROR_INADEQUATE_KEY_USAGE;
429
0
  }
430
0
431
0
  uint8_t numberOfPaddingBits;
432
0
  if (value.Read(numberOfPaddingBits) != Success) {
433
0
    return Result::ERROR_INADEQUATE_KEY_USAGE;
434
0
  }
435
0
  if (numberOfPaddingBits > 7) {
436
0
    return Result::ERROR_INADEQUATE_KEY_USAGE;
437
0
  }
438
0
439
0
  uint8_t bits;
440
0
  if (value.Read(bits) != Success) {
441
0
    // Reject empty bit masks.
442
0
    return Result::ERROR_INADEQUATE_KEY_USAGE;
443
0
  }
444
0
445
0
  // The most significant bit is numbered 0 (digitalSignature) and the least
446
0
  // significant bit is numbered 7 (encipherOnly), and the padding is in the
447
0
  // least significant bits of the last byte. The numbering of bits in a byte
448
0
  // is backwards from how we usually interpret them.
449
0
  //
450
0
  // For example, let's say bits is encoded in one byte with of value 0xB0 and
451
0
  // numberOfPaddingBits == 4. Then, bits is 10110000 in binary:
452
0
  //
453
0
  //      bit 0  bit 3
454
0
  //          |  |
455
0
  //          v  v
456
0
  //          10110000
457
0
  //              ^^^^
458
0
  //               |
459
0
  //               4 padding bits
460
0
  //
461
0
  // Since bits is the last byte, we have to consider the padding by ensuring
462
0
  // that the least significant 4 bits are all zero, since DER rules require
463
0
  // all padding bits to be zero. Then we have to look at the bit N bits to the
464
0
  // right of the most significant bit, where N is a value from the KeyUsage
465
0
  // enumeration.
466
0
  //
467
0
  // Let's say we're interested in the keyCertSign (5) bit. We'd need to look
468
0
  // at bit 5, which is zero, so keyCertSign is not asserted. (Since we check
469
0
  // that the padding is all zeros, it is OK to read from the padding bits.)
470
0
  //
471
0
  // Let's say we're interested in the digitalSignature (0) bit. We'd need to
472
0
  // look at the bit 0 (the most significant bit), which is set, so that means
473
0
  // digitalSignature is asserted. Similarly, keyEncipherment (2) and
474
0
  // dataEncipherment (3) are asserted.
475
0
  //
476
0
  // Note that since the KeyUsage enumeration is limited to values 0-7, we
477
0
  // only ever need to examine the first byte test for
478
0
  // requiredKeyUsageIfPresent.
479
0
480
0
  if (requiredKeyUsageIfPresent != KeyUsage::noParticularKeyUsageRequired) {
481
0
    // Check that the required key usage bit is set.
482
0
    if ((bits & KeyUsageToBitMask(requiredKeyUsageIfPresent)) == 0) {
483
0
      return Result::ERROR_INADEQUATE_KEY_USAGE;
484
0
    }
485
0
  }
486
0
487
0
  // RFC 5280 says "The keyCertSign bit is asserted when the subject public
488
0
  // key is used for verifying signatures on public key certificates. If the
489
0
  // keyCertSign bit is asserted, then the cA bit in the basic constraints
490
0
  // extension (Section 4.2.1.9) MUST also be asserted."
491
0
  // However, we allow end-entity certificates (i.e. certificates without
492
0
  // basicConstraints.cA set to TRUE) to claim keyCertSign for compatibility
493
0
  // reasons. This does not compromise security because we only allow
494
0
  // certificates with basicConstraints.cA set to TRUE to act as CAs.
495
0
  if (requiredKeyUsageIfPresent == KeyUsage::keyCertSign &&
496
0
      endEntityOrCA != EndEntityOrCA::MustBeCA) {
497
0
    return Result::ERROR_INADEQUATE_KEY_USAGE;
498
0
  }
499
0
500
0
  // The padding applies to the last byte, so skip to the last byte.
501
0
  while (!value.AtEnd()) {
502
0
    if (value.Read(bits) != Success) {
503
0
      return Result::ERROR_INADEQUATE_KEY_USAGE;
504
0
    }
505
0
  }
506
0
507
0
  // All of the padding bits must be zero, according to DER rules.
508
0
  uint8_t paddingMask = static_cast<uint8_t>((1 << numberOfPaddingBits) - 1);
509
0
  if ((bits & paddingMask) != 0) {
510
0
    return Result::ERROR_INADEQUATE_KEY_USAGE;
511
0
  }
512
0
513
0
  return Success;
514
0
}
515
516
// RFC5820 4.2.1.4. Certificate Policies
517
518
// "The user-initial-policy-set contains the special value any-policy if the
519
// user is not concerned about certificate policy."
520
//
521
// python DottedOIDToCode.py anyPolicy 2.5.29.32.0
522
523
static const uint8_t anyPolicy[] = {
524
  0x55, 0x1d, 0x20, 0x00
525
};
526
527
/*static*/ const CertPolicyId CertPolicyId::anyPolicy = {
528
  4, { 0x55, 0x1d, 0x20, 0x00 }
529
};
530
531
bool
532
0
CertPolicyId::IsAnyPolicy() const {
533
0
  if (this == &CertPolicyId::anyPolicy) {
534
0
    return true;
535
0
  }
536
0
  return numBytes == sizeof(::mozilla::pkix::anyPolicy) &&
537
0
         std::equal(bytes, bytes + numBytes, ::mozilla::pkix::anyPolicy);
538
0
}
539
540
bool
541
CertPolicyId::operator==(const CertPolicyId& other) const
542
0
{
543
0
  return numBytes == other.numBytes &&
544
0
         std::equal(bytes, bytes + numBytes, other.bytes);
545
0
}
546
547
// certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
548
Result
549
CheckCertificatePolicies(EndEntityOrCA endEntityOrCA,
550
                         const Input* encodedCertificatePolicies,
551
                         const Input* encodedInhibitAnyPolicy,
552
                         TrustLevel trustLevel,
553
                         const CertPolicyId& requiredPolicy)
554
0
{
555
0
  if (requiredPolicy.numBytes == 0 ||
556
0
      requiredPolicy.numBytes > sizeof requiredPolicy.bytes) {
557
0
    return Result::FATAL_ERROR_INVALID_ARGS;
558
0
  }
559
0
560
0
  bool requiredPolicyFound = requiredPolicy.IsAnyPolicy();
561
0
  if (requiredPolicyFound) {
562
0
    return Success;
563
0
  }
564
0
565
0
  // Bug 989051. Until we handle inhibitAnyPolicy we will fail close when
566
0
  // inhibitAnyPolicy extension is present and we are validating for a policy.
567
0
  if (!requiredPolicyFound && encodedInhibitAnyPolicy) {
568
0
    return Result::ERROR_POLICY_VALIDATION_FAILED;
569
0
  }
570
0
571
0
  // The root CA certificate may omit the policies that it has been
572
0
  // trusted for, so we cannot require the policies to be present in those
573
0
  // certificates. Instead, the determination of which roots are trusted for
574
0
  // which policies is made by the TrustDomain's GetCertTrust method.
575
0
  if (trustLevel == TrustLevel::TrustAnchor &&
576
0
      endEntityOrCA == EndEntityOrCA::MustBeCA) {
577
0
    requiredPolicyFound = true;
578
0
  }
579
0
580
0
  Input requiredPolicyDER;
581
0
  if (requiredPolicyDER.Init(requiredPolicy.bytes, requiredPolicy.numBytes)
582
0
        != Success) {
583
0
    return Result::FATAL_ERROR_INVALID_ARGS;
584
0
  }
585
0
586
0
  if (encodedCertificatePolicies) {
587
0
    Reader extension(*encodedCertificatePolicies);
588
0
    Reader certificatePolicies;
589
0
    Result rv = der::ExpectTagAndGetValue(extension, der::SEQUENCE,
590
0
                                          certificatePolicies);
591
0
    if (rv != Success) {
592
0
      return Result::ERROR_POLICY_VALIDATION_FAILED;
593
0
    }
594
0
    if (!extension.AtEnd()) {
595
0
      return Result::ERROR_POLICY_VALIDATION_FAILED;
596
0
    }
597
0
598
0
    do {
599
0
      // PolicyInformation ::= SEQUENCE {
600
0
      //         policyIdentifier   CertPolicyId,
601
0
      //         policyQualifiers   SEQUENCE SIZE (1..MAX) OF
602
0
      //                                 PolicyQualifierInfo OPTIONAL }
603
0
      Reader policyInformation;
604
0
      rv = der::ExpectTagAndGetValue(certificatePolicies, der::SEQUENCE,
605
0
                                     policyInformation);
606
0
      if (rv != Success) {
607
0
        return Result::ERROR_POLICY_VALIDATION_FAILED;
608
0
      }
609
0
610
0
      Reader policyIdentifier;
611
0
      rv = der::ExpectTagAndGetValue(policyInformation, der::OIDTag,
612
0
                                     policyIdentifier);
613
0
      if (rv != Success) {
614
0
        return rv;
615
0
      }
616
0
617
0
      if (policyIdentifier.MatchRest(requiredPolicyDER)) {
618
0
        requiredPolicyFound = true;
619
0
      } else if (endEntityOrCA == EndEntityOrCA::MustBeCA &&
620
0
                 policyIdentifier.MatchRest(anyPolicy)) {
621
0
        requiredPolicyFound = true;
622
0
      }
623
0
624
0
      // RFC 5280 Section 4.2.1.4 says "Optional qualifiers, which MAY be
625
0
      // present, are not expected to change the definition of the policy." Also,
626
0
      // it seems that Section 6, which defines validation, does not require any
627
0
      // matching of qualifiers. Thus, doing anything with the policy qualifiers
628
0
      // would be a waste of time and a source of potential incompatibilities, so
629
0
      // we just ignore them.
630
0
    } while (!requiredPolicyFound && !certificatePolicies.AtEnd());
631
0
  }
632
0
633
0
  if (!requiredPolicyFound) {
634
0
    return Result::ERROR_POLICY_VALIDATION_FAILED;
635
0
  }
636
0
637
0
  return Success;
638
0
}
639
640
static const long UNLIMITED_PATH_LEN = -1; // must be less than zero
641
642
//  BasicConstraints ::= SEQUENCE {
643
//          cA                      BOOLEAN DEFAULT FALSE,
644
//          pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
645
646
// RFC5280 4.2.1.9. Basic Constraints (id-ce-basicConstraints)
647
Result
648
CheckBasicConstraints(EndEntityOrCA endEntityOrCA,
649
                      const Input* encodedBasicConstraints,
650
                      const der::Version version, TrustLevel trustLevel,
651
                      unsigned int subCACount)
652
0
{
653
0
  bool isCA = false;
654
0
  long pathLenConstraint = UNLIMITED_PATH_LEN;
655
0
656
0
  if (encodedBasicConstraints) {
657
0
    Reader input(*encodedBasicConstraints);
658
0
    Result rv = der::Nested(input, der::SEQUENCE,
659
0
                            [&isCA, &pathLenConstraint](Reader& r) {
660
0
      Result nestedRv = der::OptionalBoolean(r, isCA);
661
0
      if (nestedRv != Success) {
662
0
        return nestedRv;
663
0
      }
664
0
      // TODO(bug 985025): If isCA is false, pathLenConstraint
665
0
      // MUST NOT be included (as per RFC 5280 section
666
0
      // 4.2.1.9), but for compatibility reasons, we don't
667
0
      // check this.
668
0
      return der::OptionalInteger(r, UNLIMITED_PATH_LEN, pathLenConstraint);
669
0
    });
670
0
    if (rv != Success) {
671
0
      return Result::ERROR_EXTENSION_VALUE_INVALID;
672
0
    }
673
0
    if (der::End(input) != Success) {
674
0
      return Result::ERROR_EXTENSION_VALUE_INVALID;
675
0
    }
676
0
  } else {
677
0
    // "If the basic constraints extension is not present in a version 3
678
0
    //  certificate, or the extension is present but the cA boolean is not
679
0
    //  asserted, then the certified public key MUST NOT be used to verify
680
0
    //  certificate signatures."
681
0
    //
682
0
    // For compatibility, we must accept v1 trust anchors without basic
683
0
    // constraints as CAs.
684
0
    //
685
0
    // There are devices with v1 certificates that are unlikely to be trust
686
0
    // anchors. In order to allow applications to treat this case differently
687
0
    // from other basic constraints violations (e.g. allowing certificate error
688
0
    // overrides for only this case), we return a different error code.
689
0
    //
690
0
    // TODO: add check for self-signedness?
691
0
    if (endEntityOrCA == EndEntityOrCA::MustBeCA && version == der::Version::v1) {
692
0
      if (trustLevel == TrustLevel::TrustAnchor) {
693
0
        isCA = true;
694
0
      } else {
695
0
        return Result::ERROR_V1_CERT_USED_AS_CA;
696
0
      }
697
0
    }
698
0
  }
699
0
700
0
  if (endEntityOrCA == EndEntityOrCA::MustBeEndEntity) {
701
0
    // CA certificates are not trusted as EE certs.
702
0
703
0
    if (isCA) {
704
0
      // Note that this check prevents a delegated OCSP response signing
705
0
      // certificate with the CA bit from successfully validating when we check
706
0
      // it from pkixocsp.cpp, which is a good thing.
707
0
      return Result::ERROR_CA_CERT_USED_AS_END_ENTITY;
708
0
    }
709
0
710
0
    return Success;
711
0
  }
712
0
713
0
  assert(endEntityOrCA == EndEntityOrCA::MustBeCA);
714
0
715
0
  // End-entity certificates are not allowed to act as CA certs.
716
0
  if (!isCA) {
717
0
    return Result::ERROR_CA_CERT_INVALID;
718
0
  }
719
0
720
0
  if (pathLenConstraint >= 0 &&
721
0
      static_cast<long>(subCACount) > pathLenConstraint) {
722
0
    return Result::ERROR_PATH_LEN_CONSTRAINT_INVALID;
723
0
  }
724
0
725
0
  return Success;
726
0
}
727
728
// 4.2.1.12. Extended Key Usage (id-ce-extKeyUsage)
729
730
static Result
731
MatchEKU(Reader& value, KeyPurposeId requiredEKU,
732
         EndEntityOrCA endEntityOrCA, TrustDomain& trustDomain,
733
         Time notBefore, /*in/out*/ bool& found,
734
         /*in/out*/ bool& foundOCSPSigning)
735
0
{
736
0
  // See Section 5.9 of "A Layman's Guide to a Subset of ASN.1, BER, and DER"
737
0
  // for a description of ASN.1 DER encoding of OIDs.
738
0
739
0
  // id-pkix  OBJECT IDENTIFIER  ::=
740
0
  //            { iso(1) identified-organization(3) dod(6) internet(1)
741
0
  //                    security(5) mechanisms(5) pkix(7) }
742
0
  // id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
743
0
  // id-kp-serverAuth      OBJECT IDENTIFIER ::= { id-kp 1 }
744
0
  // id-kp-clientAuth      OBJECT IDENTIFIER ::= { id-kp 2 }
745
0
  // id-kp-codeSigning     OBJECT IDENTIFIER ::= { id-kp 3 }
746
0
  // id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }
747
0
  // id-kp-OCSPSigning     OBJECT IDENTIFIER ::= { id-kp 9 }
748
0
  static const uint8_t server[] = { (40*1)+3, 6, 1, 5, 5, 7, 3, 1 };
749
0
  static const uint8_t client[] = { (40*1)+3, 6, 1, 5, 5, 7, 3, 2 };
750
0
  static const uint8_t code  [] = { (40*1)+3, 6, 1, 5, 5, 7, 3, 3 };
751
0
  static const uint8_t email [] = { (40*1)+3, 6, 1, 5, 5, 7, 3, 4 };
752
0
  static const uint8_t ocsp  [] = { (40*1)+3, 6, 1, 5, 5, 7, 3, 9 };
753
0
754
0
  // id-Netscape        OBJECT IDENTIFIER ::= { 2 16 840 1 113730 }
755
0
  // id-Netscape-policy OBJECT IDENTIFIER ::= { id-Netscape 4 }
756
0
  // id-Netscape-stepUp OBJECT IDENTIFIER ::= { id-Netscape-policy 1 }
757
0
  static const uint8_t serverStepUp[] =
758
0
    { (40*2)+16, 128+6,72, 1, 128+6,128+120,66, 4, 1 };
759
0
760
0
  bool match = false;
761
0
762
0
  if (!found) {
763
0
    switch (requiredEKU) {
764
0
      case KeyPurposeId::id_kp_serverAuth: {
765
0
        if (value.MatchRest(server)) {
766
0
          match = true;
767
0
          break;
768
0
        }
769
0
        // Potentially treat CA certs with step-up OID as also having SSL server
770
0
        // type. Comodo has issued certificates that require this behavior that
771
0
        // don't expire until June 2020!
772
0
        if (endEntityOrCA == EndEntityOrCA::MustBeCA &&
773
0
            value.MatchRest(serverStepUp)) {
774
0
          Result rv = trustDomain.NetscapeStepUpMatchesServerAuth(notBefore,
775
0
                                                                  match);
776
0
          if (rv != Success) {
777
0
            return rv;
778
0
          }
779
0
        }
780
0
        break;
781
0
      }
782
0
783
0
      case KeyPurposeId::id_kp_clientAuth:
784
0
        match = value.MatchRest(client);
785
0
        break;
786
0
787
0
      case KeyPurposeId::id_kp_codeSigning:
788
0
        match = value.MatchRest(code);
789
0
        break;
790
0
791
0
      case KeyPurposeId::id_kp_emailProtection:
792
0
        match = value.MatchRest(email);
793
0
        break;
794
0
795
0
      case KeyPurposeId::id_kp_OCSPSigning:
796
0
        match = value.MatchRest(ocsp);
797
0
        break;
798
0
799
0
      case KeyPurposeId::anyExtendedKeyUsage:
800
0
        return NotReached("anyExtendedKeyUsage should start with found==true",
801
0
                          Result::FATAL_ERROR_LIBRARY_FAILURE);
802
0
    }
803
0
  }
804
0
805
0
  if (match) {
806
0
    found = true;
807
0
    if (requiredEKU == KeyPurposeId::id_kp_OCSPSigning) {
808
0
      foundOCSPSigning = true;
809
0
    }
810
0
  } else if (value.MatchRest(ocsp)) {
811
0
    foundOCSPSigning = true;
812
0
  }
813
0
814
0
  value.SkipToEnd(); // ignore unmatched OIDs.
815
0
816
0
  return Success;
817
0
}
818
819
Result
820
CheckExtendedKeyUsage(EndEntityOrCA endEntityOrCA,
821
                      const Input* encodedExtendedKeyUsage,
822
                      KeyPurposeId requiredEKU, TrustDomain& trustDomain,
823
                      Time notBefore)
824
0
{
825
0
  // XXX: We're using Result::ERROR_INADEQUATE_CERT_TYPE here so that callers
826
0
  // can distinguish EKU mismatch from KU mismatch from basic constraints
827
0
  // mismatch. We should probably add a new error code that is more clear for
828
0
  // this type of problem.
829
0
830
0
  bool foundOCSPSigning = false;
831
0
832
0
  if (encodedExtendedKeyUsage) {
833
0
    bool found = requiredEKU == KeyPurposeId::anyExtendedKeyUsage;
834
0
835
0
    Reader input(*encodedExtendedKeyUsage);
836
0
    Result rv = der::NestedOf(input, der::SEQUENCE, der::OIDTag,
837
0
                              der::EmptyAllowed::No, [&](Reader& r) {
838
0
      return MatchEKU(r, requiredEKU, endEntityOrCA, trustDomain, notBefore,
839
0
                      found, foundOCSPSigning);
840
0
    });
841
0
    if (rv != Success) {
842
0
      return Result::ERROR_INADEQUATE_CERT_TYPE;
843
0
    }
844
0
    if (der::End(input) != Success) {
845
0
      return Result::ERROR_INADEQUATE_CERT_TYPE;
846
0
    }
847
0
848
0
    // If the EKU extension was included, then the required EKU must be in the
849
0
    // list.
850
0
    if (!found) {
851
0
      return Result::ERROR_INADEQUATE_CERT_TYPE;
852
0
    }
853
0
  }
854
0
855
0
  // pkixocsp.cpp depends on the following additional checks.
856
0
857
0
  if (endEntityOrCA == EndEntityOrCA::MustBeEndEntity) {
858
0
    // When validating anything other than an delegated OCSP signing cert,
859
0
    // reject any cert that also claims to be an OCSP responder, because such
860
0
    // a cert does not make sense. For example, if an SSL certificate were to
861
0
    // assert id-kp-OCSPSigning then it could sign OCSP responses for itself,
862
0
    // if not for this check.
863
0
    // That said, we accept CA certificates with id-kp-OCSPSigning because
864
0
    // some CAs in Mozilla's CA program have issued such intermediate
865
0
    // certificates, and because some CAs have reported some Microsoft server
866
0
    // software wrongly requires CA certificates to have id-kp-OCSPSigning.
867
0
    // Allowing this exception does not cause any security issues because we
868
0
    // require delegated OCSP response signing certificates to be end-entity
869
0
    // certificates.
870
0
    if (foundOCSPSigning && requiredEKU != KeyPurposeId::id_kp_OCSPSigning) {
871
0
      return Result::ERROR_INADEQUATE_CERT_TYPE;
872
0
    }
873
0
    // http://tools.ietf.org/html/rfc6960#section-4.2.2.2:
874
0
    // "OCSP signing delegation SHALL be designated by the inclusion of
875
0
    // id-kp-OCSPSigning in an extended key usage certificate extension
876
0
    // included in the OCSP response signer's certificate."
877
0
    //
878
0
    // id-kp-OCSPSigning is the only EKU that isn't implicitly assumed when the
879
0
    // EKU extension is missing from an end-entity certificate. However, any CA
880
0
    // certificate can issue a delegated OCSP response signing certificate, so
881
0
    // we can't require the EKU be explicitly included for CA certificates.
882
0
    if (!foundOCSPSigning && requiredEKU == KeyPurposeId::id_kp_OCSPSigning) {
883
0
      return Result::ERROR_INADEQUATE_CERT_TYPE;
884
0
    }
885
0
  }
886
0
887
0
  return Success;
888
0
}
889
890
Result
891
CheckTLSFeatures(const BackCert& subject, BackCert& potentialIssuer)
892
0
{
893
0
  const Input* issuerTLSFeatures = potentialIssuer.GetRequiredTLSFeatures();
894
0
  if (!issuerTLSFeatures) {
895
0
    return Success;
896
0
  }
897
0
898
0
  const Input* subjectTLSFeatures = subject.GetRequiredTLSFeatures();
899
0
  if (issuerTLSFeatures->GetLength() == 0 ||
900
0
      !subjectTLSFeatures ||
901
0
      !InputsAreEqual(*issuerTLSFeatures, *subjectTLSFeatures)) {
902
0
    return Result::ERROR_REQUIRED_TLS_FEATURE_MISSING;
903
0
  }
904
0
905
0
  return Success;
906
0
}
907
908
Result
909
TLSFeaturesSatisfiedInternal(const Input* requiredTLSFeatures,
910
                             const Input* stapledOCSPResponse)
911
0
{
912
0
  if (!requiredTLSFeatures) {
913
0
    return Success;
914
0
  }
915
0
916
0
  // RFC 6066 10.2: ExtensionType status_request
917
0
  const static uint8_t status_request = 5;
918
0
  const static uint8_t status_request_bytes[] = { status_request };
919
0
920
0
  Reader input(*requiredTLSFeatures);
921
0
  return der::NestedOf(input, der::SEQUENCE, der::INTEGER,
922
0
                       der::EmptyAllowed::No, [&](Reader& r) {
923
0
    if (!r.MatchRest(status_request_bytes)) {
924
0
      return Result::ERROR_REQUIRED_TLS_FEATURE_MISSING;
925
0
    }
926
0
927
0
    if (!stapledOCSPResponse) {
928
0
      return Result::ERROR_REQUIRED_TLS_FEATURE_MISSING;
929
0
    }
930
0
931
0
    return Result::Success;
932
0
  });
933
0
}
934
935
Result
936
CheckTLSFeaturesAreSatisfied(Input& cert,
937
                             const Input* stapledOCSPResponse)
938
0
{
939
0
  BackCert backCert(cert, EndEntityOrCA::MustBeEndEntity, nullptr);
940
0
  Result rv = backCert.Init();
941
0
  if (rv != Success) {
942
0
    return rv;
943
0
  }
944
0
945
0
  return TLSFeaturesSatisfiedInternal(backCert.GetRequiredTLSFeatures(),
946
0
                                      stapledOCSPResponse);
947
0
}
948
949
Result
950
CheckIssuerIndependentProperties(TrustDomain& trustDomain,
951
                                 const BackCert& cert,
952
                                 Time time,
953
                                 KeyUsage requiredKeyUsageIfPresent,
954
                                 KeyPurposeId requiredEKUIfPresent,
955
                                 const CertPolicyId& requiredPolicy,
956
                                 unsigned int subCACount,
957
                                 /*out*/ TrustLevel& trustLevel)
958
0
{
959
0
  Result rv;
960
0
961
0
  const EndEntityOrCA endEntityOrCA = cert.endEntityOrCA;
962
0
963
0
  // Check the cert's trust first, because we want to minimize the amount of
964
0
  // processing we do on a distrusted cert, in case it is trying to exploit
965
0
  // some bug in our processing.
966
0
  rv = trustDomain.GetCertTrust(endEntityOrCA, requiredPolicy, cert.GetDER(),
967
0
                                trustLevel);
968
0
  if (rv != Success) {
969
0
    return rv;
970
0
  }
971
0
972
0
  // IMPORTANT: We parse the validity interval here, so that we can use the
973
0
  // notBefore and notAfter values in checks for things that might be deprecated
974
0
  // over time. However, we must not fail for semantic errors until the end of
975
0
  // this method, in order to preserve error ranking.
976
0
  Time notBefore(Time::uninitialized);
977
0
  Time notAfter(Time::uninitialized);
978
0
  rv = ParseValidity(cert.GetValidity(), &notBefore, &notAfter);
979
0
  if (rv != Success) {
980
0
    return rv;
981
0
  }
982
0
983
0
  if (trustLevel == TrustLevel::TrustAnchor &&
984
0
      endEntityOrCA == EndEntityOrCA::MustBeEndEntity &&
985
0
      requiredEKUIfPresent == KeyPurposeId::id_kp_OCSPSigning) {
986
0
    // OCSP signer certificates can never be trust anchors, especially
987
0
    // since we don't support designated OCSP responders. All of the checks
988
0
    // below that are dependent on trustLevel rely on this overriding of the
989
0
    // trust level for OCSP signers.
990
0
    trustLevel = TrustLevel::InheritsTrust;
991
0
  }
992
0
993
0
  switch (trustLevel) {
994
0
    case TrustLevel::InheritsTrust:
995
0
      rv = CheckSignatureAlgorithm(trustDomain, endEntityOrCA, notBefore,
996
0
                                   cert.GetSignedData(), cert.GetSignature());
997
0
      if (rv != Success) {
998
0
        return rv;
999
0
      }
1000
0
      break;
1001
0
1002
0
    case TrustLevel::TrustAnchor:
1003
0
      // We don't even bother checking signatureAlgorithm or signature for
1004
0
      // syntactic validity for trust anchors, because we don't use those
1005
0
      // fields for anything, and because the trust anchor might be signed
1006
0
      // with a signature algorithm we don't actually support.
1007
0
      break;
1008
0
1009
0
    case TrustLevel::ActivelyDistrusted:
1010
0
      return Result::ERROR_UNTRUSTED_CERT;
1011
0
  }
1012
0
1013
0
  // Check the SPKI early, because it is one of the most selective properties
1014
0
  // of the certificate due to SHA-1 deprecation and the deprecation of
1015
0
  // certificates with keys weaker than RSA 2048.
1016
0
  rv = CheckSubjectPublicKeyInfo(cert.GetSubjectPublicKeyInfo(), trustDomain,
1017
0
                                 endEntityOrCA);
1018
0
  if (rv != Success) {
1019
0
    return rv;
1020
0
  }
1021
0
1022
0
  // 4.1.2.4. Issuer
1023
0
  rv = CheckIssuer(cert.GetIssuer());
1024
0
  if (rv != Success) {
1025
0
    return rv;
1026
0
  }
1027
0
1028
0
  // 4.2.1.1. Authority Key Identifier is ignored (see bug 965136).
1029
0
1030
0
  // 4.2.1.2. Subject Key Identifier is ignored (see bug 965136).
1031
0
1032
0
  // 4.2.1.3. Key Usage
1033
0
  rv = CheckKeyUsage(endEntityOrCA, cert.GetKeyUsage(),
1034
0
                     requiredKeyUsageIfPresent);
1035
0
  if (rv != Success) {
1036
0
    return rv;
1037
0
  }
1038
0
1039
0
  // 4.2.1.4. Certificate Policies
1040
0
  rv = CheckCertificatePolicies(endEntityOrCA, cert.GetCertificatePolicies(),
1041
0
                                cert.GetInhibitAnyPolicy(), trustLevel,
1042
0
                                requiredPolicy);
1043
0
  if (rv != Success) {
1044
0
    return rv;
1045
0
  }
1046
0
1047
0
  // 4.2.1.5. Policy Mappings are not supported; see the documentation about
1048
0
  //          policy enforcement in pkix.h.
1049
0
1050
0
  // 4.2.1.6. Subject Alternative Name dealt with during name constraint
1051
0
  //          checking and during name verification (CERT_VerifyCertName).
1052
0
1053
0
  // 4.2.1.7. Issuer Alternative Name is not something that needs checking.
1054
0
1055
0
  // 4.2.1.8. Subject Directory Attributes is not something that needs
1056
0
  //          checking.
1057
0
1058
0
  // 4.2.1.9. Basic Constraints.
1059
0
  rv = CheckBasicConstraints(endEntityOrCA, cert.GetBasicConstraints(),
1060
0
                             cert.GetVersion(), trustLevel, subCACount);
1061
0
  if (rv != Success) {
1062
0
    return rv;
1063
0
  }
1064
0
1065
0
  // 4.2.1.10. Name Constraints is dealt with in during path building.
1066
0
1067
0
  // 4.2.1.11. Policy Constraints are implicitly supported; see the
1068
0
  //           documentation about policy enforcement in pkix.h.
1069
0
1070
0
  // 4.2.1.12. Extended Key Usage
1071
0
  rv = CheckExtendedKeyUsage(endEntityOrCA, cert.GetExtKeyUsage(),
1072
0
                             requiredEKUIfPresent, trustDomain, notBefore);
1073
0
  if (rv != Success) {
1074
0
    return rv;
1075
0
  }
1076
0
1077
0
  // 4.2.1.13. CRL Distribution Points is not supported, though the
1078
0
  //           TrustDomain's CheckRevocation method may parse it and process it
1079
0
  //           on its own.
1080
0
1081
0
  // 4.2.1.14. Inhibit anyPolicy is implicitly supported; see the documentation
1082
0
  //           about policy enforcement in pkix.h.
1083
0
1084
0
  // IMPORTANT: Even though we parse validity above, we wait until this point to
1085
0
  // check it, so that error ranking works correctly.
1086
0
  rv = CheckValidity(time, notBefore, notAfter);
1087
0
  if (rv != Success) {
1088
0
    return rv;
1089
0
  }
1090
0
1091
0
  rv = trustDomain.CheckValidityIsAcceptable(notBefore, notAfter, endEntityOrCA,
1092
0
                                             requiredEKUIfPresent);
1093
0
  if (rv != Success) {
1094
0
    return rv;
1095
0
  }
1096
0
1097
0
  return Success;
1098
0
}
1099
1100
} } // namespace mozilla::pkix