• 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 #include "hitls_build.h"
16 #include "securec.h"
17 #include "bsl_sal.h"
18 #include "bsl_list.h"
19 #include "tls_binlog_id.h"
20 #include "bsl_uio.h"
21 #include "bsl_log_internal.h"
22 #include "bsl_log.h"
23 #include "bsl_err_internal.h"
24 #include "hitls_error.h"
25 #include "rec.h"
26 #include "app_ctx.h"
27 #include "rec.h"
28 #include "record.h"
29 #include "app.h"
30 
ReadAppData(TLS_Ctx * ctx,uint8_t * buf,uint32_t num,uint32_t * readLen)31 static int32_t ReadAppData(TLS_Ctx *ctx, uint8_t *buf, uint32_t num, uint32_t *readLen)
32 {
33     return REC_Read(ctx, REC_TYPE_APP, buf, readLen, num);
34 }
35 
APP_Read(TLS_Ctx * ctx,uint8_t * buf,uint32_t num,uint32_t * readLen)36 int32_t APP_Read(TLS_Ctx *ctx, uint8_t *buf, uint32_t num, uint32_t *readLen)
37 {
38     int32_t ret;
39     uint32_t readbytes;
40 
41     if (ctx == NULL || buf == NULL || num == 0) {
42         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15659, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
43             "APP: input null pointer or read bufLen is 0.", 0, 0, 0, 0);
44         BSL_ERR_PUSH_ERROR(HITLS_APP_ERR_ZERO_READ_BUF_LEN);
45         return HITLS_APP_ERR_ZERO_READ_BUF_LEN;
46     }
47     // read data to the buffer in non-blocking mode
48     do {
49         ret =  ReadAppData(ctx, buf, num, &readbytes);
50         if (ret != HITLS_SUCCESS) {
51             return ret;
52         }
53     } while (readbytes == 0); // do not exit the loop until data is read
54 
55     *readLen = readbytes;
56     return HITLS_SUCCESS;
57 }
58 
APP_GetMaxWriteSize(const TLS_Ctx * ctx,uint32_t * len)59 int32_t APP_GetMaxWriteSize(const TLS_Ctx *ctx, uint32_t *len)
60 {
61     return REC_GetMaxWriteSize(ctx, len);
62 }
63 
SavePendingData(TLS_Ctx * ctx,const uint8_t * data,uint32_t dataLen)64 static int32_t SavePendingData(TLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen)
65 {
66 #ifdef HITLS_TLS_PROTO_DTLS
67     if (IS_SUPPORT_DATAGRAM(ctx->config.tlsConfig.originVersionMask)) {
68         return HITLS_SUCCESS;
69     }
70 #endif
71     RecCtx *recCtx = (RecCtx *)ctx->recCtx;
72     if (recCtx->pendingData != NULL) {
73         if (recCtx->pendingData != data || recCtx->pendingDataSize != dataLen) {
74             ctx->method.sendAlert(ctx, ALERT_LEVEL_FATAL, ALERT_INTERNAL_ERROR);
75             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16241, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
76                 "The two buffer addresses are inconsistent.", 0, 0, 0, 0);
77             return HITLS_APP_ERR_WRITE_BAD_RETRY;
78         }
79     }
80     // Stores the plaintext data to be sent.
81     recCtx->pendingData = data;
82     recCtx->pendingDataSize = dataLen;
83     return HITLS_SUCCESS;
84 }
85 
CheckDataLen(TLS_Ctx * ctx,const uint8_t * data,uint32_t * sendLen)86 static int32_t CheckDataLen(TLS_Ctx *ctx, const uint8_t *data, uint32_t *sendLen)
87 {
88     uint32_t maxWriteLen = 0u;
89     int32_t ret = REC_GetMaxWriteSize(ctx, &maxWriteLen);
90     if (ret != HITLS_SUCCESS) {
91         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID15660, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
92             "APP: Get record max write size fail.", 0, 0, 0, 0);
93         return ret;
94     }
95     if (*sendLen > maxWriteLen) {
96         *sendLen = maxWriteLen;
97     }
98 
99     return SavePendingData(ctx, data, *sendLen);
100 }
101 
APP_Write(TLS_Ctx * ctx,const uint8_t * data,uint32_t dataLen,uint32_t * writeLen)102 int32_t APP_Write(TLS_Ctx *ctx, const uint8_t *data, uint32_t dataLen, uint32_t *writeLen)
103 {
104     uint32_t sendLen = dataLen;
105     int32_t ret = CheckDataLen(ctx, data, &sendLen);
106     if (ret != HITLS_SUCCESS) {
107         return ret;
108     }
109     *writeLen = 0;
110 
111     ret = REC_Write(ctx, REC_TYPE_APP, data, sendLen);
112     if (ret != HITLS_SUCCESS) {
113         return RETURN_ERROR_NUMBER_PROCESS(ret, BINLOG_ID16274, "Write fail");
114     }
115 #ifdef HITLS_TLS_FEATURE_FLIGHT
116     if (ctx->config.tlsConfig.isFlightTransmitEnable) {
117         ret = BSL_UIO_Ctrl(ctx->uio, BSL_UIO_FLUSH, 0, NULL);
118         if (ret == BSL_UIO_IO_BUSY) {
119             return HITLS_REC_NORMAL_IO_BUSY;
120         }
121         if (ret != BSL_SUCCESS) {
122             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID16112, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
123                 "fail to send handshake message in bUio.", 0, 0, 0, 0);
124             return HITLS_REC_ERR_IO_EXCEPTION;
125         }
126     }
127 #endif
128     *writeLen = sendLen;
129     ctx->recCtx->pendingData = NULL;
130     ctx->recCtx->pendingDataSize = 0;
131     return HITLS_SUCCESS;
132 }