• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef CRED_TLV_PARSER_H
17 #define CRED_TLV_PARSER_H
18 
19 #include <hc_parcel.h>
20 #include <hc_vector.h>
21 #include <hc_string.h>
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 #define USE_DEFAULT_TAG 0xFFFF
28 #define CRED_TLV_FAIL (-1)
29 #define NO_REVERT 0
30 #define NEED_REVERT 1
31 #define MAX_TOTOL_LEN (100 * 1024 * 1024)
32 
33 typedef struct CredTlvBaseT {
34     unsigned short tag;
35     unsigned int length;
36     unsigned short checkTag;
37     unsigned short hasValue;
38     int64_t (*parse)(struct CredTlvBaseT *, HcParcel *, HcBool);
39     int64_t (*getlen)(struct CredTlvBaseT *);
40     int64_t (*encode)(struct CredTlvBaseT *, HcParcel *);
41     void (*deinit)(struct CredTlvBaseT *);
42 } CredTlvBase;
43 
44 #define DECLARE_CRED_TLV_STRUCT(x) \
45     CredTlvBase base; \
46     unsigned int offsetCount; \
47     unsigned int offset[x];
48 
49 unsigned short GetCredTag(unsigned short checkTag, unsigned short defaultTag);
50 
51 #define BEGIN_CRED_TLV_STRUCT_DEFINE(TlvS, CheckTag) \
52 void Init##TlvS(TlvS *tlv, unsigned short checkTag) \
53 { \
54     typedef TlvS TlvStructType; \
55     unsigned int index = 0; \
56     (void)memset_s(&tlv->base, sizeof(tlv->base), 0, sizeof(tlv->base)); \
57     tlv->base.checkTag = GetCredTag(checkTag, CheckTag);
58 
59 #define CRED_TLV_MEMBER_OPTION(TlvMember, TlvMemberName, CheckTag) \
60     Init##TlvMember(&tlv->TlvMemberName, CheckTag); \
61     tlv->TlvMemberName.base.option = 1; \
62     tlv->offset[index++] = offsetof(TlvStructType, TlvMemberName);
63 
64 #define CRED_TLV_MEMBER(TlvMember, TlvMemberName, CheckTag) \
65     Init##TlvMember(&tlv->TlvMemberName, CheckTag); \
66     tlv->offset[index++] = offsetof(TlvStructType, TlvMemberName);
67 
68 #define END_CRED_TLV_STRUCT_DEFINE(void) \
69     tlv->offsetCount = index; \
70     tlv->base.parse = ParseCredTlvStruct; \
71     tlv->base.getlen = GetLenCredTlvStruct; \
72     tlv->base.encode = EncodeCredTlvStruct; \
73     tlv->base.deinit = DeinitCredTlvStruct; \
74 }
75 
76 #define DECLARE_CRED_TLV_FIX_LENGTH_TYPE(TlvName, TypeName) \
77 typedef struct \
78 { \
79     CredTlvBase base; \
80     TypeName data; \
81 } TlvName;
82 
83 DECLARE_CRED_TLV_FIX_LENGTH_TYPE(CredTlvInt32, int)
84 DECLARE_CRED_TLV_FIX_LENGTH_TYPE(CredTlvInt16, short)
85 DECLARE_CRED_TLV_FIX_LENGTH_TYPE(CredTlvInt8, char)
86 DECLARE_CRED_TLV_FIX_LENGTH_TYPE(CredTlvUint32, uint32_t)
87 DECLARE_CRED_TLV_FIX_LENGTH_TYPE(CredTlvUint16, uint16_t)
88 DECLARE_CRED_TLV_FIX_LENGTH_TYPE(CredTlvUint8, uint8_t)
89 DECLARE_CRED_TLV_FIX_LENGTH_TYPE(CredTlvUint64, uint64_t)
90 DECLARE_CRED_TLV_FIX_LENGTH_TYPE(CredTlvInt64, uint64_t)
91 
92 #define DEFINE_CRED_TLV_FIX_LENGTH_TYPE(TlvName, Revert) \
93 int64_t ParseCredTlv##TlvName(CredTlvBase *tlv, HcParcel *parcel, HcBool strict) \
94 { \
95     (void)strict; \
96     TlvName *realTlv = (TlvName *)(tlv); \
97     HcBool readRet = HC_FALSE; \
98     if (tlv->length != sizeof(realTlv->data)) \
99     { \
100         return CRED_TLV_FAIL; \
101     } \
102 \
103     if (Revert) \
104     { \
105         readRet = ParcelReadRevert(parcel, &realTlv->data, sizeof(realTlv->data)); \
106     } else { \
107         readRet = ParcelRead(parcel, &realTlv->data, sizeof(realTlv->data)); \
108     } \
109     if (readRet) \
110     { \
111         return tlv->length; \
112     } else { \
113         return CRED_TLV_FAIL; \
114     } \
115 } \
116 \
117 int64_t GetLenCredTlv##TlvName(CredTlvBase *tlv) \
118 { \
119     TlvName *realTlv = (TlvName *)(tlv); \
120     return (int64_t)sizeof(realTlv->data); \
121 } \
122 \
123 int64_t EncodeCredTlv##TlvName(CredTlvBase *tlv, HcParcel *parcel) \
124 { \
125     HcBool writeRet = HC_FALSE; \
126     TlvName *realTlv = (TlvName *)(tlv); \
127     if (Revert) \
128     { \
129         writeRet = ParcelWriteRevert(parcel, &realTlv->data, sizeof(realTlv->data)); \
130     } else { \
131         writeRet = ParcelWrite(parcel, &realTlv->data, sizeof(realTlv->data)); \
132     } \
133     if (writeRet) \
134     { \
135         return sizeof(realTlv->data); \
136     } else { \
137         return CRED_TLV_FAIL; \
138     } \
139 } \
140 \
141 DECLARE_CRED_TLV_PARSE_FUNC(TlvName, ParseCredTlv##TlvName, GetLenCredTlv##TlvName, EncodeCredTlv##TlvName);
142 
143 void DeinitCredTlvFixMember(CredTlvBase *tlv);
144 
145 #define DECLARE_CRED_TLV_PARSE_FUNC(TlvName, TlvParseFunc, TlvGetLenFunc, TlvEncodeFunc) \
146 void Init##TlvName(TlvName *tlv, unsigned short checkTag) \
147 { \
148     (void)memset_s(&tlv->base, sizeof(tlv->base), 0, sizeof(tlv->base)); \
149     tlv->base.parse = TlvParseFunc; \
150     tlv->base.getlen = TlvGetLenFunc; \
151     tlv->base.encode = TlvEncodeFunc; \
152     tlv->base.deinit = DeinitCredTlvFixMember; \
153     tlv->base.checkTag = checkTag; \
154 }
155 
156 #define CRED_TLV_INIT(TlvName, TlvData) Init##TlvName(TlvData, USE_DEFAULT_TAG);
157 
158 #define CRED_TLV_DEINIT(TlvData) TlvData.base.deinit((CredTlvBase *)(&TlvData));
159 typedef struct {
160     CredTlvBase base;
161     unsigned int offsetCount;
162     unsigned int offset[0];
163 } CredTlvOffsetExample;
164 
165 HcBool ParseCredTlvHead(CredTlvBase *tlv, HcParcel *parcel);
166 int64_t ParseCredTlvNode(CredTlvBase *tlv, HcParcel *parcel, HcBool strict);
167 int64_t GetlenCredTlvNode(CredTlvBase *tlv);
168 void DeinitCredTlvNode(CredTlvBase *tlv);
169 
170 int64_t ParseCredTlvStruct(CredTlvBase *tlv, HcParcel *parcel, HcBool strict);
171 int64_t EncodeCredTlvStruct(CredTlvBase *tlv, HcParcel *parcel);
172 int64_t GetLenCredTlvStruct(CredTlvBase *tlv);
173 void DeinitCredTlvStruct(CredTlvBase *tlv);
174 int64_t EncodeCredTlvNode(CredTlvBase *tlv, HcParcel *parcel, HcBool isRoot);
175 HcBool DecodeCredTlvMessage(CredTlvBase *msg, HcParcel *parcel, HcBool strict);
176 HcBool EncodeCredTlvMessage(CredTlvBase *msg, HcParcel *parcel);
177 
178 typedef struct {
179     CredTlvBase base;
180     HcParcel data;
181 } CredTlvBuffer;
182 
183 void InitCredTlvBuffer(CredTlvBuffer *tlv, unsigned short checkTag);
184 int64_t ParseCredTlvBuffer(CredTlvBase *tlv, HcParcel *parcel, HcBool strict);
185 int64_t GetlenCredTlvBuffer(CredTlvBase *tlv);
186 int64_t EncodeCredTlvBuffer(CredTlvBase *tlv, HcParcel *parcel);
187 void DeinitCredTlvBuffer(CredTlvBase *tlv);
188 
189 typedef struct {
190     CredTlvBase base;
191     HcString data;
192 } CredTlvString;
193 
194 void InitCredTlvString(CredTlvString *tlv, unsigned short checkTag);
195 int64_t ParseCredTlvString(CredTlvBase *tlv, HcParcel *parcel, HcBool strict);
196 int64_t GetlenCredTlvString(CredTlvBase *tlv);
197 int64_t EncodeCredTlvString(CredTlvBase *tlv, HcParcel *parcel);
198 void DeinitCredTlvString(CredTlvBase *tlv);
199 
200 #define DECLEAR_CRED_INIT_FUNC(TlvStruct) \
201 void Init##TlvStruct(TlvStruct *tlv, unsigned short checkTag);
202 
203 DECLEAR_CRED_INIT_FUNC(CredTlvUint64)
204 DECLEAR_CRED_INIT_FUNC(CredTlvUint32)
205 DECLEAR_CRED_INIT_FUNC(CredTlvUint16)
206 DECLEAR_CRED_INIT_FUNC(CredTlvUint8)
207 DECLEAR_CRED_INIT_FUNC(CredTlvInt64)
208 DECLEAR_CRED_INIT_FUNC(CredTlvInt32)
209 DECLEAR_CRED_INIT_FUNC(CredTlvInt16)
210 DECLEAR_CRED_INIT_FUNC(CredTlvInt8)
211 
212 #define DECLARE_CRED_TLV_VECTOR(TlvVecName, TlvVecElement) \
213 DECLARE_HC_VECTOR(Vec##TlvVecName, TlvVecElement) \
214 typedef struct { \
215     CredTlvBase base; \
216     Vec##TlvVecName data; \
217 } TlvVecName; \
218 void DeinitTlv##TlvVecName(CredTlvBase *tlv); \
219 void Init##TlvVecName(TlvVecName *tlv, unsigned short checkTag);
220 
221 #define IMPLEMENT_CRED_TLV_VECTOR(TlvVecName, TlvElementName, VecAllocCount) \
222 IMPLEMENT_HC_VECTOR(Vec##TlvVecName, TlvElementName, VecAllocCount) \
223 int64_t ParseTlv##TlvVecName(CredTlvBase *tlv, HcParcel *parcel, HcBool strict) \
224 { \
225     TlvVecName *realTlv = (TlvVecName *)(tlv); \
226     uint32_t count = 0; \
227     if (!ParcelReadUint32(parcel, &count)) { \
228         return CRED_TLV_FAIL; \
229     } \
230     int64_t totalLen = sizeof(count); \
231     uint32_t index = 0; \
232     for (index = 0; index < count; ++index) { \
233         TlvElementName tlvElement; \
234         TlvElementName *curElement = realTlv->data.pushBack(&realTlv->data, &tlvElement); \
235         if (curElement == NULL) { \
236             return CRED_TLV_FAIL; \
237         } \
238         CRED_TLV_INIT(TlvElementName, curElement); \
239 \
240         int64_t elementLen = ParseCredTlvNode((CredTlvBase *)curElement, parcel, strict); \
241         if (elementLen < 0) { \
242             return CRED_TLV_FAIL; \
243         } \
244         totalLen += elementLen; \
245         if (totalLen >= MAX_TOTOL_LEN) { \
246             return CRED_TLV_FAIL; \
247         } \
248     } \
249 \
250     return totalLen; \
251 } \
252 \
253 int64_t EncodeTlv##TlvVecName(CredTlvBase *tlv, HcParcel *parcel) \
254 { \
255     TlvVecName *realTlv = (TlvVecName *)(tlv); \
256     uint32_t index = 0; \
257     TlvElementName *element = NULL; \
258     int64_t totalLen = 4; \
259     uint32_t count = realTlv->data.size(&realTlv->data); \
260     if (!ParcelWriteUint32(parcel, count)) { \
261         return CRED_TLV_FAIL; \
262     } \
263 \
264     FOR_EACH_HC_VECTOR(realTlv->data, index, element) { \
265         if (element != NULL) { \
266             int64_t len = EncodeCredTlvNode((CredTlvBase *)element, parcel, HC_FALSE); \
267             totalLen += len; \
268             if (totalLen >= MAX_TOTOL_LEN) { \
269                 return CRED_TLV_FAIL; \
270             } \
271         } \
272     } \
273     return totalLen; \
274 } \
275 int64_t GetLenTlv##TlvVecName(CredTlvBase *tlv) \
276 { \
277     TlvVecName *realTlv = (TlvVecName *)(tlv); \
278     uint32_t index = 0; \
279     TlvElementName *element = NULL; \
280     int64_t totalLen = sizeof(int32_t); \
281     FOR_EACH_HC_VECTOR(realTlv->data, index, element) { \
282         if (element != NULL) { \
283             totalLen += GetlenCredTlvNode((CredTlvBase *)element); \
284             if (totalLen >= MAX_TOTOL_LEN) { \
285                 return CRED_TLV_FAIL; \
286             } \
287         } else { \
288             return CRED_TLV_FAIL; \
289         } \
290     } \
291     return totalLen; \
292 } \
293 \
294 void DeinitTlv##TlvVecName(CredTlvBase *tlv) \
295 { \
296     TlvVecName *realTlv = (TlvVecName *)(tlv); \
297     uint32_t index = 0; \
298     TlvElementName *element = NULL; \
299     FOR_EACH_HC_VECTOR(realTlv->data, index, element) { \
300         if (element != NULL) { \
301             CRED_TLV_DEINIT((*element)); \
302         } \
303     } \
304     DESTROY_HC_VECTOR(Vec##TlvVecName, &((TlvVecName *)tlv)->data); \
305 } \
306 \
307 void Init##TlvVecName(TlvVecName *tlv, unsigned short checkTag) \
308 { \
309     (void)memset_s(&tlv->base, sizeof(tlv->base), 0, sizeof(tlv->base)); \
310     tlv->base.parse = ParseTlv##TlvVecName; \
311     tlv->base.encode = EncodeTlv##TlvVecName; \
312     tlv->base.getlen = GetLenTlv##TlvVecName; \
313     tlv->base.deinit = DeinitTlv##TlvVecName; \
314     tlv->base.checkTag = checkTag; \
315     tlv->data = CREATE_HC_VECTOR(Vec##TlvVecName); \
316 }
317 
318 #ifdef __cplusplus
319 }
320 #endif
321 #endif
322