Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / lib / asn1 / tests / TestASN1.cpp
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    Copyright (c) 2013-2017 Nest Labs, Inc.
5  *    All rights reserved.
6  *
7  *    Licensed under the Apache License, Version 2.0 (the "License");
8  *    you may not use this file except in compliance with the License.
9  *    You may obtain a copy of the License at
10  *
11  *        http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *    Unless required by applicable law or agreed to in writing, software
14  *    distributed under the License is distributed on an "AS IS" BASIS,
15  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *    See the License for the specific language governing permissions and
17  *    limitations under the License.
18  */
19
20 /**
21  *    @file
22  *      This file implements a process to effect a functional test for
23  *      the CHIP Abstract Syntax Notifcation One (ASN1) encode and
24  *      decode interfaces.
25  *
26  */
27 #include <nlunit-test.h>
28
29 #include <stdint.h>
30 #include <stdio.h>
31 #include <string.h>
32
33 #include <support/UnitTestRegistration.h>
34
35 #include <asn1/ASN1.h>
36 #include <asn1/ASN1Macros.h>
37 #include <asn1/ASN1OID.h>
38
39 using namespace chip;
40 using namespace chip::ASN1;
41
42 enum
43 {
44     kTestVal_01_Bool      = false,
45     kTestVal_02_Bool      = true,
46     kTestVal_03_BitString = 0x0,
47     kTestVal_04_BitString = 0x1,
48     kTestVal_05_BitString = 0x3,
49     kTestVal_06_BitString = 0x17,
50     kTestVal_07_BitString = 0x37,
51     kTestVal_08_BitString = 0x187,
52     kTestVal_09_BitString = 0x3E7,
53     kTestVal_10_Int       = 0,
54     kTestVal_11_Int       = 1,
55     kTestVal_12_Int       = -1,
56     kTestVal_13_Int       = 0xFF00FF,
57     kTestVal_14_Int       = -0xFF00FF,
58     kTestVal_15_Int       = INT32_MAX,
59     kTestVal_16_Int       = INT32_MIN,
60     kTestVal_17_Int       = INT64_MAX,
61     kTestVal_18_Int       = INT64_MIN,
62     kTestVal_19_OID       = kOID_AttributeType_OrganizationName,
63     kTestVal_23_OID       = kOID_AttributeType_CommonName,
64     kTestVal_24_Int       = 42,
65 };
66
67 // clang-format off
68 static uint8_t kTestVal_20_OctetString[]        = { 0x01, 0x03, 0x05, 0x07, 0x10, 0x30, 0x50, 0x70, 0x00 };
69 static const char * kTestVal_21_PrintableString = "Sudden death in Venice";
70 static const char * kTestVal_22_UTFString       = "Ond bra\xCC\x8A""d do\xCC\x88""d i Venedig";
71 // clang-format on
72
73 // Manually copied from ASN1OID.h for testing.
74 static const uint8_t sOID_AttributeType_ChipNodeId[]         = { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0xA2, 0x7C, 0x01, 0x01 };
75 static const uint8_t sOID_SigAlgo_ECDSAWithSHA256[]          = { 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02 };
76 static const uint8_t sOID_EllipticCurve_prime256v1[]         = { 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 };
77 static const uint8_t sOID_Extension_AuthorityKeyIdentifier[] = { 0x55, 0x1D, 0x23 };
78 static const uint8_t sOID_Extension_BasicConstraints[]       = { 0x55, 0x1D, 0x13 };
79 static const uint8_t sOID_KeyPurpose_ServerAuth[]            = { 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01 };
80
81 uint8_t TestASN1_EncodedData[] = {
82     0x30, 0x81, 0xBA, 0x01, 0x01, 0x00, 0x01, 0x01, 0xFF, 0x31, 0x00, 0x03, 0x01, 0x00, 0x03, 0x02, 0x07, 0x80, 0x03, 0x02, 0x06,
83     0xC0, 0x30, 0x16, 0x30, 0x0F, 0x30, 0x08, 0x03, 0x02, 0x03, 0xE8, 0x03, 0x02, 0x02, 0xEC, 0x03, 0x03, 0x07, 0xE1, 0x80, 0x03,
84     0x03, 0x06, 0xE7, 0xC0, 0x02, 0x01, 0x00, 0x02, 0x01, 0x01, 0x02, 0x01, 0xFF, 0x02, 0x04, 0x00, 0xFF, 0x00, 0xFF, 0x02, 0x04,
85     0xFF, 0x00, 0xFF, 0x01, 0x02, 0x04, 0x7F, 0xFF, 0xFF, 0xFF, 0x02, 0x04, 0x80, 0x00, 0x00, 0x00, 0x02, 0x08, 0x7F, 0xFF, 0xFF,
86     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x04,
87     0x09, 0x01, 0x03, 0x05, 0x07, 0x10, 0x30, 0x50, 0x70, 0x00, 0x04, 0x01, 0x01, 0x04, 0x00, 0x1B, 0x00, 0x13, 0x16, 0x53, 0x75,
88     0x64, 0x64, 0x65, 0x6E, 0x20, 0x64, 0x65, 0x61, 0x74, 0x68, 0x20, 0x69, 0x6E, 0x20, 0x56, 0x65, 0x6E, 0x69, 0x63, 0x65, 0x0C,
89     0x1A, 0x4F, 0x6E, 0x64, 0x20, 0x62, 0x72, 0x61, 0xCC, 0x8A, 0x64, 0x20, 0x64, 0x6F, 0xCC, 0x88, 0x64, 0x20, 0x69, 0x20, 0x56,
90     0x65, 0x6E, 0x65, 0x64, 0x69, 0x67, 0x04, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x03, 0x04, 0x00, 0x02, 0x01, 0x2A
91 };
92
93 static ASN1_ERROR EncodeASN1TestData(ASN1Writer & writer)
94 {
95     ASN1_ERROR err = ASN1_NO_ERROR;
96
97     ASN1_START_SEQUENCE
98     {
99         ASN1_ENCODE_BOOLEAN(kTestVal_01_Bool);
100         ASN1_ENCODE_BOOLEAN(kTestVal_02_Bool);
101         ASN1_START_SET {}
102         ASN1_END_SET;
103         ASN1_ENCODE_BIT_STRING(kTestVal_03_BitString);
104         ASN1_ENCODE_BIT_STRING(kTestVal_04_BitString);
105         ASN1_ENCODE_BIT_STRING(kTestVal_05_BitString);
106         ASN1_START_SEQUENCE
107         {
108             ASN1_START_SEQUENCE
109             {
110                 ASN1_START_SEQUENCE
111                 {
112                     ASN1_ENCODE_BIT_STRING(kTestVal_06_BitString);
113                     ASN1_ENCODE_BIT_STRING(kTestVal_07_BitString);
114                 }
115                 ASN1_END_SEQUENCE;
116                 ASN1_ENCODE_BIT_STRING(kTestVal_08_BitString);
117             }
118             ASN1_END_SEQUENCE;
119             ASN1_ENCODE_BIT_STRING(kTestVal_09_BitString);
120         }
121         ASN1_END_SEQUENCE;
122         ASN1_ENCODE_INTEGER(kTestVal_10_Int);
123         ASN1_ENCODE_INTEGER(kTestVal_11_Int);
124         ASN1_ENCODE_INTEGER(kTestVal_12_Int);
125         ASN1_ENCODE_INTEGER(kTestVal_13_Int);
126         ASN1_ENCODE_INTEGER(kTestVal_14_Int);
127         ASN1_ENCODE_INTEGER(kTestVal_15_Int);
128         ASN1_ENCODE_INTEGER(kTestVal_16_Int);
129         ASN1_ENCODE_INTEGER(kTestVal_17_Int);
130         ASN1_ENCODE_INTEGER(kTestVal_18_Int);
131         ASN1_ENCODE_OBJECT_ID(kTestVal_19_OID);
132         ASN1_ENCODE_OCTET_STRING(kTestVal_20_OctetString, sizeof(kTestVal_20_OctetString));
133         ASN1_ENCODE_OCTET_STRING(kTestVal_20_OctetString, 1);
134         ASN1_ENCODE_OCTET_STRING(kTestVal_20_OctetString, 0);
135         ASN1_ENCODE_STRING(kASN1UniversalTag_GeneralString, "", 0);
136         ASN1_ENCODE_STRING(kASN1UniversalTag_PrintableString, kTestVal_21_PrintableString, strlen(kTestVal_21_PrintableString));
137         ASN1_ENCODE_STRING(kASN1UniversalTag_UTF8String, kTestVal_22_UTFString, strlen(kTestVal_22_UTFString));
138         ASN1_START_OCTET_STRING_ENCAPSULATED
139         {
140             ASN1_START_SEQUENCE
141             {
142                 ASN1_ENCODE_OBJECT_ID(kTestVal_23_OID);
143                 ASN1_START_BIT_STRING_ENCAPSULATED { ASN1_ENCODE_INTEGER(kTestVal_24_Int); }
144                 ASN1_END_ENCAPSULATED;
145             }
146             ASN1_END_SEQUENCE;
147         }
148         ASN1_END_ENCAPSULATED;
149     }
150     ASN1_END_SEQUENCE;
151
152 exit:
153     return err;
154 }
155
156 static void TestASN1_Encode(nlTestSuite * inSuite, void * inContext)
157 {
158     ASN1_ERROR err;
159     uint8_t buf[2048];
160     ASN1Writer writer;
161     uint16_t encodedLen;
162
163     writer.Init(buf, sizeof(buf));
164
165     err = EncodeASN1TestData(writer);
166     NL_TEST_ASSERT(inSuite, err == ASN1_NO_ERROR);
167
168     err = writer.Finalize();
169     NL_TEST_ASSERT(inSuite, err == ASN1_NO_ERROR);
170
171     encodedLen = writer.GetLengthWritten();
172     NL_TEST_ASSERT(inSuite, encodedLen == sizeof(TestASN1_EncodedData));
173     NL_TEST_ASSERT(inSuite, memcmp(buf, TestASN1_EncodedData, sizeof(TestASN1_EncodedData)) == 0);
174
175 #define DUMP_HEX 0
176 #if DUMP_HEX
177     for (uint16_t i = 0; i < encodedLen; i++)
178     {
179         if (i != 0 && i % 16 == 0)
180             printf("\n");
181         printf("0x%02X, ", buf[i]);
182     }
183     printf("\n");
184 #endif
185 }
186
187 static void TestASN1_Decode(nlTestSuite * inSuite, void * inContext)
188 {
189     ASN1_ERROR err = ASN1_NO_ERROR;
190     ASN1Reader reader;
191     bool boolVal;
192     uint32_t bitStringVal;
193     int64_t intVal;
194     OID oidVal;
195
196     reader.Init(TestASN1_EncodedData, sizeof(TestASN1_EncodedData));
197
198     ASN1_PARSE_ENTER_SEQUENCE
199     {
200         ASN1_PARSE_BOOLEAN(boolVal);
201         NL_TEST_ASSERT(inSuite, boolVal == kTestVal_01_Bool);
202         ASN1_PARSE_BOOLEAN(boolVal);
203         NL_TEST_ASSERT(inSuite, boolVal == kTestVal_02_Bool);
204         ASN1_PARSE_ENTER_SET {}
205         ASN1_EXIT_SET;
206         ASN1_PARSE_BIT_STRING(bitStringVal);
207         NL_TEST_ASSERT(inSuite, bitStringVal == kTestVal_03_BitString);
208         ASN1_PARSE_BIT_STRING(bitStringVal);
209         NL_TEST_ASSERT(inSuite, bitStringVal == kTestVal_04_BitString);
210         ASN1_PARSE_BIT_STRING(bitStringVal);
211         NL_TEST_ASSERT(inSuite, bitStringVal == kTestVal_05_BitString);
212         ASN1_PARSE_ENTER_SEQUENCE
213         {
214             ASN1_PARSE_ENTER_SEQUENCE
215             {
216                 ASN1_PARSE_ENTER_SEQUENCE
217                 {
218                     ASN1_PARSE_BIT_STRING(bitStringVal);
219                     NL_TEST_ASSERT(inSuite, bitStringVal == kTestVal_06_BitString);
220                     ASN1_PARSE_BIT_STRING(bitStringVal);
221                     NL_TEST_ASSERT(inSuite, bitStringVal == kTestVal_07_BitString);
222                 }
223                 ASN1_EXIT_SEQUENCE;
224                 ASN1_PARSE_BIT_STRING(bitStringVal);
225                 NL_TEST_ASSERT(inSuite, bitStringVal == kTestVal_08_BitString);
226             }
227             ASN1_EXIT_SEQUENCE;
228             ASN1_PARSE_BIT_STRING(bitStringVal);
229             NL_TEST_ASSERT(inSuite, bitStringVal == kTestVal_09_BitString);
230         }
231         ASN1_EXIT_SEQUENCE;
232         ASN1_PARSE_INTEGER(intVal);
233         NL_TEST_ASSERT(inSuite, intVal == kTestVal_10_Int);
234         ASN1_PARSE_INTEGER(intVal);
235         NL_TEST_ASSERT(inSuite, intVal == kTestVal_11_Int);
236         ASN1_PARSE_INTEGER(intVal);
237         NL_TEST_ASSERT(inSuite, intVal == kTestVal_12_Int);
238         ASN1_PARSE_INTEGER(intVal);
239         NL_TEST_ASSERT(inSuite, intVal == kTestVal_13_Int);
240         ASN1_PARSE_INTEGER(intVal);
241         NL_TEST_ASSERT(inSuite, intVal == kTestVal_14_Int);
242         ASN1_PARSE_INTEGER(intVal);
243         NL_TEST_ASSERT(inSuite, intVal == kTestVal_15_Int);
244         ASN1_PARSE_INTEGER(intVal);
245         NL_TEST_ASSERT(inSuite, intVal == kTestVal_16_Int);
246         ASN1_PARSE_INTEGER(intVal);
247         NL_TEST_ASSERT(inSuite, intVal == kTestVal_17_Int);
248         ASN1_PARSE_INTEGER(intVal);
249         NL_TEST_ASSERT(inSuite, intVal == kTestVal_18_Int);
250         ASN1_PARSE_OBJECT_ID(oidVal);
251         NL_TEST_ASSERT(inSuite, oidVal == kTestVal_19_OID);
252         ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_OctetString);
253         NL_TEST_ASSERT(inSuite, reader.GetValueLen() == sizeof(kTestVal_20_OctetString));
254         NL_TEST_ASSERT(inSuite, memcmp(reader.GetValue(), kTestVal_20_OctetString, sizeof(kTestVal_20_OctetString)) == 0);
255         ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_OctetString);
256         NL_TEST_ASSERT(inSuite, reader.GetValueLen() == 1);
257         NL_TEST_ASSERT(inSuite, reader.GetValue()[0] == kTestVal_20_OctetString[0]);
258         ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_OctetString);
259         NL_TEST_ASSERT(inSuite, reader.GetValueLen() == 0);
260         ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_GeneralString);
261         NL_TEST_ASSERT(inSuite, reader.GetValueLen() == 0);
262         ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_PrintableString);
263         NL_TEST_ASSERT(inSuite, reader.GetValueLen() == strlen(kTestVal_21_PrintableString));
264         NL_TEST_ASSERT(inSuite, memcmp(reader.GetValue(), kTestVal_21_PrintableString, strlen(kTestVal_21_PrintableString)) == 0);
265         ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_UTF8String);
266         NL_TEST_ASSERT(inSuite, reader.GetValueLen() == strlen(kTestVal_22_UTFString));
267         NL_TEST_ASSERT(inSuite, memcmp(reader.GetValue(), kTestVal_22_UTFString, strlen(kTestVal_22_UTFString)) == 0);
268         ASN1_PARSE_ENTER_ENCAPSULATED(kASN1TagClass_Universal, kASN1UniversalTag_OctetString)
269         {
270             ASN1_PARSE_ENTER_SEQUENCE
271             {
272                 ASN1_PARSE_OBJECT_ID(oidVal);
273                 NL_TEST_ASSERT(inSuite, oidVal == kTestVal_23_OID);
274                 ASN1_PARSE_ENTER_ENCAPSULATED(kASN1TagClass_Universal, kASN1UniversalTag_BitString)
275                 {
276                     ASN1_PARSE_INTEGER(intVal);
277                     NL_TEST_ASSERT(inSuite, intVal == kTestVal_24_Int);
278                 }
279                 ASN1_EXIT_ENCAPSULATED;
280             }
281             ASN1_EXIT_SEQUENCE;
282         }
283         ASN1_EXIT_ENCAPSULATED;
284     }
285     ASN1_EXIT_SEQUENCE;
286
287 exit:
288     NL_TEST_ASSERT(inSuite, err == ASN1_NO_ERROR);
289 }
290
291 static void TestASN1_NullWriter(nlTestSuite * inSuite, void * inContext)
292 {
293     ASN1_ERROR err;
294     ASN1Writer writer;
295     uint16_t encodedLen;
296
297     writer.InitNullWriter();
298
299     err = EncodeASN1TestData(writer);
300     NL_TEST_ASSERT(inSuite, err == ASN1_NO_ERROR);
301
302     err = writer.Finalize();
303     NL_TEST_ASSERT(inSuite, err == ASN1_NO_ERROR);
304
305     encodedLen = writer.GetLengthWritten();
306     NL_TEST_ASSERT(inSuite, encodedLen == 0);
307 }
308
309 static void TestASN1_ObjectID(nlTestSuite * inSuite, void * inContext)
310 {
311     ASN1_ERROR err;
312     uint8_t buf[2048];
313     ASN1Writer writer;
314     ASN1Reader reader;
315     uint16_t encodedLen;
316
317     writer.Init(buf, sizeof(buf));
318
319     ASN1_START_SEQUENCE
320     {
321         ASN1_ENCODE_OBJECT_ID(kOID_AttributeType_ChipNodeId);
322         ASN1_ENCODE_OBJECT_ID(kOID_SigAlgo_ECDSAWithSHA256);
323         ASN1_ENCODE_OBJECT_ID(kOID_EllipticCurve_prime256v1);
324         ASN1_ENCODE_OBJECT_ID(kOID_Extension_AuthorityKeyIdentifier);
325         ASN1_ENCODE_OBJECT_ID(kOID_Extension_BasicConstraints);
326         ASN1_ENCODE_OBJECT_ID(kOID_KeyPurpose_ServerAuth);
327     }
328     ASN1_END_SEQUENCE;
329
330     err = writer.Finalize();
331     NL_TEST_ASSERT(inSuite, err == ASN1_NO_ERROR);
332
333     encodedLen = writer.GetLengthWritten();
334     NL_TEST_ASSERT(inSuite, encodedLen > 0);
335
336     reader.Init(buf, encodedLen);
337
338     // Parse and check OIDs as actual ASN1 encoded values.
339     ASN1_PARSE_ENTER_SEQUENCE
340     {
341         ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId);
342         NL_TEST_ASSERT(inSuite, reader.GetValueLen() == sizeof(sOID_AttributeType_ChipNodeId));
343         NL_TEST_ASSERT(inSuite,
344                        memcmp(reader.GetValue(), sOID_AttributeType_ChipNodeId, sizeof(sOID_AttributeType_ChipNodeId)) == 0);
345
346         ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId);
347         NL_TEST_ASSERT(inSuite, reader.GetValueLen() == sizeof(sOID_SigAlgo_ECDSAWithSHA256));
348         NL_TEST_ASSERT(inSuite, memcmp(reader.GetValue(), sOID_SigAlgo_ECDSAWithSHA256, sizeof(sOID_SigAlgo_ECDSAWithSHA256)) == 0);
349
350         ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId);
351         NL_TEST_ASSERT(inSuite, reader.GetValueLen() == sizeof(sOID_EllipticCurve_prime256v1));
352         NL_TEST_ASSERT(inSuite,
353                        memcmp(reader.GetValue(), sOID_EllipticCurve_prime256v1, sizeof(sOID_EllipticCurve_prime256v1)) == 0);
354
355         ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId);
356         NL_TEST_ASSERT(inSuite, reader.GetValueLen() == sizeof(sOID_Extension_AuthorityKeyIdentifier));
357         NL_TEST_ASSERT(
358             inSuite,
359             memcmp(reader.GetValue(), sOID_Extension_AuthorityKeyIdentifier, sizeof(sOID_Extension_AuthorityKeyIdentifier)) == 0);
360
361         ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId);
362         NL_TEST_ASSERT(inSuite, reader.GetValueLen() == sizeof(sOID_Extension_BasicConstraints));
363         NL_TEST_ASSERT(inSuite,
364                        memcmp(reader.GetValue(), sOID_Extension_BasicConstraints, sizeof(sOID_Extension_BasicConstraints)) == 0);
365
366         ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId);
367         NL_TEST_ASSERT(inSuite, reader.GetValueLen() == sizeof(sOID_KeyPurpose_ServerAuth));
368         NL_TEST_ASSERT(inSuite, memcmp(reader.GetValue(), sOID_KeyPurpose_ServerAuth, sizeof(sOID_KeyPurpose_ServerAuth)) == 0);
369     }
370     ASN1_EXIT_SEQUENCE;
371
372 exit:
373     NL_TEST_ASSERT(inSuite, err == ASN1_NO_ERROR);
374 }
375
376 /**
377  *   Test Suite. It lists all the test functions.
378  */
379
380 // clang-format off
381 static const nlTest sTests[] =
382 {
383     NL_TEST_DEF("Test ASN1 encoding macros", TestASN1_Encode),
384     NL_TEST_DEF("Test ASN1 decoding macros", TestASN1_Decode),
385     NL_TEST_DEF("Test ASN1 NULL writer", TestASN1_NullWriter),
386     NL_TEST_DEF("Test ASN1 Object IDs", TestASN1_ObjectID),
387     NL_TEST_SENTINEL()
388 };
389 // clang-format on
390
391 int TestASN1(void)
392 {
393     nlTestSuite theSuite = { "Support-ASN1", &sTests[0], nullptr, nullptr };
394     nlTestRunner(&theSuite, nullptr);
395     return (nlTestRunnerStats(&theSuite));
396 }
397
398 CHIP_REGISTER_TEST_SUITE(TestASN1);