• 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 <stdlib.h>
18 #include <stdbool.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <sys/time.h>
24 
25 #include "hitls_error.h"
26 #include "hitls_type.h"
27 #include "hitls.h"
28 #include "tls.h"
29 #include "hs_ctx.h"
30 #include "bsl_errno.h"
31 #include "uio_base.h"
32 
33 #include "frame_msg.h"
34 #include "logger.h"
35 #include "hlt_type.h"
36 
37 #define SUCCESS 0
38 #define ERROR (-1)
39 
40 #define MAX_LEN (20 * 1024)
41 
42 /* set block mode. */
SetBlockMode(int32_t sd,bool isBlock)43 int32_t SetBlockMode(int32_t sd, bool isBlock)
44 {
45     if (isBlock) {
46         LOG_DEBUG("Socket Set Block Mode");
47         int flag;
48         flag = fcntl(sd, F_GETFL, 0);
49         flag &= ~O_NONBLOCK;
50         if (fcntl(sd, F_SETFL, flag) < 0) {
51             LOG_ERROR("fcntl fail");
52             return ERROR;
53         }
54     } else {
55         LOG_DEBUG("Socket Set Unblock Mode");
56         int flag;
57         flag = fcntl(sd, F_GETFL, 0);
58         flag |= O_NONBLOCK;
59         if (fcntl(sd, F_SETFL, flag) < 0) {
60             LOG_ERROR("fcntl fail");
61             return ERROR;
62         }
63     }
64     return SUCCESS;
65 }
66 
67 /**
68  * @brief   Check whether there are fatal I/O errors
69  *
70  * @param   err [IN] Error type
71  *
72  * @return  true :A fatal error occurs
73  *          false:No fatal error occurs
74  */
IsNonFatalErr(int32_t err)75 bool IsNonFatalErr(int32_t err)
76 {
77     bool ret = true;
78     /** @alias Check whether err is a fatal error and modify ret */
79     switch (err) {
80 #if defined(ENOTCONN)
81         case ENOTCONN:
82 #endif
83 
84 #ifdef EINTR
85         case EINTR:
86 #endif
87 
88 #ifdef EINPROGRESS
89         case EINPROGRESS:
90 #endif
91 
92 #ifdef EWOULDBLOCK
93 #if !defined(WSAEWOULDBLOCK) || WSAEWOULDBLOCK != EWOULDBLOCK
94         case EWOULDBLOCK:
95 #endif
96 #endif
97 
98 #ifdef EAGAIN
99 #if EWOULDBLOCK != EAGAIN
100         case EAGAIN:
101 #endif
102 #endif
103 
104 #ifdef EALREADY
105         case EALREADY:
106 #endif
107 
108 #ifdef EPROTO
109         case EPROTO:
110 #endif
111             ret = true;
112             break;
113         default:
114             ret = false;
115             break;
116     }
117     return ret;
118 }
119 
120 static HLT_FrameHandle g_frameHandle;
121 
SetFrameHandle(HLT_FrameHandle * frameHandle)122 int32_t SetFrameHandle(HLT_FrameHandle *frameHandle)
123 {
124     if (frameHandle == NULL || frameHandle->ctx == NULL) {
125         return HITLS_NULL_INPUT;
126     }
127     g_frameHandle.ctx = frameHandle->ctx;
128     g_frameHandle.frameCallBack = frameHandle->frameCallBack;
129     g_frameHandle.userData = frameHandle->userData;
130     g_frameHandle.expectHsType = frameHandle->expectHsType;
131     g_frameHandle.expectReType = frameHandle->expectReType;
132     g_frameHandle.ioState = frameHandle->ioState;
133     g_frameHandle.pointType = frameHandle->pointType;
134     g_frameHandle.method.uioWrite = frameHandle->method.uioWrite;
135     g_frameHandle.method.uioRead = frameHandle->method.uioRead;
136     g_frameHandle.method.uioCtrl = frameHandle->method.uioCtrl;
137 
138     return HITLS_SUCCESS;
139 }
140 
CleanFrameHandle(void)141 void CleanFrameHandle(void)
142 {
143     g_frameHandle.ctx = NULL;
144     g_frameHandle.frameCallBack = NULL;
145     g_frameHandle.userData = NULL;
146     g_frameHandle.expectHsType = 0;
147     g_frameHandle.expectReType = 0;
148     g_frameHandle.ioState = 0;
149     g_frameHandle.pointType = 0;
150     g_frameHandle.method.uioWrite = NULL;
151     g_frameHandle.method.uioRead = NULL;
152     g_frameHandle.method.uioCtrl = NULL;
153 }
154 
GetFrameHandle(void)155 HLT_FrameHandle *GetFrameHandle(void)
156 {
157     return &g_frameHandle;
158 }
159 
160 /* Obtain the frameType. The input parameters frameHandle and frameType must not be empty */
GetFrameType(HLT_FrameHandle * frameHandle,FRAME_Type * frameType)161 static int32_t GetFrameType(HLT_FrameHandle *frameHandle, FRAME_Type *frameType)
162 {
163     if (frameHandle->ctx == NULL) {
164         return HITLS_NULL_INPUT;
165     }
166     TLS_Ctx *tmpCtx = (TLS_Ctx *)frameHandle->ctx;
167     frameType->versionType = tmpCtx->negotiatedInfo.version > 0 ?
168         tmpCtx->negotiatedInfo.version : tmpCtx->config.tlsConfig.maxVersion;
169     frameType->keyExType = tmpCtx->hsCtx->kxCtx->keyExchAlgo;
170     frameType->recordType = frameHandle->expectReType;
171     frameType->handshakeType = frameHandle->expectHsType;
172     return HITLS_SUCCESS;
173 }
174 
175 /* Verify whether the parsed msg meets the requirements. Restrict the msg input parameter */
CheckHandleType(FRAME_Msg * msg)176 static bool CheckHandleType(FRAME_Msg *msg)
177 {
178     if (msg->recType.data != REC_TYPE_HANDSHAKE) {
179         if ((int32_t)msg->recType.data == g_frameHandle.expectReType) {
180             return true;
181         }
182     } else {
183         if ((int32_t)msg->recType.data == g_frameHandle.expectReType &&
184             (int32_t)msg->body.hsMsg.type.data == g_frameHandle.expectHsType) {
185             return true;
186         }
187     }
188     return false;
189 }
190 
191 /* Release the newbuf */
FreeNewBuf(void * newBuf)192 void FreeNewBuf(void *newBuf)
193 {
194     if (newBuf != NULL) {
195         free(newBuf);
196         newBuf = NULL;
197     }
198 }
199 
200 /* Obtain the newbuf by parsing the buffer. The input parameter of the packageLen constraint is not empty */
GetNewBuf(const void * buf,uint32_t len,uint32_t * packLen)201 uint8_t *GetNewBuf(const void *buf, uint32_t len, uint32_t *packLen)
202 {
203     uint32_t packLenTmp = 0;
204     /* Obtain the frameType */
205     FRAME_Type frameType = { 0 };
206     if (GetFrameType(&g_frameHandle, &frameType) != HITLS_SUCCESS) {
207         return NULL;
208     }
209     /* Unpack the buffer into the msg structure */
210     uint32_t parseLen = 0;
211     FRAME_Msg msg = { 0 };
212     uint32_t offset = 0;
213     uint8_t *newBuf = (uint8_t *)calloc(MAX_LEN, sizeof(uint8_t));
214     uint32_t newOffset = 0;
215 
216     while (offset < *packLen) {
217         /* Currently, encryption and decryption are not performed.
218          * Therefore, the return value is not determined
219          * because the encrypted messages such as finished messages will fail to be parsed
220          */
221         (void)FRAME_ParseMsg(&frameType, &((uint8_t*)buf)[offset], len - offset, &msg, &parseLen);
222 
223         if (CheckHandleType(&msg)) {
224             if (g_frameHandle.ioState == EXP_IO_BUSY) {
225                 FRAME_CleanMsg(&frameType, &msg);
226                 /* Set I/O to busy */
227                 *packLen = 0;
228                 FreeNewBuf(newBuf);
229                 return NULL;
230             }
231             if (g_frameHandle.userData == NULL) {
232                 g_frameHandle.userData = (void *)&frameType;
233             }
234             g_frameHandle.frameCallBack(&msg, g_frameHandle.userData);
235             if (g_frameHandle.userData == (void *)&frameType) {
236                 g_frameHandle.userData = NULL;
237             }
238             /* Pack the newly constructed msg into a buffer */
239             if (FRAME_PackMsg(&frameType, &msg, &newBuf[newOffset], MAX_LEN - newOffset, &packLenTmp) != HITLS_SUCCESS) {
240                 FRAME_CleanMsg(&frameType, &msg);
241                 FreeNewBuf(newBuf);
242                 return NULL;
243             }
244             newOffset += packLenTmp;
245         } else {
246             memcpy_s(&newBuf[newOffset], MAX_LEN - newOffset, &((uint8_t*)buf)[offset], parseLen);
247             newOffset += parseLen;
248         }
249         offset += parseLen;
250         FRAME_CleanMsg(&frameType, &msg);
251     }
252 
253     /* Check whether the package is reassembled. If not, *packLen should not be changed */
254     if (packLenTmp == 0) {
255         FreeNewBuf(newBuf);
256         return NULL;
257     }
258 
259     *packLen = newOffset;
260     return newBuf;
261 }