/* * * Copyright (c) 2020-2021 Project CHIP Authors * Copyright (c) 2013-2017 Nest Labs, Inc. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @file * This file implements a process to effect a functional test for * the CHIP Abstract Syntax Notifcation One (ASN1) encode and * decode interfaces. * */ #include #include #include #include #include #include #include #include using namespace chip; using namespace chip::ASN1; using namespace chip::TLV; enum { kTestVal_01_Bool = false, kTestVal_02_Bool = true, kTestVal_03_BitString = 0x0, kTestVal_04_BitString = 0x1, kTestVal_05_BitString = 0x3, kTestVal_06_BitString = 0x17, kTestVal_07_BitString = 0x37, kTestVal_08_BitString = 0x187, kTestVal_09_BitString = 0x3E7, kTestVal_10_Int = 0, kTestVal_11_Int = 1, kTestVal_12_Int = -1, kTestVal_13_Int = 0xFF00FF, kTestVal_14_Int = -0xFF00FF, kTestVal_15_Int = INT32_MAX, kTestVal_16_Int = INT32_MIN, kTestVal_17_Int = INT64_MAX, kTestVal_18_Int = INT64_MIN, kTestVal_19_OID = kOID_AttributeType_OrganizationName, kTestVal_23_OID = kOID_AttributeType_CommonName, kTestVal_24_Int = 42, }; // clang-format off static uint8_t kTestVal_09_BitString_AsOctetString[] = { 0xE7, 0xC0 }; static uint8_t kTestVal_20_OctetString[] = { 0x01, 0x03, 0x05, 0x07, 0x10, 0x30, 0x50, 0x70, 0x00 }; static const char kTestVal_21_PrintableString[] = "Sudden death in Venice"; static const char kTestVal_22_UTFString[] = "Ond bra\xCC\x8A""d do\xCC\x88""d i Venedig"; // clang-format on // Manually copied from ASN1OID.h for testing. static const uint8_t sOID_AttributeType_ChipNodeId[] = { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xA2, 0x7C, 0x01, 0x01 }; static const uint8_t sOID_SigAlgo_ECDSAWithSHA256[] = { 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02 }; static const uint8_t sOID_EllipticCurve_prime256v1[] = { 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 }; static const uint8_t sOID_Extension_AuthorityKeyIdentifier[] = { 0x55, 0x1D, 0x23 }; static const uint8_t sOID_Extension_BasicConstraints[] = { 0x55, 0x1D, 0x13 }; static const uint8_t sOID_KeyPurpose_ServerAuth[] = { 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01 }; uint8_t TestASN1_EncodedData[] = { 0x30, 0x81, 0xBA, 0x01, 0x01, 0x00, 0x01, 0x01, 0xFF, 0x31, 0x00, 0x03, 0x01, 0x00, 0x03, 0x02, 0x07, 0x80, 0x03, 0x02, 0x06, 0xC0, 0x30, 0x16, 0x30, 0x0F, 0x30, 0x08, 0x03, 0x02, 0x03, 0xE8, 0x03, 0x02, 0x02, 0xEC, 0x03, 0x03, 0x07, 0xE1, 0x80, 0x03, 0x03, 0x06, 0xE7, 0xC0, 0x02, 0x01, 0x00, 0x02, 0x01, 0x01, 0x02, 0x01, 0xFF, 0x02, 0x04, 0x00, 0xFF, 0x00, 0xFF, 0x02, 0x04, 0xFF, 0x00, 0xFF, 0x01, 0x02, 0x04, 0x7F, 0xFF, 0xFF, 0xFF, 0x02, 0x04, 0x80, 0x00, 0x00, 0x00, 0x02, 0x08, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x04, 0x09, 0x01, 0x03, 0x05, 0x07, 0x10, 0x30, 0x50, 0x70, 0x00, 0x04, 0x01, 0x01, 0x04, 0x00, 0x1B, 0x00, 0x13, 0x16, 0x53, 0x75, 0x64, 0x64, 0x65, 0x6E, 0x20, 0x64, 0x65, 0x61, 0x74, 0x68, 0x20, 0x69, 0x6E, 0x20, 0x56, 0x65, 0x6E, 0x69, 0x63, 0x65, 0x0C, 0x1A, 0x4F, 0x6E, 0x64, 0x20, 0x62, 0x72, 0x61, 0xCC, 0x8A, 0x64, 0x20, 0x64, 0x6F, 0xCC, 0x88, 0x64, 0x20, 0x69, 0x20, 0x56, 0x65, 0x6E, 0x65, 0x64, 0x69, 0x67, 0x04, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x03, 0x04, 0x00, 0x02, 0x01, 0x2A }; static CHIP_ERROR EncodeASN1TestData(ASN1Writer & writer) { CHIP_ERROR err = CHIP_NO_ERROR; ASN1_START_SEQUENCE { ASN1_ENCODE_BOOLEAN(kTestVal_01_Bool); ASN1_ENCODE_BOOLEAN(kTestVal_02_Bool); ASN1_START_SET {} ASN1_END_SET; ASN1_ENCODE_BIT_STRING(kTestVal_03_BitString); ASN1_ENCODE_BIT_STRING(kTestVal_04_BitString); ASN1_ENCODE_BIT_STRING(kTestVal_05_BitString); ASN1_START_SEQUENCE { ASN1_START_SEQUENCE { ASN1_START_SEQUENCE { ASN1_ENCODE_BIT_STRING(kTestVal_06_BitString); ASN1_ENCODE_BIT_STRING(kTestVal_07_BitString); } ASN1_END_SEQUENCE; ASN1_ENCODE_BIT_STRING(kTestVal_08_BitString); } ASN1_END_SEQUENCE; ASN1_ENCODE_BIT_STRING(kTestVal_09_BitString); } ASN1_END_SEQUENCE; ASN1_ENCODE_INTEGER(kTestVal_10_Int); ASN1_ENCODE_INTEGER(kTestVal_11_Int); ASN1_ENCODE_INTEGER(kTestVal_12_Int); ASN1_ENCODE_INTEGER(kTestVal_13_Int); ASN1_ENCODE_INTEGER(kTestVal_14_Int); ASN1_ENCODE_INTEGER(kTestVal_15_Int); ASN1_ENCODE_INTEGER(kTestVal_16_Int); ASN1_ENCODE_INTEGER(kTestVal_17_Int); ASN1_ENCODE_INTEGER(kTestVal_18_Int); ASN1_ENCODE_OBJECT_ID(kTestVal_19_OID); ASN1_ENCODE_OCTET_STRING(kTestVal_20_OctetString, sizeof(kTestVal_20_OctetString)); ASN1_ENCODE_OCTET_STRING(kTestVal_20_OctetString, 1); ASN1_ENCODE_OCTET_STRING(kTestVal_20_OctetString, 0); ASN1_ENCODE_STRING(kASN1UniversalTag_GeneralString, "", 0); ASN1_ENCODE_STRING(kASN1UniversalTag_PrintableString, kTestVal_21_PrintableString, static_cast(strlen(kTestVal_21_PrintableString))); ASN1_ENCODE_STRING(kASN1UniversalTag_UTF8String, kTestVal_22_UTFString, static_cast(strlen(kTestVal_22_UTFString))); ASN1_START_OCTET_STRING_ENCAPSULATED { ASN1_START_SEQUENCE { ASN1_ENCODE_OBJECT_ID(kTestVal_23_OID); ASN1_START_BIT_STRING_ENCAPSULATED { ASN1_ENCODE_INTEGER(kTestVal_24_Int); } ASN1_END_ENCAPSULATED; } ASN1_END_SEQUENCE; } ASN1_END_ENCAPSULATED; } ASN1_END_SEQUENCE; exit: return err; } TEST(TestASN1, Encode) { CHIP_ERROR err; static uint8_t buf[2048]; ASN1Writer writer; size_t encodedLen; writer.Init(buf); err = EncodeASN1TestData(writer); EXPECT_EQ(err, CHIP_NO_ERROR); encodedLen = writer.GetLengthWritten(); EXPECT_EQ(encodedLen, sizeof(TestASN1_EncodedData)); EXPECT_EQ(memcmp(buf, TestASN1_EncodedData, sizeof(TestASN1_EncodedData)), 0); #define DUMP_HEX 0 #if DUMP_HEX for (uint16_t i = 0; i < encodedLen; i++) { if (i != 0 && i % 16 == 0) printf("\n"); printf("0x%02X, ", buf[i]); } printf("\n"); #endif } TEST(TestASN1, Decode) { CHIP_ERROR err = CHIP_NO_ERROR; ASN1Reader reader; bool boolVal; uint32_t bitStringVal; int64_t intVal; OID oidVal; reader.Init(TestASN1_EncodedData); ASN1_PARSE_ENTER_SEQUENCE { ASN1_PARSE_BOOLEAN(boolVal); EXPECT_EQ(boolVal, kTestVal_01_Bool); ASN1_PARSE_BOOLEAN(boolVal); EXPECT_EQ(boolVal, kTestVal_02_Bool); ASN1_PARSE_ENTER_SET {} ASN1_EXIT_SET; ASN1_PARSE_BIT_STRING(bitStringVal); EXPECT_EQ(bitStringVal, kTestVal_03_BitString); ASN1_PARSE_BIT_STRING(bitStringVal); EXPECT_EQ(bitStringVal, kTestVal_04_BitString); ASN1_PARSE_BIT_STRING(bitStringVal); EXPECT_EQ(bitStringVal, kTestVal_05_BitString); ASN1_PARSE_ENTER_SEQUENCE { ASN1_PARSE_ENTER_SEQUENCE { ASN1_PARSE_ENTER_SEQUENCE { ASN1_PARSE_BIT_STRING(bitStringVal); EXPECT_EQ(bitStringVal, kTestVal_06_BitString); ASN1_PARSE_BIT_STRING(bitStringVal); EXPECT_EQ(bitStringVal, kTestVal_07_BitString); } ASN1_EXIT_SEQUENCE; ASN1_PARSE_BIT_STRING(bitStringVal); EXPECT_EQ(bitStringVal, kTestVal_08_BitString); } ASN1_EXIT_SEQUENCE; ASN1_PARSE_BIT_STRING(bitStringVal); EXPECT_EQ(bitStringVal, kTestVal_09_BitString); } ASN1_EXIT_SEQUENCE; ASN1_PARSE_INTEGER(intVal); EXPECT_EQ(intVal, kTestVal_10_Int); ASN1_PARSE_INTEGER(intVal); EXPECT_EQ(intVal, kTestVal_11_Int); ASN1_PARSE_INTEGER(intVal); EXPECT_EQ(intVal, kTestVal_12_Int); ASN1_PARSE_INTEGER(intVal); EXPECT_EQ(intVal, kTestVal_13_Int); ASN1_PARSE_INTEGER(intVal); EXPECT_EQ(intVal, kTestVal_14_Int); ASN1_PARSE_INTEGER(intVal); EXPECT_EQ(intVal, kTestVal_15_Int); ASN1_PARSE_INTEGER(intVal); EXPECT_EQ(intVal, kTestVal_16_Int); ASN1_PARSE_INTEGER(intVal); EXPECT_EQ(intVal, kTestVal_17_Int); ASN1_PARSE_INTEGER(intVal); EXPECT_EQ(intVal, kTestVal_18_Int); ASN1_PARSE_OBJECT_ID(oidVal); EXPECT_EQ(oidVal, kTestVal_19_OID); ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_OctetString); EXPECT_EQ(reader.GetValueLen(), sizeof(kTestVal_20_OctetString)); EXPECT_EQ(memcmp(reader.GetValue(), kTestVal_20_OctetString, sizeof(kTestVal_20_OctetString)), 0); ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_OctetString); EXPECT_EQ(reader.GetValueLen(), 1u); EXPECT_EQ(reader.GetValue()[0], kTestVal_20_OctetString[0]); ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_OctetString); EXPECT_EQ(reader.GetValueLen(), 0u); ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_GeneralString); EXPECT_EQ(reader.GetValueLen(), 0u); ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_PrintableString); EXPECT_EQ(reader.GetValueLen(), strlen(kTestVal_21_PrintableString)); EXPECT_EQ(memcmp(reader.GetValue(), kTestVal_21_PrintableString, strlen(kTestVal_21_PrintableString)), 0); ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_UTF8String); EXPECT_EQ(reader.GetValueLen(), strlen(kTestVal_22_UTFString)); EXPECT_EQ(memcmp(reader.GetValue(), kTestVal_22_UTFString, strlen(kTestVal_22_UTFString)), 0); ASN1_PARSE_ENTER_ENCAPSULATED(kASN1TagClass_Universal, kASN1UniversalTag_OctetString) { ASN1_PARSE_ENTER_SEQUENCE { ASN1_PARSE_OBJECT_ID(oidVal); EXPECT_EQ(oidVal, kTestVal_23_OID); ASN1_PARSE_ENTER_ENCAPSULATED(kASN1TagClass_Universal, kASN1UniversalTag_BitString) { ASN1_PARSE_INTEGER(intVal); EXPECT_EQ(intVal, kTestVal_24_Int); } ASN1_EXIT_ENCAPSULATED; } ASN1_EXIT_SEQUENCE; } ASN1_EXIT_ENCAPSULATED; } ASN1_EXIT_SEQUENCE; exit: EXPECT_EQ(err, CHIP_NO_ERROR); } TEST(TestASN1, NullWriter) { CHIP_ERROR err; ASN1Writer writer; size_t encodedLen; writer.InitNullWriter(); err = EncodeASN1TestData(writer); EXPECT_EQ(err, CHIP_NO_ERROR); encodedLen = writer.GetLengthWritten(); EXPECT_EQ(encodedLen, 0u); // Methods that take a reader should still read from it, // even if the output is suppressed by the null writer. TLVReader emptyTlvReader; emptyTlvReader.Init(ByteSpan()); err = writer.PutBitString(0, emptyTlvReader); EXPECT_EQ(err, CHIP_ERROR_WRONG_TLV_TYPE); emptyTlvReader.Init(ByteSpan()); err = writer.PutOctetString(kASN1TagClass_ContextSpecific, 123, emptyTlvReader); EXPECT_EQ(err, CHIP_ERROR_WRONG_TLV_TYPE); } TEST(TestASN1, ASN1UniversalTime) { struct ASN1TimeTestCase { ASN1UniversalTime asn1Time; const char * asn1TimeStr; }; struct ASN1TimeErrorTestCase { const char * asn1TimeStr; CHIP_ERROR mExpectedResult; }; // clang-format off static ASN1TimeTestCase sASN1TimeTestCases[] = { // ASN1 Universal Time ASN1_TIME String // ==================================================== { { 2020, 10, 15, 14, 23, 43 }, "201015142343Z" }, { { 2020, 12, 1, 2, 34, 0 }, "201201023400Z" }, { { 1979, 1, 30, 12, 0, 0 }, "790130120000Z" }, { { 2079, 1, 30, 12, 0, 0 }, "20790130120000Z" }, { { 2049, 3, 31, 23, 59, 59 }, "490331235959Z" }, { { 1949, 3, 31, 23, 59, 59 }, "19490331235959Z" }, { { 1950, 3, 31, 23, 59, 59 }, "500331235959Z" }, }; // clang-format on // clang-format off static ASN1TimeErrorTestCase sASN1TimeErrorTestCases[] = { // ASN1_TIME String Expected Result // ======================================================= { "201015142343z", ASN1_ERROR_UNSUPPORTED_ENCODING }, { "20105142343Z", ASN1_ERROR_UNSUPPORTED_ENCODING }, { "2010115142343Z", ASN1_ERROR_UNSUPPORTED_ENCODING }, { "201014415142343Z", ASN1_ERROR_UNSUPPORTED_ENCODING }, { "201O15142343Z", ASN1_ERROR_INVALID_ENCODING }, { "200015142343Z", ASN1_ERROR_INVALID_ENCODING }, { "201315142343Z", ASN1_ERROR_INVALID_ENCODING }, { "201000142343Z", ASN1_ERROR_INVALID_ENCODING }, { "201032142343Z", ASN1_ERROR_INVALID_ENCODING }, { "201015242343Z", ASN1_ERROR_INVALID_ENCODING }, { "201015146043Z", ASN1_ERROR_INVALID_ENCODING }, { "201015142360Z", ASN1_ERROR_INVALID_ENCODING }, }; // clang-format on for (auto & testCase : sASN1TimeTestCases) { CharSpan testStr = CharSpan(testCase.asn1TimeStr, strlen(testCase.asn1TimeStr)); ASN1UniversalTime result; EXPECT_EQ(result.ImportFrom_ASN1_TIME_string(testStr), CHIP_NO_ERROR); EXPECT_EQ(result.Year, testCase.asn1Time.Year); EXPECT_EQ(result.Month, testCase.asn1Time.Month); EXPECT_EQ(result.Day, testCase.asn1Time.Day); EXPECT_EQ(result.Hour, testCase.asn1Time.Hour); EXPECT_EQ(result.Minute, testCase.asn1Time.Minute); EXPECT_EQ(result.Second, testCase.asn1Time.Second); char buf[ASN1UniversalTime::kASN1TimeStringMaxLength]; MutableCharSpan resultTimeStr(buf); EXPECT_EQ(result.ExportTo_ASN1_TIME_string(resultTimeStr), CHIP_NO_ERROR); EXPECT_TRUE(resultTimeStr.data_equal(testStr)); } for (auto & testCase : sASN1TimeErrorTestCases) { CharSpan testStr = CharSpan(testCase.asn1TimeStr, strlen(testCase.asn1TimeStr)); ASN1UniversalTime result; EXPECT_EQ(result.ImportFrom_ASN1_TIME_string(testStr), testCase.mExpectedResult); } } TEST(TestASN1, ObjectID) { CHIP_ERROR err; static uint8_t buf[2048]; ASN1Writer writer; ASN1Reader reader; size_t encodedLen; writer.Init(buf, sizeof(buf)); ASN1_START_SEQUENCE { ASN1_ENCODE_OBJECT_ID(kOID_AttributeType_MatterNodeId); ASN1_ENCODE_OBJECT_ID(kOID_SigAlgo_ECDSAWithSHA256); ASN1_ENCODE_OBJECT_ID(kOID_EllipticCurve_prime256v1); ASN1_ENCODE_OBJECT_ID(kOID_Extension_AuthorityKeyIdentifier); ASN1_ENCODE_OBJECT_ID(kOID_Extension_BasicConstraints); ASN1_ENCODE_OBJECT_ID(kOID_KeyPurpose_ServerAuth); } ASN1_END_SEQUENCE; encodedLen = writer.GetLengthWritten(); EXPECT_GT(encodedLen, 0u); reader.Init(buf, encodedLen); // Parse and check OIDs as actual ASN1 encoded values. ASN1_PARSE_ENTER_SEQUENCE { ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId); EXPECT_EQ(reader.GetValueLen(), sizeof(sOID_AttributeType_ChipNodeId)); EXPECT_EQ(memcmp(reader.GetValue(), sOID_AttributeType_ChipNodeId, sizeof(sOID_AttributeType_ChipNodeId)), 0); ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId); EXPECT_EQ(reader.GetValueLen(), sizeof(sOID_SigAlgo_ECDSAWithSHA256)); EXPECT_EQ(memcmp(reader.GetValue(), sOID_SigAlgo_ECDSAWithSHA256, sizeof(sOID_SigAlgo_ECDSAWithSHA256)), 0); ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId); EXPECT_EQ(reader.GetValueLen(), sizeof(sOID_EllipticCurve_prime256v1)); EXPECT_EQ(memcmp(reader.GetValue(), sOID_EllipticCurve_prime256v1, sizeof(sOID_EllipticCurve_prime256v1)), 0); ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId); EXPECT_EQ(reader.GetValueLen(), sizeof(sOID_Extension_AuthorityKeyIdentifier)); EXPECT_EQ(memcmp(reader.GetValue(), sOID_Extension_AuthorityKeyIdentifier, sizeof(sOID_Extension_AuthorityKeyIdentifier)), 0); ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId); EXPECT_EQ(reader.GetValueLen(), sizeof(sOID_Extension_BasicConstraints)); EXPECT_EQ(memcmp(reader.GetValue(), sOID_Extension_BasicConstraints, sizeof(sOID_Extension_BasicConstraints)), 0); ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId); EXPECT_EQ(reader.GetValueLen(), sizeof(sOID_KeyPurpose_ServerAuth)); EXPECT_EQ(memcmp(reader.GetValue(), sOID_KeyPurpose_ServerAuth, sizeof(sOID_KeyPurpose_ServerAuth)), 0); } ASN1_EXIT_SEQUENCE; exit: EXPECT_EQ(err, CHIP_NO_ERROR); } TEST(TestASN1, FromTLVReader) { CHIP_ERROR err; static uint8_t tlvBuf[128]; static uint8_t asn1Buf1[128]; static uint8_t asn1Buf2[128]; TLVWriter tlvWriter; TLVReader tlvReader; ASN1Writer writer; ASN1Reader reader; MutableByteSpan tlvEncodedData(tlvBuf); MutableByteSpan asn1EncodedData1(asn1Buf1); MutableByteSpan asn1EncodedData2(asn1Buf2); TLVType outerContainerType; // Construct TLV Encoded Structure. { tlvWriter.Init(tlvEncodedData); err = tlvWriter.StartContainer(AnonymousTag(), kTLVType_Structure, outerContainerType); EXPECT_EQ(err, CHIP_NO_ERROR); err = tlvWriter.PutBytes(TLV::ContextTag(1), kTestVal_20_OctetString, sizeof(kTestVal_20_OctetString)); EXPECT_EQ(err, CHIP_NO_ERROR); err = tlvWriter.PutBytes(TLV::ContextTag(2), kTestVal_09_BitString_AsOctetString, sizeof(kTestVal_09_BitString_AsOctetString)); EXPECT_EQ(err, CHIP_NO_ERROR); err = tlvWriter.PutString(TLV::ContextTag(3), kTestVal_21_PrintableString); EXPECT_EQ(err, CHIP_NO_ERROR); err = tlvWriter.EndContainer(outerContainerType); EXPECT_EQ(err, CHIP_NO_ERROR); err = tlvWriter.Finalize(); EXPECT_EQ(err, CHIP_NO_ERROR); } // Construct first ASN1 SEQUESNCE using values. writer.Init(asn1EncodedData1); ASN1_START_SEQUENCE { ASN1_ENCODE_OCTET_STRING(kTestVal_20_OctetString, sizeof(kTestVal_20_OctetString)); ASN1_ENCODE_BIT_STRING(kTestVal_09_BitString); err = writer.PutValue(kASN1TagClass_Universal, kASN1UniversalTag_PrintableString, false, reinterpret_cast(kTestVal_21_PrintableString), static_cast(strlen(kTestVal_21_PrintableString))); EXPECT_EQ(err, CHIP_NO_ERROR); } ASN1_END_SEQUENCE; asn1EncodedData1.reduce_size(writer.GetLengthWritten()); // Construct second ASN1 SEQUENCE from TLVReader. tlvReader.Init(tlvEncodedData); writer.Init(asn1EncodedData2); ASN1_START_SEQUENCE { err = tlvReader.Next(kTLVType_Structure, AnonymousTag()); EXPECT_EQ(err, CHIP_NO_ERROR); err = tlvReader.EnterContainer(outerContainerType); EXPECT_EQ(err, CHIP_NO_ERROR); err = tlvReader.Next(kTLVType_ByteString, ContextTag(1)); EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.PutOctetString(kASN1TagClass_Universal, kASN1UniversalTag_OctetString, tlvReader); EXPECT_EQ(err, CHIP_NO_ERROR); err = tlvReader.Next(kTLVType_ByteString, ContextTag(2)); EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.PutBitString(6, tlvReader); EXPECT_EQ(err, CHIP_NO_ERROR); err = tlvReader.Next(kTLVType_UTF8String, ContextTag(3)); EXPECT_EQ(err, CHIP_NO_ERROR); err = writer.PutValue(kASN1TagClass_Universal, kASN1UniversalTag_PrintableString, false, tlvReader); EXPECT_EQ(err, CHIP_NO_ERROR); err = tlvReader.ExitContainer(outerContainerType); EXPECT_EQ(err, CHIP_NO_ERROR); } ASN1_END_SEQUENCE; asn1EncodedData2.reduce_size(writer.GetLengthWritten()); // Compare two ASN1 SEQUENCEs. EXPECT_TRUE(asn1EncodedData2.data_equal(asn1EncodedData1)); // Initialize ASN1Reader and test data. reader.Init(asn1EncodedData2); ASN1_PARSE_ENTER_SEQUENCE { ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_OctetString); ASSERT_NE(reader.GetValue(), nullptr); EXPECT_EQ(reader.GetValueLen(), sizeof(kTestVal_20_OctetString)); EXPECT_EQ(memcmp(reader.GetValue(), kTestVal_20_OctetString, sizeof(kTestVal_20_OctetString)), 0); uint32_t val; ASN1_PARSE_BIT_STRING(val); EXPECT_EQ(val, kTestVal_09_BitString); ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_PrintableString); ASSERT_NE(reader.GetValue(), nullptr); EXPECT_EQ(reader.GetValueLen(), strlen(kTestVal_21_PrintableString)); EXPECT_EQ(memcmp(reader.GetValue(), kTestVal_21_PrintableString, strlen(kTestVal_21_PrintableString)), 0); } ASN1_EXIT_SEQUENCE; exit: EXPECT_EQ(err, CHIP_NO_ERROR); }