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 <crypto/CHIPCryptoPAL.h>
34 : #include <lib/asn1/ASN1.h>
35 : #include <lib/core/CASEAuthTag.h>
36 : #include <lib/core/CHIPConfig.h>
37 : #include <lib/core/DataModelTypes.h>
38 : #include <lib/core/PeerId.h>
39 : #include <lib/core/TLV.h>
40 : #include <lib/support/BitFlags.h>
41 : #include <lib/support/DLLUtil.h>
42 : #include <lib/support/Span.h>
43 : #include <system/SystemClock.h>
44 :
45 : namespace chip {
46 : namespace Credentials {
47 :
48 : static constexpr uint32_t kKeyIdentifierLength = static_cast<uint32_t>(Crypto::kSubjectKeyIdentifierLength);
49 : static constexpr uint32_t kChip32bitAttrUTF8Length = 8;
50 : static constexpr uint32_t kChip64bitAttrUTF8Length = 16;
51 : static constexpr uint16_t kX509NoWellDefinedExpirationDateYear = 9999;
52 :
53 : // As per specifications (6.4.5. Node Operational Credentials Certificates)
54 : static constexpr uint32_t kMaxCHIPCertLength = 400;
55 : static constexpr uint32_t kMaxDERCertLength = 600;
56 :
57 : // As per spec section 11.24 (Wi-Fi Authentication with Per-Device Credentials)
58 : inline constexpr uint32_t kMaxCHIPCompactNetworkIdentityLength = 137;
59 :
60 : // Length of a ASN.1 DER encoded ECPrivateKey structure (RFC 5915) for a P256 key pair.
61 : inline constexpr uint32_t kP256ECPrivateKeyDERLength = 121;
62 :
63 : /** Data Element Tags for the CHIP Certificate
64 : */
65 : enum
66 : {
67 : // ---- Context-specific Tags for ChipCertificate Structure ----
68 : kTag_SerialNumber = 1, /**< [ byte string ] Certificate serial number, in BER integer encoding. */
69 : kTag_SignatureAlgorithm = 2, /**< [ unsigned int ] Enumerated value identifying the certificate signature algorithm. */
70 : kTag_Issuer = 3, /**< [ list ] The issuer distinguished name of the certificate. */
71 : kTag_NotBefore = 4, /**< [ unsigned int ] Certificate validity period start (certificate date format). */
72 : kTag_NotAfter = 5, /**< [ unsigned int ] Certificate validity period end (certificate date format). */
73 : kTag_Subject = 6, /**< [ list ] The subject distinguished name of the certificate. */
74 : kTag_PublicKeyAlgorithm = 7, /**< [ unsigned int ] Identifies the algorithm with which the public key can be used. */
75 : kTag_EllipticCurveIdentifier = 8, /**< [ unsigned int ] For EC certs, identifies the elliptic curve used. */
76 : kTag_EllipticCurvePublicKey = 9, /**< [ byte string ] The elliptic curve public key, in X9.62 encoded format. */
77 : kTag_Extensions = 10, /**< [ list ] Certificate extensions. */
78 : kTag_ECDSASignature = 11, /**< [ byte string ] The ECDSA signature for the certificate. */
79 :
80 : // ---- Context-specific Tags for certificate extensions ----
81 : kTag_BasicConstraints = 1, /**< [ structure ] Identifies whether the subject of the certificate is a CA. */
82 : kTag_KeyUsage = 2, /**< [ unsigned int ] Bits identifying key usage, per RFC5280. */
83 : kTag_ExtendedKeyUsage = 3, /**< [ array ] Enumerated values giving the purposes for which the public key can be used. */
84 : kTag_SubjectKeyIdentifier = 4, /**< [ byte string ] Identifier of the certificate's public key. */
85 : kTag_AuthorityKeyIdentifier = 5, /**< [ byte string ] Identifier of the public key used to sign the certificate. */
86 : kTag_FutureExtension = 6, /**< [ byte string ] Arbitrary extension. DER encoded SEQUENCE as in X.509 form. */
87 :
88 : // ---- Context-specific Tags for BasicConstraints Structure ----
89 : kTag_BasicConstraints_IsCA = 1, /**< [ boolean ] True if the certificate can be used to verify certificate
90 : signatures. */
91 : kTag_BasicConstraints_PathLenConstraint = 2, /**< [ unsigned int ] Maximum number of subordinate intermediate certificates. */
92 : };
93 :
94 : /** Identifies the purpose or application of certificate
95 : *
96 : * A certificate type is a label that describes a certificate's purpose or application.
97 : * Certificate types are not carried as attributes of the corresponding certificates, but
98 : * rather are derived from the certificate's structure and/or the context in which it is used.
99 : * The certificate type enumeration includes a set of pre-defined values describing commonly
100 : * used certificate applications.
101 : *
102 : * Certificate types are primarily used in the implementation of access control policies,
103 : * where access to application features is influenced by the type of certificate presented
104 : * by a requester.
105 : *
106 : * @note Cert type is an API data type only; it should never be sent over-the-wire.
107 : */
108 : enum class CertType : uint8_t
109 : {
110 : kNotSpecified = 0x00, /**< The certificate's type has not been specified. */
111 : kRoot = 0x01, /**< A Matter Root certificate (RCAC). */
112 : kICA = 0x02, /**< A Matter Intermediate CA certificate (ICAC). */
113 : kNode = 0x03, /**< A Matter node operational certificate (NOC). */
114 : kFirmwareSigning = 0x04, /**< A Matter firmware signing certificate. Note that Matter doesn't
115 : specify how firmware images are signed and implementation of
116 : firmware image signing is manufacturer-specific. The Matter
117 : certificate format supports encoding of firmware signing
118 : certificates if chosen by the manufacturer to use them. */
119 : kNetworkIdentity = 0x05, /**< A Matter Network (Client) Identity. */
120 : kVidVerificationSigner = 0x06 /**< A Matter VendorID Verification Signer Certificate. */
121 : };
122 :
123 : /** X.509 Certificate Key Purpose Flags
124 : *
125 : * The flags order must match the enumeration order of corresponding kOID_KeyPurpose values.
126 : */
127 : enum class KeyPurposeFlags : uint8_t
128 : {
129 : kServerAuth = 0x01, /**< Extended key usage is server authentication. */
130 : kClientAuth = 0x02, /**< Extended key usage is client authentication. */
131 : kCodeSigning = 0x04, /**< Extended key usage is code signing. */
132 : kEmailProtection = 0x08, /**< Extended key usage is email protection. */
133 : kTimeStamping = 0x10, /**< Extended key usage is time stamping. */
134 : kOCSPSigning = 0x20, /**< Extended key usage is OCSP signing. */
135 : };
136 :
137 : /** X.509 Certificate Key Usage Flags
138 : */
139 : enum class KeyUsageFlags : uint16_t
140 : {
141 : kDigitalSignature = 0x0001, /**< Key usage is digital signature. */
142 : kNonRepudiation = 0x0002, /**< Key usage is non-repudiation. */
143 : kKeyEncipherment = 0x0004, /**< Key usage is key encipherment. */
144 : kDataEncipherment = 0x0008, /**< Key usage is data encipherment. */
145 : kKeyAgreement = 0x0010, /**< Key usage is key agreement. */
146 : kKeyCertSign = 0x0020, /**< Key usage is key cert signing. */
147 : kCRLSign = 0x0040, /**< Key usage is CRL signing. */
148 : kEncipherOnly = 0x0080, /**< Key usage is encipher only. */
149 : kDecipherOnly = 0x0100, /**< Key usage is decipher only. */
150 : };
151 :
152 : /** CHIP Certificate Flags
153 : *
154 : * Contains information about a certificate that has been loaded into a ChipCertificateData object.
155 : */
156 : enum class CertFlags : uint16_t
157 : {
158 : kExtPresent_BasicConstraints = 0x0001, /**< Basic constraints extension is present in the certificate. */
159 : kExtPresent_KeyUsage = 0x0002, /**< Key usage extension is present in the certificate. */
160 : kExtPresent_ExtendedKeyUsage = 0x0004, /**< Extended key usage extension is present in the certificate. */
161 : kExtPresent_SubjectKeyId = 0x0008, /**< Subject key identifier extension is present in the certificate. */
162 : kExtPresent_AuthKeyId = 0x0010, /**< Authority key identifier extension is present in the certificate. */
163 : kExtPresent_FutureIsCritical = 0x0020, /**< Future extension marked as critical is present in the certificate. */
164 : kPathLenConstraintPresent = 0x0040, /**< Path length constraint is present in the certificate. */
165 : kIsCA = 0x0080, /**< Indicates that certificate is a CA certificate. */
166 : kIsTrustAnchor = 0x0100, /**< Indicates that certificate is a trust anchor. */
167 : kTBSHashPresent = 0x0200, /**< Indicates that TBS hash of the certificate was generated and stored. */
168 : };
169 :
170 : /** CHIP Certificate Decode Flags
171 : *
172 : * Contains information specifying how a certificate should be decoded.
173 : */
174 : enum class CertDecodeFlags : uint8_t
175 : {
176 : kGenerateTBSHash = 0x01, /**< Indicates that to-be-signed (TBS) hash of the certificate should be calculated when certificate is
177 : loaded. The TBS hash is then used to validate certificate signature. Normally, all certificates
178 : (except trust anchor) in the certificate validation chain require TBS hash. */
179 : kIsTrustAnchor = 0x02, /**< Indicates that the corresponding certificate is trust anchor. */
180 : };
181 :
182 : enum
183 : {
184 : kNullCertTime = 0
185 : };
186 :
187 : /**
188 : * @struct ChipRDN
189 : *
190 : * @brief
191 : * A data structure representing a Relative Distinguished Name (RDN) in a CHIP certificate.
192 : */
193 : struct ChipRDN
194 : {
195 : CharSpan mString; /**< Attribute value when encoded as a string. */
196 : uint64_t mChipVal; /**< CHIP specific DN attribute value. */
197 : chip::ASN1::OID mAttrOID = chip::ASN1::kOID_NotSpecified; /**< DN attribute CHIP OID. */
198 : bool mAttrIsPrintableString; /**< Specifies if attribute is a printable string type. */
199 :
200 : bool IsEqual(const ChipRDN & other) const;
201 104776 : bool IsEmpty() const { return mAttrOID == chip::ASN1::kOID_NotSpecified; }
202 120170 : void Clear()
203 : {
204 120170 : mAttrOID = chip::ASN1::kOID_NotSpecified;
205 120170 : mAttrIsPrintableString = false;
206 120170 : mChipVal = 0;
207 120170 : mString = CharSpan{};
208 120170 : }
209 : };
210 :
211 : /**
212 : * @brief
213 : * A data structure representing a Distinguished Name (DN) in a CHIP certificate.
214 : */
215 : class ChipDN
216 : {
217 : public:
218 : ChipDN();
219 : ~ChipDN();
220 :
221 : void Clear();
222 :
223 : /**
224 : * @brief Add CHIP-specific attribute to the DN.
225 : *
226 : * @param oid CHIP-specific OID for DN attribute.
227 : * @param val CHIP-specific DN attribute value.
228 : *
229 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
230 : **/
231 : CHIP_ERROR AddAttribute(chip::ASN1::OID oid, uint64_t val);
232 :
233 : /**
234 : * @brief Add CASE Authenticated Tags (CATs) attributes to the DN.
235 : *
236 : * @param cats Array of CAT values.
237 : *
238 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
239 : **/
240 : CHIP_ERROR AddCATs(const chip::CATValues & cats);
241 :
242 : /**
243 : * @brief Add string attribute to the DN.
244 : *
245 : * @param oid String OID for DN attribute.
246 : * @param val A CharSpan object containing a pointer and length of the DN string attribute
247 : * buffer. The value in the buffer should remain valid while the object is in use.
248 : * @param isPrintableString Specifies if attribute ASN1 type is a printable string.
249 : *
250 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
251 : **/
252 : CHIP_ERROR AddAttribute(chip::ASN1::OID oid, CharSpan val, bool isPrintableString);
253 :
254 0 : inline CHIP_ERROR AddAttribute_CommonName(CharSpan val, bool isPrintableString)
255 : {
256 0 : return AddAttribute(ASN1::kOID_AttributeType_CommonName, val, isPrintableString);
257 : }
258 : inline CHIP_ERROR AddAttribute_Surname(CharSpan val, bool isPrintableString)
259 : {
260 : return AddAttribute(ASN1::kOID_AttributeType_Surname, val, isPrintableString);
261 : }
262 : inline CHIP_ERROR AddAttribute_SerialNumber(CharSpan val, bool isPrintableString)
263 : {
264 : return AddAttribute(ASN1::kOID_AttributeType_SerialNumber, val, isPrintableString);
265 : }
266 : inline CHIP_ERROR AddAttribute_CountryName(CharSpan val, bool isPrintableString)
267 : {
268 : return AddAttribute(ASN1::kOID_AttributeType_CountryName, val, isPrintableString);
269 : }
270 : inline CHIP_ERROR AddAttribute_LocalityName(CharSpan val, bool isPrintableString)
271 : {
272 : return AddAttribute(ASN1::kOID_AttributeType_LocalityName, val, isPrintableString);
273 : }
274 : inline CHIP_ERROR AddAttribute_StateOrProvinceName(CharSpan val, bool isPrintableString)
275 : {
276 : return AddAttribute(ASN1::kOID_AttributeType_StateOrProvinceName, val, isPrintableString);
277 : }
278 : inline CHIP_ERROR AddAttribute_OrganizationName(CharSpan val, bool isPrintableString)
279 : {
280 : return AddAttribute(ASN1::kOID_AttributeType_OrganizationName, val, isPrintableString);
281 : }
282 : inline CHIP_ERROR AddAttribute_OrganizationalUnitName(CharSpan val, bool isPrintableString)
283 : {
284 : return AddAttribute(ASN1::kOID_AttributeType_OrganizationalUnitName, val, isPrintableString);
285 : }
286 : inline CHIP_ERROR AddAttribute_Title(CharSpan val, bool isPrintableString)
287 : {
288 : return AddAttribute(ASN1::kOID_AttributeType_Title, val, isPrintableString);
289 : }
290 : inline CHIP_ERROR AddAttribute_Name(CharSpan val, bool isPrintableString)
291 : {
292 : return AddAttribute(ASN1::kOID_AttributeType_Name, val, isPrintableString);
293 : }
294 : inline CHIP_ERROR AddAttribute_GivenName(CharSpan val, bool isPrintableString)
295 : {
296 : return AddAttribute(ASN1::kOID_AttributeType_GivenName, val, isPrintableString);
297 : }
298 : inline CHIP_ERROR AddAttribute_Initials(CharSpan val, bool isPrintableString)
299 : {
300 : return AddAttribute(ASN1::kOID_AttributeType_Initials, val, isPrintableString);
301 : }
302 : inline CHIP_ERROR AddAttribute_GenerationQualifier(CharSpan val, bool isPrintableString)
303 : {
304 : return AddAttribute(ASN1::kOID_AttributeType_GenerationQualifier, val, isPrintableString);
305 : }
306 : inline CHIP_ERROR AddAttribute_DNQualifier(CharSpan val, bool isPrintableString)
307 : {
308 : return AddAttribute(ASN1::kOID_AttributeType_DNQualifier, val, isPrintableString);
309 : }
310 : inline CHIP_ERROR AddAttribute_Pseudonym(CharSpan val, bool isPrintableString)
311 : {
312 : return AddAttribute(ASN1::kOID_AttributeType_Pseudonym, val, isPrintableString);
313 : }
314 : inline CHIP_ERROR AddAttribute_DomainComponent(CharSpan val, bool isPrintableString)
315 : {
316 : return AddAttribute(ASN1::kOID_AttributeType_DomainComponent, val, isPrintableString);
317 : }
318 2 : inline CHIP_ERROR AddAttribute_MatterNodeId(uint64_t val) { return AddAttribute(ASN1::kOID_AttributeType_MatterNodeId, val); }
319 : inline CHIP_ERROR AddAttribute_MatterFirmwareSigningId(uint64_t val)
320 : {
321 : return AddAttribute(ASN1::kOID_AttributeType_MatterFirmwareSigningId, val);
322 : }
323 2 : inline CHIP_ERROR AddAttribute_MatterICACId(uint64_t val) { return AddAttribute(ASN1::kOID_AttributeType_MatterICACId, val); }
324 2 : inline CHIP_ERROR AddAttribute_MatterRCACId(uint64_t val) { return AddAttribute(ASN1::kOID_AttributeType_MatterRCACId, val); }
325 2 : inline CHIP_ERROR AddAttribute_MatterFabricId(uint64_t val)
326 : {
327 2 : return AddAttribute(ASN1::kOID_AttributeType_MatterFabricId, val);
328 : }
329 0 : inline CHIP_ERROR AddAttribute_MatterCASEAuthTag(CASEAuthTag val)
330 : {
331 0 : return AddAttribute(ASN1::kOID_AttributeType_MatterCASEAuthTag, val);
332 : }
333 : inline CHIP_ERROR AddAttribute_MatterVidVerificationSignerId(uint64_t val)
334 : {
335 : return AddAttribute(ASN1::kOID_AttributeType_MatterVidVerificationSignerId, val);
336 : }
337 :
338 : /**
339 : * @brief Determine type of a CHIP certificate.
340 : * This method performs an assessment of a certificate's type based on the structure
341 : * of its subject DN.
342 : *
343 : * @param certType A reference to the certificate type value.
344 : *
345 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
346 : **/
347 : CHIP_ERROR GetCertType(CertType & certType) const;
348 :
349 : /**
350 : * @brief Retrieve the ID of a CHIP certificate.
351 : *
352 : * @param certId A reference to the certificate ID value.
353 : *
354 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
355 : **/
356 : CHIP_ERROR GetCertChipId(uint64_t & certId) const;
357 :
358 : /**
359 : * @brief Retrieve the Fabric ID of a CHIP certificate.
360 : **/
361 : CHIP_ERROR GetCertFabricId(uint64_t & fabricId) const;
362 :
363 : /**
364 : * @brief Encode ChipDN attributes in TLV form.
365 : **/
366 : CHIP_ERROR EncodeToTLV(chip::TLV::TLVWriter & writer, TLV::Tag tag) const;
367 :
368 : /**
369 : * @brief Decode ChipDN attributes from TLV encoded format.
370 : *
371 : * @param reader A TLVReader positioned at the ChipDN TLV list.
372 : **/
373 : CHIP_ERROR DecodeFromTLV(chip::TLV::TLVReader & reader);
374 :
375 : /**
376 : * @brief Encode ChipDN attributes in ASN1 form.
377 : **/
378 : CHIP_ERROR EncodeToASN1(ASN1::ASN1Writer & writer) const;
379 :
380 : /**
381 : * @brief Decode ChipDN attributes from ASN1 encoded format.
382 : *
383 : * @param reader A ASN1Reader positioned at the ChipDN ASN1 list.
384 : **/
385 : CHIP_ERROR DecodeFromASN1(ASN1::ASN1Reader & reader);
386 :
387 : bool IsEqual(const ChipDN & other) const;
388 :
389 : /**
390 : * @brief Determine if DN is empty (doesn't have DN attributes).
391 : *
392 : * @return true if DN is empty, false otherwise.
393 : **/
394 : bool IsEmpty() const { return RDNCount() == 0; }
395 :
396 : static_assert((CHIP_CONFIG_CERT_MAX_RDN_ATTRIBUTES) >= 5, "Spec requires at least 5 RDN to be supported per Matter TLV cert");
397 : ChipRDN rdn[CHIP_CONFIG_CERT_MAX_RDN_ATTRIBUTES];
398 :
399 : uint8_t RDNCount() const;
400 : };
401 :
402 : /**
403 : * @brief A data structure for holding a certificate key identifier, without the ownership of it.
404 : */
405 : using CertificateKeyId = FixedByteSpan<kKeyIdentifierLength>;
406 :
407 : /**
408 : * @brief A mutable `CertificateKeyId`.
409 : */
410 : using MutableCertificateKeyId = FixedSpan<uint8_t, kKeyIdentifierLength>;
411 :
412 : /**
413 : * @brief A storage type for `CertificateKeyId` and `MutableCertificateKeyId`.
414 : */
415 : using CertificateKeyIdStorage = std::array<uint8_t, kKeyIdentifierLength>;
416 :
417 : /**
418 : * @brief A data structure for holding a P256 ECDSA signature, without the ownership of it.
419 : */
420 : using P256ECDSASignatureSpan = FixedByteSpan<Crypto::kP256_ECDSA_Signature_Length_Raw>;
421 :
422 : /**
423 : * @brief A data structure for holding a P256 Public Key, without the ownership of it.
424 : */
425 : using P256PublicKeySpan = FixedByteSpan<Crypto::kP256_PublicKey_Length>;
426 :
427 : /**
428 : * @brief A data structure for holding a P256 Integer, without the ownership of it.
429 : */
430 : using P256IntegerSpan = FixedByteSpan<Crypto::kP256_FE_Length>;
431 :
432 : /**
433 : * @struct ChipCertificateData
434 : *
435 : * @brief
436 : * In-memory representation of data extracted from a CHIP certificate.
437 : *
438 : * Some of the fields in this structure are pointers to the fields in the original
439 : * CHIP certificate. That CHIP certificate is stored in a separate buffer and it is
440 : * required that data in that buffer remains valid while the corresponding
441 : * ChipCertificateData structure is used.
442 : */
443 : struct ChipCertificateData
444 : {
445 : ChipCertificateData();
446 : ~ChipCertificateData();
447 :
448 : void Clear();
449 : bool IsEqual(const ChipCertificateData & other) const;
450 :
451 : ByteSpan mSerialNumber; /**< Certificate Serial Number. */
452 : ChipDN mSubjectDN; /**< Certificate Subject DN. */
453 : ChipDN mIssuerDN; /**< Certificate Issuer DN. */
454 : CertificateKeyId mSubjectKeyId; /**< Certificate Subject public key identifier. */
455 : CertificateKeyId mAuthKeyId; /**< Certificate Authority public key identifier. */
456 : uint32_t mNotBeforeTime; /**< Certificate validity: Not Before field. */
457 : uint32_t mNotAfterTime; /**< Certificate validity: Not After field. */
458 : P256PublicKeySpan mPublicKey; /**< Certificate public key. */
459 : uint16_t mPubKeyCurveOID; /**< Public key Elliptic Curve CHIP OID. */
460 : uint16_t mPubKeyAlgoOID; /**< Public key algorithm CHIP OID. */
461 : uint16_t mSigAlgoOID; /**< Certificate signature algorithm CHIP OID. */
462 : BitFlags<CertFlags> mCertFlags; /**< Certificate data flags. */
463 : BitFlags<KeyUsageFlags> mKeyUsageFlags; /**< Certificate key usage extensions flags. */
464 : BitFlags<KeyPurposeFlags> mKeyPurposeFlags; /**< Certificate extended key usage extensions flags. */
465 : uint8_t mPathLenConstraint; /**< Basic constraint: path length. */
466 : P256ECDSASignatureSpan mSignature; /**< Certificate signature. */
467 :
468 : uint8_t mTBSHash[Crypto::kSHA256_Hash_Length]; /**< Certificate TBS hash. */
469 : };
470 :
471 : /**
472 : * @brief Decode CHIP certificate.
473 : * It is required that the CHIP certificate in the chipCert buffer stays valid while
474 : * the certData is used.
475 : *
476 : * @param chipCert Buffer containing CHIP certificate.
477 : * @param certData Structure containing data extracted from the CHIP certificate.
478 : *
479 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
480 : **/
481 : CHIP_ERROR DecodeChipCert(const ByteSpan chipCert, ChipCertificateData & certData, BitFlags<CertDecodeFlags> decodeFlags = {});
482 :
483 : /**
484 : * @brief Decode CHIP certificate.
485 : * It is required that the CHIP certificate in the reader's underlying buffer stays valid while
486 : * the certData is used.
487 : *
488 : * @param reader A TLVReader positioned at the CHIP certificate TLV structure.
489 : * @param certData Structure containing data extracted from the CHIP certificate.
490 : *
491 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
492 : **/
493 : CHIP_ERROR DecodeChipCert(chip::TLV::TLVReader & reader, ChipCertificateData & certData,
494 : BitFlags<CertDecodeFlags> decodeFlags = {});
495 :
496 : /**
497 : * @brief Decode CHIP Distinguished Name (DN).
498 : * It is required that the CHIP DN in the reader's underlying buffer stays valid while
499 : * the dn structure is used.
500 : *
501 : * @param reader A TLVReader positioned at the CHIP DN TLV structure.
502 : * @param dn Distinguished Name structure.
503 : *
504 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
505 : **/
506 : CHIP_ERROR DecodeChipDN(chip::TLV::TLVReader & reader, ChipDN & dn);
507 :
508 : /**
509 : * @brief Convert standard X.509 certificate to CHIP certificate.
510 : *
511 : * @param x509Cert CHIP X.509 DER encoded certificate.
512 : * @param chipCert Buffer to store converted certificate in CHIP format.
513 : *
514 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
515 : **/
516 : CHIP_ERROR ConvertX509CertToChipCert(const ByteSpan x509Cert, MutableByteSpan & chipCert);
517 :
518 : /**
519 : * @brief Convert CHIP certificate to the standard X.509 DER encoded certificate.
520 : *
521 : * @param chipCert CHIP certificate in CHIP TLV encoding.
522 : * @param x509Cert Buffer to store converted certificate in X.509 DER format.
523 : *
524 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
525 : **/
526 : CHIP_ERROR ConvertChipCertToX509Cert(const ByteSpan chipCert, MutableByteSpan & x509Cert);
527 :
528 : /**
529 : * @brief Verifies the signature of a certificate.
530 : *
531 : * @param cert The certificate to be verified.
532 : * @param signer The certificate containing the public key used to verify the signature.
533 : *
534 : * @return Returns a CHIP_ERROR on validation or other error, CHIP_NO_ERROR otherwise
535 : *
536 : * The certificate to be verified must have been decoded with TBS hash calculation enabled.
537 : *
538 : * Note that this function performs ONLY signature verification. No Subject and Issuer DN
539 : * comparison, Key Usage extension checks or similar validation is performed.
540 : **/
541 : CHIP_ERROR VerifyCertSignature(const ChipCertificateData & cert, const ChipCertificateData & signer);
542 :
543 : /**
544 : * Validate CHIP Root CA Certificate (RCAC) in ByteSpan TLV-encoded form.
545 : * This function performs RCAC parsing, checks SubjectDN validity, verifies that SubjectDN
546 : * and IssuerDN are equal, verifies that SKID and AKID are equal, validates certificate signature.
547 : *
548 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
549 : */
550 : CHIP_ERROR ValidateChipRCAC(const ByteSpan & rcac);
551 :
552 : /**
553 : * Validates a Network (Client) Identity in TLV-encoded form.
554 : * Accepts either a full certificate or the compact-pdc-identity format.
555 : *
556 : * This function parses the certificate, ensures the rigid fields have the values mandated by the
557 : * specification, and validates the certificate signature.
558 : *
559 : * @param cert The network identity certificate to validate.
560 : *
561 : * @return CHIP_NO_ERROR on success, CHIP_ERROR_WRONG_CERT_TYPE if the certificate does
562 : * not conform to the requirements for a Network Identity, CHIP_ERROR_INVALID_SIGNATURE
563 : * if the certificate has an invalid signature, or another CHIP_ERROR.
564 : *
565 : * @see section 11.24 (Wi-Fi Authentication with Per-Device Credentials) of the Matter spec
566 : */
567 : CHIP_ERROR ValidateChipNetworkIdentity(const ByteSpan & cert);
568 :
569 : /**
570 : * Convenience variant of `ValidateChipNetworkIdentity` that, upon successful validation, also
571 : * calculates the key identifier for the Network (Client) Identity.
572 : * @see ValidateChipNetworkIdentity
573 : * @see ExtractIdentifierFromChipNetworkIdentity
574 : */
575 : CHIP_ERROR ValidateChipNetworkIdentity(const ByteSpan & cert, MutableCertificateKeyId outKeyId);
576 :
577 : struct FutureExtension
578 : {
579 : ByteSpan OID;
580 : ByteSpan Extension;
581 : };
582 :
583 : struct X509CertRequestParams
584 : {
585 : int64_t SerialNumber;
586 : uint32_t ValidityStart;
587 : uint32_t ValidityEnd;
588 : ChipDN SubjectDN;
589 : ChipDN IssuerDN;
590 : Optional<FutureExtension> FutureExt;
591 : };
592 :
593 : /**
594 : * @brief Generate a new X.509 DER encoded Root CA certificate
595 : *
596 : * @param requestParams Certificate request parameters.
597 : * @param issuerKeypair The certificate signing key
598 : * @param x509Cert Buffer to store signed certificate in X.509 DER format.
599 : *
600 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
601 : **/
602 : CHIP_ERROR NewRootX509Cert(const X509CertRequestParams & requestParams, const Crypto::P256Keypair & issuerKeypair,
603 : MutableByteSpan & x509Cert);
604 :
605 : /**
606 : * @brief Generate a new X.509 DER encoded Intermediate CA certificate
607 : *
608 : * @param requestParams Certificate request parameters.
609 : * @param subjectPubkey The public key of subject
610 : * @param issuerKeypair The certificate signing key
611 : * @param x509Cert Buffer to store signed certificate in X.509 DER format.
612 : *
613 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
614 : **/
615 : CHIP_ERROR NewICAX509Cert(const X509CertRequestParams & requestParams, const Crypto::P256PublicKey & subjectPubkey,
616 : const Crypto::P256Keypair & issuerKeypair, MutableByteSpan & x509Cert);
617 :
618 : /**
619 : * @brief Generate a new X.509 DER encoded Node operational certificate
620 : *
621 : * @param requestParams Certificate request parameters.
622 : * @param subjectPubkey The public key of subject
623 : * @param issuerKeypair The certificate signing key
624 : * @param x509Cert Buffer to store signed certificate in X.509 DER format.
625 : *
626 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
627 : **/
628 : CHIP_ERROR NewNodeOperationalX509Cert(const X509CertRequestParams & requestParams, const Crypto::P256PublicKey & subjectPubkey,
629 : const Crypto::P256Keypair & issuerKeypair, MutableByteSpan & x509Cert);
630 :
631 : /**
632 : * @brief Generates a Network (Client) Identity certificate in TLV-encoded form.
633 : *
634 : * @param keypair The key pair underlying the identity.
635 : * @param outCompactCert Buffer to store the signed certificate in compact-pdc-identity TLV format.
636 : * Must be at least `kMaxCHIPCompactNetworkIdentityLength` bytes long.
637 : *
638 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
639 : **/
640 : CHIP_ERROR NewChipNetworkIdentity(const Crypto::P256Keypair & keypair, MutableByteSpan & outCompactCert);
641 :
642 : /**
643 : * @brief Generate a new X.509 DER encoded VendorID Verification Signer CA certificate
644 : *
645 : * @param requestParams Certificate request parameters.
646 : * @param subjectPubkey The public key of subject
647 : * @param issuerKeypair The certificate signing key
648 : * @param x509Cert Buffer to store signed certificate in X.509 DER format.
649 : *
650 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise
651 : **/
652 : CHIP_ERROR NewVidVerificationSignerX509Cert(const X509CertRequestParams & requestParams,
653 : const Crypto::P256PublicKey & subjectPubkey, const Crypto::P256Keypair & issuerKeypair,
654 : MutableByteSpan & x509Cert);
655 :
656 : /**
657 : * @brief
658 : * Convert a certificate date/time (in the form of an ASN.1 universal time structure) into a CHIP Epoch time.
659 : *
660 : * @note
661 : * This function makes no attempt to verify the correct range of the input time other than year.
662 : * Therefore callers must make sure the supplied values are valid prior to invocation.
663 : *
664 : * @param asn1Time The calendar date/time to be converted.
665 : * @param epochTime A reference to an integer that will receive CHIP Epoch time.
666 : *
667 : * @retval #CHIP_NO_ERROR If the input time was successfully converted.
668 : * @retval #ASN1_ERROR_UNSUPPORTED_ENCODING If the input time contained a year value that could not
669 : * be represented in a CHIP epoch UTC time value.
670 : **/
671 : CHIP_ERROR ASN1ToChipEpochTime(const chip::ASN1::ASN1UniversalTime & asn1Time, uint32_t & epochTime);
672 :
673 : /**
674 : * @brief
675 : * Convert a CHIP epoch UTC time into an ASN.1 universal time structure.
676 : *
677 : * @param epochTime A CHIP epoch UTC time to be converted.
678 : * @param asn1Time A reference to an ASN1UniversalTime structure to receive the date/time.
679 : *
680 : * @retval #CHIP_NO_ERROR If the input time was successfully converted.
681 : */
682 : CHIP_ERROR ChipEpochToASN1Time(uint32_t epochTime, chip::ASN1::ASN1UniversalTime & asn1Time);
683 :
684 : /**
685 : * @return True if the OID represents a CHIP-defined 64-bit distinguished named attribute.
686 : **/
687 36403 : inline bool IsChip64bitDNAttr(chip::ASN1::OID oid)
688 : {
689 31929 : return (oid == chip::ASN1::kOID_AttributeType_MatterNodeId || oid == chip::ASN1::kOID_AttributeType_MatterFirmwareSigningId ||
690 24887 : oid == chip::ASN1::kOID_AttributeType_MatterICACId || oid == chip::ASN1::kOID_AttributeType_MatterRCACId ||
691 68332 : oid == chip::ASN1::kOID_AttributeType_MatterFabricId ||
692 36403 : oid == chip::ASN1::kOID_AttributeType_MatterVidVerificationSignerId);
693 : }
694 :
695 : /**
696 : * @return True if the OID represents a CHIP-defined 32-bit distinguished named attribute.
697 : **/
698 11248 : inline bool IsChip32bitDNAttr(chip::ASN1::OID oid)
699 : {
700 11248 : return (oid == chip::ASN1::kOID_AttributeType_MatterCASEAuthTag);
701 : }
702 :
703 : /**
704 : * @return True if the OID represents a CHIP-defined distinguished named attribute.
705 : **/
706 15727 : inline bool IsChipDNAttr(chip::ASN1::OID oid)
707 : {
708 15727 : return (IsChip64bitDNAttr(oid) || IsChip32bitDNAttr(oid));
709 : }
710 :
711 : /**
712 : * @brief Convert an ASN.1 DER encoded integer to a raw big-endian integer.
713 : *
714 : * @param derInt P256 integer in ASN.1 DER encoded form.
715 : * @param rawInt Buffer to store converted raw integer.
716 : * @param rawIntLen The length of the converted raw integer.
717 : *
718 : * @retval #CHIP_NO_ERROR If the integer value was successfully converted.
719 : */
720 : CHIP_ERROR ConvertIntegerDERToRaw(ByteSpan derInt, uint8_t * rawInt, const uint16_t rawIntLen);
721 :
722 : /**
723 : * @brief Convert a raw CHIP signature to an ASN.1 DER encoded signature structure.
724 : *
725 : * @param[in] rawSig P256 ECDSA signature in raw form.
726 : * @param[in,out] derSig Output buffer to receive the converted ASN.1 DER encoded signature.
727 : * `derSig` must be at least `kMax_ECDSA_Signature_Length_Der` bytes long.
728 : * The `derSig` size will be set to the actual DER encoded signature length on success.
729 : *
730 : * @retval #CHIP_NO_ERROR If the signature value was successfully converted.
731 : */
732 : CHIP_ERROR ConvertECDSASignatureRawToDER(P256ECDSASignatureSpan rawSig, MutableByteSpan & derSig);
733 :
734 : /**
735 : * @brief Convert a raw CHIP ECDSA signature to an ASN.1 DER encoded signature structure.
736 : *
737 : * @param rawSig P256 ECDSA signature in raw form.
738 : * @param writer A reference to the ASN1Writer to store ASN.1 DER encoded signature.
739 : *
740 : * @retval #CHIP_NO_ERROR If the signature value was successfully converted.
741 : */
742 : CHIP_ERROR ConvertECDSASignatureRawToDER(P256ECDSASignatureSpan rawSig, ASN1::ASN1Writer & writer);
743 :
744 : /**
745 : * @brief Convert an ASN.1 DER encoded ECDSA signature to a raw CHIP signature.
746 : *
747 : * @param reader A reference to the ASN1Reader positioned at the beginning of the
748 : * DER encoded ECDSA signature.
749 : * @param writer A reference to the TLVWriter to store TLV encoded ECDSA signature element.
750 : * @param tag Tag to use for TLV encoded signature.
751 : *
752 : * @retval #CHIP_NO_ERROR If the signature value was successfully converted.
753 : */
754 : CHIP_ERROR ConvertECDSASignatureDERToRaw(ASN1::ASN1Reader & reader, chip::TLV::TLVWriter & writer, uint64_t tag);
755 :
756 : /**
757 : * @brief Convert a raw ECDSA P256 key pair to an ASN.1 DER encoded ECPrivateKey structure (RFC 5915).
758 : *
759 : * @param rawKeypair The raw P256 key pair.
760 : * @param outDerKeypair Output buffer to receive the ASN.1 DER encoded key pair.
761 : * Must have a capacity of at least `kP256ECPrivateKeyDERLength` bytes.
762 : *
763 : * @retval #CHIP_NO_ERROR If the key pair was successfully converted, or a CHIP_ERROR otherwise.
764 : */
765 : CHIP_ERROR ConvertECDSAKeypairRawToDER(const Crypto::P256SerializedKeypair & rawKeypair, MutableByteSpan & outDerKeypair);
766 :
767 : /**
768 : * Extract the Fabric ID from an operational certificate that has already been
769 : * parsed.
770 : *
771 : * This function can be used to extract Fabric ID from an ICA certificate.
772 : * These certificates may not contain a NodeID, so ExtractNodeIdFabricIdFromOpCert()
773 : * cannot be used for such certificates.
774 : *
775 : * @return CHIP_ERROR_NOT_FOUND if the passed-in cert does not have RDN
776 : * corresponding to FabricID.
777 : */
778 : CHIP_ERROR ExtractFabricIdFromCert(const ChipCertificateData & cert, FabricId * fabricId);
779 :
780 : /**
781 : * Extract Node ID and Fabric ID from an operational certificate that has already been
782 : * parsed.
783 : *
784 : * @return CHIP_ERROR_NOT_FOUND if the passed-in cert does not have at
785 : * least one NodeId RDN and one FabricId RDN in the Subject DN. No other
786 : * validation (e.g. checkign that there is exactly one RDN of each type) is
787 : * performed.
788 : */
789 : CHIP_ERROR ExtractNodeIdFabricIdFromOpCert(const ChipCertificateData & opcert, NodeId * nodeId, FabricId * fabricId);
790 :
791 : /**
792 : * Extract Node ID, Fabric ID and Compressed Fabric ID from an operational
793 : * certificate and its associated root certificate.
794 : *
795 : * @return CHIP_ERROR on failure or CHIP_NO_ERROR otherwise.
796 : */
797 : CHIP_ERROR ExtractNodeIdFabricIdCompressedFabricIdFromOpCerts(ByteSpan rcac, ByteSpan noc, CompressedFabricId & compressedFabricId,
798 : FabricId & fabricId, NodeId & nodeId);
799 :
800 : /**
801 : * Extract Node ID and Compressed Fabric ID from an operational certificate
802 : * and its associated root certificate.
803 : *
804 : * @return CHIP_ERROR on failure or CHIP_NO_ERROR otherwise.
805 : */
806 : CHIP_ERROR ExtractNodeIdCompressedFabricIdFromOpCerts(ByteSpan rcac, ByteSpan noc, CompressedFabricId & compressedFabricId,
807 : NodeId & nodeId);
808 :
809 : /**
810 : * Extract CASE Authenticated Tags from an operational certificate in ByteSpan TLV-encoded form.
811 : *
812 : * All values in the 'cats' struct will be set either to a valid CAT value or zero (undefined) value.
813 : *
814 : * @return CHIP_ERROR_INVALID_ARGUMENT if the passed-in cert is not NOC.
815 : * @return CHIP_ERROR_BUFFER_TOO_SMALL if there are too many CATs in the NOC
816 : */
817 : CHIP_ERROR ExtractCATsFromOpCert(const ByteSpan & opcert, CATValues & cats);
818 :
819 : /**
820 : * Extract CASE Authenticated Tags from an operational certificate that has already been
821 : * parsed.
822 : *
823 : * All values in the 'cats' struct will be set either to a valid CAT value or to the kUndefinedCAT value.
824 : *
825 : * @return CHIP_ERROR_INVALID_ARGUMENT if the passed-in cert is not NOC.
826 : * @return CHIP_ERROR_BUFFER_TOO_SMALL if the passed-in CATs array is too small.
827 : */
828 : CHIP_ERROR ExtractCATsFromOpCert(const ChipCertificateData & opcert, CATValues & cats);
829 :
830 : /**
831 : * Extract Fabric ID from an operational certificate in ByteSpan TLV-encoded
832 : * form. This does not perform any sort of validation on the certificate
833 : * structure other than parsing it.
834 : *
835 : * Can return any error that can be returned from parsing the cert or from the
836 : * ChipCertificateData* version of ExtractNodeIdFabricIdFromOpCert.
837 : */
838 : CHIP_ERROR ExtractFabricIdFromCert(const ByteSpan & opcert, FabricId * fabricId);
839 :
840 : /**
841 : * Extract Node ID and Fabric ID from an operational certificate in ByteSpan TLV-encoded
842 : * form. This does not perform any sort of validation on the certificate
843 : * structure other than parsing it.
844 : *
845 : * Can return any error that can be returned from parsing the cert or from the
846 : * ChipCertificateData* version of ExtractNodeIdFabricIdFromOpCert.
847 : */
848 : CHIP_ERROR ExtractNodeIdFabricIdFromOpCert(const ByteSpan & opcert, NodeId * nodeId, FabricId * fabricId);
849 :
850 : /**
851 : * Extract Public Key from a chip certificate in ByteSpan TLV-encoded form.
852 : * This does not perform any sort of validation on the certificate structure
853 : * other than parsing it.
854 : *
855 : * Can return any error that can be returned from parsing the cert.
856 : */
857 : CHIP_ERROR ExtractPublicKeyFromChipCert(const ByteSpan & chipCert, P256PublicKeySpan & publicKey);
858 :
859 : /**
860 : * Extract Not Before Time from a chip certificate in ByteSpan TLV-encoded form.
861 : * Output format is seconds referenced from the CHIP epoch.
862 : *
863 : * This does not perform any sort of validation on the certificate structure
864 : * other than parsing it.
865 : *
866 : * @param chipCert CHIP certificate in TLV-encoded form
867 : * @param notBeforeChipEpochTime (out) certificate NotBefore time as seconds from the CHIP epoch
868 : * @return CHIP_NO_ERROR if certificate parsing was successful, else an appropriate CHIP_ERROR
869 : */
870 : CHIP_ERROR ExtractNotBeforeFromChipCert(const ByteSpan & chipCert, chip::System::Clock::Seconds32 & notBeforeChipEpochTime);
871 :
872 : /**
873 : * Extract Subject Key Identifier from a chip certificate in ByteSpan TLV-encoded form.
874 : * This does not perform any sort of validation on the certificate structure
875 : * other than parsing it.
876 : *
877 : * Can return any error that can be returned from parsing the cert.
878 : */
879 : CHIP_ERROR ExtractSKIDFromChipCert(const ByteSpan & chipCert, CertificateKeyId & skid);
880 :
881 : /**
882 : * Extract Subject Distinguished Name (DN) from a chip certificate in ByteSpan TLV-encoded form.
883 : * It is required that the certificate in the chipCert buffer stays valid while the `dn` output is used.
884 : *
885 : * Can return any error that can be returned from parsing the cert.
886 : */
887 : CHIP_ERROR ExtractSubjectDNFromChipCert(const ByteSpan & chipCert, ChipDN & dn);
888 :
889 : /**
890 : * Extract Subject Distinguished Name (DN) from a chip certificate in ByteSpan X509 DER-encoded form.
891 : * It is required that the certificate in the chipCert buffer stays valid while the `dn` output is used.
892 : *
893 : * Can return any error that can be returned from converting and parsing the cert.
894 : */
895 : CHIP_ERROR ExtractSubjectDNFromX509Cert(const ByteSpan & x509Cert, ChipDN & dn);
896 :
897 : /**
898 : * Extracts the key identifier from a Network (Client) Identity in TLV-encoded form.
899 : * Does NOT perform full validation of the identity certificate.
900 : *
901 : * @return CHIP_NO_ERROR on success, CHIP_ERROR_WRONG_CERT_TYPE if the certificate is
902 : * not a Network (Client) Identity, or another CHIP_ERROR if parsing fails.
903 : */
904 : CHIP_ERROR ExtractIdentifierFromChipNetworkIdentity(const ByteSpan & cert, MutableCertificateKeyId outKeyId);
905 :
906 : } // namespace Credentials
907 : } // namespace chip
|