LCOV - code coverage report
Current view: top level - security/pkix/include/pkix - pkixtypes.h (source / functions) Hit Total Coverage
Test: output.info Lines: 2 11 18.2 %
Date: 2017-07-14 16:53:18 Functions: 2 11 18.2 %
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             : #ifndef mozilla_pkix_pkixtypes_h
      26             : #define mozilla_pkix_pkixtypes_h
      27             : 
      28             : #include "pkix/Input.h"
      29             : #include "pkix/Time.h"
      30             : #include "stdint.h"
      31             : 
      32             : namespace mozilla { namespace pkix {
      33             : 
      34             : enum class DigestAlgorithm
      35             : {
      36             :   sha512 = 1,
      37             :   sha384 = 2,
      38             :   sha256 = 3,
      39             :   sha1 = 4,
      40             : };
      41             : 
      42             : enum class NamedCurve
      43             : {
      44             :   // secp521r1 (OID 1.3.132.0.35, RFC 5480)
      45             :   secp521r1 = 1,
      46             : 
      47             :   // secp384r1 (OID 1.3.132.0.34, RFC 5480)
      48             :   secp384r1 = 2,
      49             : 
      50             :   // secp256r1 (OID 1.2.840.10045.3.1.7, RFC 5480)
      51             :   secp256r1 = 3,
      52             : };
      53             : 
      54           0 : struct SignedDigest final
      55             : {
      56             :   Input digest;
      57             :   DigestAlgorithm digestAlgorithm;
      58             :   Input signature;
      59             : 
      60             :   void operator=(const SignedDigest&) = delete;
      61             : };
      62             : 
      63             : enum class EndEntityOrCA { MustBeEndEntity = 0, MustBeCA = 1 };
      64             : 
      65             : enum class KeyUsage : uint8_t
      66             : {
      67             :   digitalSignature = 0,
      68             :   nonRepudiation   = 1,
      69             :   keyEncipherment  = 2,
      70             :   dataEncipherment = 3,
      71             :   keyAgreement     = 4,
      72             :   keyCertSign      = 5,
      73             :   // cRLSign       = 6,
      74             :   // encipherOnly  = 7,
      75             :   // decipherOnly  = 8,
      76             :   noParticularKeyUsageRequired = 0xff,
      77             : };
      78             : 
      79             : enum class KeyPurposeId
      80             : {
      81             :   anyExtendedKeyUsage = 0,
      82             :   id_kp_serverAuth = 1,           // id-kp-serverAuth
      83             :   id_kp_clientAuth = 2,           // id-kp-clientAuth
      84             :   id_kp_codeSigning = 3,          // id-kp-codeSigning
      85             :   id_kp_emailProtection = 4,      // id-kp-emailProtection
      86             :   id_kp_OCSPSigning = 9,          // id-kp-OCSPSigning
      87             : };
      88             : 
      89             : struct CertPolicyId final
      90             : {
      91             :   uint16_t numBytes;
      92             :   static const uint16_t MAX_BYTES = 24;
      93             :   uint8_t bytes[MAX_BYTES];
      94             : 
      95             :   bool IsAnyPolicy() const;
      96             :   bool operator==(const CertPolicyId& other) const;
      97             : 
      98             :   static const CertPolicyId anyPolicy;
      99             : };
     100             : 
     101             : enum class TrustLevel
     102             : {
     103             :   TrustAnchor = 1,        // certificate is a trusted root CA certificate or
     104             :                           // equivalent *for the given policy*.
     105             :   ActivelyDistrusted = 2, // certificate is known to be bad
     106             :   InheritsTrust = 3       // certificate must chain to a trust anchor
     107             : };
     108             : 
     109             : // Extensions extracted during the verification flow.
     110             : // See TrustDomain::NoteAuxiliaryExtension.
     111             : enum class AuxiliaryExtension
     112             : {
     113             :   // Certificate Transparency data, specifically Signed Certificate
     114             :   // Timestamps (SCTs). See RFC 6962.
     115             : 
     116             :   // SCT list embedded in the end entity certificate. Called by BuildCertChain
     117             :   // after the certificate containing the SCTs has passed the revocation checks.
     118             :   EmbeddedSCTList = 1,
     119             :   // SCT list from OCSP response. Called by VerifyEncodedOCSPResponse
     120             :   // when its result is a success and the SCT list is present.
     121             :   SCTListFromOCSPResponse = 2
     122             : };
     123             : 
     124             : // CertID references the information needed to do revocation checking for the
     125             : // certificate issued by the given issuer with the given serial number.
     126             : //
     127             : // issuer must be the DER-encoded issuer field from the certificate for which
     128             : // revocation checking is being done, **NOT** the subject field of the issuer
     129             : // certificate. (Those two fields must be equal to each other, but they may not
     130             : // be encoded exactly the same, and the encoding matters for OCSP.)
     131             : // issuerSubjectPublicKeyInfo is the entire DER-encoded subjectPublicKeyInfo
     132             : // field from the issuer's certificate. serialNumber is the entire DER-encoded
     133             : // serial number from the subject certificate (the certificate for which we are
     134             : // checking the revocation status).
     135             : struct CertID final
     136             : {
     137             : public:
     138           0 :   CertID(Input issuer, Input issuerSubjectPublicKeyInfo, Input serialNumber)
     139           0 :     : issuer(issuer)
     140             :     , issuerSubjectPublicKeyInfo(issuerSubjectPublicKeyInfo)
     141           0 :     , serialNumber(serialNumber)
     142             :   {
     143           0 :   }
     144             :   const Input issuer;
     145             :   const Input issuerSubjectPublicKeyInfo;
     146             :   const Input serialNumber;
     147             : 
     148             :   void operator=(const CertID&) = delete;
     149             : };
     150             : 
     151             : class DERArray
     152             : {
     153             : public:
     154             :   // Returns the number of DER-encoded items in the array.
     155             :   virtual size_t GetLength() const = 0;
     156             : 
     157             :   // Returns a weak (non-owning) pointer the ith DER-encoded item in the array
     158             :   // (0-indexed). The result is guaranteed to be non-null if i < GetLength(),
     159             :   // and the result is guaranteed to be nullptr if i >= GetLength().
     160             :   virtual const Input* GetDER(size_t i) const = 0;
     161             : protected:
     162           0 :   DERArray() { }
     163           0 :   virtual ~DERArray() { }
     164             : };
     165             : 
     166             : // Applications control the behavior of path building and verification by
     167             : // implementing the TrustDomain interface. The TrustDomain is used for all
     168             : // cryptography and for determining which certificates are trusted or
     169             : // distrusted.
     170             : class TrustDomain
     171             : {
     172             : public:
     173          15 :   virtual ~TrustDomain() { }
     174             : 
     175             :   // Determine the level of trust in the given certificate for the given role.
     176             :   // This will be called for every certificate encountered during path
     177             :   // building.
     178             :   //
     179             :   // When policy.IsAnyPolicy(), then no policy-related checking should be done.
     180             :   // When !policy.IsAnyPolicy(), then GetCertTrust MUST NOT return with
     181             :   // trustLevel == TrustAnchor unless the given cert is considered a trust
     182             :   // anchor *for that policy*. In particular, if the user has marked an
     183             :   // intermediate certificate as trusted, but that intermediate isn't in the
     184             :   // list of EV roots, then GetCertTrust must result in
     185             :   // trustLevel == InheritsTrust instead of trustLevel == TrustAnchor
     186             :   // (assuming the candidate cert is not actively distrusted).
     187             :   virtual Result GetCertTrust(EndEntityOrCA endEntityOrCA,
     188             :                               const CertPolicyId& policy,
     189             :                               Input candidateCertDER,
     190             :                               /*out*/ TrustLevel& trustLevel) = 0;
     191             : 
     192             :   class IssuerChecker
     193             :   {
     194             :   public:
     195             :     // potentialIssuerDER is the complete DER encoding of the certificate to
     196             :     // be checked as a potential issuer.
     197             :     //
     198             :     // If additionalNameConstraints is not nullptr then it must point to an
     199             :     // encoded NameConstraints extension value; in that case, those name
     200             :     // constraints will be checked in addition to any any name constraints
     201             :     // contained in potentialIssuerDER.
     202             :     virtual Result Check(Input potentialIssuerDER,
     203             :             /*optional*/ const Input* additionalNameConstraints,
     204             :                  /*out*/ bool& keepGoing) = 0;
     205             :   protected:
     206             :     IssuerChecker();
     207             :     virtual ~IssuerChecker();
     208             : 
     209             :     IssuerChecker(const IssuerChecker&) = delete;
     210             :     void operator=(const IssuerChecker&) = delete;
     211             :   };
     212             : 
     213             :   // Search for a CA certificate with the given name. The implementation must
     214             :   // call checker.Check with the DER encoding of the potential issuer
     215             :   // certificate. The implementation must follow these rules:
     216             :   //
     217             :   // * The implementation must be reentrant and must limit the amount of stack
     218             :   //   space it uses; see the note on reentrancy and stack usage below.
     219             :   // * When checker.Check does not return Success then immediately return its
     220             :   //   return value.
     221             :   // * When checker.Check returns Success and sets keepGoing = false, then
     222             :   //   immediately return Success.
     223             :   // * When checker.Check returns Success and sets keepGoing = true, then
     224             :   //   call checker.Check again with a different potential issuer certificate,
     225             :   //   if any more are available.
     226             :   // * When no more potential issuer certificates are available, return
     227             :   //   Success.
     228             :   // * Don't call checker.Check with the same potential issuer certificate more
     229             :   //   than once in a given call of FindIssuer.
     230             :   // * The given time parameter may be used to filter out certificates that are
     231             :   //   not valid at the given time, or it may be ignored.
     232             :   //
     233             :   // Note on reentrancy and stack usage: checker.Check will attempt to
     234             :   // recursively build a certificate path from the potential issuer it is given
     235             :   // to a trusted root, as determined by this TrustDomain. That means that
     236             :   // checker.Check may call any/all of the methods on this TrustDomain. In
     237             :   // particular, there will be call stacks that look like this:
     238             :   //
     239             :   //    BuildCertChain
     240             :   //      [...]
     241             :   //        TrustDomain::FindIssuer
     242             :   //          [...]
     243             :   //            IssuerChecker::Check
     244             :   //              [...]
     245             :   //                TrustDomain::FindIssuer
     246             :   //                  [...]
     247             :   //                    IssuerChecker::Check
     248             :   //                      [...]
     249             :   //
     250             :   // checker.Check is responsible for limiting the recursion to a reasonable
     251             :   // limit.
     252             :   //
     253             :   // checker.Check will verify that the subject's issuer field matches the
     254             :   // potential issuer's subject field. It will also check that the potential
     255             :   // issuer is valid at the given time. However, if the FindIssuer
     256             :   // implementation has an efficient way of filtering potential issuers by name
     257             :   // and/or validity period itself, then it is probably better for performance
     258             :   // for it to do so.
     259             :   virtual Result FindIssuer(Input encodedIssuerName,
     260             :                             IssuerChecker& checker, Time time) = 0;
     261             : 
     262             :   // Called as soon as we think we have a valid chain but before revocation
     263             :   // checks are done. This function can be used to compute additional checks,
     264             :   // especially checks that require the entire certificate chain. This callback
     265             :   // can also be used to save a copy of the built certificate chain for later
     266             :   // use.
     267             :   //
     268             :   // This function may be called multiple times, regardless of whether it
     269             :   // returns success or failure. It is guaranteed that BuildCertChain will not
     270             :   // return Success unless the last call to IsChainValid returns Success. Further,
     271             :   // it is guaranteed that when BuildCertChain returns Success the last chain
     272             :   // passed to IsChainValid is the valid chain that should be used for further
     273             :   // operations that require the whole chain.
     274             :   //
     275             :   // Keep in mind, in particular, that if the application saves a copy of the
     276             :   // certificate chain the last invocation of IsChainValid during a validation,
     277             :   // it is still possible for BuildCertChain to fail, in which case the
     278             :   // application must not assume anything about the validity of the last
     279             :   // certificate chain passed to IsChainValid; especially, it would be very
     280             :   // wrong to assume that the certificate chain is valid.
     281             :   //
     282             :   // certChain.GetDER(0) is the trust anchor.
     283             :   virtual Result IsChainValid(const DERArray& certChain, Time time,
     284             :                               const CertPolicyId& requiredPolicy) = 0;
     285             : 
     286             :   virtual Result CheckRevocation(EndEntityOrCA endEntityOrCA,
     287             :                                  const CertID& certID, Time time,
     288             :                                  Duration validityDuration,
     289             :                     /*optional*/ const Input* stapledOCSPresponse,
     290             :                     /*optional*/ const Input* aiaExtension) = 0;
     291             : 
     292             :   // Check that the given digest algorithm is acceptable for use in signatures.
     293             :   //
     294             :   // Return Success if the algorithm is acceptable,
     295             :   // Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED if the algorithm is not
     296             :   // acceptable, or another error code if another error occurred.
     297             :   virtual Result CheckSignatureDigestAlgorithm(DigestAlgorithm digestAlg,
     298             :                                                EndEntityOrCA endEntityOrCA,
     299             :                                                Time notBefore) = 0;
     300             : 
     301             :   // Check that the RSA public key size is acceptable.
     302             :   //
     303             :   // Return Success if the key size is acceptable,
     304             :   // Result::ERROR_INADEQUATE_KEY_SIZE if the key size is not acceptable,
     305             :   // or another error code if another error occurred.
     306             :   virtual Result CheckRSAPublicKeyModulusSizeInBits(
     307             :                    EndEntityOrCA endEntityOrCA,
     308             :                    unsigned int modulusSizeInBits) = 0;
     309             : 
     310             :   // Verify the given RSA PKCS#1.5 signature on the given digest using the
     311             :   // given RSA public key.
     312             :   //
     313             :   // CheckRSAPublicKeyModulusSizeInBits will be called before calling this
     314             :   // function, so it is not necessary to repeat those checks here. However,
     315             :   // VerifyRSAPKCS1SignedDigest *is* responsible for doing the mathematical
     316             :   // verification of the public key validity as specified in NIST SP 800-56A.
     317             :   virtual Result VerifyRSAPKCS1SignedDigest(
     318             :                    const SignedDigest& signedDigest,
     319             :                    Input subjectPublicKeyInfo) = 0;
     320             : 
     321             :   // Check that the given named ECC curve is acceptable for ECDSA signatures.
     322             :   //
     323             :   // Return Success if the curve is acceptable,
     324             :   // Result::ERROR_UNSUPPORTED_ELLIPTIC_CURVE if the curve is not acceptable,
     325             :   // or another error code if another error occurred.
     326             :   virtual Result CheckECDSACurveIsAcceptable(EndEntityOrCA endEntityOrCA,
     327             :                                              NamedCurve curve) = 0;
     328             : 
     329             :   // Verify the given ECDSA signature on the given digest using the given ECC
     330             :   // public key.
     331             :   //
     332             :   // CheckECDSACurveIsAcceptable will be called before calling this function,
     333             :   // so it is not necessary to repeat that check here. However,
     334             :   // VerifyECDSASignedDigest *is* responsible for doing the mathematical
     335             :   // verification of the public key validity as specified in NIST SP 800-56A.
     336             :   virtual Result VerifyECDSASignedDigest(const SignedDigest& signedDigest,
     337             :                                          Input subjectPublicKeyInfo) = 0;
     338             : 
     339             :   // Check that the validity duration is acceptable.
     340             :   //
     341             :   // Return Success if the validity duration is acceptable,
     342             :   // Result::ERROR_VALIDITY_TOO_LONG if the validity duration is not acceptable,
     343             :   // or another error code if another error occurred.
     344             :   virtual Result CheckValidityIsAcceptable(Time notBefore, Time notAfter,
     345             :                                            EndEntityOrCA endEntityOrCA,
     346             :                                            KeyPurposeId keyPurpose) = 0;
     347             : 
     348             :   // For compatibility, a CA certificate with an extended key usage that
     349             :   // contains the id-Netscape-stepUp OID but does not contain the
     350             :   // id-kp-serverAuth OID may be considered valid for issuing server auth
     351             :   // certificates. This function allows TrustDomain implementations to control
     352             :   // this setting based on the start of the validity period of the certificate
     353             :   // in question.
     354             :   virtual Result NetscapeStepUpMatchesServerAuth(Time notBefore,
     355             :                                                  /*out*/ bool& matches) = 0;
     356             : 
     357             :   // Some certificate or OCSP response extensions do not directly participate
     358             :   // in the verification flow, but might still be of interest to the clients
     359             :   // (notably Certificate Transparency data, RFC 6962). Such extensions are
     360             :   // extracted and passed to this function for further processing.
     361             :   virtual void NoteAuxiliaryExtension(AuxiliaryExtension extension,
     362             :                                       Input extensionData) = 0;
     363             : 
     364             :   // Compute a digest of the data in item using the given digest algorithm.
     365             :   //
     366             :   // item contains the data to hash.
     367             :   // digestBuf points to a buffer to where the digest will be written.
     368             :   // digestBufLen will be the size of the digest output (20 for SHA-1,
     369             :   // 32 for SHA-256, etc.).
     370             :   //
     371             :   // TODO: Taking the output buffer as (uint8_t*, size_t) is counter to our
     372             :   // other, extensive, memory safety efforts in mozilla::pkix, and we should
     373             :   // find a way to provide a more-obviously-safe interface.
     374             :   virtual Result DigestBuf(Input item,
     375             :                            DigestAlgorithm digestAlg,
     376             :                            /*out*/ uint8_t* digestBuf,
     377             :                            size_t digestBufLen) = 0;
     378             : protected:
     379          15 :   TrustDomain() { }
     380             : 
     381             :   TrustDomain(const TrustDomain&) = delete;
     382             :   void operator=(const TrustDomain&) = delete;
     383             : };
     384             : 
     385             : enum class FallBackToSearchWithinSubject { No = 0, Yes = 1 };
     386             : 
     387             : // Applications control the behavior of matching presented name information from
     388             : // a certificate against a reference hostname by implementing the
     389             : // NameMatchingPolicy interface. Used in concert with CheckCertHostname.
     390             : class NameMatchingPolicy
     391             : {
     392             : public:
     393           0 :   virtual ~NameMatchingPolicy() { }
     394             : 
     395             :   // Given that the certificate in question has a notBefore field with the given
     396             :   // value, should name matching fall back to searching within the subject
     397             :   // common name field?
     398             :   virtual Result FallBackToCommonName(
     399             :     Time notBefore,
     400             :     /*out*/ FallBackToSearchWithinSubject& fallBackToCommonName) = 0;
     401             : 
     402             : protected:
     403           0 :   NameMatchingPolicy() { }
     404             : 
     405             :   NameMatchingPolicy(const NameMatchingPolicy&) = delete;
     406             :   void operator=(const NameMatchingPolicy&) = delete;
     407             : };
     408             : 
     409             : } } // namespace mozilla::pkix
     410             : 
     411             : #endif // mozilla_pkix_pkixtypes_h

Generated by: LCOV version 1.13