LCOV - code coverage report
Current view: top level - security/pkix/lib - pkixcheck.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 56 379 14.8 %
Date: 2017-07-14 16:53:18 Functions: 4 23 17.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13