• 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 <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 }