Apply Upstream code (2021-03-15)
[platform/upstream/connectedhomeip.git] / src / credentials / CHIPCert.h
1 /*
2  *
3  *    Copyright (c) 2020-2021 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 <string.h>
31
32 #include <asn1/ASN1.h>
33 #include <core/CHIPConfig.h>
34 #include <core/CHIPTLV.h>
35 #include <crypto/CHIPCryptoPAL.h>
36 #include <support/BitFlags.h>
37 #include <support/DLLUtil.h>
38
39 namespace chip {
40 namespace Credentials {
41
42 static constexpr uint32_t kKeyIdentifierLength                 = 20;
43 static constexpr uint32_t kChipIdUTF8Length                    = 16;
44 static constexpr uint16_t kX509NoWellDefinedExpirationDateYear = 9999;
45
46 /** Data Element Tags for the CHIP Certificate
47  */
48 enum
49 {
50     // ---- Top-level Protocol-Specific Tags ----
51     kTag_ChipCertificate      = 1, /**< [ structure ] A CHIP certificate. */
52     kTag_ChipCertificateArray = 2, /**< [ array ] An array of CHIP certificates. */
53
54     // ---- Context-specific Tags for ChipCertificate Structure ----
55     kTag_SerialNumber            = 1,  /**< [ byte string ] Certificate serial number, in BER integer encoding. */
56     kTag_SignatureAlgorithm      = 2,  /**< [ unsigned int ] Enumerated value identifying the certificate signature algorithm. */
57     kTag_Issuer                  = 3,  /**< [ list ] The issuer distinguished name of the certificate. */
58     kTag_NotBefore               = 4,  /**< [ unsigned int ] Certificate validity period start (certificate date format). */
59     kTag_NotAfter                = 5,  /**< [ unsigned int ] Certificate validity period end (certificate date format). */
60     kTag_Subject                 = 6,  /**< [ list ] The subject distinguished name of the certificate. */
61     kTag_PublicKeyAlgorithm      = 7,  /**< [ unsigned int ] Identifies the algorithm with which the public key can be used. */
62     kTag_EllipticCurveIdentifier = 8,  /**< [ unsigned int ] For EC certs, identifies the elliptic curve used. */
63     kTag_EllipticCurvePublicKey  = 9,  /**< [ byte string ] The elliptic curve public key, in X9.62 encoded format. */
64     kTag_ECDSASignature          = 10, /**< [ structure ] The ECDSA signature for the certificate. */
65     // ---- Tags identifying certificate extensions (tag numbers 128 - 255) ----
66     kCertificateExtensionTagsStart = 128,
67     kTag_BasicConstraints          = 128, /**< [ structure ] Identifies whether the subject of the certificate is a CA. */
68     kTag_KeyUsage                  = 129, /**< [ unsigned int ] Bits identifying key usage, per RFC5280. */
69     kTag_ExtendedKeyUsage          = 130, /**< [ array ] Array of enumerated values giving the purposes for which
70                                              the public key can be used, per RFC5280. */
71     kTag_SubjectKeyIdentifier    = 131,   /**< [ byte string ] Identifier of the certificate's public key. */
72     kTag_AuthorityKeyIdentifier  = 132,   /**< [ byte string ] Identifier of the public key used to sign the certificate. */
73     kCertificateExtensionTagsEnd = 255,
74
75     // ---- Context-specific Tags for ECDSASignature Structure ----
76     kTag_ECDSASignature_r = 1, /**< [ byte string ] ECDSA r value, in ASN.1 integer encoding. */
77     kTag_ECDSASignature_s = 2, /**< [ byte string ] ECDSA s value, in ASN.1 integer encoding. */
78
79     // ---- Context-specific Tags for BasicConstraints Structure ----
80     kTag_BasicConstraints_IsCA = 1,              /**< [ boolean ] True if the certificate can be used to verify certificate
81                                                     signatures. */
82     kTag_BasicConstraints_PathLenConstraint = 2, /**< [ unsigned int ] Maximum number of subordinate intermediate certificates. */
83 };
84
85 /** Identifies the purpose or application of certificate
86  *
87  * A certificate type is a label that describes a certificate's purpose or application.
88  * Certificate types are not carried as attributes of the corresponding certificates, but
89  * rather are derived from the certificate's structure and/or the context in which it is used.
90  * The certificate type enumeration includes a set of pre-defined values describing commonly
91  * used certificate applications.  Developers can also extend the certificate type value
92  * range with application-specific types that described custom certificates or certificates
93  * with unique security properties.
94  *
95  * Certificate types are primarily used in the implementation of access control policies,
96  * where access to application features is influenced by the type of certificate presented
97  * by a requester.
98  *
99  * @note Cert type is an API data type only; it should never be sent over-the-wire.
100  */
101 enum
102 {
103     kCertType_NotSpecified    = 0x00, /**< The certificate's type has not been specified. */
104     kCertType_CA              = 0x01, /**< A CHIP CA certificate. */
105     kCertType_Node            = 0x02, /**< A CHIP node certificate. */
106     kCertType_FirmwareSigning = 0x03, /**< A CHIP firmware signing certificate. */
107     kCertType_AppDefinedBase  = 0x7F, /**< Application-specific certificate types should have values >= this value. */
108 };
109
110 /** X.509 Certificate Key Purpose Flags
111  *
112  *    The flags order must match the enumeration order of corresponding kOID_KeyPurpose values.
113  */
114 enum class KeyPurposeFlags : uint8_t
115 {
116     kServerAuth      = 0x01, /**< Extended key usage is server authentication. */
117     kClientAuth      = 0x02, /**< Extended key usage is client authentication. */
118     kCodeSigning     = 0x04, /**< Extended key usage is code signing. */
119     kEmailProtection = 0x08, /**< Extended key usage is email protection. */
120     kTimeStamping    = 0x10, /**< Extended key usage is time stamping. */
121     kOCSPSigning     = 0x20, /**< Extended key usage is OCSP signing. */
122 };
123
124 /** X.509 Certificate Key Usage Flags
125  */
126 enum class KeyUsageFlags : uint16_t
127 {
128     kDigitalSignature = 0x0001, /**< Key usage is digital signature. */
129     kNonRepudiation   = 0x0002, /**< Key usage is non-repudiation. */
130     kKeyEncipherment  = 0x0004, /**< Key usage is key encipherment. */
131     kDataEncipherment = 0x0008, /**< Key usage is data encipherment. */
132     kKeyAgreement     = 0x0010, /**< Key usage is key agreement. */
133     kKeyCertSign      = 0x0020, /**< Key usage is key cert signing. */
134     kCRLSign          = 0x0040, /**< Key usage is CRL signing. */
135     kEncipherOnly     = 0x0080, /**< Key usage is encipher only. */
136     kDecipherOnly     = 0x0100, /**< Key usage is decipher only. */
137 };
138
139 /** CHIP Certificate Flags
140  *
141  * Contains information about a certificate that has been loaded into a ChipCertificateData object.
142  */
143 enum class CertFlags : uint16_t
144 {
145     kExtPresent_BasicConstraints = 0x0001, /**< Basic constraints extension is present in the certificate. */
146     kExtPresent_KeyUsage         = 0x0002, /**< Key usage extension is present in the certificate. */
147     kExtPresent_ExtendedKeyUsage = 0x0004, /**< Extended key usage extension is present in the certificate. */
148     kExtPresent_SubjectKeyId     = 0x0008, /**< Subject key identifier extension is present in the certificate. */
149     kExtPresent_AuthKeyId        = 0x0010, /**< Authority key identifier extension is present in the certificate. */
150     kPathLenConstraintPresent    = 0x0020, /**< Path length constraint is present in the certificate. */
151     kIsCA                        = 0x0040, /**< Indicates that certificate is a CA certificate. */
152     kIsTrustAnchor               = 0x0080, /**< Indicates that certificate is a trust anchor. */
153     kTBSHashPresent              = 0x0100, /**< Indicates that TBS hash of the certificate was generated and stored. */
154 };
155
156 /** CHIP Certificate Decode Flags
157  *
158  * Contains information specifying how a certificate should be decoded.
159  */
160 enum class CertDecodeFlags : uint8_t
161 {
162     kGenerateTBSHash = 0x01, /**< Indicates that to-be-signed (TBS) hash of the certificate should be calculated when certificate is
163                                 loaded. The TBS hash is then used to validate certificate signature. Normally, all certificates
164                                 (except trust anchor) in the certificate validation chain require TBS hash. */
165     kIsTrustAnchor = 0x02,   /**< Indicates that the corresponding certificate is trust anchor. */
166 };
167
168 /** CHIP Certificate Validate Flags
169  *
170  * Contains information specifying how a certificate should be validated.
171  */
172 enum class CertValidateFlags : uint8_t
173 {
174     kIgnoreNotBefore = 0x01, /**< Indicate that a Not Before field should be ignored when doing certificate validation. This
175                                 flag applies to all certificates in the validation chain. */
176     kIgnoreNotAfter = 0x02,  /**< Indicate that a Not After field should be ignored when doing certificate validation. This
177                                 flag applies to all certificates in the validation chain. */
178 };
179
180 enum
181 {
182     kNullCertTime = 0
183 };
184
185 /**
186  *  @struct ChipDN
187  *
188  *  @brief
189  *    A data structure representing a Distinguished Name (DN) in a CHIP certificate.
190  */
191 struct ChipDN
192 {
193     union
194     {
195         uint64_t mChipId; /**< CHIP specific DN attribute value. */
196         struct
197         {
198             const uint8_t * mValue; /**< Pointer to the DN attribute value. */
199             uint32_t mLen;          /**< DN attribute length. */
200         } mString;                  /**< DN attribute structure when encoded as a string. */
201     } mAttrValue;                   /**< DN attribute value union: string or unsigned integer. */
202     chip::ASN1::OID mAttrOID;       /**< DN attribute CHIP OID. */
203
204     bool IsEqual(const ChipDN & other) const;
205     bool IsEmpty() const { return mAttrOID == chip::ASN1::kOID_NotSpecified; }
206     void Clear() { mAttrOID = chip::ASN1::kOID_NotSpecified; }
207 };
208
209 /**
210  *  @struct CertificateKeyId
211  *
212  *  @brief
213  *    A data structure representing a certificate key identifier.
214  */
215 struct CertificateKeyId
216 {
217     const uint8_t * mId; /**< Pointer to the key identifier. Encoded as Octet String and represented as the ASN.1 DER Integer (X.690
218                             standard). */
219     uint8_t mLen;        /**< Key identifier length. */
220
221     bool IsEqual(const CertificateKeyId & other) const;
222     bool IsEmpty() const { return mId == nullptr; }
223     void Clear() { mId = nullptr; }
224 };
225
226 /**
227  *  @struct ChipCertificateData
228  *
229  *  @brief
230  *    In-memory representation of data extracted from a CHIP certificate.
231  *
232  *    Some of the fields in this structure are pointers to the fields in the original
233  *    CHIP certificate. That CHIP certificate is stored in a separate buffer and it is
234  *    required that data in that buffer remains valid while the corresponding
235  *    ChipCertificateData structure is used.
236  */
237 struct ChipCertificateData
238 {
239     ChipCertificateData();
240     ~ChipCertificateData();
241
242     void Clear();
243
244     ChipDN mSubjectDN;                          /**< Certificate Subject DN. */
245     ChipDN mIssuerDN;                           /**< Certificate Issuer DN. */
246     CertificateKeyId mSubjectKeyId;             /**< Certificate Subject public key identifier. */
247     CertificateKeyId mAuthKeyId;                /**< Certificate Authority public key identifier. */
248     uint32_t mNotBeforeTime;                    /**< Certificate validity: Not Before field. */
249     uint32_t mNotAfterTime;                     /**< Certificate validity: Not After field. */
250     const uint8_t * mPublicKey;                 /**< Pointer to the certificate public key. */
251     uint8_t mPublicKeyLen;                      /**< Certificate public key length. */
252     uint16_t mPubKeyCurveOID;                   /**< Public key Elliptic Curve CHIP OID. */
253     uint16_t mPubKeyAlgoOID;                    /**< Public key algorithm CHIP OID. */
254     uint16_t mSigAlgoOID;                       /**< Certificate signature algorithm CHIP OID. */
255     BitFlags<CertFlags> mCertFlags;             /**< Certificate data flags. */
256     BitFlags<KeyUsageFlags> mKeyUsageFlags;     /**< Certificate key usage extensions flags. */
257     BitFlags<KeyPurposeFlags> mKeyPurposeFlags; /**< Certificate extended key usage extensions flags. */
258     uint8_t mPathLenConstraint;                 /**< Basic constraint: path length. */
259     uint8_t mCertType;                          /**< Certificate type. */
260     struct
261     {
262         const uint8_t * R; /**< Pointer to the R element of the signature, encoded as ASN.1 DER Integer. */
263         uint8_t RLen;      /**< Length of R. */
264         const uint8_t * S; /**< Pointer to the S element of the signature, encoded as ASN.1 DER Integer. */
265         uint8_t SLen;      /**< Length of R. */
266     } mSignature;          /**< Certificate signature structure. */
267     uint8_t mTBSHash[chip::Crypto::kSHA256_Hash_Length]; /**< Certificate TBS hash. */
268 };
269
270 /**
271  *  @struct ValidationContext
272  *
273  *  @brief
274  *    Context information used during certification validation.
275  */
276 struct ValidationContext
277 {
278     uint32_t mEffectiveTime;                        /**< Current CHIP Epoch UTC time. */
279     const ChipCertificateData * mTrustAnchor;       /**< Pointer to the Trust Anchor Certificate data structure. */
280     const ChipCertificateData * mSigningCert;       /**< Pointer to the Signing Certificate data structure. */
281     BitFlags<KeyUsageFlags> mRequiredKeyUsages;     /**< Key usage extensions that should be present in the
282                                                        validated certificate. */
283     BitFlags<KeyPurposeFlags> mRequiredKeyPurposes; /**< Extended Key usage extensions that should be present
284                                                        in the validated certificate. */
285     BitFlags<CertValidateFlags> mValidateFlags;     /**< Certificate validation flags, specifying how a certificate
286                                                        should be validated. */
287     uint8_t mRequiredCertType;                      /**< Required certificate type. */
288
289     void Reset();
290 };
291
292 /**
293  *  @class ChipCertificateSet
294  *
295  *  @brief
296  *    Collection of CHIP certificate data providing methods for
297  *    certificate validation and signature verification.
298  */
299 class DLL_EXPORT ChipCertificateSet
300 {
301 public:
302     ChipCertificateSet();
303     ~ChipCertificateSet();
304
305     /**
306      * @brief Initialize ChipCertificateSet.
307      *        This initialization method is used when all memory structures needed for operation are
308      *        allocated internally using chip::Platform::MemoryAlloc() and freed with chip::Platform::MemoryFree().
309      *
310      * @param maxCertsArraySize  Maximum number of CHIP certificates to be loaded to the set.
311      * @param decodeBufSize      Size of the buffer that should be allocated to perform CHIP certificate decoding.
312      *
313      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
314      **/
315     CHIP_ERROR Init(uint8_t maxCertsArraySize, uint16_t decodeBufSize);
316
317     /**
318      * @brief Initialize ChipCertificateSet.
319      *        This initialization method is used when all memory structures needed for operation are
320      *        allocated externally and methods in this class don't need to deal with memory allocations.
321      *
322      * @param certsArray      A pointer to the array of the ChipCertificateData structures.
323      * @param certsArraySize  Number of ChipCertificateData entries in the array.
324      * @param decodeBuf       Buffer to use for temporary storage of intermediate processing results.
325      * @param decodeBufSize   Size of decoding buffer.
326      *
327      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
328      **/
329     CHIP_ERROR Init(ChipCertificateData * certsArray, uint8_t certsArraySize, uint8_t * decodeBuf, uint16_t decodeBufSize);
330
331     /**
332      * @brief Release resources allocated by this class.
333      **/
334     void Release();
335
336     /**
337      * @brief Clear certificate data loaded into this set.
338      **/
339     void Clear();
340
341     /**
342      * @brief Load CHIP certificate into set.
343      *        It is required that the CHIP certificate in the chipCert buffer stays valid while
344      *        the certificate data in the set is used.
345      *        In case of an error the certificate set is left in the same state as prior to this call.
346      *
347      * @param chipCert     Buffer containing certificate encoded in CHIP format.
348      * @param chipCertLen  The length of the certificate buffer.
349      * @param decodeFlags  Certificate decoding option flags.
350      *
351      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
352      **/
353     CHIP_ERROR LoadCert(const uint8_t * chipCert, uint32_t chipCertLen, BitFlags<CertDecodeFlags> decodeFlags);
354
355     /**
356      * @brief Load CHIP certificate into set.
357      *        It is required that the CHIP certificate in the reader's underlying buffer stays valid while
358      *        the certificate data in the set is used.
359      *        In case of an error the certificate set is left in the same state as prior to this call.
360      *
361      * @param reader       A TLVReader positioned at the CHIP certificate TLV structure.
362      * @param decodeFlags  Certificate decoding option flags.
363      *
364      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
365      **/
366     CHIP_ERROR LoadCert(chip::TLV::TLVReader & reader, BitFlags<CertDecodeFlags> decodeFlags);
367
368     /**
369      * @brief Load CHIP certificates into set.
370      *        It is required that the CHIP certificates in the chipCerts buffer stays valid while
371      *        the certificates data in the set is used.
372      *        In case of an error the certificate set is left in the same state as prior to this call.
373      *
374      * @param chipCerts     Buffer containing array of certificates or a single certificate encoded in CHIP TLV form.
375      * @param chipCertsLen  The length of the certificates buffer.
376      * @param decodeFlags   Certificate decoding option flags.
377      *
378      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
379      **/
380     CHIP_ERROR LoadCerts(const uint8_t * chipCerts, uint32_t chipCertsLen, BitFlags<CertDecodeFlags> decodeFlags);
381
382     /**
383      * @brief Load CHIP certificates into set.
384      *        It is required that the CHIP certificates in the reader's underlying buffer stays valid while
385      *        the certificates data in the set is used.
386      *        In case of an error the certificate set is left in the same state as prior to this call.
387      *
388      * @param reader       A TLVReader positioned at the CHIP certificates TLV array
389      *                     or TLV structure for a single certificate.
390      * @param decodeFlags  Certificate decoding option flags.
391      *
392      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
393      **/
394     CHIP_ERROR LoadCerts(chip::TLV::TLVReader & reader, BitFlags<CertDecodeFlags> decodeFlags);
395
396     /**
397      * @brief Add trusted anchor key to the certificate set.
398      *        It is required that the public key and public key Id in the pubKey and pubKeyId buffers
399      *        stay valid while the certificate set is used.
400      *        In case of an error the certificate set is left in the same state as prior to this call.
401      *
402      * @param caId         CA certificate CHIP identifier.
403      * @param curveOID     Elliptic curve CHIP OID.
404      * @param pubKey       Trusted public key.
405      * @param pubKeyLen    The length of the trusted public key.
406      * @param pubKeyId     Trusted public key identifier.
407      * @param pubKeyIdLen  The length of the trusted public key identifier.
408      *
409      * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
410      **/
411     CHIP_ERROR AddTrustedKey(uint64_t caId, chip::ASN1::OID curveOID, const uint8_t * pubKey, uint8_t pubKeyLen,
412                              const uint8_t * pubKeyId, uint8_t pubKeyIdLen);
413
414     /**
415      * @brief Find certificate in the set.
416      *
417      * @param subjectKeyId  Subject key identifier of the certificate to be found in the set.
418      *
419      * @return A pointer to the certificate data On success. Otherwise, NULL if no certificate found.
420      **/
421     const ChipCertificateData * FindCert(const CertificateKeyId & subjectKeyId) const;
422
423     /**
424      * @return A pointer to the set of certificate data entries.
425      **/
426     const ChipCertificateData * GetCertSet() const { return mCerts; }
427
428     /**
429      * @return A pointer to the last certificate data in the set. Returns NULL if certificate set is empty.
430      **/
431     const ChipCertificateData * GetLastCert() const { return (mCertCount > 0) ? &mCerts[mCertCount - 1] : nullptr; }
432
433     /**
434      * @return Number of certificates loaded into the set.
435      **/
436     uint8_t GetCertCount() const { return mCertCount; }
437
438     /**
439      * @brief Check whether certificate is in the set.
440      *
441      * @param cert  Pointer to the ChipCertificateData structures.
442      *
443      * @return True if certificate is in the set, false otherwise.
444      **/
445     bool IsCertInTheSet(const ChipCertificateData * cert) const;
446
447     /**
448      * @brief Validate CHIP certificate.
449      *
450      * @param cert     Pointer to the CHIP certificiate to be validated. The certificate is
451      *                 required to be in this set, otherwise this function returns error.
452      * @param context  Certificate validation context.
453      *
454      * @return Returns a CHIP_ERROR on validation or other error, CHIP_NO_ERROR otherwise
455      **/
456     CHIP_ERROR ValidateCert(const ChipCertificateData * cert, ValidationContext & context);
457
458     /**
459      * @brief Find and validate CHIP certificate.
460      *
461      * @param subjectDN     Subject distinguished name to use as certificate search parameter.
462      * @param subjectKeyId  Subject key identifier to use as certificate search parameter.
463      * @param context       Certificate validation context.
464      * @param cert          A pointer to the valid CHIP certificate that matches search criteria.
465      *
466      * @return Returns a CHIP_ERROR on validation or other error, CHIP_NO_ERROR otherwise
467      **/
468     CHIP_ERROR FindValidCert(const ChipDN & subjectDN, const CertificateKeyId & subjectKeyId, ValidationContext & context,
469                              ChipCertificateData *& cert);
470
471     /**
472      * @brief Verify CHIP certificate signature.
473      *
474      * @param cert    Pointer to the CHIP certificiate which signature should be validated.
475      * @param caCert  Pointer to the CA certificate of the verified certificate.
476      *
477      * @return Returns a CHIP_ERROR on validation or other error, CHIP_NO_ERROR otherwise
478      **/
479     static CHIP_ERROR VerifySignature(const ChipCertificateData * cert, const ChipCertificateData * caCert);
480
481 private:
482     ChipCertificateData * mCerts; /**< Pointer to an array of certificate data. */
483     uint8_t mCertCount;           /**< Number of certificates in mCerts
484                                      array. We maintain the invariant that all
485                                      the slots at indices less than
486                                      mCertCount have been constructed and slots
487                                      at indices >= mCertCount have either never
488                                      had their constructor called, or have had
489                                      their destructor called since then. */
490     uint8_t mMaxCerts;            /**< Length of mCerts array. */
491     uint8_t * mDecodeBuf;         /**< Certificate decode buffer. */
492     uint16_t mDecodeBufSize;      /**< Certificate decode buffer size. */
493     bool mMemoryAllocInternal;    /**< Indicates whether temporary memory buffers are allocated internally. */
494
495     /**
496      * @brief Find and validate CHIP certificate.
497      *
498      * @param subjectDN      Subject distinguished name to use as certificate search parameter.
499      * @param subjectKeyId   Subject key identifier to use as certificate search parameter.
500      * @param context        Certificate validation context.
501      * @param validateFlags  Certificate validation flags.
502      * @param depth          Depth of the current certificate in the certificate validation chain.
503      * @param cert           A pointer to the valid CHIP certificate that matches search criteria.
504      *
505      * @return Returns a CHIP_ERROR on validation or other error, CHIP_NO_ERROR otherwise
506      **/
507     CHIP_ERROR FindValidCert(const ChipDN & subjectDN, const CertificateKeyId & subjectKeyId, ValidationContext & context,
508                              BitFlags<CertValidateFlags> validateFlags, uint8_t depth, ChipCertificateData *& cert);
509
510     /**
511      * @brief Validate CHIP certificate.
512      *
513      * @param cert           Pointer to the CHIP certificiate to be validated.
514      * @param context        Certificate validation context.
515      * @param validateFlags  Certificate validation flags.
516      * @param depth          Depth of the current certificate in the certificate validation chain.
517      *
518      * @return Returns a CHIP_ERROR on validation or other error, CHIP_NO_ERROR otherwise
519      **/
520     CHIP_ERROR ValidateCert(const ChipCertificateData * cert, ValidationContext & context,
521                             BitFlags<CertValidateFlags> validateFlags, uint8_t depth);
522 };
523
524 /**
525  * @brief Decode CHIP certificate.
526  *        It is required that the CHIP certificate in the chipCert buffer stays valid while
527  *        the certData is used.
528  *
529  * @param chipCert     Buffer containing CHIP certificate.
530  * @param chipCertLen  The length of the CHIP certificate.
531  * @param certData     Structure containing data extracted from the CHIP certificate.
532  *
533  * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
534  **/
535 CHIP_ERROR DecodeChipCert(const uint8_t * chipCert, uint32_t chipCertLen, ChipCertificateData & certData);
536
537 /**
538  * @brief Decode CHIP certificate.
539  *        It is required that the CHIP certificate in the reader's underlying buffer stays valid while
540  *        the certData is used.
541  *
542  * @param reader    A TLVReader positioned at the CHIP certificate TLV structure.
543  * @param certData  Structure containing data extracted from the CHIP certificate.
544  *
545  * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
546  **/
547 CHIP_ERROR DecodeChipCert(chip::TLV::TLVReader & reader, ChipCertificateData & certData);
548
549 /**
550  * @brief Decode CHIP Distinguished Name (DN).
551  *        It is required that the CHIP DN in the reader's underlying buffer stays valid while
552  *        the dn structure is used.
553  *
554  * @param reader  A TLVReader positioned at the CHIP DN TLV structure.
555  * @param dn      Distinguished Name structure.
556  *
557  * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
558  **/
559 CHIP_ERROR DecodeChipDN(chip::TLV::TLVReader & reader, ChipDN & dn);
560
561 /**
562  * @brief Convert standard X.509 certificate to CHIP certificate.
563  *
564  * @param x509Cert        Buffer containing X.509 DER encoded certificate.
565  * @param x509CertLen     The length of the X.509 DER encoded certificate.
566  * @param chipCertBuf     Buffer to store converted certificate in CHIP format.
567  * @param chipCertBufSize The size of the buffer to store converted certificate.
568  * @param chipCertLen     The length of the converted certificate.
569  *
570  * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
571  **/
572 CHIP_ERROR ConvertX509CertToChipCert(const uint8_t * x509Cert, uint32_t x509CertLen, uint8_t * chipCertBuf,
573                                      uint32_t chipCertBufSize, uint32_t & chipCertLen);
574
575 /**
576  * @brief Convert CHIP certificate to the standard X.509 DER encoded certificate.
577  *
578  * @param chipCert        Buffer containing CHIP certificate.
579  * @param chipCertLen     The length of the CHIP certificate.
580  * @param x509CertBuf     Buffer to store converted certificate in X.509 DER format.
581  * @param x509CertBufSize The size of the buffer to store converted certificate.
582  * @param x509CertLen     The length of the converted certificate.
583  *
584  * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
585  **/
586 CHIP_ERROR ConvertChipCertToX509Cert(const uint8_t * chipCert, uint32_t chipCertLen, uint8_t * x509CertBuf,
587                                      uint32_t x509CertBufSize, uint32_t & x509CertLen);
588
589 /**
590  * Determine type of a CHIP certificate.
591  *
592  * This function performs an assessment of a certificate's type and sets cert.mCertType value
593  * based on the structure of its subject DN and the extensions present. Applications are free
594  * to override this assessment by setting cert.mCertType to another value, including an
595  * application-defined one.
596  *
597  * In general, applications will only trust a peer's certificate if it chains to a trusted
598  * root certificate.  However, the type assigned to a certificate can influence the *nature*
599  * of this trust, e.g. to allow or disallow access to certain features.  Because of this,
600  * changes to this algorithm can have VERY SIGNIFICANT and POTENTIALLY CATASTROPHIC effects
601  * on overall system security, and should not be made without a thorough understanding of
602  * the implications.
603  **/
604 CHIP_ERROR DetermineCertType(ChipCertificateData & cert);
605
606 /**
607  * @brief
608  *   Convert a certificate date/time (in the form of an ASN.1 universal time structure) into a CHIP Epoch UTC time.
609  *
610  * @note
611  *   This function makes no attempt to verify the correct range of the input time other than year.
612  *   Therefore callers must make sure the supplied values are valid prior to invocation.
613  *
614  * @param asn1Time   The calendar date/time to be converted.
615  * @param epochTime  A reference to an integer that will receive CHIP Epoch UTC time.
616  *
617  * @retval  #CHIP_NO_ERROR                      If the input time was successfully converted.
618  * @retval  #ASN1_ERROR_UNSUPPORTED_ENCODING    If the input time contained a year value that could not
619  *                                              be represented in a CHIP epoch UTC time value.
620  **/
621 CHIP_ERROR ASN1ToChipEpochTime(const chip::ASN1::ASN1UniversalTime & asn1Time, uint32_t & epochTime);
622
623 /**
624  * @brief
625  *   Convert a CHIP epoch UTC time into an ASN.1 universal time structure.
626  *
627  * @param epochTime  A CHIP epoch UTC time to be converted.
628  * @param asn1Time   A reference to an ASN1UniversalTime structure to receive the date/time.
629  *
630  * @retval  #CHIP_NO_ERROR                      If the input time was successfully converted.
631  */
632 CHIP_ERROR ChipEpochToASN1Time(uint32_t epochTime, chip::ASN1::ASN1UniversalTime & asn1Time);
633
634 /**
635  *  @return  True if the OID represents a CHIP-defined X.509 distinguished named attribute.
636  **/
637 inline bool IsChipX509Attr(chip::ASN1::OID oid)
638 {
639     return (oid == chip::ASN1::kOID_AttributeType_ChipNodeId || oid == chip::ASN1::kOID_AttributeType_ChipCAId ||
640             oid == chip::ASN1::kOID_AttributeType_ChipSoftwarePublisherId || oid == chip::ASN1::kOID_AttributeType_ChipFabricId);
641 }
642
643 /**
644  *  @return  True if the OID represents a CHIP-defined X.509 distinguished named attribute
645  *           that contains a 64-bit CHIP id.
646  **/
647 inline bool IsChipIdX509Attr(chip::ASN1::OID oid)
648 {
649     return (oid == chip::ASN1::kOID_AttributeType_ChipNodeId || oid == chip::ASN1::kOID_AttributeType_ChipCAId ||
650             oid == chip::ASN1::kOID_AttributeType_ChipSoftwarePublisherId);
651 }
652
653 } // namespace Credentials
654 } // namespace chip