1 /*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "securec.h"
17 #include "attest_tls.h"
18 #include "attest_utils.h"
19 #include "attest_utils_log.h"
20 #include "attest_channel.h"
21
22 #define MAX_REQUEST_SIZE 2048
23 const int32_t TLS_READ_TIMEOUT_MS = 500; // time unit is ms
24
25 typedef int32_t(*VerifyFunc)(void*, mbedtls_x509_crt*, int32_t, uint32_t*);
26
LazyVerifyCert(void * data,mbedtls_x509_crt * crt,int32_t depth,uint32_t * flags)27 static int32_t LazyVerifyCert(void* data, mbedtls_x509_crt* crt, int32_t depth, uint32_t* flags)
28 {
29 (void)depth;
30 if (crt == NULL || flags == NULL) {
31 return ERR_NET_INVALID_ARG;
32 }
33 if (((*flags & MBEDTLS_X509_BADCERT_EXPIRED) != 0) || ((*flags & MBEDTLS_X509_BADCERT_FUTURE) != 0)) {
34 (*flags) &= ~(MBEDTLS_X509_BADCERT_EXPIRED | MBEDTLS_X509_BADCERT_FUTURE);
35 }
36 if (*flags != 0) {
37 int32_t certsNum = GetCommonCertSize();
38 int32_t i = 0;
39 while (i < certsNum) {
40 mbedtls_x509_crt caCert;
41 mbedtls_x509_crt_init(&caCert);
42 int32_t ret = LoadCommonOtherCert(&caCert, (unsigned int)i);
43 if (ret != 0) {
44 mbedtls_x509_crt_free(&caCert);
45 return ERR_NET_PARSE_CERT_FAIL;
46 }
47 i++;
48 ret = mbedtls_x509_crt_verify(crt, &caCert, NULL, NULL, flags, NULL, NULL);
49 if ((ret != 0) && (ret != MBEDTLS_ERR_X509_CERT_VERIFY_FAILED)) {
50 mbedtls_x509_crt_free(&caCert);
51 continue;
52 }
53
54 (*flags) &= ~(MBEDTLS_X509_BADCERT_EXPIRED | MBEDTLS_X509_BADCERT_FUTURE);
55 mbedtls_x509_crt_free(&caCert);
56 if (*flags == 0) {
57 break;
58 }
59 }
60 }
61 ((void)data);
62 return ATTEST_OK;
63 }
64
TLSSetupConfig(TLSSession * session)65 static int32_t TLSSetupConfig(TLSSession* session)
66 {
67 if (session == NULL) {
68 ATTEST_LOG_ERROR("[TLSSetupConfig] Invalid parameter.");
69 return ERR_NET_INVALID_ARG;
70 }
71 TLSConfig* tlsConfig = &(session->tlsConfig);
72 int32_t ret = mbedtls_ssl_config_defaults(&(tlsConfig->sslConf), MBEDTLS_SSL_IS_CLIENT,
73 MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
74 if (ret != 0) {
75 ATTEST_LOG_ERROR("[TLSSetupConfig] Set default configuration failed, return -0x%x.", -ret);
76 return ERR_NET_SET_SSL_CONFIG_FAIL;
77 }
78
79 mbedtls_ssl_conf_authmode(&(tlsConfig->sslConf), MBEDTLS_SSL_VERIFY_REQUIRED);
80 ret = mbedtls_ssl_conf_max_frag_len(&(tlsConfig->sslConf), MBEDTLS_SSL_MAX_FRAG_LEN_4096);
81 if (ret != 0) {
82 ATTEST_LOG_ERROR("[TLSSetupConfig] Set up max fragment failed, return -0x%x.", -ret);
83 return ERR_NET_SET_SSL_CONFIG_FAIL;
84 }
85 mbedtls_ssl_conf_ca_chain(&(tlsConfig->sslConf), &(tlsConfig->caCert), NULL);
86 mbedtls_ssl_conf_verify(&(tlsConfig->sslConf), (VerifyFunc)LazyVerifyCert, NULL);
87
88 mbedtls_ssl_conf_rng(&(tlsConfig->sslConf), mbedtls_ctr_drbg_random, &(tlsConfig->ctrDrbgCtx));
89 mbedtls_ssl_conf_read_timeout(&(tlsConfig->sslConf), TLS_READ_TIMEOUT_MS);
90
91 ret = mbedtls_ssl_setup(&(tlsConfig->sslCtx), &(tlsConfig->sslConf));
92 if (ret != 0) {
93 ATTEST_LOG_ERROR("[TLSSetupConfig] Set up net configuration failed, return -0x%x.", -ret);
94 return ERR_NET_SETUP_FAIL;
95 }
96 ret = mbedtls_ssl_set_hostname(&(tlsConfig->sslCtx), session->serverInfo.hostName);
97 if (ret != 0) {
98 return ERR_NET_SET_HOSTNAME_FAIL;
99 }
100
101 mbedtls_ssl_set_bio(&(tlsConfig->sslCtx), &(tlsConfig->netCtx), mbedtls_net_send,
102 mbedtls_net_recv, mbedtls_net_recv_timeout);
103
104 return ATTEST_OK;
105 }
106
TLSConnect(TLSSession * session)107 int32_t TLSConnect(TLSSession* session)
108 {
109 ATTEST_LOG_DEBUG("[TLSConnect] Begin.");
110 if (session == NULL) {
111 return ERR_NET_INVALID_ARG;
112 }
113
114 TLSConfig* tlsConfig = &(session->tlsConfig);
115 mbedtls_net_init(&(tlsConfig->netCtx));
116 mbedtls_ssl_init(&(tlsConfig->sslCtx));
117 mbedtls_ssl_config_init(&(tlsConfig->sslConf));
118 mbedtls_ctr_drbg_init(&(tlsConfig->ctrDrbgCtx));
119 mbedtls_x509_crt_init(&(tlsConfig->caCert));
120 mbedtls_entropy_init(&(tlsConfig->entropyCtx));
121
122 int32_t ret = mbedtls_ctr_drbg_seed(&(tlsConfig->ctrDrbgCtx), mbedtls_entropy_func,
123 &(tlsConfig->entropyCtx), (const uint8_t *)session->entropySeed, strlen(session->entropySeed));
124 if (ret != 0) {
125 ATTEST_LOG_ERROR("[TLSConnect] Generate DRGB seed failed, ret = -0x%x.", -ret);
126 return ERR_NET_DRBG_SEED_FAIL;
127 }
128
129 // Load the trusted CA
130 if ((ret = LoadCommonCert(&(tlsConfig->caCert))) != 0) {
131 ATTEST_LOG_ERROR("[TLSConnect] TLS load cert failed, ret = -0x%x.", -ret);
132 return ret;
133 }
134
135 ret = mbedtls_net_connect(&(tlsConfig->netCtx),
136 session->serverInfo.hostName, session->serverInfo.port, MBEDTLS_NET_PROTO_TCP);
137 if (ret != 0) {
138 ATTEST_LOG_ERROR("[TLSConnect] Connect to server failed, ret = -0x%x.", -ret);
139 return ERR_NET_CONNECT_FAIL;
140 }
141
142 ret = mbedtls_net_set_nonblock(&(tlsConfig->netCtx));
143 if (ret != 0) {
144 ATTEST_LOG_ERROR("[TLSConnect] Set non block failed, ret = -0x%x.", -ret);
145 return ERR_NET_SET_NON_BLOCK_FAIL;
146 }
147
148 ret = TLSSetupConfig(session);
149 if (ret != 0) {
150 ATTEST_LOG_ERROR("[TLSConnect] Set TLS session failed, ret = -0x%x.", -ret);
151 return ERR_NET_SETUP_FAIL;
152 }
153
154 while ((ret = mbedtls_ssl_handshake(&(tlsConfig->sslCtx))) != 0) {
155 if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE &&
156 ret != MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) {
157 ATTEST_LOG_ERROR("[TLSConnect] Handshake with server failed, ret = -0x%x.", -ret);
158 return ERR_NET_HANDSHAKE_FAIL;
159 }
160 }
161 ATTEST_LOG_DEBUG("[TLSConnect] End.");
162 return ATTEST_OK;
163 }
164
TLSWrite(const TLSSession * session,const uint8_t * buf,size_t len)165 int32_t TLSWrite(const TLSSession* session, const uint8_t* buf, size_t len)
166 {
167 if (session == NULL || buf == NULL || len > MAX_REQUEST_SIZE) {
168 return ERR_NET_INVALID_ARG;
169 }
170 size_t writeLen = 0;
171 while (writeLen < len) {
172 int32_t ret = mbedtls_ssl_write((mbedtls_ssl_context *)&(session->tlsConfig.sslCtx),
173 (uint8_t*)(buf + writeLen), len - writeLen);
174 if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE &&
175 ret != MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) {
176 ATTEST_LOG_ERROR("[TLSWrite] Write to server failed, ret = -0x%x.", -ret);
177 return ERR_NET_WRITE_FAIL;
178 }
179 if (ret >= 0) {
180 writeLen += ret;
181 }
182 }
183 return ATTEST_OK;
184 }
185
TLSRead(const TLSSession * session,uint8_t * buf,size_t len)186 int32_t TLSRead(const TLSSession* session, uint8_t* buf, size_t len)
187 {
188 if (session == NULL || buf == NULL || len == 0) {
189 return ERR_NET_INVALID_ARG;
190 }
191 size_t readLen = 0;
192 while (readLen < len) {
193 int32_t ret = mbedtls_ssl_read((mbedtls_ssl_context *)&(session->tlsConfig.sslCtx), (uint8_t*)(buf + readLen),
194 len - readLen);
195 if (ret < 0 && ret != MBEDTLS_ERR_SSL_TIMEOUT && ret != MBEDTLS_ERR_SSL_WANT_READ &&
196 ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret != MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) {
197 return ERR_NET_READ_FAIL;
198 }
199 if (ret >= 0) {
200 readLen += ret;
201 }
202 }
203 return ATTEST_OK;
204 }
205
TLSClose(TLSSession * session)206 int32_t TLSClose(TLSSession* session)
207 {
208 if (session == NULL) {
209 return ATTEST_ERR;
210 }
211 int32_t ret;
212 TLSConfig* tlsConfig = &(session->tlsConfig);
213 do {
214 ret = mbedtls_ssl_close_notify(&(tlsConfig->sslCtx));
215 } while (ret == MBEDTLS_ERR_SSL_WANT_WRITE);
216 mbedtls_net_free(&(tlsConfig->netCtx));
217 mbedtls_x509_crt_free(&(tlsConfig->caCert));
218 mbedtls_ssl_free(&(tlsConfig->sslCtx));
219 mbedtls_ssl_config_free(&(tlsConfig->sslConf));
220 mbedtls_ctr_drbg_free(&(tlsConfig->ctrDrbgCtx));
221 mbedtls_entropy_free(&(tlsConfig->entropyCtx));
222 return ret;
223 }
224