• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2020 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 "tls_client.h"
17 
18 #include <stdio.h>
19 #include <string.h>
20 #include "securec.h"
21 //#include "securec.h"
22 #include "tls_certificate.h"
23 #include "mbedtls_log.h"
24 
25 #include "mbedtls/build_info.h"
26 
SslDebug(void * ctx,int level,const char * file,int line,const char * str)27 static void SslDebug(void *ctx, int level, const char *file, int line, const char *str)
28 {
29     LOGD("%s:%04d: %s.", file, line, str);
30 }
31 
MbedtlsSslCertificateVerify(MbedTLSSession * session)32 static int MbedtlsSslCertificateVerify(MbedTLSSession *session)
33 {
34     if (session == NULL) {
35         return -RET_ERROR;
36     }
37     int ret = mbedtls_ssl_get_verify_result(&session->ssl);
38     if (ret != 0) {
39         LOGD("verify peer certificate fail...");
40         (void)memset_s(session->buffer, session->buffer_len, 0x00, session->buffer_len);
41         mbedtls_x509_crt_verify_info((char *)session->buffer, session->buffer_len, "  ! ", ret);
42         LOGD("verification info: %s.", session->buffer);
43         return -RET_ERROR;
44     }
45     return RET_EOK;
46 }
47 
MbedtlsClientInit(MbedTLSSession * session,void * entropy,size_t entropyLen)48 int MbedtlsClientInit(MbedTLSSession *session, void *entropy, size_t entropyLen)
49 {
50     if (session == NULL || entropy == NULL) {
51         return -RET_ERROR;
52     }
53     mbedtls_net_init(&session->server_fd);
54     mbedtls_ssl_init(&session->ssl);
55     mbedtls_ssl_config_init(&session->conf);
56     mbedtls_ctr_drbg_init(&session->ctr_drbg);
57     mbedtls_entropy_init(&session->entropy);
58     mbedtls_x509_crt_init(&session->cacert);
59     int ret = mbedtls_ctr_drbg_seed(&session->ctr_drbg, mbedtls_entropy_func, &session->entropy,
60                                     (unsigned char *)entropy, entropyLen);
61     if (ret != 0) {
62         LOGD("mbedtls_ctr_drbg_seed error, return -0x%x.", -ret);
63         return ret;
64     }
65     LOGD("mbedtls client struct init success...");
66     return RET_EOK;
67 }
68 
MbedtlsClientClose(MbedTLSSession * session)69 int MbedtlsClientClose(MbedTLSSession *session)
70 {
71     if (session == NULL) {
72         return -RET_ERROR;
73     }
74     mbedtls_ssl_close_notify(&session->ssl);
75     mbedtls_net_free(&session->server_fd);
76     mbedtls_x509_crt_free(&session->cacert);
77     mbedtls_entropy_free(&session->entropy);
78     mbedtls_ctr_drbg_free(&session->ctr_drbg);
79     mbedtls_ssl_config_free(&session->conf);
80     mbedtls_ssl_free(&session->ssl);
81     LOGD("MbedTLS connection close success.");
82     return RET_EOK;
83 }
84 
MbedtlsClientContext(MbedTLSSession * session)85 int MbedtlsClientContext(MbedTLSSession *session)
86 {
87     if (session == NULL) {
88         return -RET_ERROR;
89     }
90     int ret = mbedtls_x509_crt_parse(&session->cacert, (const unsigned char *)G_MBEDTLS_ROOT_CERTIFICATE,
91                                      G_MBEDTLS_ROOT_CERTIFICATE_LEN);
92     if (ret < 0) {
93         LOGE("mbedtls_x509_crt_parse error,  return -0x%x.", -ret);
94         return ret;
95     }
96 
97     LOGD("Loading the CA root certificate success...");
98 
99     // Hostname set here should match CN in server certificate
100     if (session->host != NULL) {
101         ret = mbedtls_ssl_set_hostname(&session->ssl, session->host);
102         if (ret != 0) {
103             LOGD("mbedtls_ssl_set_hostname error, return -0x%x", -ret);
104             return ret;
105         }
106     }
107 
108     ret = mbedtls_ssl_config_defaults(&session->conf,
109                                       MBEDTLS_SSL_IS_CLIENT,
110                                       MBEDTLS_SSL_TRANSPORT_STREAM,
111                                       MBEDTLS_SSL_PRESET_DEFAULT);
112     if (ret != 0) {
113         LOGD("mbedtls_ssl_config_defaults error, return -0x%x.", -ret);
114         return ret;
115     }
116 
117     // If you want to verify the validity of the server certificate,
118     // you need to replace MBEDTLS_SSL_VERIFY_NONE with MBEDTLS_SSL_VERIFY_REQUIRED
119     mbedtls_ssl_conf_authmode(&session->conf, MBEDTLS_SSL_VERIFY_NONE);
120     mbedtls_ssl_conf_ca_chain(&session->conf, &session->cacert, NULL);
121     mbedtls_ssl_conf_rng(&session->conf, mbedtls_ctr_drbg_random, &session->ctr_drbg);
122     mbedtls_ssl_conf_dbg(&session->conf, SslDebug, NULL);
123     ret = mbedtls_ssl_setup(&session->ssl, &session->conf);
124     if (ret != 0) {
125         LOGD("mbedtls_ssl_setup error, return -0x%x.", -ret);
126         return ret;
127     }
128     LOGD("mbedtls client context init success...");
129 
130     return RET_EOK;
131 }
132 
MbedtlsClientConnect(MbedTLSSession * session)133 int MbedtlsClientConnect(MbedTLSSession *session)
134 {
135     if (session == NULL) {
136         return -RET_ERROR;
137     }
138     LOGI("connect: host:%s, port: %s", session->host, session->port);
139 
140     int ret = mbedtls_net_connect(&session->server_fd, session->host, session->port, MBEDTLS_NET_PROTO_TCP);
141     if (ret != 0) {
142         LOGD("mbedtls_net_connect error, return -0x%x.", -ret);
143         return ret;
144     }
145     LOGD("Connected %s:%s fd:%d, success...", session->host, session->port, session->server_fd.fd);
146 
147     mbedtls_ssl_set_bio(&session->ssl, &session->server_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
148     LOGD("ssl state=%d", session->ssl.state);
149 
150     while ((ret = mbedtls_ssl_handshake(&session->ssl)) != 0) {
151         LOGD("mbedtls_ssl_handshake ret=0x%x.", -ret);
152         if (RET_EOK != MbedtlsSslCertificateVerify(session)) {
153             return -RET_ERROR;
154         }
155         if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
156             LOGD("mbedtls_ssl_handshake error, return -0x%x.", -ret);
157             return ret;
158         }
159     }
160 
161     if (RET_EOK != MbedtlsSslCertificateVerify(session)) {
162         LOGD("Certificate verified err...");
163         return -RET_ERROR;
164     }
165 
166     LOGD("Certificate verified success...");
167 
168     return RET_EOK;
169 }
170 
MbedtlsClientRead(MbedTLSSession * session,unsigned char * buf,size_t len)171 int MbedtlsClientRead(MbedTLSSession *session, unsigned char *buf, size_t len)
172 {
173     if (session == NULL || buf == NULL) {
174         return -RET_ERROR;
175     }
176     int ret = mbedtls_ssl_read(&session->ssl, (unsigned char *)buf, len);
177     if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
178         LOGD("MbedtlsClientRead data error, return -0x%x.", -ret);
179     }
180     return ret;
181 }
182 
MbedtlsClientWrite(MbedTLSSession * session,const unsigned char * buf,size_t len)183 int MbedtlsClientWrite(MbedTLSSession *session, const unsigned char *buf, size_t len)
184 {
185     if (session == NULL || buf == NULL) {
186         return -RET_ERROR;
187     }
188     int ret = mbedtls_ssl_write(&session->ssl, (unsigned char *)buf, len);
189     if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
190         LOGD("MbedtlsClientWrite data error, return -0x%x.", -ret);
191     }
192     return ret;
193 }