blob: f0b78df9ea2ec7aaf91c294f47d2253a301e3422 [file] [log] [blame]
Evgeny Margolis53538582021-01-12 09:14:24 -08001/*
2 *
Evgeny Margolis20c1f602022-01-26 06:09:18 -08003 * Copyright (c) 2020-2022 Project CHIP Authors
Evgeny Margolis53538582021-01-12 09:14:24 -08004 * 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
Zang MingJie53dd5832021-09-03 03:05:16 +080030#include <cstdint>
Evgeny Margolis53538582021-01-12 09:14:24 -080031#include <string.h>
32
Evgeny Margolis53538582021-01-12 09:14:24 -080033#include <crypto/CHIPCryptoPAL.h>
Zang MingJie53dd5832021-09-03 03:05:16 +080034#include <lib/asn1/ASN1.h>
Evgeny Margolised367ec2021-12-13 12:31:04 -080035#include <lib/core/CASEAuthTag.h>
Zang MingJie53dd5832021-09-03 03:05:16 +080036#include <lib/core/CHIPConfig.h>
Evgeny Margolisea87cc62021-11-29 22:08:00 -080037#include <lib/core/DataModelTypes.h>
Boris Zbarsky8af99812021-07-15 01:58:05 -040038#include <lib/core/PeerId.h>
Martin Turon82bfcd52023-01-09 13:30:38 -080039#include <lib/core/TLV.h>
Zang MingJie53dd5832021-09-03 03:05:16 +080040#include <lib/support/BitFlags.h>
41#include <lib/support/DLLUtil.h>
42#include <lib/support/Span.h>
Evgeny Margolis53538582021-01-12 09:14:24 -080043
44namespace chip {
45namespace Credentials {
46
Tennessee Carmel-Veilleuxab5734c2021-11-27 12:08:31 -050047static constexpr uint32_t kKeyIdentifierLength = static_cast<uint32_t>(Crypto::kSubjectKeyIdentifierLength);
Evgeny Margolis7d334762021-04-14 09:25:47 -070048static constexpr uint32_t kChip32bitAttrUTF8Length = 8;
49static constexpr uint32_t kChip64bitAttrUTF8Length = 16;
Evgeny Margolisfbc95962021-02-17 10:23:44 -080050static constexpr uint16_t kX509NoWellDefinedExpirationDateYear = 9999;
Evgeny Margolisac22f1b2021-02-10 11:30:02 -080051
Evgeny Margolis08b56502021-06-30 21:34:42 -070052// As per specifications (6.3.5. Node Operational Credentials Certificates)
Pankaj Gargda453462021-06-22 19:53:34 -070053static constexpr uint32_t kMaxCHIPCertLength = 400;
Evgeny Margolis08b56502021-06-30 21:34:42 -070054static constexpr uint32_t kMaxDERCertLength = 600;
Pankaj Gargda453462021-06-22 19:53:34 -070055
Evgeny Margolis2f03d3a2021-07-03 07:08:23 -070056// The decode buffer is used to reconstruct TBS section of X.509 certificate, which doesn't include signature.
Tennessee Carmel-Veilleux51a49a92021-07-14 16:05:06 -040057static constexpr uint32_t kMaxCHIPCertDecodeBufLength = kMaxDERCertLength - Crypto::kMax_ECDSA_Signature_Length_Der;
Evgeny Margolis2f03d3a2021-07-03 07:08:23 -070058
Evgeny Margolis53538582021-01-12 09:14:24 -080059/** Data Element Tags for the CHIP Certificate
60 */
61enum
62{
Evgeny Margolis53538582021-01-12 09:14:24 -080063 // ---- Context-specific Tags for ChipCertificate Structure ----
64 kTag_SerialNumber = 1, /**< [ byte string ] Certificate serial number, in BER integer encoding. */
65 kTag_SignatureAlgorithm = 2, /**< [ unsigned int ] Enumerated value identifying the certificate signature algorithm. */
66 kTag_Issuer = 3, /**< [ list ] The issuer distinguished name of the certificate. */
67 kTag_NotBefore = 4, /**< [ unsigned int ] Certificate validity period start (certificate date format). */
68 kTag_NotAfter = 5, /**< [ unsigned int ] Certificate validity period end (certificate date format). */
69 kTag_Subject = 6, /**< [ list ] The subject distinguished name of the certificate. */
70 kTag_PublicKeyAlgorithm = 7, /**< [ unsigned int ] Identifies the algorithm with which the public key can be used. */
71 kTag_EllipticCurveIdentifier = 8, /**< [ unsigned int ] For EC certs, identifies the elliptic curve used. */
72 kTag_EllipticCurvePublicKey = 9, /**< [ byte string ] The elliptic curve public key, in X9.62 encoded format. */
Evgeny Margolise09e11b2021-04-19 10:57:13 -070073 kTag_Extensions = 10, /**< [ list ] Certificate extensions. */
Evgeny Margolis85eb6042021-06-08 10:39:09 -070074 kTag_ECDSASignature = 11, /**< [ byte string ] The ECDSA signature for the certificate. */
Evgeny Margolise09e11b2021-04-19 10:57:13 -070075
76 // ---- Context-specific Tags for certificate extensions ----
77 kTag_BasicConstraints = 1, /**< [ structure ] Identifies whether the subject of the certificate is a CA. */
78 kTag_KeyUsage = 2, /**< [ unsigned int ] Bits identifying key usage, per RFC5280. */
79 kTag_ExtendedKeyUsage = 3, /**< [ array ] Enumerated values giving the purposes for which the public key can be used. */
80 kTag_SubjectKeyIdentifier = 4, /**< [ byte string ] Identifier of the certificate's public key. */
81 kTag_AuthorityKeyIdentifier = 5, /**< [ byte string ] Identifier of the public key used to sign the certificate. */
Evgeny Margolisbf61e872021-06-24 16:00:01 -070082 kTag_FutureExtension = 6, /**< [ byte string ] Arbitrary extension. DER encoded SEQUENCE as in X.509 form. */
Evgeny Margolis53538582021-01-12 09:14:24 -080083
Evgeny Margolis53538582021-01-12 09:14:24 -080084 // ---- Context-specific Tags for BasicConstraints Structure ----
Evgeny Margolisac22f1b2021-02-10 11:30:02 -080085 kTag_BasicConstraints_IsCA = 1, /**< [ boolean ] True if the certificate can be used to verify certificate
Evgeny Margolis53538582021-01-12 09:14:24 -080086 signatures. */
Evgeny Margolisac22f1b2021-02-10 11:30:02 -080087 kTag_BasicConstraints_PathLenConstraint = 2, /**< [ unsigned int ] Maximum number of subordinate intermediate certificates. */
Evgeny Margolis53538582021-01-12 09:14:24 -080088};
89
90/** Identifies the purpose or application of certificate
91 *
92 * A certificate type is a label that describes a certificate's purpose or application.
93 * Certificate types are not carried as attributes of the corresponding certificates, but
94 * rather are derived from the certificate's structure and/or the context in which it is used.
95 * The certificate type enumeration includes a set of pre-defined values describing commonly
Evgeny Margolis7d334762021-04-14 09:25:47 -070096 * used certificate applications.
Evgeny Margolis53538582021-01-12 09:14:24 -080097 *
98 * Certificate types are primarily used in the implementation of access control policies,
99 * where access to application features is influenced by the type of certificate presented
100 * by a requester.
101 *
102 * @note Cert type is an API data type only; it should never be sent over-the-wire.
103 */
Karsten Sperling441aad72023-08-19 02:33:09 +1200104enum class CertType : uint8_t
Evgeny Margolis53538582021-01-12 09:14:24 -0800105{
Karsten Sperling441aad72023-08-19 02:33:09 +1200106 kNotSpecified = 0x00, /**< The certificate's type has not been specified. */
107 kRoot = 0x01, /**< A CHIP Root certificate. */
108 kICA = 0x02, /**< A CHIP Intermediate CA certificate. */
109 kNode = 0x03, /**< A CHIP node certificate. */
110 kFirmwareSigning = 0x04, /**< A CHIP firmware signing certificate. Note that CHIP doesn't
111 specify how firmware images are signed and implementation of
112 firmware image signing is manufacturer-specific. The CHIP
113 certificate format supports encoding of firmware signing
114 certificates if chosen by the manufacturer to use them. */
Evgeny Margolis53538582021-01-12 09:14:24 -0800115};
116
117/** X.509 Certificate Key Purpose Flags
118 *
119 * The flags order must match the enumeration order of corresponding kOID_KeyPurpose values.
120 */
121enum class KeyPurposeFlags : uint8_t
122{
123 kServerAuth = 0x01, /**< Extended key usage is server authentication. */
124 kClientAuth = 0x02, /**< Extended key usage is client authentication. */
125 kCodeSigning = 0x04, /**< Extended key usage is code signing. */
126 kEmailProtection = 0x08, /**< Extended key usage is email protection. */
127 kTimeStamping = 0x10, /**< Extended key usage is time stamping. */
128 kOCSPSigning = 0x20, /**< Extended key usage is OCSP signing. */
129};
130
131/** X.509 Certificate Key Usage Flags
132 */
133enum class KeyUsageFlags : uint16_t
134{
135 kDigitalSignature = 0x0001, /**< Key usage is digital signature. */
136 kNonRepudiation = 0x0002, /**< Key usage is non-repudiation. */
137 kKeyEncipherment = 0x0004, /**< Key usage is key encipherment. */
138 kDataEncipherment = 0x0008, /**< Key usage is data encipherment. */
139 kKeyAgreement = 0x0010, /**< Key usage is key agreement. */
140 kKeyCertSign = 0x0020, /**< Key usage is key cert signing. */
141 kCRLSign = 0x0040, /**< Key usage is CRL signing. */
142 kEncipherOnly = 0x0080, /**< Key usage is encipher only. */
143 kDecipherOnly = 0x0100, /**< Key usage is decipher only. */
144};
145
146/** CHIP Certificate Flags
147 *
148 * Contains information about a certificate that has been loaded into a ChipCertificateData object.
149 */
150enum class CertFlags : uint16_t
151{
152 kExtPresent_BasicConstraints = 0x0001, /**< Basic constraints extension is present in the certificate. */
Evgeny Margolisac22f1b2021-02-10 11:30:02 -0800153 kExtPresent_KeyUsage = 0x0002, /**< Key usage extension is present in the certificate. */
154 kExtPresent_ExtendedKeyUsage = 0x0004, /**< Extended key usage extension is present in the certificate. */
155 kExtPresent_SubjectKeyId = 0x0008, /**< Subject key identifier extension is present in the certificate. */
156 kExtPresent_AuthKeyId = 0x0010, /**< Authority key identifier extension is present in the certificate. */
Evgeny Margolisba9c5032021-04-21 21:47:27 -0700157 kExtPresent_FutureIsCritical = 0x0020, /**< Future extension marked as critical is present in the certificate. */
158 kPathLenConstraintPresent = 0x0040, /**< Path length constraint is present in the certificate. */
159 kIsCA = 0x0080, /**< Indicates that certificate is a CA certificate. */
160 kIsTrustAnchor = 0x0100, /**< Indicates that certificate is a trust anchor. */
161 kTBSHashPresent = 0x0200, /**< Indicates that TBS hash of the certificate was generated and stored. */
Evgeny Margolis53538582021-01-12 09:14:24 -0800162};
163
164/** CHIP Certificate Decode Flags
165 *
166 * Contains information specifying how a certificate should be decoded.
167 */
168enum class CertDecodeFlags : uint8_t
169{
170 kGenerateTBSHash = 0x01, /**< Indicates that to-be-signed (TBS) hash of the certificate should be calculated when certificate is
171 loaded. The TBS hash is then used to validate certificate signature. Normally, all certificates
172 (except trust anchor) in the certificate validation chain require TBS hash. */
173 kIsTrustAnchor = 0x02, /**< Indicates that the corresponding certificate is trust anchor. */
174};
175
Evgeny Margolis53538582021-01-12 09:14:24 -0800176enum
177{
178 kNullCertTime = 0
179};
180
181/**
Evgeny Margolis7d334762021-04-14 09:25:47 -0700182 * @struct ChipRDN
Evgeny Margolis53538582021-01-12 09:14:24 -0800183 *
184 * @brief
Evgeny Margolis7d334762021-04-14 09:25:47 -0700185 * A data structure representing a Relative Distinguished Name (RDN) in a CHIP certificate.
Evgeny Margolis53538582021-01-12 09:14:24 -0800186 */
Evgeny Margolis7d334762021-04-14 09:25:47 -0700187struct ChipRDN
Evgeny Margolis53538582021-01-12 09:14:24 -0800188{
Evgeny Margolis20c1f602022-01-26 06:09:18 -0800189 CharSpan mString; /**< Attribute value when encoded as a string. */
190 uint64_t mChipVal; /**< CHIP specific DN attribute value. */
191 chip::ASN1::OID mAttrOID = chip::ASN1::kOID_NotSpecified; /**< DN attribute CHIP OID. */
192 bool mAttrIsPrintableString; /**< Specifies if attribute is a printable string type. */
Evgeny Margolis53538582021-01-12 09:14:24 -0800193
Evgeny Margolis7d334762021-04-14 09:25:47 -0700194 bool IsEqual(const ChipRDN & other) const;
Evgeny Margolis53538582021-01-12 09:14:24 -0800195 bool IsEmpty() const { return mAttrOID == chip::ASN1::kOID_NotSpecified; }
Tennessee Carmel-Veilleuxeba8dee2022-08-29 15:40:07 -0400196 void Clear()
197 {
198 mAttrOID = chip::ASN1::kOID_NotSpecified;
199 mAttrIsPrintableString = false;
200 mChipVal = 0;
201 mString = CharSpan{};
202 }
Evgeny Margolis53538582021-01-12 09:14:24 -0800203};
204
205/**
Evgeny Margolis7d334762021-04-14 09:25:47 -0700206 * @brief
207 * A data structure representing a Distinguished Name (DN) in a CHIP certificate.
208 */
209class ChipDN
210{
211public:
212 ChipDN();
213 ~ChipDN();
214
215 void Clear();
216
217 /**
218 * @brief Add CHIP-specific attribute to the DN.
219 *
220 * @param oid CHIP-specific OID for DN attribute.
221 * @param val CHIP-specific DN attribute value.
222 *
223 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
224 **/
225 CHIP_ERROR AddAttribute(chip::ASN1::OID oid, uint64_t val);
226
227 /**
Evgeny Margolisa8dcee42022-03-23 09:50:37 -0700228 * @brief Add CASE Authenticated Tags (CATs) attributes to the DN.
229 *
230 * @param cats Array of CAT values.
231 *
232 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
233 **/
234 CHIP_ERROR AddCATs(const chip::CATValues & cats);
235
236 /**
Evgeny Margolis7d334762021-04-14 09:25:47 -0700237 * @brief Add string attribute to the DN.
238 *
239 * @param oid String OID for DN attribute.
Evgeny Margolisbaf2ca02021-10-26 18:42:29 -0700240 * @param val A CharSpan object containing a pointer and length of the DN string attribute
Evgeny Margolis08b56502021-06-30 21:34:42 -0700241 * buffer. The value in the buffer should remain valid while the object is in use.
Evgeny Margolis20c1f602022-01-26 06:09:18 -0800242 * @param isPrintableString Specifies if attribute ASN1 type is a printable string.
Evgeny Margolis7d334762021-04-14 09:25:47 -0700243 *
244 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
245 **/
Evgeny Margolis20c1f602022-01-26 06:09:18 -0800246 CHIP_ERROR AddAttribute(chip::ASN1::OID oid, CharSpan val, bool isPrintableString);
Evgeny Margolis7d334762021-04-14 09:25:47 -0700247
Evgeny Margolis8720d462022-04-11 09:53:48 -0700248 inline CHIP_ERROR AddAttribute_CommonName(CharSpan val, bool isPrintableString)
249 {
250 return AddAttribute(ASN1::kOID_AttributeType_CommonName, val, isPrintableString);
251 }
252 inline CHIP_ERROR AddAttribute_Surname(CharSpan val, bool isPrintableString)
253 {
254 return AddAttribute(ASN1::kOID_AttributeType_Surname, val, isPrintableString);
255 }
256 inline CHIP_ERROR AddAttribute_SerialNumber(CharSpan val, bool isPrintableString)
257 {
258 return AddAttribute(ASN1::kOID_AttributeType_SerialNumber, val, isPrintableString);
259 }
260 inline CHIP_ERROR AddAttribute_CountryName(CharSpan val, bool isPrintableString)
261 {
262 return AddAttribute(ASN1::kOID_AttributeType_CountryName, val, isPrintableString);
263 }
264 inline CHIP_ERROR AddAttribute_LocalityName(CharSpan val, bool isPrintableString)
265 {
266 return AddAttribute(ASN1::kOID_AttributeType_LocalityName, val, isPrintableString);
267 }
268 inline CHIP_ERROR AddAttribute_StateOrProvinceName(CharSpan val, bool isPrintableString)
269 {
270 return AddAttribute(ASN1::kOID_AttributeType_StateOrProvinceName, val, isPrintableString);
271 }
272 inline CHIP_ERROR AddAttribute_OrganizationName(CharSpan val, bool isPrintableString)
273 {
274 return AddAttribute(ASN1::kOID_AttributeType_OrganizationName, val, isPrintableString);
275 }
276 inline CHIP_ERROR AddAttribute_OrganizationalUnitName(CharSpan val, bool isPrintableString)
277 {
278 return AddAttribute(ASN1::kOID_AttributeType_OrganizationalUnitName, val, isPrintableString);
279 }
280 inline CHIP_ERROR AddAttribute_Title(CharSpan val, bool isPrintableString)
281 {
282 return AddAttribute(ASN1::kOID_AttributeType_Title, val, isPrintableString);
283 }
284 inline CHIP_ERROR AddAttribute_Name(CharSpan val, bool isPrintableString)
285 {
286 return AddAttribute(ASN1::kOID_AttributeType_Name, val, isPrintableString);
287 }
288 inline CHIP_ERROR AddAttribute_GivenName(CharSpan val, bool isPrintableString)
289 {
290 return AddAttribute(ASN1::kOID_AttributeType_GivenName, val, isPrintableString);
291 }
292 inline CHIP_ERROR AddAttribute_Initials(CharSpan val, bool isPrintableString)
293 {
294 return AddAttribute(ASN1::kOID_AttributeType_Initials, val, isPrintableString);
295 }
296 inline CHIP_ERROR AddAttribute_GenerationQualifier(CharSpan val, bool isPrintableString)
297 {
298 return AddAttribute(ASN1::kOID_AttributeType_GenerationQualifier, val, isPrintableString);
299 }
300 inline CHIP_ERROR AddAttribute_DNQualifier(CharSpan val, bool isPrintableString)
301 {
302 return AddAttribute(ASN1::kOID_AttributeType_DNQualifier, val, isPrintableString);
303 }
304 inline CHIP_ERROR AddAttribute_Pseudonym(CharSpan val, bool isPrintableString)
305 {
306 return AddAttribute(ASN1::kOID_AttributeType_Pseudonym, val, isPrintableString);
307 }
308 inline CHIP_ERROR AddAttribute_DomainComponent(CharSpan val, bool isPrintableString)
309 {
310 return AddAttribute(ASN1::kOID_AttributeType_DomainComponent, val, isPrintableString);
311 }
312 inline CHIP_ERROR AddAttribute_MatterNodeId(uint64_t val) { return AddAttribute(ASN1::kOID_AttributeType_MatterNodeId, val); }
313 inline CHIP_ERROR AddAttribute_MatterFirmwareSigningId(uint64_t val)
314 {
315 return AddAttribute(ASN1::kOID_AttributeType_MatterFirmwareSigningId, val);
316 }
317 inline CHIP_ERROR AddAttribute_MatterICACId(uint64_t val) { return AddAttribute(ASN1::kOID_AttributeType_MatterICACId, val); }
318 inline CHIP_ERROR AddAttribute_MatterRCACId(uint64_t val) { return AddAttribute(ASN1::kOID_AttributeType_MatterRCACId, val); }
319 inline CHIP_ERROR AddAttribute_MatterFabricId(uint64_t val)
320 {
321 return AddAttribute(ASN1::kOID_AttributeType_MatterFabricId, val);
322 }
323 inline CHIP_ERROR AddAttribute_MatterCASEAuthTag(CASEAuthTag val)
324 {
325 return AddAttribute(ASN1::kOID_AttributeType_MatterCASEAuthTag, val);
326 }
327
Evgeny Margolis7d334762021-04-14 09:25:47 -0700328 /**
329 * @brief Determine type of a CHIP certificate.
330 * This method performs an assessment of a certificate's type based on the structure
331 * of its subject DN.
332 *
333 * @param certType A reference to the certificate type value.
334 *
335 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
336 **/
Karsten Sperling441aad72023-08-19 02:33:09 +1200337 CHIP_ERROR GetCertType(CertType & certType) const;
Evgeny Margolis7d334762021-04-14 09:25:47 -0700338
Joseph Kellyda45bb32021-06-02 23:38:33 -0400339 /**
340 * @brief Retrieve the ID of a CHIP certificate.
341 *
342 * @param certId A reference to the certificate ID value.
343 *
344 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
345 **/
Lazar Kovacic16f80612021-06-18 06:50:51 +0200346 CHIP_ERROR GetCertChipId(uint64_t & certId) const;
Joseph Kellyda45bb32021-06-02 23:38:33 -0400347
Joseph Kelly410b9f92021-07-28 10:20:48 -0400348 /**
349 * @brief Retrieve the Fabric ID of a CHIP certificate.
350 **/
351 CHIP_ERROR GetCertFabricId(uint64_t & fabricId) const;
352
Evgeny Margolis20c1f602022-01-26 06:09:18 -0800353 /**
Evgeny Margolis7c695232022-03-28 13:12:38 -0700354 * @brief Encode ChipDN attributes in TLV form.
355 **/
356 CHIP_ERROR EncodeToTLV(chip::TLV::TLVWriter & writer, TLV::Tag tag) const;
357
358 /**
Evgeny Margolis20c1f602022-01-26 06:09:18 -0800359 * @brief Decode ChipDN attributes from TLV encoded format.
360 *
361 * @param reader A TLVReader positioned at the ChipDN TLV list.
362 **/
363 CHIP_ERROR DecodeFromTLV(chip::TLV::TLVReader & reader);
364
365 /**
366 * @brief Encode ChipDN attributes in ASN1 form.
367 **/
368 CHIP_ERROR EncodeToASN1(ASN1::ASN1Writer & writer) const;
369
Evgeny Margolis7c695232022-03-28 13:12:38 -0700370 /**
371 * @brief Decode ChipDN attributes from ASN1 encoded format.
372 *
373 * @param reader A ASN1Reader positioned at the ChipDN ASN1 list.
374 **/
375 CHIP_ERROR DecodeFromASN1(ASN1::ASN1Reader & reader);
376
Evgeny Margolis7d334762021-04-14 09:25:47 -0700377 bool IsEqual(const ChipDN & other) const;
378
379 /**
380 * @brief Determine if DN is empty (doesn't have DN attributes).
381 *
382 * @return true if DN is empty, false otherwise.
383 **/
384 bool IsEmpty() const { return RDNCount() == 0; }
385
Tennessee Carmel-Veilleux6ba2a092022-04-07 09:12:12 -0400386 static_assert((CHIP_CONFIG_CERT_MAX_RDN_ATTRIBUTES) >= 5, "Spec requires at least 5 RDN to be supported per Matter TLV cert");
Evgeny Margolis7d334762021-04-14 09:25:47 -0700387 ChipRDN rdn[CHIP_CONFIG_CERT_MAX_RDN_ATTRIBUTES];
388
389 uint8_t RDNCount() const;
390};
391
392/**
Evgeny Margolis08b56502021-06-30 21:34:42 -0700393 * @brief A data structure for holding a certificate key identifier, without the ownership of it.
Evgeny Margolis53538582021-01-12 09:14:24 -0800394 */
Evgeny Margolis08b56502021-06-30 21:34:42 -0700395using CertificateKeyId = FixedByteSpan<kKeyIdentifierLength>;
Evgeny Margolis53538582021-01-12 09:14:24 -0800396
Evgeny Margolis08b56502021-06-30 21:34:42 -0700397/**
398 * @brief A data structure for holding a P256 ECDSA signature, without the ownership of it.
399 */
400using P256ECDSASignatureSpan = FixedByteSpan<Crypto::kP256_ECDSA_Signature_Length_Raw>;
401
402/**
403 * @brief A data structure for holding a P256 Public Key, without the ownership of it.
404 */
Boris Zbarskydfd71fe2022-04-14 23:29:44 -0400405using P256PublicKeySpan = FixedByteSpan<Crypto::kP256_PublicKey_Length>;
Evgeny Margolis08b56502021-06-30 21:34:42 -0700406
407/**
408 * @brief A data structure for holding a P256 Integer, without the ownership of it.
409 */
410using P256IntegerSpan = FixedByteSpan<Crypto::kP256_FE_Length>;
Evgeny Margolis53538582021-01-12 09:14:24 -0800411
412/**
413 * @struct ChipCertificateData
414 *
415 * @brief
416 * In-memory representation of data extracted from a CHIP certificate.
417 *
418 * Some of the fields in this structure are pointers to the fields in the original
419 * CHIP certificate. That CHIP certificate is stored in a separate buffer and it is
420 * required that data in that buffer remains valid while the corresponding
421 * ChipCertificateData structure is used.
422 */
423struct ChipCertificateData
424{
425 ChipCertificateData();
426 ~ChipCertificateData();
427
428 void Clear();
Pankaj Gargc2cc13d2021-05-27 12:23:25 -0700429 bool IsEqual(const ChipCertificateData & other) const;
Evgeny Margolis53538582021-01-12 09:14:24 -0800430
Joseph Kellyda45bb32021-06-02 23:38:33 -0400431 ByteSpan mCertificate; /**< Original raw buffer data. */
Kevin Schoedel8ea423a2021-03-11 11:49:18 -0500432 ChipDN mSubjectDN; /**< Certificate Subject DN. */
433 ChipDN mIssuerDN; /**< Certificate Issuer DN. */
434 CertificateKeyId mSubjectKeyId; /**< Certificate Subject public key identifier. */
435 CertificateKeyId mAuthKeyId; /**< Certificate Authority public key identifier. */
436 uint32_t mNotBeforeTime; /**< Certificate validity: Not Before field. */
437 uint32_t mNotAfterTime; /**< Certificate validity: Not After field. */
Evgeny Margolis08b56502021-06-30 21:34:42 -0700438 P256PublicKeySpan mPublicKey; /**< Certificate public key. */
Kevin Schoedel8ea423a2021-03-11 11:49:18 -0500439 uint16_t mPubKeyCurveOID; /**< Public key Elliptic Curve CHIP OID. */
440 uint16_t mPubKeyAlgoOID; /**< Public key algorithm CHIP OID. */
441 uint16_t mSigAlgoOID; /**< Certificate signature algorithm CHIP OID. */
442 BitFlags<CertFlags> mCertFlags; /**< Certificate data flags. */
443 BitFlags<KeyUsageFlags> mKeyUsageFlags; /**< Certificate key usage extensions flags. */
444 BitFlags<KeyPurposeFlags> mKeyPurposeFlags; /**< Certificate extended key usage extensions flags. */
445 uint8_t mPathLenConstraint; /**< Basic constraint: path length. */
Evgeny Margolis08b56502021-06-30 21:34:42 -0700446 P256ECDSASignatureSpan mSignature; /**< Certificate signature. */
Evgeny Margolis85eb6042021-06-08 10:39:09 -0700447
448 uint8_t mTBSHash[Crypto::kSHA256_Hash_Length]; /**< Certificate TBS hash. */
Evgeny Margolis53538582021-01-12 09:14:24 -0800449};
450
451/**
Evgeny Margolis53538582021-01-12 09:14:24 -0800452 * @brief Decode CHIP certificate.
453 * It is required that the CHIP certificate in the chipCert buffer stays valid while
454 * the certData is used.
455 *
456 * @param chipCert Buffer containing CHIP certificate.
Evgeny Margolis53538582021-01-12 09:14:24 -0800457 * @param certData Structure containing data extracted from the CHIP certificate.
458 *
459 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
460 **/
Evgeny Margolis3640d362021-08-16 13:30:28 -0700461CHIP_ERROR DecodeChipCert(const ByteSpan chipCert, ChipCertificateData & certData);
Evgeny Margolis53538582021-01-12 09:14:24 -0800462
463/**
464 * @brief Decode CHIP certificate.
465 * It is required that the CHIP certificate in the reader's underlying buffer stays valid while
466 * the certData is used.
467 *
468 * @param reader A TLVReader positioned at the CHIP certificate TLV structure.
469 * @param certData Structure containing data extracted from the CHIP certificate.
470 *
471 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
472 **/
473CHIP_ERROR DecodeChipCert(chip::TLV::TLVReader & reader, ChipCertificateData & certData);
474
475/**
476 * @brief Decode CHIP Distinguished Name (DN).
477 * It is required that the CHIP DN in the reader's underlying buffer stays valid while
478 * the dn structure is used.
479 *
480 * @param reader A TLVReader positioned at the CHIP DN TLV structure.
481 * @param dn Distinguished Name structure.
482 *
483 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
484 **/
485CHIP_ERROR DecodeChipDN(chip::TLV::TLVReader & reader, ChipDN & dn);
486
487/**
488 * @brief Convert standard X.509 certificate to CHIP certificate.
489 *
Evgeny Margolis08b56502021-06-30 21:34:42 -0700490 * @param x509Cert CHIP X.509 DER encoded certificate.
Evgeny Margolis3640d362021-08-16 13:30:28 -0700491 * @param chipCert Buffer to store converted certificate in CHIP format.
Evgeny Margolis53538582021-01-12 09:14:24 -0800492 *
493 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
494 **/
Evgeny Margolis3640d362021-08-16 13:30:28 -0700495CHIP_ERROR ConvertX509CertToChipCert(const ByteSpan x509Cert, MutableByteSpan & chipCert);
Evgeny Margolis53538582021-01-12 09:14:24 -0800496
497/**
498 * @brief Convert CHIP certificate to the standard X.509 DER encoded certificate.
499 *
Evgeny Margolis08b56502021-06-30 21:34:42 -0700500 * @param chipCert CHIP certificate in CHIP TLV encoding.
Andrei Litvin0fcf1732021-08-20 17:50:27 -0400501 * @param x509Cert Buffer to store converted certificate in X.509 DER format.
Evgeny Margolis53538582021-01-12 09:14:24 -0800502 *
503 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
504 **/
Evgeny Margolis3640d362021-08-16 13:30:28 -0700505CHIP_ERROR ConvertChipCertToX509Cert(const ByteSpan chipCert, MutableByteSpan & x509Cert);
Pankaj Garg237cfd02021-05-03 14:32:48 -0700506
Evgeny Margolised040c22022-07-15 07:30:09 -0700507/**
508 * Validate CHIP Root CA Certificate (RCAC) in ByteSpan TLV-encoded form.
509 * This function performs RCAC parsing, checks SubjectDN validity, verifies that SubjectDN
510 * and IssuerDN are equal, verifies that SKID and AKID are equal, validates certificate signature.
511 *
512 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
513 */
514CHIP_ERROR ValidateChipRCAC(const ByteSpan & rcac);
515
Evgeny Margoliscfdb3082022-08-23 06:41:28 -0700516struct FutureExtension
517{
518 ByteSpan OID;
519 ByteSpan Extension;
520};
521
Pankaj Garg237cfd02021-05-03 14:32:48 -0700522struct X509CertRequestParams
523{
524 int64_t SerialNumber;
Pankaj Garg237cfd02021-05-03 14:32:48 -0700525 uint32_t ValidityStart;
526 uint32_t ValidityEnd;
Evgeny Margolis20c1f602022-01-26 06:09:18 -0800527 ChipDN SubjectDN;
528 ChipDN IssuerDN;
Evgeny Margoliscfdb3082022-08-23 06:41:28 -0700529 Optional<FutureExtension> FutureExt;
Pankaj Garg237cfd02021-05-03 14:32:48 -0700530};
531
532/**
533 * @brief Generate a new X.509 DER encoded Root CA certificate
534 *
535 * @param requestParams Certificate request parameters.
536 * @param issuerKeypair The certificate signing key
Pankaj Garg7b000572021-08-13 20:14:29 -0700537 * @param x509Cert Buffer to store signed certificate in X.509 DER format.
Pankaj Garg237cfd02021-05-03 14:32:48 -0700538 *
539 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
540 **/
Pankaj Garg7b000572021-08-13 20:14:29 -0700541CHIP_ERROR NewRootX509Cert(const X509CertRequestParams & requestParams, Crypto::P256Keypair & issuerKeypair,
542 MutableByteSpan & x509Cert);
Pankaj Garg237cfd02021-05-03 14:32:48 -0700543
544/**
545 * @brief Generate a new X.509 DER encoded Intermediate CA certificate
546 *
547 * @param requestParams Certificate request parameters.
Pankaj Garg237cfd02021-05-03 14:32:48 -0700548 * @param subjectPubkey The public key of subject
549 * @param issuerKeypair The certificate signing key
Pankaj Garg7b000572021-08-13 20:14:29 -0700550 * @param x509Cert Buffer to store signed certificate in X.509 DER format.
Pankaj Garg237cfd02021-05-03 14:32:48 -0700551 *
552 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
553 **/
Evgeny Margolis20c1f602022-01-26 06:09:18 -0800554CHIP_ERROR NewICAX509Cert(const X509CertRequestParams & requestParams, const Crypto::P256PublicKey & subjectPubkey,
555 Crypto::P256Keypair & issuerKeypair, MutableByteSpan & x509Cert);
Pankaj Garg237cfd02021-05-03 14:32:48 -0700556
557/**
558 * @brief Generate a new X.509 DER encoded Node operational certificate
559 *
560 * @param requestParams Certificate request parameters.
Pankaj Garg237cfd02021-05-03 14:32:48 -0700561 * @param subjectPubkey The public key of subject
562 * @param issuerKeypair The certificate signing key
Pankaj Garg7b000572021-08-13 20:14:29 -0700563 * @param x509Cert Buffer to store signed certificate in X.509 DER format.
Pankaj Garg237cfd02021-05-03 14:32:48 -0700564 *
565 * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
566 **/
Evgeny Margolis20c1f602022-01-26 06:09:18 -0800567CHIP_ERROR NewNodeOperationalX509Cert(const X509CertRequestParams & requestParams, const Crypto::P256PublicKey & subjectPubkey,
568 Crypto::P256Keypair & issuerKeypair, MutableByteSpan & x509Cert);
Pankaj Garg237cfd02021-05-03 14:32:48 -0700569
570/**
Evgeny Margolis53538582021-01-12 09:14:24 -0800571 * @brief
Michael Sandstedt8cc291d2022-06-07 10:02:58 -0500572 * Convert a certificate date/time (in the form of an ASN.1 universal time structure) into a CHIP Epoch time.
Evgeny Margolis53538582021-01-12 09:14:24 -0800573 *
574 * @note
575 * This function makes no attempt to verify the correct range of the input time other than year.
576 * Therefore callers must make sure the supplied values are valid prior to invocation.
577 *
Evgeny Margolisfbc95962021-02-17 10:23:44 -0800578 * @param asn1Time The calendar date/time to be converted.
Michael Sandstedt8cc291d2022-06-07 10:02:58 -0500579 * @param epochTime A reference to an integer that will receive CHIP Epoch time.
Evgeny Margolis53538582021-01-12 09:14:24 -0800580 *
581 * @retval #CHIP_NO_ERROR If the input time was successfully converted.
582 * @retval #ASN1_ERROR_UNSUPPORTED_ENCODING If the input time contained a year value that could not
Evgeny Margolisfbc95962021-02-17 10:23:44 -0800583 * be represented in a CHIP epoch UTC time value.
Evgeny Margolis53538582021-01-12 09:14:24 -0800584 **/
Evgeny Margolisfbc95962021-02-17 10:23:44 -0800585CHIP_ERROR ASN1ToChipEpochTime(const chip::ASN1::ASN1UniversalTime & asn1Time, uint32_t & epochTime);
Evgeny Margolis53538582021-01-12 09:14:24 -0800586
587/**
588 * @brief
Evgeny Margolisfbc95962021-02-17 10:23:44 -0800589 * Convert a CHIP epoch UTC time into an ASN.1 universal time structure.
Evgeny Margolis53538582021-01-12 09:14:24 -0800590 *
Evgeny Margolisfbc95962021-02-17 10:23:44 -0800591 * @param epochTime A CHIP epoch UTC time to be converted.
592 * @param asn1Time A reference to an ASN1UniversalTime structure to receive the date/time.
Evgeny Margolis53538582021-01-12 09:14:24 -0800593 *
Evgeny Margolisfbc95962021-02-17 10:23:44 -0800594 * @retval #CHIP_NO_ERROR If the input time was successfully converted.
Evgeny Margolis53538582021-01-12 09:14:24 -0800595 */
Evgeny Margolisfbc95962021-02-17 10:23:44 -0800596CHIP_ERROR ChipEpochToASN1Time(uint32_t epochTime, chip::ASN1::ASN1UniversalTime & asn1Time);
Evgeny Margolis53538582021-01-12 09:14:24 -0800597
598/**
Evgeny Margolis7d334762021-04-14 09:25:47 -0700599 * @return True if the OID represents a CHIP-defined 64-bit distinguished named attribute.
Evgeny Margolis53538582021-01-12 09:14:24 -0800600 **/
Evgeny Margolis7d334762021-04-14 09:25:47 -0700601inline bool IsChip64bitDNAttr(chip::ASN1::OID oid)
Evgeny Margolis53538582021-01-12 09:14:24 -0800602{
Evgeny Margolis8720d462022-04-11 09:53:48 -0700603 return (oid == chip::ASN1::kOID_AttributeType_MatterNodeId || oid == chip::ASN1::kOID_AttributeType_MatterFirmwareSigningId ||
604 oid == chip::ASN1::kOID_AttributeType_MatterICACId || oid == chip::ASN1::kOID_AttributeType_MatterRCACId ||
605 oid == chip::ASN1::kOID_AttributeType_MatterFabricId);
Evgeny Margolis53538582021-01-12 09:14:24 -0800606}
607
608/**
Evgeny Margolis7d334762021-04-14 09:25:47 -0700609 * @return True if the OID represents a CHIP-defined 32-bit distinguished named attribute.
Evgeny Margolis53538582021-01-12 09:14:24 -0800610 **/
Evgeny Margolis7d334762021-04-14 09:25:47 -0700611inline bool IsChip32bitDNAttr(chip::ASN1::OID oid)
Evgeny Margolis53538582021-01-12 09:14:24 -0800612{
Evgeny Margolis8720d462022-04-11 09:53:48 -0700613 return (oid == chip::ASN1::kOID_AttributeType_MatterCASEAuthTag);
Evgeny Margolis7d334762021-04-14 09:25:47 -0700614}
615
616/**
617 * @return True if the OID represents a CHIP-defined distinguished named attribute.
618 **/
619inline bool IsChipDNAttr(chip::ASN1::OID oid)
620{
621 return (IsChip64bitDNAttr(oid) || IsChip32bitDNAttr(oid));
Evgeny Margolis53538582021-01-12 09:14:24 -0800622}
623
Evgeny Margolis85eb6042021-06-08 10:39:09 -0700624/**
625 * @brief Convert an ASN.1 DER encoded integer to a raw big-endian integer.
626 *
Evgeny Margolis08b56502021-06-30 21:34:42 -0700627 * @param derInt P256 integer in ASN.1 DER encoded form.
Evgeny Margolis85eb6042021-06-08 10:39:09 -0700628 * @param rawInt Buffer to store converted raw integer.
629 * @param rawIntLen The length of the converted raw integer.
630 *
631 * @retval #CHIP_NO_ERROR If the integer value was successfully converted.
632 */
Evgeny Margolis08b56502021-06-30 21:34:42 -0700633CHIP_ERROR ConvertIntegerDERToRaw(ByteSpan derInt, uint8_t * rawInt, const uint16_t rawIntLen);
Evgeny Margolis85eb6042021-06-08 10:39:09 -0700634
635/**
Evgeny Margolis85eb6042021-06-08 10:39:09 -0700636 * @brief Convert a raw CHIP signature to an ASN.1 DER encoded signature structure.
637 *
Evgeny Margolis8e86c9e2021-09-15 21:22:30 -0700638 * @param[in] rawSig P256 ECDSA signature in raw form.
639 * @param[in,out] derSig Output buffer to receive the converted ASN.1 DER encoded signature.
640 * `derSig` must be at least `kMax_ECDSA_Signature_Length_Der` bytes long.
641 * The `derSig` size will be set to the actual DER encoded signature length on success.
Evgeny Margolis85eb6042021-06-08 10:39:09 -0700642 *
643 * @retval #CHIP_NO_ERROR If the signature value was successfully converted.
644 */
Evgeny Margolis8e86c9e2021-09-15 21:22:30 -0700645CHIP_ERROR ConvertECDSASignatureRawToDER(P256ECDSASignatureSpan rawSig, MutableByteSpan & derSig);
Evgeny Margolis85eb6042021-06-08 10:39:09 -0700646
647/**
648 * @brief Convert a raw CHIP ECDSA signature to an ASN.1 DER encoded signature structure.
649 *
Evgeny Margolis08b56502021-06-30 21:34:42 -0700650 * @param rawSig P256 ECDSA signature in raw form.
Evgeny Margolis85eb6042021-06-08 10:39:09 -0700651 * @param writer A reference to the ASN1Writer to store ASN.1 DER encoded signature.
652 *
653 * @retval #CHIP_NO_ERROR If the signature value was successfully converted.
654 */
Evgeny Margolis08b56502021-06-30 21:34:42 -0700655CHIP_ERROR ConvertECDSASignatureRawToDER(P256ECDSASignatureSpan rawSig, ASN1::ASN1Writer & writer);
Evgeny Margolis85eb6042021-06-08 10:39:09 -0700656
657/**
658 * @brief Convert an ASN.1 DER encoded ECDSA signature to a raw CHIP signature.
659 *
660 * @param reader A reference to the ASN1Reader positioned at the beginning of the
661 * DER encoded ECDSA signature.
662 * @param writer A reference to the TLVWriter to store TLV encoded ECDSA signature element.
663 * @param tag Tag to use for TLV encoded signature.
664 *
665 * @retval #CHIP_NO_ERROR If the signature value was successfully converted.
666 */
667CHIP_ERROR ConvertECDSASignatureDERToRaw(ASN1::ASN1Reader & reader, chip::TLV::TLVWriter & writer, uint64_t tag);
668
Boris Zbarsky8af99812021-07-15 01:58:05 -0400669/**
Michael Sandstedt54b5b692022-01-27 10:51:40 -0600670 * Extract the Fabric ID from an operational certificate that has already been
671 * parsed.
Pankaj Garg5e3f4f62021-08-19 08:58:48 -0700672 *
673 * This function can be used to extract Fabric ID from an ICA certificate.
Pankaj Garg6efec202021-08-25 10:47:29 -0700674 * These certificates may not contain a NodeID, so ExtractNodeIdFabricIdFromOpCert()
Pankaj Garg5e3f4f62021-08-19 08:58:48 -0700675 * cannot be used for such certificates.
676 *
Evgeny Margolisc1b56482022-03-10 11:02:32 -0800677 * @return CHIP_ERROR_NOT_FOUND if the passed-in cert does not have RDN
Pankaj Garg5e3f4f62021-08-19 08:58:48 -0700678 * corresponding to FabricID.
679 */
680CHIP_ERROR ExtractFabricIdFromCert(const ChipCertificateData & cert, FabricId * fabricId);
681
682/**
Pankaj Garg6efec202021-08-25 10:47:29 -0700683 * Extract Node ID and Fabric ID from an operational certificate that has already been
Boris Zbarsky8af99812021-07-15 01:58:05 -0400684 * parsed.
685 *
Evgeny Margolisc1b56482022-03-10 11:02:32 -0800686 * @return CHIP_ERROR_NOT_FOUND if the passed-in cert does not have at
Boris Zbarsky8af99812021-07-15 01:58:05 -0400687 * least one NodeId RDN and one FabricId RDN in the Subject DN. No other
688 * validation (e.g. checkign that there is exactly one RDN of each type) is
689 * performed.
690 */
Pankaj Garg6efec202021-08-25 10:47:29 -0700691CHIP_ERROR ExtractNodeIdFabricIdFromOpCert(const ChipCertificateData & opcert, NodeId * nodeId, FabricId * fabricId);
Boris Zbarsky8af99812021-07-15 01:58:05 -0400692
693/**
Michael Sandstedt87d36982022-01-24 12:38:13 -0600694 * Extract Node ID, Fabric ID and Compressed Fabric ID from an operational
C Freeman09a49212022-01-24 21:19:43 -0500695 * certificate and its associated root certificate.
Michael Sandstedt87d36982022-01-24 12:38:13 -0600696 *
697 * @return CHIP_ERROR on failure or CHIP_NO_ERROR otherwise.
698 */
C Freeman09a49212022-01-24 21:19:43 -0500699CHIP_ERROR ExtractNodeIdFabricIdCompressedFabricIdFromOpCerts(ByteSpan rcac, ByteSpan noc, CompressedFabricId & compressedFabricId,
700 FabricId & fabricId, NodeId & nodeId);
Michael Sandstedt87d36982022-01-24 12:38:13 -0600701
702/**
703 * Extract Node ID and Compressed Fabric ID from an operational certificate
C Freeman09a49212022-01-24 21:19:43 -0500704 * and its associated root certificate.
Michael Sandstedt87d36982022-01-24 12:38:13 -0600705 *
706 * @return CHIP_ERROR on failure or CHIP_NO_ERROR otherwise.
707 */
C Freeman09a49212022-01-24 21:19:43 -0500708CHIP_ERROR ExtractNodeIdCompressedFabricIdFromOpCerts(ByteSpan rcac, ByteSpan noc, CompressedFabricId & compressedFabricId,
709 NodeId & nodeId);
Michael Sandstedt87d36982022-01-24 12:38:13 -0600710
711/**
Evgeny Margolisea87cc62021-11-29 22:08:00 -0800712 * Extract CASE Authenticated Tags from an operational certificate in ByteSpan TLV-encoded form.
713 *
714 * All values in the 'cats' struct will be set either to a valid CAT value or zero (undefined) value.
715 *
716 * @return CHIP_ERROR_INVALID_ARGUMENT if the passed-in cert is not NOC.
717 * @return CHIP_ERROR_BUFFER_TOO_SMALL if there are too many CATs in the NOC
718 */
719CHIP_ERROR ExtractCATsFromOpCert(const ByteSpan & opcert, CATValues & cats);
720
721/**
Evgeny Margolis38387902021-11-12 11:01:21 -0800722 * Extract CASE Authenticated Tags from an operational certificate that has already been
723 * parsed.
724 *
Evgeny Margolisea87cc62021-11-29 22:08:00 -0800725 * All values in the 'cats' struct will be set either to a valid CAT value or to the kUndefinedCAT value.
Evgeny Margolis38387902021-11-12 11:01:21 -0800726 *
727 * @return CHIP_ERROR_INVALID_ARGUMENT if the passed-in cert is not NOC.
728 * @return CHIP_ERROR_BUFFER_TOO_SMALL if the passed-in CATs array is too small.
729 */
Evgeny Margolisea87cc62021-11-29 22:08:00 -0800730CHIP_ERROR ExtractCATsFromOpCert(const ChipCertificateData & opcert, CATValues & cats);
Evgeny Margolis38387902021-11-12 11:01:21 -0800731
732/**
Evgeny Margolised040c22022-07-15 07:30:09 -0700733 * Extract Fabric ID from an operational certificate in ByteSpan TLV-encoded
Michael Sandstedt54b5b692022-01-27 10:51:40 -0600734 * form. This does not perform any sort of validation on the certificate
735 * structure other than parsing it.
736 *
737 * Can return any error that can be returned from parsing the cert or from the
738 * ChipCertificateData* version of ExtractNodeIdFabricIdFromOpCert.
739 */
740CHIP_ERROR ExtractFabricIdFromCert(const ByteSpan & opcert, FabricId * fabricId);
741
742/**
Pankaj Garg6efec202021-08-25 10:47:29 -0700743 * Extract Node ID and Fabric ID from an operational certificate in ByteSpan TLV-encoded
Boris Zbarsky8af99812021-07-15 01:58:05 -0400744 * form. This does not perform any sort of validation on the certificate
745 * structure other than parsing it.
746 *
747 * Can return any error that can be returned from parsing the cert or from the
Pankaj Garg6efec202021-08-25 10:47:29 -0700748 * ChipCertificateData* version of ExtractNodeIdFabricIdFromOpCert.
Boris Zbarsky8af99812021-07-15 01:58:05 -0400749 */
Pankaj Garg6efec202021-08-25 10:47:29 -0700750CHIP_ERROR ExtractNodeIdFabricIdFromOpCert(const ByteSpan & opcert, NodeId * nodeId, FabricId * fabricId);
Boris Zbarsky8af99812021-07-15 01:58:05 -0400751
752/**
Evgeny Margolisaff44332021-09-14 16:14:47 -0700753 * Extract Public Key from a chip certificate in ByteSpan TLV-encoded form.
754 * This does not perform any sort of validation on the certificate structure
Evgeny Margolis7c695232022-03-28 13:12:38 -0700755 * other than parsing it.
Boris Zbarsky8af99812021-07-15 01:58:05 -0400756 *
Evgeny Margolisaff44332021-09-14 16:14:47 -0700757 * Can return any error that can be returned from parsing the cert.
Boris Zbarsky8af99812021-07-15 01:58:05 -0400758 */
Evgeny Margolisaff44332021-09-14 16:14:47 -0700759CHIP_ERROR ExtractPublicKeyFromChipCert(const ByteSpan & chipCert, P256PublicKeySpan & publicKey);
760
761/**
Michael Sandstedt8cc291d2022-06-07 10:02:58 -0500762 * Extract Not Before Time from a chip certificate in ByteSpan TLV-encoded form.
763 * Output format is seconds referenced from the CHIP epoch.
764 *
Michael Sandstedt8cc291d2022-06-07 10:02:58 -0500765 * This does not perform any sort of validation on the certificate structure
766 * other than parsing it.
767 *
768 * @param chipCert CHIP certificate in TLV-encoded form
769 * @param notBeforeChipEpochTime (out) certificate NotBefore time as seconds from the CHIP epoch
770 * @return CHIP_NO_ERROR if certificate parsing was successful, else an appropriate CHIP_ERROR
771 */
772CHIP_ERROR ExtractNotBeforeFromChipCert(const ByteSpan & chipCert, chip::System::Clock::Seconds32 & notBeforeChipEpochTime);
773
774/**
Evgeny Margolisaff44332021-09-14 16:14:47 -0700775 * Extract Subject Key Identifier from a chip certificate in ByteSpan TLV-encoded form.
776 * This does not perform any sort of validation on the certificate structure
Evgeny Margolis7c695232022-03-28 13:12:38 -0700777 * other than parsing it.
Evgeny Margolisaff44332021-09-14 16:14:47 -0700778 *
779 * Can return any error that can be returned from parsing the cert.
780 */
781CHIP_ERROR ExtractSKIDFromChipCert(const ByteSpan & chipCert, CertificateKeyId & skid);
Boris Zbarsky8af99812021-07-15 01:58:05 -0400782
Evgeny Margolis7c695232022-03-28 13:12:38 -0700783/**
784 * Extract Subject Distinguished Name (DN) from a chip certificate in ByteSpan TLV-encoded form.
785 * It is required that the certificate in the chipCert buffer stays valid while the `dn` output is used.
786 *
787 * Can return any error that can be returned from parsing the cert.
788 */
789CHIP_ERROR ExtractSubjectDNFromChipCert(const ByteSpan & chipCert, ChipDN & dn);
790
791/**
792 * Extract Subject Distinguished Name (DN) from a chip certificate in ByteSpan X509 DER-encoded form.
793 * It is required that the certificate in the chipCert buffer stays valid while the `dn` output is used.
794 *
795 * Can return any error that can be returned from converting and parsing the cert.
796 */
797CHIP_ERROR ExtractSubjectDNFromX509Cert(const ByteSpan & x509Cert, ChipDN & dn);
798
Evgeny Margolis53538582021-01-12 09:14:24 -0800799} // namespace Credentials
800} // namespace chip