Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / lib / asn1 / ASN1Macros.h
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 defines convenience macros for dealing with Abstract
23  *      Syntax Notation One (ASN.1) encoded data.
24  *
25  */
26
27 #pragma once
28
29 #include <support/CodeUtils.h>
30
31 // Local variable names used by utility macros.
32
33 #define ASN1_READER reader
34 #define ASN1_ERR err
35
36 // Utility Macros for parsing ASN1
37
38 #define ASN1_VERIFY_TAG(CLASS, TAG)                                                                                                \
39     VerifyOrExit(ASN1_READER.GetClass() == (CLASS) && ASN1_READER.GetTag() == (TAG), ASN1_ERR = ASN1_ERROR_INVALID_ENCODING);
40
41 #define ASN1_PARSE_ELEMENT(CLASS, TAG)                                                                                             \
42     do                                                                                                                             \
43     {                                                                                                                              \
44         ASN1_ERR = ASN1_READER.Next();                                                                                             \
45         SuccessOrExit(ASN1_ERR);                                                                                                   \
46                                                                                                                                    \
47         ASN1_VERIFY_TAG(CLASS, TAG);                                                                                               \
48     } while (0)
49
50 #define ASN1_PARSE_ANY                                                                                                             \
51     do                                                                                                                             \
52     {                                                                                                                              \
53         ASN1_ERR = ASN1_READER.Next();                                                                                             \
54         SuccessOrExit(ASN1_ERR);                                                                                                   \
55     } while (0)
56
57 #define ASN1_ENTER_CONSTRUCTED(CLASS, TAG)                                                                                         \
58     do                                                                                                                             \
59     {                                                                                                                              \
60         ASN1_VERIFY_TAG(CLASS, TAG);                                                                                               \
61                                                                                                                                    \
62         ASN1_ERR = ASN1_READER.EnterConstructedType();                                                                             \
63         SuccessOrExit(ASN1_ERR);
64
65 #define ASN1_PARSE_ENTER_CONSTRUCTED(CLASS, TAG)                                                                                   \
66     do                                                                                                                             \
67     {                                                                                                                              \
68         ASN1_ERR = ASN1_READER.Next();                                                                                             \
69         SuccessOrExit(ASN1_ERR);                                                                                                   \
70                                                                                                                                    \
71         ASN1_VERIFY_TAG(CLASS, TAG);                                                                                               \
72                                                                                                                                    \
73         ASN1_ERR = ASN1_READER.EnterConstructedType();                                                                             \
74         SuccessOrExit(ASN1_ERR);
75
76 #define ASN1_EXIT_CONSTRUCTED                                                                                                      \
77     ASN1_ERR = ASN1_READER.Next();                                                                                                 \
78     if (ASN1_ERR == ASN1_NO_ERROR)                                                                                                 \
79         ASN1_ERR = ASN1_ERROR_INVALID_ENCODING;                                                                                    \
80     else if (ASN1_ERR == ASN1_END)                                                                                                 \
81         ASN1_ERR = ASN1_NO_ERROR;                                                                                                  \
82     SuccessOrExit(ASN1_ERR);                                                                                                       \
83                                                                                                                                    \
84     ASN1_ERR = ASN1_READER.ExitConstructedType();                                                                                  \
85     SuccessOrExit(ASN1_ERR);                                                                                                       \
86     }                                                                                                                              \
87     while (0)
88
89 #define ASN1_PARSE_ENTER_SEQUENCE ASN1_PARSE_ENTER_CONSTRUCTED(kASN1TagClass_Universal, kASN1UniversalTag_Sequence)
90
91 #define ASN1_ENTER_SEQUENCE ASN1_ENTER_CONSTRUCTED(kASN1TagClass_Universal, kASN1UniversalTag_Sequence)
92
93 #define ASN1_EXIT_SEQUENCE ASN1_EXIT_CONSTRUCTED
94
95 #define ASN1_PARSE_ENTER_SET ASN1_PARSE_ENTER_CONSTRUCTED(kASN1TagClass_Universal, kASN1UniversalTag_Set)
96
97 #define ASN1_ENTER_SET ASN1_ENTER_CONSTRUCTED(kASN1TagClass_Universal, kASN1UniversalTag_Set)
98
99 #define ASN1_EXIT_SET ASN1_EXIT_CONSTRUCTED
100
101 #define ASN1_ENTER_ENCAPSULATED(CLASS, TAG)                                                                                        \
102     do                                                                                                                             \
103     {                                                                                                                              \
104         ASN1_VERIFY_TAG(CLASS, TAG);                                                                                               \
105                                                                                                                                    \
106         ASN1_ERR = ASN1_READER.EnterEncapsulatedType();                                                                            \
107         SuccessOrExit(ASN1_ERR);
108
109 #define ASN1_PARSE_ENTER_ENCAPSULATED(CLASS, TAG)                                                                                  \
110     do                                                                                                                             \
111     {                                                                                                                              \
112         ASN1_ERR = ASN1_READER.Next();                                                                                             \
113         SuccessOrExit(ASN1_ERR);                                                                                                   \
114                                                                                                                                    \
115         ASN1_VERIFY_TAG(CLASS, TAG);                                                                                               \
116                                                                                                                                    \
117         ASN1_ERR = ASN1_READER.EnterEncapsulatedType();                                                                            \
118         SuccessOrExit(ASN1_ERR);
119
120 #define ASN1_EXIT_ENCAPSULATED                                                                                                     \
121     ASN1_ERR = ASN1_READER.Next();                                                                                                 \
122     if (ASN1_ERR == ASN1_NO_ERROR)                                                                                                 \
123         ASN1_ERR = ASN1_ERROR_INVALID_ENCODING;                                                                                    \
124     else if (ASN1_ERR == ASN1_END)                                                                                                 \
125         ASN1_ERR = ASN1_NO_ERROR;                                                                                                  \
126     SuccessOrExit(ASN1_ERR);                                                                                                       \
127                                                                                                                                    \
128     ASN1_ERR = ASN1_READER.ExitEncapsulatedType();                                                                                 \
129     SuccessOrExit(ASN1_ERR);                                                                                                       \
130     }                                                                                                                              \
131     while (0)
132
133 #define ASN1_PARSE_INTEGER(OUT_VAL)                                                                                                \
134     do                                                                                                                             \
135     {                                                                                                                              \
136         ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_Integer);                                                    \
137                                                                                                                                    \
138         ASN1_ERR = ASN1_READER.GetInteger(OUT_VAL);                                                                                \
139         SuccessOrExit(ASN1_ERR);                                                                                                   \
140     } while (0)
141
142 #define ASN1_GET_INTEGER(OUT_VAL)                                                                                                  \
143     do                                                                                                                             \
144     {                                                                                                                              \
145         ASN1_ERR = ASN1_READER.GetInteger(OUT_VAL);                                                                                \
146         SuccessOrExit(ASN1_ERR);                                                                                                   \
147     } while (0)
148
149 #define ASN1_PARSE_BOOLEAN(OUT_VAL)                                                                                                \
150     do                                                                                                                             \
151     {                                                                                                                              \
152         ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_Boolean);                                                    \
153                                                                                                                                    \
154         ASN1_ERR = ASN1_READER.GetBoolean(OUT_VAL);                                                                                \
155         SuccessOrExit(ASN1_ERR);                                                                                                   \
156     } while (0)
157
158 #define ASN1_GET_BOOLEAN(OUT_VAL)                                                                                                  \
159     do                                                                                                                             \
160     {                                                                                                                              \
161         ASN1_ERR = ASN1_READER.GetBoolean(OUT_VAL);                                                                                \
162         SuccessOrExit(ASN1_ERR);                                                                                                   \
163     } while (0)
164
165 #define ASN1_PARSE_OBJECT_ID(OUT_VAL)                                                                                              \
166     do                                                                                                                             \
167     {                                                                                                                              \
168         ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_ObjectId);                                                   \
169                                                                                                                                    \
170         ASN1_ERR = ASN1_READER.GetObjectId(OUT_VAL);                                                                               \
171         SuccessOrExit(ASN1_ERR);                                                                                                   \
172     } while (0)
173
174 #define ASN1_GET_OBJECT_ID(OUT_VAL)                                                                                                \
175     do                                                                                                                             \
176     {                                                                                                                              \
177         ASN1_ERR = ASN1_READER.GetObjectId(OUT_VAL);                                                                               \
178         SuccessOrExit(ASN1_ERR);                                                                                                   \
179     } while (0)
180
181 #define ASN1_PARSE_NULL ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_Null)
182
183 #define ASN1_PARSE_TIME(OUT_VAL)                                                                                                   \
184     do                                                                                                                             \
185     {                                                                                                                              \
186         ASN1_PARSE_ANY;                                                                                                            \
187                                                                                                                                    \
188         if (ASN1_READER.GetClass() == kASN1TagClass_Universal && ASN1_READER.GetTag() == kASN1UniversalTag_UTCTime)                \
189             ASN1_ERR = ASN1_READER.GetUTCTime(OUT_VAL);                                                                            \
190         else if (ASN1_READER.GetClass() == kASN1TagClass_Universal && ASN1_READER.GetTag() == kASN1UniversalTag_GeneralizedTime)   \
191             ASN1_ERR = ASN1_READER.GetGeneralizedTime(OUT_VAL);                                                                    \
192         else                                                                                                                       \
193             ASN1_ERR = ASN1_ERROR_INVALID_ENCODING;                                                                                \
194         SuccessOrExit(ASN1_ERR);                                                                                                   \
195     } while (0)
196
197 #define ASN1_PARSE_BIT_STRING(OUT_VAL)                                                                                             \
198     do                                                                                                                             \
199     {                                                                                                                              \
200         ASN1_PARSE_ELEMENT(kASN1TagClass_Universal, kASN1UniversalTag_BitString);                                                  \
201                                                                                                                                    \
202         ASN1_ERR = ASN1_READER.GetBitString(OUT_VAL);                                                                              \
203         SuccessOrExit(ASN1_ERR);                                                                                                   \
204     } while (0)
205
206 #define ASN1_GET_BIT_STRING(OUT_VAL)                                                                                               \
207     do                                                                                                                             \
208     {                                                                                                                              \
209         ASN1_ERR = ASN1_READER.GetBitString(OUT_VAL);                                                                              \
210         SuccessOrExit(ASN1_ERR);                                                                                                   \
211     } while (0)
212
213 // Utility Macros for encoding ASN1
214
215 #define ASN1_START_CONSTRUCTED(CLASS, TAG)                                                                                         \
216     do                                                                                                                             \
217     {                                                                                                                              \
218         ASN1_ERR = writer.StartConstructedType(CLASS, TAG);                                                                        \
219         SuccessOrExit(ASN1_ERR);
220
221 #define ASN1_END_CONSTRUCTED                                                                                                       \
222     ASN1_ERR = writer.EndConstructedType();                                                                                        \
223     SuccessOrExit(ASN1_ERR);                                                                                                       \
224     }                                                                                                                              \
225     while (0)
226
227 #define ASN1_START_SEQUENCE ASN1_START_CONSTRUCTED(kASN1TagClass_Universal, kASN1UniversalTag_Sequence)
228
229 #define ASN1_END_SEQUENCE ASN1_END_CONSTRUCTED
230
231 #define ASN1_START_SET ASN1_START_CONSTRUCTED(kASN1TagClass_Universal, kASN1UniversalTag_Set)
232
233 #define ASN1_END_SET ASN1_END_CONSTRUCTED
234
235 #define ASN1_ENCODE_INTEGER(VAL)                                                                                                   \
236     do                                                                                                                             \
237     {                                                                                                                              \
238         ASN1_ERR = writer.PutInteger(VAL);                                                                                         \
239         SuccessOrExit(ASN1_ERR);                                                                                                   \
240     } while (0);
241
242 #define ASN1_ENCODE_BOOLEAN(VAL)                                                                                                   \
243     do                                                                                                                             \
244     {                                                                                                                              \
245         ASN1_ERR = writer.PutBoolean(VAL);                                                                                         \
246         SuccessOrExit(ASN1_ERR);                                                                                                   \
247     } while (0);
248
249 #define ASN1_ENCODE_BIT_STRING(VAL)                                                                                                \
250     do                                                                                                                             \
251     {                                                                                                                              \
252         ASN1_ERR = writer.PutBitString(VAL);                                                                                       \
253         SuccessOrExit(ASN1_ERR);                                                                                                   \
254     } while (0);
255
256 #define ASN1_ENCODE_OBJECT_ID(OID)                                                                                                 \
257     do                                                                                                                             \
258     {                                                                                                                              \
259         ASN1_ERR = writer.PutObjectId(OID);                                                                                        \
260         SuccessOrExit(ASN1_ERR);                                                                                                   \
261     } while (0);
262
263 #define ASN1_ENCODE_STRING(TAG, VAL, LEN)                                                                                          \
264     do                                                                                                                             \
265     {                                                                                                                              \
266         ASN1_ERR = writer.PutString(TAG, VAL, LEN);                                                                                \
267         SuccessOrExit(ASN1_ERR);                                                                                                   \
268     } while (0);
269
270 #define ASN1_ENCODE_OCTET_STRING(VAL, LEN)                                                                                         \
271     do                                                                                                                             \
272     {                                                                                                                              \
273         ASN1_ERR = writer.PutOctetString(VAL, LEN);                                                                                \
274         SuccessOrExit(ASN1_ERR);                                                                                                   \
275     } while (0);
276
277 #define ASN1_ENCODE_TIME(VAL)                                                                                                      \
278     do                                                                                                                             \
279     {                                                                                                                              \
280         ASN1_ERR = writer.PutTime(VAL);                                                                                            \
281         SuccessOrExit(ASN1_ERR);                                                                                                   \
282     } while (0);
283
284 #define ASN1_ENCODE_NULL                                                                                                           \
285     do                                                                                                                             \
286     {                                                                                                                              \
287         ASN1_ERR = writer.PutNull();                                                                                               \
288         SuccessOrExit(ASN1_ERR);                                                                                                   \
289     } while (0);
290
291 #define ASN1_START_ENCAPSULATED(CLASS, TAG, BIT_STRING_ENCODING)                                                                   \
292     do                                                                                                                             \
293     {                                                                                                                              \
294         ASN1_ERR = writer.StartEncapsulatedType(CLASS, TAG, BIT_STRING_ENCODING);                                                  \
295         SuccessOrExit(ASN1_ERR);
296
297 #define ASN1_START_OCTET_STRING_ENCAPSULATED ASN1_START_ENCAPSULATED(kASN1TagClass_Universal, kASN1UniversalTag_OctetString, false)
298
299 #define ASN1_START_BIT_STRING_ENCAPSULATED ASN1_START_ENCAPSULATED(kASN1TagClass_Universal, kASN1UniversalTag_BitString, true)
300
301 #define ASN1_END_ENCAPSULATED                                                                                                      \
302     ASN1_ERR = writer.EndEncapsulatedType();                                                                                       \
303     SuccessOrExit(ASN1_ERR);                                                                                                       \
304     }                                                                                                                              \
305     while (0)