• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 
16 #include <stdlib.h>
17 #include <stdint.h>
18 #include "hitls_build.h"
19 #ifdef HITLS_TLS_FEATURE_CUSTOM_EXTENSION
20 #include "tls_binlog_id.h"
21 #include "bsl_log_internal.h"
22 #include "bsl_log.h"
23 #include "bsl_err_internal.h"
24 #include "bsl_bytes.h"
25 #include "hitls_error.h"
26 #include "hitls_config.h"
27 #include "tls.h"
28 #include "hs_msg.h"
29 #include "hs_ctx.h"
30 #include "hs.h"
31 #include "securec.h"
32 #include "bsl_errno.h"
33 #include "bsl_sal.h"
34 #include "custom_extensions.h"
35 #include "alert.h"
36 
IsPackNeedCustomExtensions(CustomExt_Methods * exts,uint32_t context)37 bool IsPackNeedCustomExtensions(CustomExt_Methods *exts, uint32_t context)
38 {
39     uint32_t i = 0;
40 
41     if (exts == NULL) {
42         return false;
43     }
44     CustomExt_Method *meth = exts->meths;
45     if (meth == NULL) {
46         return false;
47     }
48     for (i = 0; i < exts->methsCount; i++, meth++) {
49         if ((context & meth->context) != 0) {
50             return true;
51         }
52     }
53 
54     return false;
55 }
56 
IsParseNeedCustomExtensions(CustomExt_Methods * exts,uint16_t extType,uint32_t context)57 bool IsParseNeedCustomExtensions(CustomExt_Methods *exts, uint16_t extType, uint32_t context)
58 {
59     uint32_t i = 0;
60 
61     if (exts == NULL) {
62         return false;
63     }
64 
65     CustomExt_Method *meth = exts->meths;
66 
67     if (meth == NULL) {
68         return false;
69     }
70 
71     for (i = 0; i < exts->methsCount; i++, meth++) {
72         if (extType == meth->extType && (context & meth->context) != 0) {
73             return true;
74         }
75     }
76     return false;
77 }
78 
IsCustomExtensionTypeAdded(CustomExt_Methods * exts,uint16_t extType)79 bool IsCustomExtensionTypeAdded(CustomExt_Methods *exts, uint16_t extType)
80 {
81     uint32_t i = 0;
82 
83     if (exts == NULL) {
84         return false;
85     }
86     CustomExt_Method *meth = exts->meths;
87     if (meth == NULL) {
88         return false;
89     }
90     for (i = 0; i < exts->methsCount; i++, meth++) {
91         if (extType == meth->extType) {
92             return true;
93         }
94     }
95     return false;
96 }
97 
FindCustomExtensions(CustomExt_Methods * exts,uint16_t extType,uint32_t context)98 CustomExt_Method *FindCustomExtensions(CustomExt_Methods *exts, uint16_t extType, uint32_t context)
99 {
100     uint32_t i = 0;
101 
102     if (exts == NULL) {
103         return NULL;
104     }
105 
106     CustomExt_Method *meth = exts->meths;
107 
108     if (meth == NULL) {
109         return NULL;
110     }
111 
112     for (i = 0; i < exts->methsCount; i++, meth++) {
113         if (extType == meth->extType && (context & meth->context) != 0) {
114             return meth;
115         }
116     }
117     return NULL;
118 }
119 
HITLS_CFG_AddCustomExtension(HITLS_Config * config,const HITLS_CustomExtParams * params)120 uint32_t HITLS_CFG_AddCustomExtension(HITLS_Config *config, const HITLS_CustomExtParams *params)
121 {
122     CustomExt_Method *meth = NULL;
123     CustomExt_Method *tmp = NULL;
124 
125     if (config == NULL || params == NULL) {
126         return HITLS_NULL_INPUT;
127     }
128 
129     if (params->addCb == NULL && params->freeCb != NULL) {
130         return HITLS_INVALID_INPUT;
131     }
132 
133     CustomExt_Methods *exts = config->customExts;
134 
135     if (IsCustomExtensionTypeAdded(exts, params->extType) ||
136         FindCustomExtensions(exts, params->extType, params->context) != NULL) {
137         return HITLS_CONFIG_DUP_CUSTOM_EXT;
138     }
139 
140     if (exts == NULL) {
141         exts = (CustomExt_Methods *)BSL_SAL_Malloc(sizeof(CustomExt_Methods));
142         if (exts == NULL) {
143             return HITLS_MEMALLOC_FAIL;
144         }
145         exts->meths = NULL;
146         exts->methsCount = 0;
147         config->customExts = exts;
148     }
149 
150     tmp = BSL_SAL_Realloc(exts->meths, (exts->methsCount + 1) * sizeof(CustomExt_Method),
151                           exts->methsCount * sizeof(CustomExt_Method));
152     if (tmp == NULL) {
153         return HITLS_MEMALLOC_FAIL;
154     }
155 
156     exts->meths = tmp;
157     meth = exts->meths + exts->methsCount;
158 
159     memset_s(meth, sizeof(*meth), 0, sizeof(*meth));
160     meth->extType = params->extType;
161     meth->context = params->context;
162     meth->addCb = params->addCb;
163     meth->freeCb = params->freeCb;
164     meth->addArg = params->addArg;
165     meth->parseCb = params->parseCb;
166     meth->parseArg = params->parseArg;
167     exts->methsCount++;
168 
169     return HITLS_SUCCESS;
170 }
171 
HITLS_AddCustomExtension(HITLS_Ctx * ctx,const HITLS_CustomExtParams * params)172 uint32_t HITLS_AddCustomExtension(HITLS_Ctx *ctx, const HITLS_CustomExtParams *params)
173 {
174     if (ctx == NULL || params == NULL) {
175         return HITLS_NULL_INPUT;
176     }
177 
178     return HITLS_CFG_AddCustomExtension(&(ctx->config.tlsConfig), params);
179 }
180 
181 
PackCustomExtensions(const struct TlsCtx * ctx,uint8_t * buf,uint32_t bufLen,uint32_t * len,uint32_t context,HITLS_X509_Cert * cert,uint32_t certIndex)182 int32_t PackCustomExtensions(const struct TlsCtx *ctx, uint8_t *buf, uint32_t bufLen, uint32_t *len, uint32_t context, HITLS_X509_Cert *cert, uint32_t certIndex)
183 {
184     uint32_t offset = 0u;
185     uint32_t alert = 0u;
186 
187     if (ctx == NULL || buf == NULL || len == NULL) {
188         return HITLS_NULL_INPUT;
189     }
190 
191     CustomExt_Methods *exts = CUSTOM_EXT_FROM_CTX(ctx);
192     CustomExt_Method *meth = NULL;
193     uint32_t ret = 0;
194     if (exts == NULL) {
195         *len = 0;
196         return HITLS_SUCCESS;
197     }
198 
199     for (uint32_t i = 0; i < exts->methsCount; i++) {
200         uint8_t *out = NULL;
201         uint32_t outLen = 0;
202 
203         meth = exts->meths + i;
204 
205         if ((meth->context & context) == 0) {
206             continue;
207         }
208 
209         if (meth->addCb != NULL) {
210             ret = meth->addCb(ctx, meth->extType, context, &out, &outLen, cert, certIndex, &alert, meth->addArg);
211             if (ret != HITLS_ADD_CUSTOM_EXTENSION_RET_PACK && ret != HITLS_ADD_CUSTOM_EXTENSION_RET_PASS) {
212                 ALERT_Send(ctx, ALERT_LEVEL_FATAL, alert);
213                 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17350, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
214                     "pack custom extension content fail.", 0, 0, 0, 0);
215                 return ret;
216             }
217         }
218 
219         if (ret == HITLS_ADD_CUSTOM_EXTENSION_RET_PACK) {
220             if (bufLen - offset >= outLen + sizeof(uint16_t) + sizeof(uint16_t)) {
221                 BSL_Uint16ToByte(meth->extType, &buf[offset]);
222                 offset += sizeof(uint16_t);
223 
224                 BSL_Uint16ToByte(outLen, &buf[offset]);
225                 offset += sizeof(uint16_t);
226 
227                 (void)memcpy_s(&buf[offset], bufLen - offset, out, outLen);
228                 offset += outLen;
229             } else {
230                 return HITLS_PACK_NOT_ENOUGH_BUF_LENGTH;
231             }
232         }
233 
234         if (meth->freeCb != NULL && out != NULL) {
235             meth->freeCb(ctx, meth->extType, context, out, meth->addArg);
236         }
237     }
238 
239     *len = offset;
240     return HITLS_SUCCESS;
241 }
242 
ParseCustomExtensions(const struct TlsCtx * ctx,const uint8_t * buf,uint16_t extType,uint32_t extLen,uint32_t context,HITLS_X509_Cert * cert,uint32_t certIndex)243 int32_t ParseCustomExtensions(const struct TlsCtx *ctx, const uint8_t *buf, uint16_t extType, uint32_t extLen,
244     uint32_t context, HITLS_X509_Cert *cert, uint32_t certIndex)
245 {
246     uint32_t alert = 0u;
247 
248     CustomExt_Methods *exts = CUSTOM_EXT_FROM_CTX(ctx);
249     CustomExt_Method *meth;
250 
251     meth = FindCustomExtensions(exts, extType, context);
252     if (meth == NULL) {
253         return HITLS_SUCCESS;
254     }
255 
256     // Create a local pointer starting from the position after the type byte
257     if (meth->parseCb != NULL) {
258         uint32_t ret = meth->parseCb(ctx, meth->extType, context, &buf, &extLen, cert, certIndex, &alert, meth->parseArg);
259         if (ret != HITLS_SUCCESS) {
260             ALERT_Send(ctx, ALERT_LEVEL_FATAL, alert);
261             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID17351, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
262                                   "parse custom extension content fail.", 0, 0, 0, 0);
263             return ret;
264         }
265     }
266 
267     return HITLS_SUCCESS;
268 }
269 
FreeCustomExtensions(CustomExt_Methods * exts)270 void FreeCustomExtensions(CustomExt_Methods *exts)
271 {
272     if (exts == NULL) {
273         return;
274     }
275     if (exts->meths == NULL) {
276         BSL_SAL_Free(exts);
277         return;
278     }
279     BSL_SAL_Free(exts->meths);
280     BSL_SAL_Free(exts);
281 }
282 
DupCustomExtensions(CustomExt_Methods * exts)283 CustomExt_Methods *DupCustomExtensions(CustomExt_Methods *exts)
284 {
285     if (exts == NULL) {
286         return NULL;
287     }
288     CustomExt_Methods *newExts = (CustomExt_Methods *)BSL_SAL_Malloc(sizeof(CustomExt_Methods));
289     if (newExts == NULL) {
290         return NULL;
291     }
292     newExts->meths = (CustomExt_Method *)BSL_SAL_Dump(exts->meths, exts->methsCount * sizeof(CustomExt_Method));
293     if (newExts->meths == NULL) {
294         BSL_SAL_Free(newExts);
295         return NULL;
296     }
297     newExts->methsCount = exts->methsCount;
298     return newExts;
299 }
300 #endif /* HITLS_TLS_FEATURE_CUSTOM_EXTENSION */
301