LCOV - code coverage report
Current view: top level - credentials - CHIPCertificateSet.h (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 11 13 84.6 %
Date: 2024-02-15 08:20:41 Functions: 5 7 71.4 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  *    Copyright (c) 2020-2022 Project CHIP Authors
       4             :  *    Copyright (c) 2019 Google LLC.
       5             :  *    Copyright (c) 2013-2017 Nest Labs, Inc.
       6             :  *    All rights reserved.
       7             :  *
       8             :  *    Licensed under the Apache License, Version 2.0 (the "License");
       9             :  *    you may not use this file except in compliance with the License.
      10             :  *    You may obtain a copy of the License at
      11             :  *
      12             :  *        http://www.apache.org/licenses/LICENSE-2.0
      13             :  *
      14             :  *    Unless required by applicable law or agreed to in writing, software
      15             :  *    distributed under the License is distributed on an "AS IS" BASIS,
      16             :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      17             :  *    See the License for the specific language governing permissions and
      18             :  *    limitations under the License.
      19             :  */
      20             : 
      21             : /**
      22             :  *    @file
      23             :  *      This file defines data types and objects for modeling and
      24             :  *      working with CHIP certificates.
      25             :  *
      26             :  */
      27             : 
      28             : #pragma once
      29             : 
      30             : #include <cstdint>
      31             : #include <string.h>
      32             : 
      33             : #include "CHIPCert.h"
      34             : #include "CertificateValidityPolicy.h"
      35             : #include <lib/support/Variant.h>
      36             : 
      37             : namespace chip {
      38             : namespace Credentials {
      39             : 
      40             : struct CurrentChipEpochTime : chip::System::Clock::Seconds32
      41             : {
      42             :     template <typename... Args>
      43          14 :     CurrentChipEpochTime(Args &&... args) : chip::System::Clock::Seconds32(std::forward<Args>(args)...)
      44          14 :     {}
      45             : };
      46             : 
      47             : struct LastKnownGoodChipEpochTime : chip::System::Clock::Seconds32
      48             : {
      49             :     template <typename... Args>
      50           0 :     LastKnownGoodChipEpochTime(Args &&... args) : chip::System::Clock::Seconds32(std::forward<Args>(args)...)
      51           0 :     {}
      52             : };
      53             : 
      54             : using EffectiveTime = Variant<CurrentChipEpochTime, LastKnownGoodChipEpochTime>;
      55             : 
      56             : /**
      57             :  *  @struct ValidationContext
      58             :  *
      59             :  *  @brief
      60             :  *    Context information used during certification validation.
      61             :  */
      62             : struct ValidationContext
      63             : {
      64             :     EffectiveTime mEffectiveTime;                   /**< Current or last known good CHIP Epoch time. */
      65             :     const ChipCertificateData * mTrustAnchor;       /**< Pointer to the Trust Anchor Certificate data structure.
      66             :                                                        This value is set during certificate validation process
      67             :                                                        to indicate to the caller the trust anchor of the
      68             :                                                        validated certificate. */
      69             :     BitFlags<KeyUsageFlags> mRequiredKeyUsages;     /**< Key usage extensions that should be present in the
      70             :                                                        validated certificate. */
      71             :     BitFlags<KeyPurposeFlags> mRequiredKeyPurposes; /**< Extended Key usage extensions that should be present
      72             :                                                        in the validated certificate. */
      73             :     CertType mRequiredCertType;                     /**< Required certificate type. */
      74             : 
      75             :     CertificateValidityPolicy * mValidityPolicy =
      76             :         nullptr; /**< Optional application policy to apply for certificate validity period evaluation. */
      77             : 
      78             :     void Reset();
      79             : 
      80             :     template <typename T>
      81          14 :     void SetEffectiveTime(chip::System::Clock::Seconds32 chipTime)
      82             :     {
      83          14 :         mEffectiveTime.Set<T>(chipTime);
      84          14 :     }
      85             : 
      86             :     template <typename T>
      87          14 :     CHIP_ERROR SetEffectiveTimeFromUnixTime(chip::System::Clock::Seconds32 unixTime)
      88             :     {
      89             :         uint32_t chipTime;
      90          14 :         VerifyOrReturnError(UnixEpochToChipEpochTime(unixTime.count(), chipTime), CHIP_ERROR_INVALID_TIME);
      91          14 :         SetEffectiveTime<T>(chip::System::Clock::Seconds32(chipTime));
      92          14 :         return CHIP_NO_ERROR;
      93             :     }
      94             : 
      95             :     template <typename T>
      96             :     CHIP_ERROR SetEffectiveTimeFromAsn1Time(const ASN1::ASN1UniversalTime & asn1Time)
      97             :     {
      98             :         uint32_t chipTime;
      99             :         ReturnErrorOnFailure(ASN1ToChipEpochTime(asn1Time, chipTime));
     100             :         SetEffectiveTime<T>(chip::System::Clock::Seconds32(chipTime));
     101             :         return CHIP_NO_ERROR;
     102             :     }
     103             : };
     104             : 
     105             : /**
     106             :  *  @class ChipCertificateSet
     107             :  *
     108             :  *  @brief
     109             :  *    Collection of CHIP certificate data providing methods for
     110             :  *    certificate validation and signature verification.
     111             :  */
     112             : class DLL_EXPORT ChipCertificateSet
     113             : {
     114             : public:
     115             :     ChipCertificateSet();
     116             :     ~ChipCertificateSet();
     117             : 
     118             :     ChipCertificateSet & operator=(ChipCertificateSet && aOther)
     119             :     {
     120             :         mCerts               = aOther.mCerts;
     121             :         aOther.mCerts        = nullptr;
     122             :         mCertCount           = aOther.mCertCount;
     123             :         mMaxCerts            = aOther.mMaxCerts;
     124             :         mMemoryAllocInternal = aOther.mMemoryAllocInternal;
     125             : 
     126             :         return *this;
     127             :     }
     128             : 
     129             :     /**
     130             :      * @brief Initialize ChipCertificateSet.
     131             :      *        This initialization method is used when all memory structures needed for operation are
     132             :      *        allocated internally using chip::Platform::MemoryAlloc() and freed with chip::Platform::MemoryFree().
     133             :      *
     134             :      * @param maxCertsArraySize  Maximum number of CHIP certificates to be loaded to the set.
     135             :      *
     136             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     137             :      **/
     138             :     CHIP_ERROR Init(uint8_t maxCertsArraySize);
     139             : 
     140             :     /**
     141             :      * @brief Initialize ChipCertificateSet.
     142             :      *        This initialization method is used when all memory structures needed for operation are
     143             :      *        allocated externally and methods in this class don't need to deal with memory allocations.
     144             :      *
     145             :      * @param certsArray      A pointer to the array of the ChipCertificateData structures.
     146             :      * @param certsArraySize  Number of ChipCertificateData entries in the array.
     147             :      *
     148             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     149             :      **/
     150             :     CHIP_ERROR Init(ChipCertificateData * certsArray, uint8_t certsArraySize);
     151             : 
     152             :     /**
     153             :      * @brief Release resources allocated by this class.
     154             :      **/
     155             :     void Release();
     156             : 
     157             :     /**
     158             :      * @brief Clear certificate data loaded into this set.
     159             :      **/
     160             :     void Clear();
     161             : 
     162             :     /**
     163             :      * @brief Load CHIP certificate into set.
     164             :      *        It is required that the CHIP certificate in the chipCert buffer stays valid while
     165             :      *        the certificate data in the set is used.
     166             :      *        In case of an error the certificate set is left in the same state as prior to this call.
     167             :      *
     168             :      * @param chipCert     Buffer containing certificate encoded in CHIP format.
     169             :      * @param decodeFlags  Certificate decoding option flags.
     170             :      *
     171             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     172             :      **/
     173             :     CHIP_ERROR LoadCert(const ByteSpan chipCert, BitFlags<CertDecodeFlags> decodeFlags);
     174             : 
     175             :     /**
     176             :      * @brief Load CHIP certificate into set.
     177             :      *        It is required that the CHIP certificate in the reader's underlying buffer stays valid while
     178             :      *        the certificate data in the set is used.
     179             :      *        In case of an error the certificate set is left in the same state as prior to this call.
     180             :      *
     181             :      * @param reader       A TLVReader positioned at the CHIP certificate TLV structure.
     182             :      * @param decodeFlags  Certificate decoding option flags.
     183             :      * @param chipCert     Buffer containing certificate encoded on CHIP format. It is required that this CHIP certificate
     184             :      *                     in chipCert ByteSpan stays valid while the certificate data in the set is used.
     185             :      *
     186             :      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
     187             :      **/
     188             :     CHIP_ERROR LoadCert(chip::TLV::TLVReader & reader, BitFlags<CertDecodeFlags> decodeFlags, ByteSpan chipCert = ByteSpan());
     189             : 
     190             :     CHIP_ERROR ReleaseLastCert();
     191             : 
     192             :     /**
     193             :      * @brief Find certificate in the set.
     194             :      *
     195             :      * @param subjectKeyId  Subject key identifier of the certificate to be found in the set.
     196             :      *
     197             :      * @return A pointer to the certificate data On success. Otherwise, NULL if no certificate found.
     198             :      **/
     199             :     const ChipCertificateData * FindCert(const CertificateKeyId & subjectKeyId) const;
     200             : 
     201             :     /**
     202             :      * @return A pointer to the set of certificate data entries.
     203             :      **/
     204        1833 :     const ChipCertificateData * GetCertSet() const { return mCerts; }
     205             : 
     206             :     /**
     207             :      * @return A pointer to the last certificate data in the set. Returns NULL if certificate set is empty.
     208             :      **/
     209        2380 :     const ChipCertificateData * GetLastCert() const { return (mCertCount > 0) ? &mCerts[mCertCount - 1] : nullptr; }
     210             : 
     211             :     /**
     212             :      * @return Number of certificates loaded into the set.
     213             :      **/
     214             :     uint8_t GetCertCount() const { return mCertCount; }
     215             : 
     216             :     /**
     217             :      * @brief Check whether certificate is in the set.
     218             :      *
     219             :      * @param cert  Pointer to the ChipCertificateData structures.
     220             :      *
     221             :      * @return True if certificate is in the set, false otherwise.
     222             :      **/
     223             :     bool IsCertInTheSet(const ChipCertificateData * cert) const;
     224             : 
     225             :     /**
     226             :      * @brief Validate CHIP certificate.
     227             :      *
     228             :      * @param cert     Pointer to the CHIP certificate to be validated. The certificate is
     229             :      *                 required to be in this set, otherwise this function returns error.
     230             :      * @param context  Certificate validation context.
     231             :      *
     232             :      * @return Returns a CHIP_ERROR on validation or other error, CHIP_NO_ERROR otherwise
     233             :      **/
     234             :     CHIP_ERROR ValidateCert(const ChipCertificateData * cert, ValidationContext & context);
     235             : 
     236             :     /**
     237             :      * @brief Find and validate CHIP certificate.
     238             :      *
     239             :      * @param[in]  subjectDN     Subject distinguished name to use as certificate search parameter.
     240             :      * @param[in]  subjectKeyId  Subject key identifier to use as certificate search parameter.
     241             :      * @param[in]  context       Certificate validation context.
     242             :      * @param[out] certData      A slot to write a pointer to the CHIP certificate data that matches search criteria.
     243             :      *
     244             :      * @return Returns a CHIP_ERROR on validation or other error, CHIP_NO_ERROR otherwise
     245             :      **/
     246             :     CHIP_ERROR FindValidCert(const ChipDN & subjectDN, const CertificateKeyId & subjectKeyId, ValidationContext & context,
     247             :                              const ChipCertificateData ** certData);
     248             : 
     249             :     // Deprecated, use the equivalent free function VerifyCertSignature()
     250             :     static CHIP_ERROR VerifySignature(const ChipCertificateData * cert, const ChipCertificateData * caCert);
     251             : 
     252             : private:
     253             :     ChipCertificateData * mCerts; /**< Pointer to an array of certificate data. */
     254             :     uint8_t mCertCount;           /**< Number of certificates in mCerts
     255             :                                      array. We maintain the invariant that all
     256             :                                      the slots at indices less than
     257             :                                      mCertCount have been constructed and slots
     258             :                                      at indices >= mCertCount have either never
     259             :                                      had their constructor called, or have had
     260             :                                      their destructor called since then. */
     261             :     uint8_t mMaxCerts;            /**< Length of mCerts array. */
     262             :     bool mMemoryAllocInternal;    /**< Indicates whether temporary memory buffers are allocated internally. */
     263             : 
     264             :     /**
     265             :      * @brief Find and validate CHIP certificate.
     266             :      *
     267             :      * @param[in]  subjectDN      Subject distinguished name to use as certificate search parameter.
     268             :      * @param[in]  subjectKeyId   Subject key identifier to use as certificate search parameter.
     269             :      * @param[in]  context        Certificate validation context.
     270             :      * @param[in]  depth          Depth of the current certificate in the certificate validation chain.
     271             :      * @param[out] certData       A slot to write a pointer to the CHIP certificate data that matches search criteria.
     272             :      *
     273             :      * @return Returns a CHIP_ERROR on validation or other error, CHIP_NO_ERROR otherwise
     274             :      **/
     275             :     CHIP_ERROR FindValidCert(const ChipDN & subjectDN, const CertificateKeyId & subjectKeyId, ValidationContext & context,
     276             :                              uint8_t depth, const ChipCertificateData ** certData);
     277             : 
     278             :     /**
     279             :      * @brief Validate CHIP certificate.
     280             :      *
     281             :      * @param cert           Pointer to the CHIP certificate to be validated.
     282             :      * @param context        Certificate validation context.
     283             :      * @param depth          Depth of the current certificate in the certificate validation chain.
     284             :      *
     285             :      * @return Returns a CHIP_ERROR on validation or other error, CHIP_NO_ERROR otherwise
     286             :      **/
     287             :     CHIP_ERROR ValidateCert(const ChipCertificateData * cert, ValidationContext & context, uint8_t depth);
     288             : };
     289             : 
     290             : } // namespace Credentials
     291             : } // namespace chip

Generated by: LCOV version 1.14