• 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 "hitls_build.h"
17 #include "securec.h"
18 #include "bsl_sal.h"
19 #include "tls_binlog_id.h"
20 #include "bsl_log_internal.h"
21 #include "bsl_log.h"
22 #include "bsl_err_internal.h"
23 #include "hitls_error.h"
24 #include "tls.h"
25 #include "rec.h"
26 #ifdef HITLS_TLS_FEATURE_FLIGHT
27 #include "bsl_uio.h"
28 #include "hitls.h"
29 #endif
30 #include "record.h"
31 #include "alert.h"
32 
33 #define ALERT_DATA_LEN 2u   /* alert data length */
34 
35 /** Alert context, which records the sending and receiving information */
36 struct AlertCtx {
37     uint8_t flag;           /* send and receive flags, for details, see ALERT_FLAG */
38     bool isFlush;           /* whether the message is sent successfully */
39     uint8_t warnCount;      /* count the number of consecutive received warnings */
40     uint8_t level;          /* Alert level. For details, see ALERT_Level */
41     uint8_t description;    /* Alert description: For details, see ALERT_Description */
42     uint8_t reverse;        /* reserve, 4-byte aligned */
43 };
44 
ALERT_GetFlag(const TLS_Ctx * ctx)45 bool ALERT_GetFlag(const TLS_Ctx *ctx)
46 {
47     return (ctx->alertCtx->flag != ALERT_FLAG_NO);
48 }
49 
ALERT_GetInfo(const TLS_Ctx * ctx,ALERT_Info * info)50 void ALERT_GetInfo(const TLS_Ctx *ctx, ALERT_Info *info)
51 {
52     struct AlertCtx *alertCtx = ctx->alertCtx;
53     info->flag = alertCtx->flag;
54     info->level = alertCtx->level;
55     info->description = alertCtx->description;
56     return;
57 }
58 
ALERT_CleanInfo(const TLS_Ctx * ctx)59 void ALERT_CleanInfo(const TLS_Ctx *ctx)
60 {
61     uint8_t alertCount = ctx->alertCtx->warnCount;
62     (void)memset_s(ctx->alertCtx, sizeof(struct AlertCtx), 0, sizeof(struct AlertCtx));
63     ctx->alertCtx->warnCount = alertCount;
64     return;
65 }
66 
67 /* check whether the operation is abnormal */
AlertIsAbnormalInput(const struct AlertCtx * alertCtx,ALERT_Level level)68 bool AlertIsAbnormalInput(const struct AlertCtx *alertCtx, ALERT_Level level)
69 {
70     if (level != ALERT_LEVEL_FATAL && level != ALERT_LEVEL_WARNING) {
71         return true;
72     }
73     if (alertCtx->flag != ALERT_FLAG_NO) {
74         // a critical alert exists and cannot be overwritten
75         if (alertCtx->level == ALERT_LEVEL_FATAL) {
76             return true;
77         }
78         // common alarms are not allowed to overwrite CLOSE NOTIFY
79         if (level == ALERT_LEVEL_WARNING &&
80             alertCtx->level == ALERT_LEVEL_WARNING &&
81             alertCtx->description == ALERT_CLOSE_NOTIFY) {
82             return true;
83         }
84     }
85     return false;
86 }
87 
ALERT_Send(const TLS_Ctx * ctx,ALERT_Level level,ALERT_Description description)88 void ALERT_Send(const TLS_Ctx *ctx, ALERT_Level level, ALERT_Description description)
89 {
90     struct AlertCtx *alertCtx = ctx->alertCtx;
91     // prevent abnormal operations
92     if (AlertIsAbnormalInput(alertCtx, level)) {
93         return;
94     }
95     alertCtx->level = (uint8_t)level;
96     alertCtx->description = (uint8_t)description;
97     alertCtx->flag = ALERT_FLAG_SEND;
98     alertCtx->isFlush = false;
99     return;
100 }
101 
ALERT_Flush(TLS_Ctx * ctx)102 int32_t ALERT_Flush(TLS_Ctx *ctx)
103 {
104     struct AlertCtx *alertCtx = ctx->alertCtx;
105     int32_t ret;
106     if (alertCtx->flag != ALERT_FLAG_SEND) {
107         BSL_ERR_PUSH_ERROR(HITLS_ALERT_NO_WANT_SEND);
108         return HITLS_ALERT_NO_WANT_SEND;
109     }
110     if (alertCtx->isFlush == false) {
111         if (ctx->recCtx != NULL && ctx->recCtx->pendingData != NULL && alertCtx->description == ALERT_CLOSE_NOTIFY) {
112             return HITLS_REC_NORMAL_IO_BUSY;
113         }
114         uint8_t data[ALERT_DATA_LEN];
115         /** obtain the alert level */
116         data[0] = alertCtx->level;
117         data[1] = alertCtx->description;
118         if (ctx->negotiatedInfo.version == HITLS_VERSION_SSL30 && alertCtx->description == ALERT_PROTOCOL_VERSION) {
119             data[1] = ALERT_HANDSHAKE_FAILURE;
120         }
121         /** write the record */
122         ret = REC_Write(ctx, REC_TYPE_ALERT, data, ALERT_DATA_LEN);
123         if (ret != HITLS_SUCCESS) {
124             return RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID16267, "Write fail");
125         }
126         alertCtx->isFlush = true;
127         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15768, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN,
128             "Sent an Alert msg:level[%u] description[%u]", data[0], data[1], 0, 0);
129     }
130 #ifdef HITLS_TLS_FEATURE_FLIGHT
131     /* if isFlightTransmitEnable is enabled, the stored handshake information needs to be sent */
132     uint8_t isFlightTransmitEnable = 0;
133     (void)HITLS_GetFlightTransmitSwitch(ctx, &isFlightTransmitEnable);
134     if (isFlightTransmitEnable == 1) {
135         ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_FLUSH, 0, NULL);
136         if (ret == BSL_UIO_IO_BUSY) {
137             BSL_ERR_PUSH_ERROR(HITLS_REC_NORMAL_IO_BUSY);
138             return HITLS_REC_NORMAL_IO_BUSY;
139         }
140         if (ret != BSL_SUCCESS) {
141             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16111, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
142                 "fail to send alert message in bUio.", 0, 0, 0, 0);
143             BSL_ERR_PUSH_ERROR(HITLS_REC_ERR_IO_EXCEPTION);
144             return HITLS_REC_ERR_IO_EXCEPTION;
145         }
146     }
147 #endif /* HITLS_TLS_FEATURE_FLIGHT */
148     return HITLS_SUCCESS;
149 }
150 
151 #ifdef HITLS_TLS_PROTO_TLS13
ALERT_GetVersion(const TLS_Ctx * ctx)152 static uint32_t ALERT_GetVersion(const TLS_Ctx *ctx)
153 {
154     if (ctx->negotiatedInfo.version > 0) {
155         /* the version has been negotiated */
156         return ctx->negotiatedInfo.version;
157     } else {
158         /* if the version is not negotiated, the latest version supported by the local end is returned */
159         return ctx->config.tlsConfig.maxVersion;
160     }
161 }
162 #endif /* HITLS_TLS_PROTO_TLS13 */
163 
ALERT_Init(TLS_Ctx * ctx)164 int32_t ALERT_Init(TLS_Ctx *ctx)
165 {
166     if (ctx == NULL) {
167         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15772, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "ctx null.", 0, 0, 0, 0);
168         BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT);
169         return HITLS_NULL_INPUT;
170     }
171     // prevent multi init of ctx->alertCtx
172     if (ctx->alertCtx != NULL) {
173         return HITLS_SUCCESS;
174     }
175     ctx->alertCtx = (struct AlertCtx *)BSL_SAL_Malloc(sizeof(struct AlertCtx));
176     if (ctx->alertCtx == NULL) {
177         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15773, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
178             "malloc alert ctx fail.", 0, 0, 0, 0);
179         BSL_ERR_PUSH_ERROR(HITLS_MEMALLOC_FAIL);
180         return HITLS_MEMALLOC_FAIL;
181     }
182     (void)memset_s(ctx->alertCtx, sizeof(struct AlertCtx), 0, sizeof(struct AlertCtx));
183     return HITLS_SUCCESS;
184 }
185 
ALERT_Deinit(TLS_Ctx * ctx)186 void ALERT_Deinit(TLS_Ctx *ctx)
187 {
188     if (ctx == NULL) {
189         return;
190     }
191     BSL_SAL_FREE(ctx->alertCtx);
192     return;
193 }
194 
ProcessDecryptedAlert(TLS_Ctx * ctx,const uint8_t * data,uint32_t dataLen)195 int32_t ProcessDecryptedAlert(TLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen)
196 {
197     struct AlertCtx *alertCtx = ctx->alertCtx;
198 
199     /** if the message lengths are not equal, an error code is returned */
200     if (dataLen != ALERT_DATA_LEN) {
201         BSL_ERR_PUSH_ERROR(HITLS_REC_NORMAL_RECV_UNEXPECT_MSG);
202         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15769, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
203             "get a alert msg with illegal len %u", dataLen, 0, 0, 0);
204         ALERT_Send(ctx, ALERT_LEVEL_FATAL, ALERT_UNEXPECTED_MESSAGE);
205         return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG;
206     }
207 
208     /** record the alert message */
209     if (data[0] == ALERT_LEVEL_FATAL || data[0] == ALERT_LEVEL_WARNING) {
210         // prevent abnormal operations
211         if (AlertIsAbnormalInput(alertCtx, data[0]) == true) {
212             return RETURN_ERROR_NUMBER_PROCESS(HITLS_REC_NORMAL_RECV_UNEXPECT_MSG, BINLOG_ID16268, "input abnormal");
213         }
214         alertCtx->flag = ALERT_FLAG_RECV;
215         alertCtx->level = data[0];
216         alertCtx->description = data[1];
217 #ifdef HITLS_TLS_PROTO_TLS13
218         if (ALERT_GetVersion(ctx) == HITLS_VERSION_TLS13 && alertCtx->description != ALERT_CLOSE_NOTIFY) {
219             alertCtx->level = ALERT_LEVEL_FATAL;
220         }
221 #endif
222         if (alertCtx->level == ALERT_LEVEL_FATAL) {
223             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16269, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
224                 "alert fatal", 0, 0, 0, 0);
225             BSL_ERR_PUSH_ERROR(HITLS_REC_NORMAL_RECV_UNEXPECT_MSG);
226         }
227         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15770, BSL_LOG_LEVEL_WARN, BSL_LOG_BINLOG_TYPE_RUN,
228             "got a alert msg:level[%u] description[%u]", data[0], data[1], 0, 0);
229         return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG;
230     }
231 
232     BSL_ERR_PUSH_ERROR(HITLS_REC_NORMAL_RECV_UNEXPECT_MSG);
233     BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15771, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
234         "get a alert msg with illegal type", 0, 0, 0, 0);
235     /** Decoding error. Send an alert. */
236     ALERT_Send(ctx, ALERT_LEVEL_FATAL, ALERT_ILLEGAL_PARAMETER);
237     return HITLS_REC_NORMAL_RECV_UNEXPECT_MSG;
238 }
239 #ifdef HITLS_TLS_PROTO_TLS13
ProcessPlainAlert(TLS_Ctx * ctx,const uint8_t * data,uint32_t dataLen)240 int32_t ProcessPlainAlert(TLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen)
241 {
242     if (ctx->isClient == true && REC_HaveReadSuiteInfo(ctx)) {
243         return RETURN_ALERT_PROCESS(ctx, HITLS_REC_NORMAL_RECV_UNEXPECT_MSG, BINLOG_ID16270,
244             "receive plain alert", ALERT_UNEXPECTED_MESSAGE);
245     }
246     if (ctx->isClient == false && ctx->plainAlertForbid == true) {
247         return RETURN_ALERT_PROCESS(ctx, HITLS_REC_NORMAL_RECV_UNEXPECT_MSG, BINLOG_ID16271,
248             "tls1.3 forbid to receive plain alert", ALERT_UNEXPECTED_MESSAGE);
249     }
250     return ProcessDecryptedAlert(ctx, data, dataLen);
251 }
252 #endif /* HITLS_TLS_PROTO_TLS13 */
ALERT_ClearWarnCount(TLS_Ctx * ctx)253 void ALERT_ClearWarnCount(TLS_Ctx *ctx)
254 {
255     ctx->alertCtx->warnCount = 0;
256     return;
257 }
258 
ALERT_HaveExceeded(TLS_Ctx * ctx,uint8_t threshold)259 bool ALERT_HaveExceeded(TLS_Ctx *ctx, uint8_t threshold)
260 {
261     ctx->alertCtx->warnCount += 1;
262     return ctx->alertCtx->warnCount >= threshold;
263 }
264 
265 #ifdef HITLS_BSL_LOG
ReturnAlertProcess(TLS_Ctx * ctx,int32_t err,uint32_t logId,const void * logStr,ALERT_Description description)266 int32_t ReturnAlertProcess(TLS_Ctx *ctx, int32_t err, uint32_t logId, const void *logStr,
267     ALERT_Description description)
268 {
269     if (logStr != NULL) {
270         BSL_LOG_BINLOG_FIXLEN(logId, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, logStr, 0, 0, 0, 0);
271     }
272     if (description != ALERT_UNKNOWN) {
273         ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, description);
274     }
275     return err;
276 }
277 
ReturnErrorNumberProcess(int32_t err,uint32_t logId,const void * logStr)278 int32_t ReturnErrorNumberProcess(int32_t err, uint32_t logId, const void *logStr)
279 {
280     (void)logStr;
281     BSL_LOG_BINLOG_FIXLEN(logId, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, logStr, 0, 0, 0, 0);
282     return err;
283 }
284 #endif /* HITLS_BSL_LOG */