• 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 <stdio.h>
17 #include <time.h>
18 #include "securec.h"
19 #include "attest_tls.h"
20 #include "attest_utils.h"
21 #include "attest_utils_log.h"
22 #include "attest_channel.h"
23 
24 #define MAX_REQUEST_SIZE 2048
25 #define ATTEST_TIME_DIFF_YEAR_1900 1900
26 #define ATTEST_TIME_DIFF_MONTH_ONE 1
27 const int32_t TLS_READ_TIMEOUT_MS = 500; // time unit is ms
28 
29 typedef int32_t(*VerifyFunc)(void*, mbedtls_x509_crt*, int32_t, uint32_t*);
30 
X509CheckTime(const mbedtls_x509_time * before,const mbedtls_x509_time * after)31 static int32_t X509CheckTime(const mbedtls_x509_time *before, const mbedtls_x509_time *after)
32 {
33     if (before == NULL || after == NULL) {
34         ATTEST_LOG_ERROR("[X509CheckTime] time is null");
35         return ATTEST_ERR;
36     }
37     if (before->year > after->year) {
38         return ATTEST_ERR;
39     } else if (before->year < after->year) {
40         return ATTEST_OK;
41     }
42     // same year
43     if (before->mon > after->mon) {
44         return ATTEST_ERR;
45     } else if (before->mon < after->mon) {
46         return ATTEST_OK;
47     }
48     // same year and mon
49     if (before->day > after->day) {
50         return ATTEST_ERR;
51     } else if (before->day < after->day) {
52         return ATTEST_OK;
53     }
54     // same year, mon and day
55     if (before->hour > after->hour) {
56         return ATTEST_ERR;
57     } else if (before->hour < after->hour) {
58         return ATTEST_OK;
59     }
60     // same year, mon, day and hour
61     if (before->min > after->min) {
62         return ATTEST_ERR;
63     } else if (before->min < after->min) {
64         return ATTEST_OK;
65     }
66     // same year, mon, day, hour and min
67     if (before->sec > after->sec) {
68         return ATTEST_ERR;
69     } else if (before->sec < after->sec) {
70         return ATTEST_OK;
71     }
72     return ATTEST_OK;
73 }
74 
VerifyCrtTime(mbedtls_x509_crt * crt,uint32_t * flags)75 static int32_t VerifyCrtTime(mbedtls_x509_crt* crt, uint32_t* flags)
76 {
77     time_t nowTime;
78     (void)time(&nowTime);
79     struct tm *theNowTm = gmtime(&nowTime);
80     if (theNowTm == NULL) {
81         ATTEST_LOG_ERROR("[VerifyCrtTime] failed to get time");
82         return ATTEST_ERR;
83     }
84     // UTC TIME
85     mbedtls_x509_time curTime = {0};
86     // Obtain the current year, starting from 1900, so add 1900
87     curTime.year = ATTEST_TIME_DIFF_YEAR_1900 + theNowTm->tm_year;
88     // Obtain the current month, ranging from 0 to 11, so add 1
89     curTime.mon = ATTEST_TIME_DIFF_MONTH_ONE + theNowTm->tm_mon;
90     // Obtain the current number of days in the month, ranging from 1 to 31
91     curTime.day = theNowTm->tm_mday;
92     curTime.hour = theNowTm->tm_hour;
93     curTime.min = theNowTm->tm_min;
94     curTime.sec = theNowTm->tm_sec;
95 
96     // check time is past
97     int32_t ret = X509CheckTime(&curTime, &crt->valid_to);
98     if (ret != ATTEST_OK) {
99         ATTEST_LOG_ERROR("[VerifyCrtTime] time is past");
100         *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
101         return ATTEST_ERR;
102     }
103     // check time is future
104     ret = X509CheckTime(&crt->valid_from, &curTime);
105     if (ret != ATTEST_OK) {
106         ATTEST_LOG_ERROR("[VerifyCrtTime] time is future");
107         *flags |= MBEDTLS_X509_BADCERT_FUTURE;
108         return ATTEST_ERR;
109     }
110     return ATTEST_OK;
111 }
112 
LazyVerifyCert(void * data,mbedtls_x509_crt * crt,int32_t depth,uint32_t * flags)113 static int32_t LazyVerifyCert(void* data, mbedtls_x509_crt* crt, int32_t depth, uint32_t* flags)
114 {
115     ((void)data);
116     ATTEST_LOG_DEBUG("[LazyVerifyCert] depth:%d", depth);
117     if (crt == NULL || flags == NULL) {
118         ATTEST_LOG_ERROR("[LazyVerifyCert] crt or flags is null");
119         return ERR_NET_INVALID_ARG;
120     }
121 
122     // Verify certificate time
123     int32_t ret = VerifyCrtTime(crt, flags);
124     if (ret != ATTEST_OK) {
125         ATTEST_LOG_ERROR("[LazyVerifyCert] cert time is invalid");
126         return ERR_NET_CERT_VERIFY_FAIL;
127     }
128 
129     if (*flags != 0) {
130         int32_t certsNum = GetCommonCertSize();
131         int32_t i = 0;
132         while (i < certsNum) {
133             mbedtls_x509_crt caCert;
134             mbedtls_x509_crt_init(&caCert);
135             ret = LoadCommonOtherCert(&caCert, (unsigned int)i);
136             if (ret != 0) {
137                 mbedtls_x509_crt_free(&caCert);
138                 return ERR_NET_PARSE_CERT_FAIL;
139             }
140             i++;
141             ret = mbedtls_x509_crt_verify(crt, &caCert, NULL, NULL, flags, NULL, NULL);
142             if ((ret != 0) && (ret != MBEDTLS_ERR_X509_CERT_VERIFY_FAILED)) {
143                 mbedtls_x509_crt_free(&caCert);
144                 continue;
145             }
146             mbedtls_x509_crt_free(&caCert);
147             if (*flags == 0) {
148                 break;
149             }
150         }
151     }
152     if (*flags != 0) {
153         ATTEST_LOG_ERROR("[LazyVerifyCert] flags:0x%X", *flags);
154         return ERR_NET_CERT_VERIFY_FAIL;
155     }
156     return ATTEST_OK;
157 }
158 
TLSSetupConfig(TLSSession * session)159 static int32_t TLSSetupConfig(TLSSession* session)
160 {
161     if (session == NULL) {
162         ATTEST_LOG_ERROR("[TLSSetupConfig] Invalid parameter.");
163         return ERR_NET_INVALID_ARG;
164     }
165     TLSConfig* tlsConfig = &(session->tlsConfig);
166     int32_t ret = mbedtls_ssl_config_defaults(&(tlsConfig->sslConf), MBEDTLS_SSL_IS_CLIENT,
167         MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
168     if (ret != 0) {
169         ATTEST_LOG_ERROR("[TLSSetupConfig] Set default configuration failed, return -0x%x.", -ret);
170         return ERR_NET_SET_SSL_CONFIG_FAIL;
171     }
172 
173     mbedtls_ssl_conf_authmode(&(tlsConfig->sslConf), MBEDTLS_SSL_VERIFY_REQUIRED);
174     ret = mbedtls_ssl_conf_max_frag_len(&(tlsConfig->sslConf), MBEDTLS_SSL_MAX_FRAG_LEN_4096);
175     if (ret != 0) {
176         ATTEST_LOG_ERROR("[TLSSetupConfig] Set up max fragment failed, return -0x%x.", -ret);
177         return ERR_NET_SET_SSL_CONFIG_FAIL;
178     }
179     mbedtls_ssl_conf_ca_chain(&(tlsConfig->sslConf), &(tlsConfig->caCert), NULL);
180     mbedtls_ssl_conf_verify(&(tlsConfig->sslConf), (VerifyFunc)LazyVerifyCert, NULL);
181 
182     mbedtls_ssl_conf_rng(&(tlsConfig->sslConf), mbedtls_ctr_drbg_random, &(tlsConfig->ctrDrbgCtx));
183     mbedtls_ssl_conf_read_timeout(&(tlsConfig->sslConf), TLS_READ_TIMEOUT_MS);
184 
185     ret = mbedtls_ssl_setup(&(tlsConfig->sslCtx), &(tlsConfig->sslConf));
186     if (ret != 0) {
187         ATTEST_LOG_ERROR("[TLSSetupConfig] Set up net configuration failed, return -0x%x.", -ret);
188         return ERR_NET_SETUP_FAIL;
189     }
190     ret = mbedtls_ssl_set_hostname(&(tlsConfig->sslCtx), session->serverInfo.hostName);
191     if (ret != 0) {
192         return ERR_NET_SET_HOSTNAME_FAIL;
193     }
194 
195     mbedtls_ssl_set_bio(&(tlsConfig->sslCtx), &(tlsConfig->netCtx), mbedtls_net_send,
196         mbedtls_net_recv, mbedtls_net_recv_timeout);
197 
198     return ATTEST_OK;
199 }
200 
TLSConnect(TLSSession * session)201 int32_t TLSConnect(TLSSession* session)
202 {
203     ATTEST_LOG_DEBUG("[TLSConnect] Begin.");
204     if (session == NULL) {
205         return ERR_NET_INVALID_ARG;
206     }
207     TLSConfig* tlsConfig = &(session->tlsConfig);
208     mbedtls_net_init(&(tlsConfig->netCtx));
209     mbedtls_ssl_init(&(tlsConfig->sslCtx));
210     mbedtls_ssl_config_init(&(tlsConfig->sslConf));
211     mbedtls_ctr_drbg_init(&(tlsConfig->ctrDrbgCtx));
212     mbedtls_x509_crt_init(&(tlsConfig->caCert));
213     mbedtls_entropy_init(&(tlsConfig->entropyCtx));
214     int32_t ret = mbedtls_ctr_drbg_seed(&(tlsConfig->ctrDrbgCtx), mbedtls_entropy_func,
215         &(tlsConfig->entropyCtx), (const uint8_t *)session->entropySeed, strlen(session->entropySeed));
216     if (ret != 0) {
217         ATTEST_LOG_ERROR("[TLSConnect] Generate DRGB seed failed, ret = -0x%x.", -ret);
218         return ERR_NET_DRBG_SEED_FAIL;
219     }
220     if ((ret = LoadCommonCert(&(tlsConfig->caCert))) != 0) {
221         ATTEST_LOG_ERROR("[TLSConnect] TLS load cert failed, ret = -0x%x.", -ret);
222         return ret;
223     }
224 
225     ret = mbedtls_net_connect(&(tlsConfig->netCtx),
226         session->serverInfo.hostName, session->serverInfo.port, MBEDTLS_NET_PROTO_TCP);
227     if (ret != 0) {
228         ATTEST_LOG_ERROR("[TLSConnect] Connect to server failed, ret = -0x%x.", -ret);
229         return ERR_NET_CONNECT_FAIL;
230     }
231     ret = mbedtls_net_set_nonblock(&(tlsConfig->netCtx));
232     if (ret != 0) {
233         ATTEST_LOG_ERROR("[TLSConnect] Set non block failed, ret = -0x%x.", -ret);
234         return ERR_NET_SET_NON_BLOCK_FAIL;
235     }
236     ret = TLSSetupConfig(session);
237     if (ret != 0) {
238         ATTEST_LOG_ERROR("[TLSConnect] Set TLS session failed, ret = -0x%x.", -ret);
239         return ERR_NET_SETUP_FAIL;
240     }
241 
242     while ((ret = mbedtls_ssl_handshake(&(tlsConfig->sslCtx))) != 0) {
243         if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE &&
244             ret != MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) {
245             ATTEST_LOG_ERROR("[TLSConnect] Handshake with server failed, ret = -0x%x.", -ret);
246             return ERR_NET_HANDSHAKE_FAIL;
247         }
248     }
249     ATTEST_LOG_DEBUG("[TLSConnect] End.");
250     return ATTEST_OK;
251 }
252 
TLSWrite(const TLSSession * session,const uint8_t * buf,size_t len)253 int32_t TLSWrite(const TLSSession* session, const uint8_t* buf, size_t len)
254 {
255     if (session == NULL || buf == NULL || len > MAX_REQUEST_SIZE) {
256         return ERR_NET_INVALID_ARG;
257     }
258     size_t writeLen = 0;
259     while (writeLen < len) {
260         int32_t ret = mbedtls_ssl_write((mbedtls_ssl_context *)&(session->tlsConfig.sslCtx),
261                                         (uint8_t*)(buf + writeLen), len - writeLen);
262         if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE &&
263             ret != MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) {
264             ATTEST_LOG_ERROR("[TLSWrite] Write to server failed, ret = -0x%x.", -ret);
265             return ERR_NET_WRITE_FAIL;
266         }
267         if (ret >= 0) {
268             writeLen += ret;
269         }
270     }
271     return ATTEST_OK;
272 }
273 
TLSRead(const TLSSession * session,uint8_t * buf,size_t len)274 int32_t TLSRead(const TLSSession* session, uint8_t* buf, size_t len)
275 {
276     if (session == NULL || buf == NULL || len == 0) {
277         return ERR_NET_INVALID_ARG;
278     }
279     size_t readLen = 0;
280     while (readLen < len) {
281         int32_t ret = mbedtls_ssl_read((mbedtls_ssl_context *)&(session->tlsConfig.sslCtx), (uint8_t*)(buf + readLen),
282                                        len - readLen);
283         if (ret < 0 && ret != MBEDTLS_ERR_SSL_TIMEOUT && ret != MBEDTLS_ERR_SSL_WANT_READ &&
284             ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret != MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) {
285             return ERR_NET_READ_FAIL;
286         }
287         if (ret >= 0) {
288             readLen += ret;
289         }
290     }
291     return ATTEST_OK;
292 }
293 
TLSClose(TLSSession * session)294 int32_t TLSClose(TLSSession* session)
295 {
296     if (session == NULL) {
297         return ATTEST_ERR;
298     }
299     int32_t ret;
300     TLSConfig* tlsConfig = &(session->tlsConfig);
301     do {
302         ret = mbedtls_ssl_close_notify(&(tlsConfig->sslCtx));
303     } while (ret == MBEDTLS_ERR_SSL_WANT_WRITE);
304     mbedtls_net_free(&(tlsConfig->netCtx));
305     mbedtls_x509_crt_free(&(tlsConfig->caCert));
306     mbedtls_ssl_free(&(tlsConfig->sslCtx));
307     mbedtls_ssl_config_free(&(tlsConfig->sslConf));
308     mbedtls_ctr_drbg_free(&(tlsConfig->ctrDrbgCtx));
309     mbedtls_entropy_free(&(tlsConfig->entropyCtx));
310     return ret;
311 }
312