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 <stdio.h>
17 #include <stdint.h>
18 #include "securec.h"
19 #include "lock.h"
20 #include "logger.h"
21 #include "hitls_func.h"
22 #include "process.h"
23 #include "tls_res.h"
24
25 #define SUCCESS 0
26 #define ERROR (-1)
27
28 ResList g_ctxList;
29 ResList g_sslList;
30
InitTlsResList(void)31 int InitTlsResList(void)
32 {
33 // Initializes the CTX resource management linked list.
34 (void)memset_s(&g_ctxList, sizeof(ResList), 0, sizeof(ResList));
35 g_ctxList.resListLock = OsLockNew();
36 if (g_ctxList.resListLock == NULL) {
37 LOG_ERROR("OsLockNew Error");
38 return ERROR;
39 }
40 // Indicates the head element in the linked list, which does not store any resource.
41 g_ctxList.res = (Res *)malloc(sizeof(Res));
42 if (g_ctxList.res == NULL) {
43 OsLockDestroy(g_ctxList.resListLock);
44 return ERROR;
45 }
46 (void)memset_s(g_ctxList.res, sizeof(Res), 0, sizeof(Res));
47 g_ctxList.num = 0;
48
49 // Initializing the SSL Resource Management Linked List
50 (void)memset_s(&g_sslList, sizeof(ResList), 0, sizeof(ResList));
51 g_sslList.resListLock = OsLockNew();
52 if (g_sslList.resListLock == NULL) {
53 LOG_ERROR("OsLockNew Error");
54 free(g_ctxList.res);
55 OsLockDestroy(g_ctxList.resListLock);
56 g_ctxList.resListLock = NULL;
57 return ERROR;
58 }
59 // Indicates the head element in the linked list, which does not store any resource.
60 g_sslList.res = (Res *)malloc(sizeof(Res));
61 if (g_sslList.res == NULL) {
62 free(g_ctxList.res);
63 OsLockDestroy(g_ctxList.resListLock);
64 OsLockDestroy(g_sslList.resListLock);
65 return ERROR;
66 }
67 (void)memset_s(g_sslList.res, sizeof(Res), 0, sizeof(Res));
68 g_sslList.num = 0;
69 return SUCCESS;
70 }
71
InsertResToList(ResList * resList,Res tempRes)72 int InsertResToList(ResList *resList, Res tempRes)
73 {
74 int id;
75 Res *curRes = NULL;
76 Res *res = (Res*)malloc(sizeof(Res));
77 if (res == NULL) {
78 return ERROR;
79 }
80 memset_s(res, sizeof(Res), 0, sizeof(Res));
81
82 // Insert in the lock
83 OsLock(resList->resListLock);
84
85 id = resList->num;
86
87 res->ctxId = tempRes.ctxId;
88 res->tlsRes = tempRes.tlsRes;
89 res->next = NULL;
90 res->id = id;
91 // In the linked list, the first element is NULL by default and is used as the start element.
92 curRes = resList->res->next;
93 // When the first element is empty
94 if (curRes == NULL) {
95 resList->res->next = res;
96 resList->num++;
97 OsUnLock(resList->resListLock);
98 return id;
99 }
100 // Find the tail element
101 while (curRes->next != NULL) {
102 curRes = curRes->next;
103 }
104 curRes->next = res;
105 resList->num++;
106 OsUnLock(resList->resListLock);
107 return id;
108 }
109
InsertCtxToList(void * tlsRes)110 int InsertCtxToList(void *tlsRes)
111 {
112 ResList *resList = GetCtxList();
113 Res ctxRes = {0};
114 ctxRes.tlsRes = tlsRes;
115 ctxRes.ctxId = -1; // This field is used only in the SSL linked list.
116 return InsertResToList(resList, ctxRes);
117 }
118
GetTlsIdFromResList(ResList * resList,const void * tls)119 static int GetTlsIdFromResList(ResList *resList, const void *tls)
120 {
121 Res *tlsRes = GetResFromTlsResList(resList, tls);
122 if (tlsRes == NULL) {
123 LOG_ERROR("GetResFromTlsResList ERROR");
124 return ERROR;
125 }
126 // Indicates the serial number of a resource.
127 return tlsRes->id;
128 }
129
InsertSslToList(void * ctx,void * ssl)130 int InsertSslToList(void *ctx, void *ssl)
131 {
132 int ctxId;
133 Res sslRes = {0};
134 ResList *ctxList = GetCtxList();
135 ResList *sslList = GetSslList();
136
137 ctxId = GetTlsIdFromResList(ctxList, ctx);
138 if (ctxId == ERROR) {
139 LOG_ERROR("GetTlsIdFromResList Error");
140 return ERROR;
141 }
142
143 sslRes.tlsRes = ssl;
144 sslRes.ctxId = ctxId; // This field is used only in the SSL linked list and indicates the CTX that is created.
145 return InsertResToList(sslList, sslRes);
146 }
147
GetCtxList(void)148 ResList *GetCtxList(void)
149 {
150 return &g_ctxList;
151 }
152
GetSslList(void)153 ResList *GetSslList(void)
154 {
155 return &g_sslList;
156 }
157
GetResFromTlsResList(ResList * resList,const void * tlsRes)158 Res *GetResFromTlsResList(ResList *resList, const void *tlsRes)
159 {
160 Res *tmpRes = NULL;
161 OsLock(resList->resListLock);
162 // In the linked list, the first element is NULL by default and is used as the start element.
163 tmpRes = resList->res->next;
164 while (tmpRes != NULL) {
165 if (tmpRes->tlsRes == tlsRes) {
166 OsUnLock(resList->resListLock);
167 return tmpRes;
168 }
169 tmpRes = tmpRes->next;
170 }
171 OsUnLock(resList->resListLock);
172 return NULL;
173 }
174
GetResFromId(ResList * resList,int id)175 static Res *GetResFromId(ResList *resList, int id)
176 {
177 Res *tmpRes = NULL;
178 OsLock(resList->resListLock);
179 // In the linked list, the first element is NULL by default and is used as the start element.
180 tmpRes = resList->res->next;
181 while (tmpRes != NULL) {
182 if (tmpRes->id == id) {
183 OsUnLock(resList->resListLock);
184 return tmpRes;
185 }
186 tmpRes = tmpRes->next;
187 }
188 OsUnLock(resList->resListLock);
189 return NULL;
190 }
191
GetTlsResFromId(ResList * resList,int id)192 void *GetTlsResFromId(ResList *resList, int id)
193 {
194 Res *res = GetResFromId(resList, id);
195 if (res == NULL) {
196 LOG_ERROR("GetResFromId error");
197 return NULL;
198 }
199 return res->tlsRes;
200 }
201
GetCtxIdFromSsl(const void * tls)202 int GetCtxIdFromSsl(const void *tls)
203 {
204 ResList *sslList = GetSslList();
205 Res *tmpRes = GetResFromTlsResList(sslList, tls);
206 if (tmpRes == NULL) {
207 LOG_ERROR("GetResFromTlsResList ERROR");
208 return ERROR;
209 }
210 // CTX ID corresponding to SSL
211 return tmpRes->ctxId;
212 }
213
GetLastResFromList(ResList * resList)214 static void *GetLastResFromList(ResList *resList)
215 {
216 Res *headRes = resList->res;
217 Res *frontRes = NULL;
218 Res *nextRes = NULL;
219
220 if (resList->num == 0) {
221 return NULL;
222 }
223
224 frontRes = headRes->next;
225 nextRes = frontRes;
226 // Find the last element
227 while ((nextRes != NULL) && (nextRes->tlsRes != NULL)) {
228 frontRes = nextRes;
229 nextRes = frontRes->next;
230 }
231 resList->num--;
232 return frontRes;
233 }
234
FreeResList(ResList * resList)235 void FreeResList(ResList *resList)
236 {
237 Res *curRes = NULL;
238 Res *tmpRes = NULL;
239 OsLock(resList->resListLock);
240 curRes = resList->res->next;
241 while (curRes != NULL) {
242 tmpRes = curRes->next;
243 free(curRes);
244 curRes = tmpRes;
245 }
246 OsUnLock(resList->resListLock);
247 free(resList->res);
248 OsLockDestroy(resList->resListLock);
249 }
250
FreeCtx(TLS_TYPE tlsType,Res * ctxRes)251 void FreeCtx(TLS_TYPE tlsType, Res *ctxRes)
252 {
253 switch (tlsType) {
254 case HITLS:
255 HitlsFreeCtx(ctxRes->tlsRes);
256 break;
257 default:
258 /* Unknown type */
259 return;
260 }
261 ctxRes->tlsRes = NULL;
262 return;
263 }
264
FreeSsl(TLS_TYPE tlsType,Res * sslRes)265 void FreeSsl(TLS_TYPE tlsType, Res *sslRes)
266 {
267 switch (tlsType) {
268 case HITLS:
269 HitlsFreeSsl(sslRes->tlsRes);
270 break;
271 default:
272 /* Unknown type */
273 return;
274 }
275 sslRes->tlsRes = NULL;
276 return;
277 }
278
FreeTlsResList(void)279 void FreeTlsResList(void)
280 {
281 Process *process = GetProcess();
282 TLS_TYPE type = process->tlsType;
283
284 // Clearing CTX Resources
285 ResList *ctxList = GetCtxList();
286 void *resCtx = GetLastResFromList(ctxList);
287 while (resCtx != NULL) {
288 FreeCtx(type, resCtx);
289 resCtx = GetLastResFromList(ctxList);
290 }
291 FreeResList(ctxList);
292
293 // Clearing SSL Resources
294 ResList *sslList = GetSslList();
295 void *sslRes = GetLastResFromList(sslList);
296 while (sslRes != NULL) {
297 FreeSsl(type, sslRes);
298 sslRes = GetLastResFromList(sslList);
299 }
300 FreeResList(sslList);
301 return;
302 }
303
FreeResFromSsl(const void * ctx)304 int FreeResFromSsl(const void *ctx)
305 {
306 Process *process = GetProcess();
307 TLS_TYPE type = process->tlsType;
308 ResList *sslList = GetSslList();
309 Res *preRes = NULL;
310 Res *curRes = NULL;
311 Res *nextRes = NULL;
312
313 OsLock(sslList->resListLock);
314 preRes = sslList->res;
315 curRes = sslList->res->next;
316 while (curRes != NULL) {
317 if (curRes->tlsRes == ctx) {
318 nextRes = curRes->next;
319 FreeSsl(type, curRes);
320 FreeCtx(type, curRes);
321 free(curRes);
322 preRes->next = nextRes;
323 sslList->num--;
324 OsUnLock(sslList->resListLock);
325 return SUCCESS;
326 }
327 preRes = curRes;
328 curRes = curRes->next;
329 }
330 OsUnLock(sslList->resListLock);
331 return ERROR;
332 }