deeb94b8b590fbdf93dd20e4f8eac29ae3b1965c
[platform/upstream/connectedhomeip.git] / src / credentials / tests / TestChipCert.cpp
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  *      Unit tests for CHIP certificate functionality.
24  *
25  */
26
27 #include <core/CHIPTLV.h>
28 #include <credentials/CHIPCert.h>
29 #include <support/CHIPMem.h>
30 #include <support/CodeUtils.h>
31 #include <support/ErrorStr.h>
32 #include <support/UnitTestRegistration.h>
33
34 #include <nlunit-test.h>
35
36 #include "CHIPCert_test_vectors.h"
37
38 using namespace chip;
39 using namespace chip::ASN1;
40 using namespace chip::TLV;
41 using namespace chip::Credentials;
42 using namespace chip::TestCerts;
43
44 enum
45 {
46     kStandardCertsCount = 3,
47     kTestCertBufSize    = 1024, // Size of buffer needed to hold any of the test certificates
48                                 // (in either CHIP or DER form), or to decode the certificates.
49 };
50
51 static const BitFlags<uint8_t, CertValidateFlags> sIgnoreNotBeforeFlag(CertValidateFlags::kIgnoreNotBefore);
52 static const BitFlags<uint8_t, CertValidateFlags> sIgnoreNotAfterFlag(CertValidateFlags::kIgnoreNotAfter);
53
54 static const BitFlags<uint8_t, CertDecodeFlags> sNullDecodeFlag;
55 static const BitFlags<uint8_t, CertDecodeFlags> sGenTBSHashFlag(CertDecodeFlags::kGenerateTBSHash);
56 static const BitFlags<uint8_t, CertDecodeFlags> sTrustAnchorFlag(CertDecodeFlags::kIsTrustAnchor);
57
58 static const BitFlags<uint8_t, TestCertLoadFlags> sNullLoadFlag;
59 static const BitFlags<uint8_t, TestCertLoadFlags> sDerFormFlag(TestCertLoadFlags::kDERForm);
60 static const BitFlags<uint8_t, TestCertLoadFlags> sSupIsCAFlag(TestCertLoadFlags::kSuppressIsCA);
61 static const BitFlags<uint8_t, TestCertLoadFlags> sSupKeyUsageFlag(TestCertLoadFlags::kSuppressKeyUsage);
62 static const BitFlags<uint8_t, TestCertLoadFlags> sSupKeyCertSignFlag(TestCertLoadFlags::kSuppressKeyCertSign);
63 static const BitFlags<uint8_t, TestCertLoadFlags> sPathLenZeroFlag(TestCertLoadFlags::kSetPathLenConstZero);
64 static const BitFlags<uint8_t, TestCertLoadFlags> sAppDefCertTypeFlag(TestCertLoadFlags::kSetAppDefinedCertType);
65
66 static const BitFlags<uint8_t, KeyPurposeFlags> sNullKPFlag;
67 static const BitFlags<uint8_t, KeyPurposeFlags> sSA(KeyPurposeFlags::kServerAuth);
68 static const BitFlags<uint8_t, KeyPurposeFlags> sCA(KeyPurposeFlags::kClientAuth);
69 static const BitFlags<uint8_t, KeyPurposeFlags> sCS(KeyPurposeFlags::kCodeSigning);
70 static const BitFlags<uint8_t, KeyPurposeFlags> sEP(KeyPurposeFlags::kEmailProtection);
71 static const BitFlags<uint8_t, KeyPurposeFlags> sTS(KeyPurposeFlags::kTimeStamping);
72 static const BitFlags<uint8_t, KeyPurposeFlags> sOS(KeyPurposeFlags::kOCSPSigning);
73 static const BitFlags<uint8_t, KeyPurposeFlags> sSAandCA(sSA.Raw() | sCA.Raw());
74 static const BitFlags<uint8_t, KeyPurposeFlags> sSAandCS(sSA.Raw() | sCS.Raw());
75 static const BitFlags<uint8_t, KeyPurposeFlags> sSAandEP(sSA.Raw() | sEP.Raw());
76 static const BitFlags<uint8_t, KeyPurposeFlags> sSAandTS(sSA.Raw() | sTS.Raw());
77
78 static const BitFlags<uint16_t, KeyUsageFlags> sNullKUFlag;
79 static const BitFlags<uint16_t, KeyUsageFlags> sDS(KeyUsageFlags::kDigitalSignature);
80 static const BitFlags<uint16_t, KeyUsageFlags> sNR(KeyUsageFlags::kNonRepudiation);
81 static const BitFlags<uint16_t, KeyUsageFlags> sKE(KeyUsageFlags::kKeyEncipherment);
82 static const BitFlags<uint16_t, KeyUsageFlags> sDE(KeyUsageFlags::kDataEncipherment);
83 static const BitFlags<uint16_t, KeyUsageFlags> sKA(KeyUsageFlags::kKeyAgreement);
84 static const BitFlags<uint16_t, KeyUsageFlags> sKC(KeyUsageFlags::kKeyCertSign);
85 static const BitFlags<uint16_t, KeyUsageFlags> sCR(KeyUsageFlags::kCRLSign);
86 static const BitFlags<uint16_t, KeyUsageFlags> sEO(KeyUsageFlags::kEncipherOnly);
87 static const BitFlags<uint16_t, KeyUsageFlags> sDO(KeyUsageFlags::kDecipherOnly);
88 static const BitFlags<uint16_t, KeyUsageFlags> sDSandNR(sDS.Raw() | sNR.Raw());
89 static const BitFlags<uint16_t, KeyUsageFlags> sDSandKE(sDS.Raw() | sKE.Raw());
90 static const BitFlags<uint16_t, KeyUsageFlags> sDSandDE(sDS.Raw() | sDE.Raw());
91 static const BitFlags<uint16_t, KeyUsageFlags> sDSandKA(sDS.Raw() | sKA.Raw());
92 static const BitFlags<uint16_t, KeyUsageFlags> sDSandKC(sDS.Raw() | sKC.Raw());
93 static const BitFlags<uint16_t, KeyUsageFlags> sDSandCR(sDS.Raw() | sCR.Raw());
94 static const BitFlags<uint16_t, KeyUsageFlags> sDSandEO(sDS.Raw() | sEO.Raw());
95 static const BitFlags<uint16_t, KeyUsageFlags> sDSandDO(sDS.Raw() | sDO.Raw());
96 static const BitFlags<uint16_t, KeyUsageFlags> sKCandDS(sKC.Raw() | sDS.Raw());
97 static const BitFlags<uint16_t, KeyUsageFlags> sKCandNR(sKC.Raw() | sNR.Raw());
98 static const BitFlags<uint16_t, KeyUsageFlags> sKCandKE(sKC.Raw() | sKE.Raw());
99 static const BitFlags<uint16_t, KeyUsageFlags> sKCandDE(sKC.Raw() | sDE.Raw());
100 static const BitFlags<uint16_t, KeyUsageFlags> sKCandKA(sKC.Raw() | sKA.Raw());
101 static const BitFlags<uint16_t, KeyUsageFlags> sKCandCR(sKC.Raw() | sCR.Raw());
102 static const BitFlags<uint16_t, KeyUsageFlags> sKCandEO(sKC.Raw() | sEO.Raw());
103 static const BitFlags<uint16_t, KeyUsageFlags> sKCandDO(sKC.Raw() | sDO.Raw());
104
105 static CHIP_ERROR LoadStandardCerts(ChipCertificateSet & certSet)
106 {
107     CHIP_ERROR err;
108
109     err = LoadTestCert(certSet, TestCertTypes::kRoot, sNullLoadFlag, sTrustAnchorFlag);
110     SuccessOrExit(err);
111
112     err = LoadTestCert(certSet, TestCertTypes::kNodeCA, sNullLoadFlag, sGenTBSHashFlag);
113     SuccessOrExit(err);
114
115     err = LoadTestCert(certSet, TestCertTypes::kNode01, sNullLoadFlag, sGenTBSHashFlag);
116     SuccessOrExit(err);
117
118 exit:
119     return err;
120 }
121
122 static CHIP_ERROR SetEffectiveTime(ValidationContext & validContext, uint16_t year, uint8_t mon, uint8_t day, uint8_t hour = 0,
123                                    uint8_t min = 0, uint8_t sec = 0)
124 {
125     ASN1UniversalTime effectiveTime;
126
127     effectiveTime.Year   = year;
128     effectiveTime.Month  = mon;
129     effectiveTime.Day    = day;
130     effectiveTime.Hour   = hour;
131     effectiveTime.Minute = min;
132     effectiveTime.Second = sec;
133
134     return ASN1ToChipEpochTime(effectiveTime, validContext.mEffectiveTime);
135 }
136
137 static void TestChipCert_ChipToX509(nlTestSuite * inSuite, void * inContext)
138 {
139     CHIP_ERROR err;
140     const uint8_t * inCert;
141     uint32_t inCertLen;
142     const uint8_t * expectedOutCert;
143     uint32_t expectedOutCertLen;
144     uint8_t outCertBuf[kTestCertBufSize];
145     uint32_t outCertLen;
146
147     for (size_t i = 0; i < gNumTestCerts; i++)
148     {
149         uint8_t certType = gTestCerts[i];
150
151         err = GetTestCert(certType, sNullLoadFlag, inCert, inCertLen);
152         NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
153         err = GetTestCert(certType, sDerFormFlag, expectedOutCert, expectedOutCertLen);
154         NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
155
156         err = ConvertChipCertToX509Cert(inCert, inCertLen, outCertBuf, sizeof(outCertBuf), outCertLen);
157         NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
158         NL_TEST_ASSERT(inSuite, outCertLen == expectedOutCertLen);
159         NL_TEST_ASSERT(inSuite, memcmp(outCertBuf, expectedOutCert, outCertLen) == 0);
160     }
161 }
162
163 static void TestChipCert_X509ToChip(nlTestSuite * inSuite, void * inContext)
164 {
165     CHIP_ERROR err;
166     const uint8_t * inCert;
167     uint32_t inCertLen;
168     const uint8_t * expectedOutCert;
169     uint32_t expectedOutCertLen;
170     uint8_t outCertBuf[kTestCertBufSize];
171     uint32_t outCertLen;
172
173     for (size_t i = 0; i < gNumTestCerts; i++)
174     {
175         uint8_t certType = gTestCerts[i];
176
177         err = GetTestCert(certType, sDerFormFlag, inCert, inCertLen);
178         NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
179         err = GetTestCert(certType, sNullLoadFlag, expectedOutCert, expectedOutCertLen);
180         NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
181
182         err = ConvertX509CertToChipCert(inCert, inCertLen, outCertBuf, sizeof(outCertBuf), outCertLen);
183         NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
184         NL_TEST_ASSERT(inSuite, outCertLen == expectedOutCertLen);
185         NL_TEST_ASSERT(inSuite, memcmp(outCertBuf, expectedOutCert, outCertLen) == 0);
186     }
187 }
188
189 static void TestChipCert_CertValidation(nlTestSuite * inSuite, void * inContext)
190 {
191     CHIP_ERROR err;
192     ChipCertificateSet certSet;
193     ValidationContext validContext;
194     enum
195     {
196         kMaxCertsPerTestCase = 10
197     };
198
199     struct ValidationTestCase
200     {
201         int mSubjectCertIndex;
202         uint8_t mValidateFlags;
203         uint8_t mRequiredCertType;
204         CHIP_ERROR mExpectedResult;
205         int mExpectedCertIndex;
206         int mExpectedTrustAnchorIndex;
207         struct
208         {
209             uint8_t Type;
210             BitFlags<uint8_t, CertDecodeFlags> DecodeFlags;
211             BitFlags<uint8_t, TestCertLoadFlags> LoadFlags;
212         } InputCerts[kMaxCertsPerTestCase];
213     };
214
215     // Short-hand names to make the test cases table more concise.
216     enum
217     {
218         CTNS   = kCertType_NotSpecified,
219         CTCA   = kCertType_CA,
220         CTNode = kCertType_Node,
221         CTFS   = kCertType_FirmwareSigning,
222         CTAD   = kCertType_AppDefinedBase,
223     };
224
225     // clang-format off
226     static const ValidationTestCase sValidationTestCases[] = {
227         //            Reqd                                    Exp   Exp                             Cert             Cert
228         // Subj Valid Cert                                    Cert  TA     Cert                     Decode           Load
229         // Ind  Flags Type    Expected Result                 Index Index  Type                     Flags            Flags
230         // ==================================================================================================================================
231
232         // Basic validation of leaf certificate with different load orders.
233         {  2,   0,    CTNS,   CHIP_NO_ERROR,                  2,    0, { { TestCertTypes::kRoot,    sTrustAnchorFlag, sNullLoadFlag       },
234                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sNullLoadFlag       },
235                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       } } },
236         {  1,   0,    CTNS,   CHIP_NO_ERROR,                  1,    0, { { TestCertTypes::kRoot,    sTrustAnchorFlag, sNullLoadFlag       },
237                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       },
238                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sNullLoadFlag       } } },
239         {  0,   0,    CTNS,   CHIP_NO_ERROR,                  0,    2, { { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       },
240                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sNullLoadFlag       },
241                                                                          { TestCertTypes::kRoot,    sTrustAnchorFlag, sNullLoadFlag       } } },
242
243         // Validation of leaf certificate with root key only.
244         {  1,   0,    CTNS,   CHIP_NO_ERROR,                  1,    0, { { TestCertTypes::kRootKey, sNullDecodeFlag,  sNullLoadFlag       },
245                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       },
246                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sNullLoadFlag       } } },
247
248         // Validation with two copies of root certificate, one trusted, one untrusted.
249         {  2,   0,    CTNS,   CHIP_NO_ERROR,                  2,    1, { { TestCertTypes::kRoot,    sNullDecodeFlag,  sNullLoadFlag       },
250                                                                          { TestCertTypes::kRoot,    sTrustAnchorFlag, sNullLoadFlag       },
251                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       },
252                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sNullLoadFlag       } } },
253
254         // Validation with trusted root key and trusted root certificate.
255         {  2,   0,    CTNS,   CHIP_NO_ERROR,                  2,    0, { { TestCertTypes::kRootKey, sNullDecodeFlag,  sNullLoadFlag       },
256                                                                          { TestCertTypes::kRoot,    sTrustAnchorFlag, sNullLoadFlag       },
257                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       },
258                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sNullLoadFlag       } } },
259
260         // Validation with trusted root key and untrusted root certificate.
261         {  3,   0,    CTNS,   CHIP_NO_ERROR,                  3,    1, { { TestCertTypes::kRoot,    sNullDecodeFlag,  sNullLoadFlag       },
262                                                                          { TestCertTypes::kRootKey, sNullDecodeFlag,  sNullLoadFlag       },
263                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sNullLoadFlag       },
264                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       } } },
265
266         // Failure due to missing CA certificate.
267         {  1,   0,    CTNS,   CHIP_ERROR_CA_CERT_NOT_FOUND,  -1,   -1, { { TestCertTypes::kRoot,    sTrustAnchorFlag, sNullLoadFlag       },
268                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       } } },
269
270         // Failure due to missing root certificate.
271         {  1,   0,    CTNS,   CHIP_ERROR_CA_CERT_NOT_FOUND,  -1,   -1, { { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sNullLoadFlag       },
272                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       } } },
273
274         // Failure due to lack of TBS hash.
275         {  1,   0,    CTNS,   CHIP_ERROR_INVALID_ARGUMENT,   -1,   -1, { { TestCertTypes::kRoot,    sTrustAnchorFlag, sNullLoadFlag       },
276                                                                          { TestCertTypes::kNode01,  sNullDecodeFlag,  sNullLoadFlag       },
277                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sNullLoadFlag       } } },
278
279         // Failure due to untrusted root.
280         {  1,   0,    CTNS,   CHIP_ERROR_CA_CERT_NOT_FOUND,  -1,   -1, { { TestCertTypes::kRoot,    sNullDecodeFlag,  sNullLoadFlag       },
281                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       },
282                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sNullLoadFlag       } } },
283
284         // Failure due to intermediate cert with isCA flag = false
285         {  2,   0,    CTNS,   CHIP_ERROR_CA_CERT_NOT_FOUND,  -1,   -1, { { TestCertTypes::kRoot,    sTrustAnchorFlag, sNullLoadFlag       },
286                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sSupIsCAFlag        },
287                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       } } },
288
289         // Failure due to CA cert with no key usage.
290         {  2,   0,    CTNS,   CHIP_ERROR_CA_CERT_NOT_FOUND,  -1,   -1, { { TestCertTypes::kRoot,    sTrustAnchorFlag, sNullLoadFlag       },
291                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sSupKeyUsageFlag    },
292                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       } } },
293
294         // Failure due to CA cert with no cert sign key usage.
295         {  2,   0,    CTNS,   CHIP_ERROR_CA_CERT_NOT_FOUND,  -1,   -1, { { TestCertTypes::kRoot,    sTrustAnchorFlag, sNullLoadFlag       },
296                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sSupKeyCertSignFlag },
297                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       } } },
298
299         // Failure due to 3-level deep cert chain and root cert with path constraint == 0
300         {  2,   0,    CTNS,   CHIP_ERROR_CA_CERT_NOT_FOUND,  -1,   -1, { { TestCertTypes::kRoot,    sTrustAnchorFlag, sPathLenZeroFlag    },
301                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sNullLoadFlag       },
302                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       } } },
303
304         // Require a specific certificate type.
305         {  2,   0,    CTNode, CHIP_NO_ERROR,                  2,    0, { { TestCertTypes::kRoot,    sTrustAnchorFlag, sNullLoadFlag       },
306                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sNullLoadFlag       },
307                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       } } },
308
309         // Require a certificate with an application-defined type.
310         {  2,   0,    CTAD,   CHIP_NO_ERROR,                  2,    0, { { TestCertTypes::kRoot,    sTrustAnchorFlag, sNullLoadFlag       },
311                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sNullLoadFlag       },
312                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sAppDefCertTypeFlag } } },
313
314         // Select between two identical certificates with different types.
315         {  2,   0,    CTAD,   CHIP_NO_ERROR,                  3,    0, { { TestCertTypes::kRoot,    sTrustAnchorFlag, sNullLoadFlag       },
316                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sNullLoadFlag       },
317                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       },
318                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sAppDefCertTypeFlag } } },
319
320         // Failure due to required certificate type not found.
321         {  2,   0,    CTCA,   CHIP_ERROR_WRONG_CERT_TYPE,    -1,   -1, { { TestCertTypes::kRoot,    sTrustAnchorFlag, sNullLoadFlag       },
322                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sNullLoadFlag       },
323                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       } } },
324
325         // Failure due to CA certificate having wrong type.
326         {  2,   0,    CTNode, CHIP_ERROR_CA_CERT_NOT_FOUND,  -1,   -1, { { TestCertTypes::kRoot,    sTrustAnchorFlag, sNullLoadFlag       },
327                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sAppDefCertTypeFlag },
328                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       } } },
329
330         // Failure due to root certificate having wrong type.
331         {  2,   0,    CTNode, CHIP_ERROR_CA_CERT_NOT_FOUND,  -1,   -1, { { TestCertTypes::kRoot,    sTrustAnchorFlag, sAppDefCertTypeFlag },
332                                                                          { TestCertTypes::kNodeCA,  sGenTBSHashFlag,  sNullLoadFlag       },
333                                                                          { TestCertTypes::kNode01,  sGenTBSHashFlag,  sNullLoadFlag       } } },
334     };
335     // clang-format on
336     static const size_t sNumValidationTestCases = sizeof(sValidationTestCases) / sizeof(sValidationTestCases[0]);
337
338     for (unsigned i = 0; i < sNumValidationTestCases; i++)
339     {
340         ChipCertificateData * resultCert    = nullptr;
341         const ValidationTestCase & testCase = sValidationTestCases[i];
342
343         // Initialize the certificate set and load the specified test certificates.
344         certSet.Init(kMaxCertsPerTestCase, kTestCertBufSize);
345         for (size_t i2 = 0; i2 < kMaxCertsPerTestCase; i2++)
346         {
347             if (testCase.InputCerts[i2].Type != TestCertTypes::kNone)
348             {
349                 err = LoadTestCert(certSet, testCase.InputCerts[i2].Type, testCase.InputCerts[i2].LoadFlags,
350                                    testCase.InputCerts[i2].DecodeFlags);
351                 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
352             }
353         }
354         // Make sure the test case is valid.
355         NL_TEST_ASSERT(inSuite, testCase.mSubjectCertIndex >= 0 && testCase.mSubjectCertIndex < certSet.GetCertCount());
356         if (testCase.mExpectedResult == CHIP_NO_ERROR)
357         {
358             NL_TEST_ASSERT(inSuite, testCase.mExpectedCertIndex >= 0 && testCase.mExpectedCertIndex < certSet.GetCertCount());
359             NL_TEST_ASSERT(inSuite,
360                            testCase.mExpectedTrustAnchorIndex >= 0 && testCase.mExpectedTrustAnchorIndex < certSet.GetCertCount());
361         }
362
363         // Initialize the validation context.
364         validContext.Reset();
365         err = SetEffectiveTime(validContext, 2021, 1, 1);
366         NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
367         validContext.mRequiredKeyUsages.Set(KeyUsageFlags::kDigitalSignature);
368         validContext.mRequiredKeyPurposes.Set(KeyPurposeFlags::kServerAuth);
369         validContext.mValidateFlags.SetRaw(testCase.mValidateFlags);
370         validContext.mRequiredCertType = testCase.mRequiredCertType;
371
372         // Locate the subject DN and key id that will be used as input the FindValidCert() method.
373         const ChipDN & subjectDN              = certSet.GetCertSet()[testCase.mSubjectCertIndex].mSubjectDN;
374         const CertificateKeyId & subjectKeyId = certSet.GetCertSet()[testCase.mSubjectCertIndex].mSubjectKeyId;
375
376         // Invoke the FindValidCert() method (the method being tested).
377         err = certSet.FindValidCert(subjectDN, subjectKeyId, validContext, resultCert);
378         NL_TEST_ASSERT(inSuite, err == testCase.mExpectedResult);
379
380         // If the test case is expected to be successful...
381         if (err == CHIP_NO_ERROR)
382         {
383             // Verify that the method found the correct certificate.
384             NL_TEST_ASSERT(inSuite, resultCert == &certSet.GetCertSet()[testCase.mExpectedCertIndex]);
385
386             // Verify that the method selected the correct trust anchor.
387             NL_TEST_ASSERT(inSuite, validContext.mTrustAnchor == &certSet.GetCertSet()[testCase.mExpectedTrustAnchorIndex]);
388         }
389
390         // Clear the certificate set.
391         certSet.Release();
392     }
393 }
394
395 static void TestChipCert_CertValidTime(nlTestSuite * inSuite, void * inContext)
396 {
397     CHIP_ERROR err;
398     ChipCertificateSet certSet;
399     ValidationContext validContext;
400
401     certSet.Init(kStandardCertsCount, kTestCertBufSize);
402
403     err = LoadStandardCerts(certSet);
404     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
405
406     validContext.Reset();
407     validContext.mRequiredKeyUsages.Set(KeyUsageFlags::kDigitalSignature);
408     validContext.mRequiredKeyPurposes.Set(KeyPurposeFlags::kServerAuth);
409
410     // Before certificate validity period.
411     err = SetEffectiveTime(validContext, 2020, 1, 3);
412     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
413     err = certSet.ValidateCert(certSet.GetLastCert(), validContext);
414     NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_CERT_NOT_VALID_YET);
415
416     // 1 second before validity period.
417     err = SetEffectiveTime(validContext, 2020, 10, 15, 14, 23, 42);
418     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
419     err = certSet.ValidateCert(certSet.GetLastCert(), validContext);
420     NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_CERT_NOT_VALID_YET);
421
422     // 1st second of validity period.
423     err = SetEffectiveTime(validContext, 2020, 10, 15, 14, 23, 43);
424     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
425     err = certSet.ValidateCert(certSet.GetLastCert(), validContext);
426     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
427
428     // Validity period.
429     err = SetEffectiveTime(validContext, 2022, 02, 23, 12, 30, 01);
430     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
431     err = certSet.ValidateCert(certSet.GetLastCert(), validContext);
432     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
433
434     // Last second of validity period.
435     err = SetEffectiveTime(validContext, 2040, 10, 15, 14, 23, 42);
436     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
437     err = certSet.ValidateCert(certSet.GetLastCert(), validContext);
438     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
439
440     // 1 second after end of certificate validity period.
441     err = SetEffectiveTime(validContext, 2040, 10, 15, 14, 23, 43);
442     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
443     err = certSet.ValidateCert(certSet.GetLastCert(), validContext);
444     NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_CERT_EXPIRED);
445
446     // After end of certificate validity period.
447     err = SetEffectiveTime(validContext, 2042, 4, 25, 0, 0, 0);
448     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
449     err = certSet.ValidateCert(certSet.GetLastCert(), validContext);
450     NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_CERT_EXPIRED);
451
452     // Ignore 'not before' time.
453     validContext.mValidateFlags.Set(sIgnoreNotBeforeFlag);
454     err = SetEffectiveTime(validContext, 2020, 4, 23, 23, 59, 59);
455     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
456     err = certSet.ValidateCert(certSet.GetLastCert(), validContext);
457     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
458
459     // Ignore 'not after' time.
460     validContext.mValidateFlags.Set(sIgnoreNotAfterFlag);
461     err = SetEffectiveTime(validContext, 2042, 5, 25, 0, 0, 0);
462     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
463     err = certSet.ValidateCert(certSet.GetLastCert(), validContext);
464     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
465
466     certSet.Release();
467 }
468
469 static void TestChipCert_CertUsage(nlTestSuite * inSuite, void * inContext)
470 {
471     CHIP_ERROR err;
472     ChipCertificateSet certSet;
473     ValidationContext validContext;
474
475     struct UsageTestCase
476     {
477         uint8_t mCertIndex;
478         BitFlags<uint16_t, KeyUsageFlags> mRequiredKeyUsages;
479         BitFlags<uint8_t, KeyPurposeFlags> mRequiredKeyPurposes;
480         CHIP_ERROR mExpectedResult;
481     };
482
483     // clang-format off
484     static UsageTestCase sUsageTestCases[] = {
485         // Cert Key
486         // Ind  Usages       Key Purposes     Expected Result
487         // =========================================================================
488
489         // ----- Key Usages for leaf Certificate -----
490         {  2,  sDS,          sNullKPFlag,     CHIP_NO_ERROR                        },
491         {  2,  sNR,          sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
492         {  2,  sKE,          sNullKPFlag,     CHIP_NO_ERROR                        },
493         {  2,  sDE,          sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
494         {  2,  sKA,          sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
495         {  2,  sKC,          sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
496         {  2,  sCR,          sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
497         {  2,  sEO,          sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
498         {  2,  sDO,          sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
499         {  2,  sDSandNR,     sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
500         {  2,  sDSandKE,     sNullKPFlag,     CHIP_NO_ERROR                        },
501         {  2,  sDSandDE,     sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
502         {  2,  sDSandKA,     sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
503         {  2,  sDSandKC,     sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
504         {  2,  sDSandCR,     sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
505         {  2,  sDSandEO,     sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
506         {  2,  sDSandDO,     sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
507
508         // ----- Key Usages for CA Certificate -----
509         {  1,  sDS,          sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
510         {  1,  sNR,          sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
511         {  1,  sKE,          sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
512         {  1,  sDE,          sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
513         {  1,  sKA,          sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
514         {  1,  sKC,          sNullKPFlag,     CHIP_NO_ERROR                        },
515         {  1,  sCR,          sNullKPFlag,     CHIP_NO_ERROR                        },
516         {  1,  sEO,          sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
517         {  1,  sDO,          sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
518         {  1,  sKCandDS,     sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
519         {  1,  sKCandNR,     sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
520         {  1,  sKCandKE,     sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
521         {  1,  sKCandDE,     sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
522         {  1,  sKCandKA,     sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
523         {  1,  sKCandCR,     sNullKPFlag,     CHIP_NO_ERROR                        },
524         {  1,  sKCandEO,     sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
525         {  1,  sKCandDO,     sNullKPFlag,     CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
526
527         // ----- Key Purposes for leaf Certificate -----
528         {  2,  sNullKUFlag,  sSA,             CHIP_NO_ERROR                        },
529         {  2,  sNullKUFlag,  sCA,             CHIP_NO_ERROR                        },
530         {  2,  sNullKUFlag,  sCS,             CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
531         {  2,  sNullKUFlag,  sEP,             CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
532         {  2,  sNullKUFlag,  sTS,             CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
533         {  2,  sNullKUFlag,  sSAandCA,        CHIP_NO_ERROR                        },
534         {  2,  sNullKUFlag,  sSAandCS,        CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
535         {  2,  sNullKUFlag,  sSAandEP,        CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
536         {  2,  sNullKUFlag,  sSAandTS,        CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
537
538         // ----- Key Purposes for CA Certificate -----
539         {  1,  sNullKUFlag,  sSA,             CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
540         {  1,  sNullKUFlag,  sCA,             CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
541         {  1,  sNullKUFlag,  sCS,             CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
542         {  1,  sNullKUFlag,  sEP,             CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
543         {  1,  sNullKUFlag,  sTS,             CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
544         {  1,  sNullKUFlag,  sSAandCA,        CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
545         {  1,  sNullKUFlag,  sSAandCS,        CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
546         {  1,  sNullKUFlag,  sSAandEP,        CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
547         {  1,  sNullKUFlag,  sSAandTS,        CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
548
549         // ----- Combinations -----
550         {  2,  sDSandNR,     sSAandCA,        CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
551         {  2,  sDSandKE,     sSAandCS,        CHIP_ERROR_CERT_USAGE_NOT_ALLOWED    },
552         {  2,  sDSandKE,     sSAandCA,        CHIP_NO_ERROR                        },
553     };
554     // clang-format on
555     size_t sNumUsageTestCases = sizeof(sUsageTestCases) / sizeof(sUsageTestCases[0]);
556
557     certSet.Init(kStandardCertsCount, kTestCertBufSize);
558
559     err = LoadStandardCerts(certSet);
560     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
561
562     for (size_t i = 0; i < sNumUsageTestCases; i++)
563     {
564         validContext.Reset();
565         validContext.mRequiredKeyUsages   = sUsageTestCases[i].mRequiredKeyUsages;
566         validContext.mRequiredKeyPurposes = sUsageTestCases[i].mRequiredKeyPurposes;
567
568         err = SetEffectiveTime(validContext, 2020, 10, 16);
569         NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
570
571         err = certSet.ValidateCert(&certSet.GetCertSet()[sUsageTestCases[i].mCertIndex], validContext);
572         NL_TEST_ASSERT(inSuite, err == sUsageTestCases[i].mExpectedResult);
573     }
574
575     certSet.Release();
576 }
577
578 static void TestChipCert_CertType(nlTestSuite * inSuite, void * inContext)
579 {
580     CHIP_ERROR err;
581     ChipCertificateSet certSet;
582
583     struct TestCase
584     {
585         uint8_t Cert;
586         uint8_t ExpectedCertType;
587     };
588
589     // clang-format off
590     static TestCase sTestCases[] = {
591         // Cert                             ExpectedCertType
592         // =============================================================
593         {  TestCertTypes::kRoot,            kCertType_CA              },
594         {  TestCertTypes::kRootKey,         kCertType_CA              },
595         {  TestCertTypes::kNodeCA,          kCertType_CA              },
596         {  TestCertTypes::kNode01,          kCertType_Node            },
597         {  TestCertTypes::kFirmwareSigning, kCertType_FirmwareSigning },
598     };
599     // clang-format on
600     static const size_t sNumTestCases = sizeof(sTestCases) / sizeof(sTestCases[0]);
601
602     for (unsigned i = 0; i < sNumTestCases; i++)
603     {
604         const TestCase & testCase = sTestCases[i];
605
606         // Initialize the certificate set and load the test certificate.
607         certSet.Init(1, kTestCertBufSize);
608         err = LoadTestCert(certSet, testCase.Cert, sNullLoadFlag, sNullDecodeFlag);
609         NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
610         NL_TEST_ASSERT(inSuite, certSet.GetCertSet()->mCertType == testCase.ExpectedCertType);
611     }
612 }
613
614 /**
615  *  Set up the test suite.
616  */
617 int TestChipCert_Setup(void * inContext)
618 {
619     CHIP_ERROR error = chip::Platform::MemoryInit();
620
621     if (error != CHIP_NO_ERROR)
622     {
623         return FAILURE;
624     }
625
626     return SUCCESS;
627 }
628
629 /**
630  *  Tear down the test suite.
631  */
632 int TestChipCert_Teardown(void * inContext)
633 {
634     chip::Platform::MemoryShutdown();
635     return SUCCESS;
636 }
637
638 /**
639  *   Test Suite. It lists all the test functions.
640  */
641 // clang-format off
642 static const nlTest sTests[] = {
643     NL_TEST_DEF("Test CHIP Certificate CHIP to X509 Conversion", TestChipCert_ChipToX509),
644     NL_TEST_DEF("Test CHIP Certificate X509 to CHIP Conversion", TestChipCert_X509ToChip),
645     NL_TEST_DEF("Test CHIP Certificate Validation", TestChipCert_CertValidation),
646     NL_TEST_DEF("Test CHIP Certificate Validation time", TestChipCert_CertValidTime),
647     NL_TEST_DEF("Test CHIP Certificate Usage", TestChipCert_CertUsage),
648     NL_TEST_DEF("Test CHIP Certificate Type", TestChipCert_CertType),
649     NL_TEST_SENTINEL()
650 };
651 // clang-format on
652
653 int TestChipCert(void)
654 {
655     // clang-format off
656     nlTestSuite theSuite =
657     {
658         "Credentials-CHIP-Certs",
659         &sTests[0],
660         TestChipCert_Setup,
661         TestChipCert_Teardown
662     };
663     // clang-format on
664     nlTestRunner(&theSuite, nullptr);
665     return (nlTestRunnerStats(&theSuite));
666 }
667
668 CHIP_REGISTER_TEST_SUITE(TestChipCert);