From 10763283aae6a6b5d529c1ac6f891f813db00733 Mon Sep 17 00:00:00 2001 From: Evgeny Margolis Date: Fri, 6 May 2022 12:44:36 -0700 Subject: [PATCH] Add Support of Authorized PAA List to the Certification Declaration Structure. (#18062) --- src/credentials/CertificationDeclaration.cpp | 126 ++++++++++++++---- src/credentials/CertificationDeclaration.h | 77 ++++++----- .../tests/TestCertificationDeclaration.cpp | 117 +++++++++++++++- 3 files changed, 265 insertions(+), 55 deletions(-) diff --git a/src/credentials/CertificationDeclaration.cpp b/src/credentials/CertificationDeclaration.cpp index 9c129f24ad831e..141191efca9e8c 100644 --- a/src/credentials/CertificationDeclaration.cpp +++ b/src/credentials/CertificationDeclaration.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2021-2022 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -60,6 +60,7 @@ enum kTag_CertificationType = 8, /**< [ unsigned int ] Certification Type. */ kTag_DACOriginVendorId = 9, /**< [ unsigned int, optional ] DAC origin vendor identifier. */ kTag_DACOriginProductId = 10, /**< [ unsigned int, optional ] DAC origin product identifier. */ + kTag_AuthorizedPAAList = 11, /**< [ array, optional ] Authorized PAA List. */ }; CHIP_ERROR EncodeCertificationElements(const CertificationElements & certElements, MutableByteSpan & encodedCertElements) @@ -75,7 +76,7 @@ CHIP_ERROR EncodeCertificationElements(const CertificationElements & certElement ReturnErrorOnFailure(writer.Put(ContextTag(kTag_VendorId), certElements.VendorId)); VerifyOrReturnError(certElements.ProductIdsCount > 0, CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrReturnError(certElements.ProductIdsCount <= kMaxProductIdsCountPerCD, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(certElements.ProductIdsCount <= kMaxProductIdsCount, CHIP_ERROR_INVALID_ARGUMENT); ReturnErrorOnFailure(writer.StartContainer(ContextTag(kTag_ProductIdArray), kTLVType_Array, outerContainer2)); for (uint8_t i = 0; i < certElements.ProductIdsCount; i++) @@ -95,6 +96,18 @@ CHIP_ERROR EncodeCertificationElements(const CertificationElements & certElement ReturnErrorOnFailure(writer.Put(ContextTag(kTag_DACOriginVendorId), certElements.DACOriginVendorId)); ReturnErrorOnFailure(writer.Put(ContextTag(kTag_DACOriginProductId), certElements.DACOriginProductId)); } + if (certElements.AuthorizedPAAListCount > 0) + { + VerifyOrReturnError(certElements.AuthorizedPAAListCount <= kMaxAuthorizedPAAListCount, CHIP_ERROR_INVALID_ARGUMENT); + + ReturnErrorOnFailure(writer.StartContainer(ContextTag(kTag_AuthorizedPAAList), kTLVType_Array, outerContainer2)); + for (uint8_t i = 0; i < certElements.AuthorizedPAAListCount; i++) + { + ReturnErrorOnFailure(writer.Put(AnonymousTag(), ByteSpan(certElements.AuthorizedPAAList[i]))); + } + ReturnErrorOnFailure(writer.EndContainer(outerContainer2)); + } + ReturnErrorOnFailure(writer.EndContainer(outerContainer1)); ReturnErrorOnFailure(writer.Finalize()); @@ -170,6 +183,27 @@ CHIP_ERROR DecodeCertificationElements(const ByteSpan & encodedCertElements, Cer } VerifyOrReturnError(err == CHIP_END_OF_TLV || err == CHIP_ERROR_UNEXPECTED_TLV_ELEMENT || err == CHIP_NO_ERROR, err); + if (err != CHIP_END_OF_TLV && reader.GetTag() == ContextTag(kTag_AuthorizedPAAList)) + { + VerifyOrReturnError(reader.GetType() == kTLVType_Array, CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); + + ReturnErrorOnFailure(reader.EnterContainer(outerContainer2)); + + certElements.AuthorizedPAAListCount = 0; + while ((err = reader.Next(kTLVType_ByteString, AnonymousTag())) == CHIP_NO_ERROR) + { + VerifyOrReturnError(reader.GetLength() == kKeyIdentifierLength, CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); + + ReturnErrorOnFailure( + reader.GetBytes(certElements.AuthorizedPAAList[certElements.AuthorizedPAAListCount++], kKeyIdentifierLength)); + } + VerifyOrReturnError(err == CHIP_END_OF_TLV, err); + ReturnErrorOnFailure(reader.ExitContainer(outerContainer2)); + + err = reader.Next(); + } + VerifyOrReturnError(err == CHIP_END_OF_TLV || err == CHIP_ERROR_UNEXPECTED_TLV_ELEMENT || err == CHIP_NO_ERROR, err); + ReturnErrorOnFailure(reader.ExitContainer(outerContainer1)); ReturnErrorOnFailure(reader.VerifyEndOfContainer()); @@ -182,6 +216,7 @@ CHIP_ERROR DecodeCertificationElements(const ByteSpan & encodedCertElements, Cer CHIP_ERROR err; TLVReader reader; TLVType outerContainer; + TLVType outerContainer2; VerifyOrReturnError(encodedCertElements.size() <= kMaxCMSSignedCDMessage, CHIP_ERROR_INVALID_ARGUMENT); @@ -198,8 +233,15 @@ CHIP_ERROR DecodeCertificationElements(const ByteSpan & encodedCertElements, Cer ReturnErrorOnFailure(reader.Get(certDeclContent.vendorId)); ReturnErrorOnFailure(reader.Next(kTLVType_Array, ContextTag(kTag_ProductIdArray))); + ReturnErrorOnFailure(reader.EnterContainer(outerContainer2)); - // skip PID Array + while ((err = reader.Next(kTLVType_UnsignedInteger, AnonymousTag())) == CHIP_NO_ERROR) + { + // Verifies that the TLV structure of PID Array is correct + // but skip the values + } + VerifyOrReturnError(err == CHIP_END_OF_TLV, err); + ReturnErrorOnFailure(reader.ExitContainer(outerContainer2)); ReturnErrorOnFailure(reader.Next(ContextTag(kTag_DeviceTypeId))); ReturnErrorOnFailure(reader.Get(certDeclContent.deviceTypeId)); @@ -236,6 +278,28 @@ CHIP_ERROR DecodeCertificationElements(const ByteSpan & encodedCertElements, Cer } VerifyOrReturnError(err == CHIP_END_OF_TLV || err == CHIP_ERROR_UNEXPECTED_TLV_ELEMENT || err == CHIP_NO_ERROR, err); + if (err != CHIP_END_OF_TLV && reader.GetTag() == ContextTag(kTag_AuthorizedPAAList)) + { + VerifyOrReturnError(reader.GetType() == kTLVType_Array, CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); + + ReturnErrorOnFailure(reader.EnterContainer(outerContainer2)); + + while ((err = reader.Next(kTLVType_ByteString, AnonymousTag())) == CHIP_NO_ERROR) + { + VerifyOrReturnError(reader.GetLength() == kKeyIdentifierLength, CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); + // Verifies that the TLV structure of the Authorized PAA List is correct + // but skip the values + } + VerifyOrReturnError(err == CHIP_END_OF_TLV, err); + + ReturnErrorOnFailure(reader.ExitContainer(outerContainer2)); + + certDeclContent.authorizedPAAListPresent = true; + + err = reader.Next(); + } + VerifyOrReturnError(err == CHIP_END_OF_TLV || err == CHIP_ERROR_UNEXPECTED_TLV_ELEMENT || err == CHIP_NO_ERROR, err); + ReturnErrorOnFailure(reader.ExitContainer(outerContainer)); ReturnErrorOnFailure(reader.VerifyEndOfContainer()); @@ -245,57 +309,73 @@ CHIP_ERROR DecodeCertificationElements(const ByteSpan & encodedCertElements, Cer bool CertificationElementsDecoder::IsProductIdIn(const ByteSpan & encodedCertElements, uint16_t productId) { - VerifyOrReturnError(PrepareToReadProductIdList(encodedCertElements) == CHIP_NO_ERROR, false); + VerifyOrReturnError(FindAndEnterArray(encodedCertElements, ContextTag(kTag_ProductIdArray)) == CHIP_NO_ERROR, false); uint16_t cdProductId = 0; - CHIP_ERROR error = CHIP_NO_ERROR; - - while ((error = GetNextProductId(cdProductId)) == CHIP_NO_ERROR) + while (GetNextProductId(cdProductId) == CHIP_NO_ERROR) { if (productId == cdProductId) { return true; } } - return false; } -CHIP_ERROR CertificationElementsDecoder::PrepareToReadProductIdList(const ByteSpan & encodedCertElements) +CHIP_ERROR CertificationElementsDecoder::FindAndEnterArray(const ByteSpan & encodedCertElements, Tag arrayTag) { - mIsInitialized = false; - mCertificationDeclarationData = encodedCertElements; + TLVType outerContainerType1; + TLVType outerContainerType2; - mReader.Init(mCertificationDeclarationData); + mReader.Init(encodedCertElements); ReturnErrorOnFailure(mReader.Next(kTLVType_Structure, AnonymousTag())); - ReturnErrorOnFailure(mReader.EnterContainer(mOuterContainerType1)); + ReturnErrorOnFailure(mReader.EnterContainer(outerContainerType1)); - // position to ProductId Array + // position to arrayTag Array CHIP_ERROR error = CHIP_NO_ERROR; do { - error = mReader.Next(kTLVType_Array, ContextTag(kTag_ProductIdArray)); - // return error code if Next method returned different than CHIP_NO_ERROR. - // also return if different error code than CHIP_ERROR_WRONG_TLV_TYPE/CHIP_ERROR_UNEXPECTED_TLV_ELEMENT, which means that - // the expected type and tags do not match. - VerifyOrReturnError( - error == CHIP_NO_ERROR || error == CHIP_ERROR_WRONG_TLV_TYPE || error == CHIP_ERROR_UNEXPECTED_TLV_ELEMENT, error); + error = mReader.Next(kTLVType_Array, arrayTag); + // Return error code unless one of three things happened: + // 1. We found the right thing (CHIP_NO_ERROR returned). + // 2. The next tag is not the one we are looking for (CHIP_ERROR_UNEXPECTED_TLV_ELEMENT). + VerifyOrReturnError(error == CHIP_NO_ERROR || error == CHIP_ERROR_UNEXPECTED_TLV_ELEMENT, error); } while (error != CHIP_NO_ERROR); - ReturnErrorOnFailure(mReader.EnterContainer(mOuterContainerType2)); + ReturnErrorOnFailure(mReader.EnterContainer(outerContainerType2)); - mIsInitialized = true; return CHIP_NO_ERROR; } CHIP_ERROR CertificationElementsDecoder::GetNextProductId(uint16_t & productId) { - VerifyOrReturnError(mIsInitialized, CHIP_ERROR_INCORRECT_STATE); ReturnErrorOnFailure(mReader.Next(AnonymousTag())); ReturnErrorOnFailure(mReader.Get(productId)); return CHIP_NO_ERROR; } +bool CertificationElementsDecoder::HasAuthorizedPAA(const ByteSpan & encodedCertElements, const ByteSpan & authorizedPAA) +{ + VerifyOrReturnError(FindAndEnterArray(encodedCertElements, ContextTag(kTag_AuthorizedPAAList)) == CHIP_NO_ERROR, false); + + ByteSpan cdAuthorizedPAA; + while (GetNextAuthorizedPAA(cdAuthorizedPAA) == CHIP_NO_ERROR) + { + if (authorizedPAA.data_equal(cdAuthorizedPAA)) + { + return true; + } + } + return false; +} + +CHIP_ERROR CertificationElementsDecoder::GetNextAuthorizedPAA(ByteSpan & authorizedPAA) +{ + ReturnErrorOnFailure(mReader.Next(AnonymousTag())); + ReturnErrorOnFailure(mReader.Get(authorizedPAA)); + return CHIP_NO_ERROR; +} + namespace { CHIP_ERROR EncodeEncapsulatedContent(const ByteSpan & cdContent, ASN1Writer & writer) diff --git a/src/credentials/CertificationDeclaration.h b/src/credentials/CertificationDeclaration.h index 755e1a5d50f870..5485b1c0dbe768 100644 --- a/src/credentials/CertificationDeclaration.h +++ b/src/credentials/CertificationDeclaration.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2021-2022 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,6 +24,7 @@ #pragma once +#include #include #include #include @@ -34,40 +35,46 @@ namespace chip { namespace Credentials { -static constexpr uint32_t kMaxProductIdsCountPerCD = 100; -static constexpr uint32_t kCertificateIdLength = 19; +static constexpr uint32_t kMaxProductIdsCount = 100; +static constexpr uint32_t kMaxAuthorizedPAAListCount = 10; +static constexpr uint32_t kCertificateIdLength = 19; static constexpr uint32_t kCertificationElements_TLVEncodedMaxLength = TLV::EstimateStructOverhead(sizeof(uint16_t), // FormatVersion sizeof(uint16_t), // VendorId // ProductIds. Formally, the following extression should be used here: - // ( TLV::EstimateStructOverhead(sizeof(uint16_t)) * kMaxProductIdsCountPerCD ), + // ( TLV::EstimateStructOverhead(sizeof(uint16_t)) * kMaxProductIdsCount ), // Because exact structure of the elements of this array is known, more accurate estimate is used. - (1 + sizeof(uint16_t)) * kMaxProductIdsCountPerCD, - sizeof(uint32_t), // DeviceTypeId - kCertificateIdLength, // CertificateId - sizeof(uint8_t), // SecurityLevel - sizeof(uint16_t), // SecurityInformation - sizeof(uint16_t), // VersionNumber - sizeof(uint8_t), // CertificationType - sizeof(uint16_t), // DACOriginVendorId - sizeof(uint16_t)); // DACOriginProductId + (1 + sizeof(uint16_t)) * kMaxProductIdsCount, + sizeof(uint32_t), // DeviceTypeId + kCertificateIdLength, // CertificateId + sizeof(uint8_t), // SecurityLevel + sizeof(uint16_t), // SecurityInformation + sizeof(uint16_t), // VersionNumber + sizeof(uint8_t), // CertificationType + sizeof(uint16_t), // DACOriginVendorId + sizeof(uint16_t), // DACOriginProductId + (2 + kKeyIdentifierLength) * kMaxAuthorizedPAAListCount); // AuthorizedPAAList static constexpr uint32_t kMaxCMSSignedCDMessage = 183 + kCertificationElements_TLVEncodedMaxLength; struct CertificationElements { - uint16_t FormatVersion; - uint16_t VendorId; - uint16_t ProductIds[kMaxProductIdsCountPerCD]; - uint8_t ProductIdsCount; - uint32_t DeviceTypeId; - char CertificateId[kCertificateIdLength + 1]; - uint8_t SecurityLevel; - uint16_t SecurityInformation; - uint16_t VersionNumber; - uint8_t CertificationType; - uint16_t DACOriginVendorId; - uint16_t DACOriginProductId; - bool DACOriginVIDandPIDPresent; + typedef uint8_t KeyId[kKeyIdentifierLength]; + + uint16_t FormatVersion = 0; + uint16_t VendorId = VendorId::NotSpecified; + uint16_t ProductIds[kMaxProductIdsCount] = { 0 }; + uint8_t ProductIdsCount = 0; + uint32_t DeviceTypeId = 0; + char CertificateId[kCertificateIdLength + 1] = { 0 }; + uint8_t SecurityLevel = 0; + uint16_t SecurityInformation = 0; + uint16_t VersionNumber = 0; + uint8_t CertificationType = 0; + uint16_t DACOriginVendorId = VendorId::NotSpecified; + uint16_t DACOriginProductId = 0; + bool DACOriginVIDandPIDPresent = false; + KeyId AuthorizedPAAList[kMaxAuthorizedPAAListCount] = { { 0 } }; + uint8_t AuthorizedPAAListCount = 0; }; struct CertificationElementsWithoutPIDs @@ -82,6 +89,7 @@ struct CertificationElementsWithoutPIDs uint16_t dacOriginVendorId = VendorId::NotSpecified; uint16_t dacOriginProductId = 0; bool dacOriginVIDandPIDPresent = false; + bool authorizedPAAListPresent = false; char certificateId[kCertificateIdLength + 1] = { 0 }; }; @@ -89,16 +97,23 @@ class CertificationElementsDecoder { public: bool IsProductIdIn(const ByteSpan & encodedCertElements, uint16_t productId); + bool HasAuthorizedPAA(const ByteSpan & encodedCertElements, const ByteSpan & authorizedPAA); private: - CHIP_ERROR PrepareToReadProductIdList(const ByteSpan & encodedCertElements); + /** + * @brief Positions mReader inside at the top of an Array with listTag tag. + * + * @param[in] encodedCertElements TLV encoded structure of CD elements. + * @param[in] listTag A tag of an array to be found in the encodedCertElements TLV structure. + * + * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise + **/ + CHIP_ERROR FindAndEnterArray(const ByteSpan & encodedCertElements, TLV::Tag listTag); + CHIP_ERROR GetNextProductId(uint16_t & productId); + CHIP_ERROR GetNextAuthorizedPAA(ByteSpan & authorizedPAA); - ByteSpan mCertificationDeclarationData; - bool mIsInitialized = false; TLV::TLVReader mReader; - TLV::TLVType mOuterContainerType1 = TLV::kTLVType_Structure; - TLV::TLVType mOuterContainerType2 = TLV::kTLVType_Structure; }; /** diff --git a/src/credentials/tests/TestCertificationDeclaration.cpp b/src/credentials/tests/TestCertificationDeclaration.cpp index 3d15f39f2ea02e..cda5f90b05124e 100644 --- a/src/credentials/tests/TestCertificationDeclaration.cpp +++ b/src/credentials/tests/TestCertificationDeclaration.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2021-2022 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -203,6 +203,13 @@ static void TestCD_EncodeDecode(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, decodedElements.DACOriginVendorId == testCase.cdElements.DACOriginVendorId); NL_TEST_ASSERT(inSuite, decodedElements.DACOriginProductId == testCase.cdElements.DACOriginProductId); } + NL_TEST_ASSERT(inSuite, decodedElements.AuthorizedPAAListCount == testCase.cdElements.AuthorizedPAAListCount); + for (uint8_t j = 0; j < decodedElements.AuthorizedPAAListCount; j++) + { + NL_TEST_ASSERT( + inSuite, + memcmp(decodedElements.AuthorizedPAAList[j], testCase.cdElements.AuthorizedPAAList[j], kKeyIdentifierLength) == 0); + } } } @@ -347,6 +354,113 @@ static void TestCD_CertificationElementsDecoder(nlTestSuite * inSuite, void * in NL_TEST_ASSERT(inSuite, certificationDeclarationContent.dacOriginVendorId == testCase.cdElements.DACOriginVendorId); NL_TEST_ASSERT(inSuite, certificationDeclarationContent.dacOriginProductId == testCase.cdElements.DACOriginProductId); } + if (testCase.cdElements.AuthorizedPAAListCount > 0) + { + NL_TEST_ASSERT(inSuite, certificationDeclarationContent.authorizedPAAListPresent); + } + else + { + NL_TEST_ASSERT(inSuite, !certificationDeclarationContent.authorizedPAAListPresent); + } + } +} + +static void TestCD_EncodeDecode_Random(nlTestSuite * inSuite, void * inContext) +{ + CertificationElements randomElements = { .FormatVersion = 0x6F, + .VendorId = 0x88EA, + .ProductIds = { 0 }, + .ProductIdsCount = kMaxProductIdsCount, + .DeviceTypeId = 0x1234, + .CertificateId = "ZIG20141ZB330001-24", + .SecurityLevel = 10, + .SecurityInformation = 0xFA, + .VersionNumber = 0x28CA, + .CertificationType = 1, + .DACOriginVendorId = 0x01DC, + .DACOriginProductId = 0x10EE, + .DACOriginVIDandPIDPresent = false, + .AuthorizedPAAList = { { 0 } }, + .AuthorizedPAAListCount = kMaxAuthorizedPAAListCount }; + + uint16_t pid = 0x8000; + for (uint8_t j = 0; j < randomElements.ProductIdsCount; j++, pid++) + { + randomElements.ProductIds[j] = pid; + } + uint8_t kid[kKeyIdentifierLength] = { 0xF4, 0x44, 0xCA, 0xBB, 0xC5, 0x01, 0x65, 0x77, 0xAA, 0x8B, + 0x44, 0xFF, 0xB9, 0x0F, 0xCC, 0xA1, 0x40, 0xFE, 0x66, 0x20 }; + for (uint8_t j = 0; j < randomElements.AuthorizedPAAListCount; j++) + { + kid[(j % kKeyIdentifierLength)] ^= 0xFF; + memcpy(randomElements.AuthorizedPAAList[j], kid, kKeyIdentifierLength); + } + + uint8_t encodedCertElemBuf[kCertificationElements_TLVEncodedMaxLength]; + MutableByteSpan encodedCDPayload(encodedCertElemBuf); + CertificationElements decodedElements; + + NL_TEST_ASSERT(inSuite, EncodeCertificationElements(randomElements, encodedCDPayload) == CHIP_NO_ERROR); + + NL_TEST_ASSERT(inSuite, DecodeCertificationElements(encodedCDPayload, decodedElements) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, decodedElements.FormatVersion == randomElements.FormatVersion); + NL_TEST_ASSERT(inSuite, decodedElements.VendorId == randomElements.VendorId); + NL_TEST_ASSERT(inSuite, decodedElements.ProductIdsCount == randomElements.ProductIdsCount); + for (uint8_t j = 0; j < decodedElements.ProductIdsCount; j++) + { + NL_TEST_ASSERT(inSuite, decodedElements.ProductIds[j] == randomElements.ProductIds[j]); + } + NL_TEST_ASSERT(inSuite, decodedElements.DeviceTypeId == randomElements.DeviceTypeId); + NL_TEST_ASSERT(inSuite, memcmp(decodedElements.CertificateId, randomElements.CertificateId, kCertificateIdLength) == 0); + NL_TEST_ASSERT(inSuite, decodedElements.SecurityLevel == randomElements.SecurityLevel); + NL_TEST_ASSERT(inSuite, decodedElements.SecurityInformation == randomElements.SecurityInformation); + NL_TEST_ASSERT(inSuite, decodedElements.VersionNumber == randomElements.VersionNumber); + NL_TEST_ASSERT(inSuite, decodedElements.CertificationType == randomElements.CertificationType); + NL_TEST_ASSERT(inSuite, decodedElements.DACOriginVIDandPIDPresent == randomElements.DACOriginVIDandPIDPresent); + if (decodedElements.DACOriginVIDandPIDPresent) + { + NL_TEST_ASSERT(inSuite, decodedElements.DACOriginVendorId == randomElements.DACOriginVendorId); + NL_TEST_ASSERT(inSuite, decodedElements.DACOriginProductId == randomElements.DACOriginProductId); + } + NL_TEST_ASSERT(inSuite, decodedElements.AuthorizedPAAListCount == randomElements.AuthorizedPAAListCount); + for (uint8_t j = 0; j < decodedElements.AuthorizedPAAListCount; j++) + { + NL_TEST_ASSERT( + inSuite, memcmp(decodedElements.AuthorizedPAAList[j], randomElements.AuthorizedPAAList[j], kKeyIdentifierLength) == 0); + } + + CertificationElementsWithoutPIDs decodedElements2; + CertificationElementsDecoder cdElementsDecoder; + NL_TEST_ASSERT(inSuite, DecodeCertificationElements(encodedCDPayload, decodedElements2) == CHIP_NO_ERROR); + + NL_TEST_ASSERT(inSuite, decodedElements2.formatVersion == randomElements.FormatVersion); + NL_TEST_ASSERT(inSuite, decodedElements2.vendorId == randomElements.VendorId); + for (uint8_t j = 0; j < randomElements.ProductIdsCount; j++) + { + NL_TEST_ASSERT(inSuite, cdElementsDecoder.IsProductIdIn(encodedCDPayload, randomElements.ProductIds[j])); + // now test for an unexistent ProductId + NL_TEST_ASSERT(inSuite, cdElementsDecoder.IsProductIdIn(encodedCDPayload, pid++) == false); + } + NL_TEST_ASSERT(inSuite, decodedElements2.deviceTypeId == randomElements.DeviceTypeId); + NL_TEST_ASSERT(inSuite, memcmp(decodedElements2.certificateId, randomElements.CertificateId, kCertificateIdLength) == 0); + NL_TEST_ASSERT(inSuite, decodedElements2.securityLevel == randomElements.SecurityLevel); + NL_TEST_ASSERT(inSuite, decodedElements2.securityInformation == randomElements.SecurityInformation); + NL_TEST_ASSERT(inSuite, decodedElements2.versionNumber == randomElements.VersionNumber); + NL_TEST_ASSERT(inSuite, decodedElements2.certificationType == randomElements.CertificationType); + NL_TEST_ASSERT(inSuite, decodedElements2.dacOriginVIDandPIDPresent == randomElements.DACOriginVIDandPIDPresent); + if (decodedElements2.dacOriginVIDandPIDPresent) + { + NL_TEST_ASSERT(inSuite, decodedElements2.dacOriginVendorId == randomElements.DACOriginVendorId); + NL_TEST_ASSERT(inSuite, decodedElements2.dacOriginProductId == randomElements.DACOriginProductId); + } + NL_TEST_ASSERT(inSuite, decodedElements2.authorizedPAAListPresent); + for (uint8_t j = 0; j < randomElements.AuthorizedPAAListCount; j++) + { + NL_TEST_ASSERT(inSuite, + cdElementsDecoder.HasAuthorizedPAA(encodedCDPayload, ByteSpan(randomElements.AuthorizedPAAList[j]))); + // now test for an unexistent PAA + kid[(kKeyIdentifierLength - 1 - j) % kKeyIdentifierLength] ^= 0x5A; + NL_TEST_ASSERT(inSuite, cdElementsDecoder.HasAuthorizedPAA(encodedCDPayload, ByteSpan(kid)) == false); } } @@ -359,6 +473,7 @@ static const nlTest sTests[] = { NL_TEST_DEF_FN(TestCD_EncodeDecode), NL_TEST_DEF_FN(TestCD_CMSSignAndVerify), NL_TEST_DEF_FN(TestCD_CMSVerifyAndExtract), NL_TEST_DEF_FN(TestCD_CertificationElementsDecoder), + NL_TEST_DEF_FN(TestCD_EncodeDecode_Random), NL_TEST_SENTINEL() }; int TestCertificationDeclaration(void)