• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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