xref: /nrf52832-nimble/rt-thread/components/net/sal_socket/impl/proto_mbedtls.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*
2*10465441SEvalZero  * Copyright (c) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero  *
4*10465441SEvalZero  * SPDX-License-Identifier: Apache-2.0
5*10465441SEvalZero  *
6*10465441SEvalZero  * Change Logs:
7*10465441SEvalZero  * Date           Author       Notes
8*10465441SEvalZero  * 2018-11-12     ChenYong     First version
9*10465441SEvalZero  */
10*10465441SEvalZero 
11*10465441SEvalZero #include <rtthread.h>
12*10465441SEvalZero 
13*10465441SEvalZero #ifdef RT_USING_DFS
14*10465441SEvalZero #include <dfs_posix.h>
15*10465441SEvalZero #endif
16*10465441SEvalZero 
17*10465441SEvalZero #ifdef SAL_USING_TLS
18*10465441SEvalZero #include <sal_tls.h>
19*10465441SEvalZero #endif
20*10465441SEvalZero #include <netdb.h>
21*10465441SEvalZero #include <sal.h>
22*10465441SEvalZero 
23*10465441SEvalZero #ifdef SAL_USING_TLS
24*10465441SEvalZero 
25*10465441SEvalZero #if !defined(MBEDTLS_CONFIG_FILE)
26*10465441SEvalZero #include <mbedtls/config.h>
27*10465441SEvalZero #else
28*10465441SEvalZero #include MBEDTLS_CONFIG_FILE
29*10465441SEvalZero #endif
30*10465441SEvalZero 
31*10465441SEvalZero #include <tls_certificate.h>
32*10465441SEvalZero #include <tls_client.h>
33*10465441SEvalZero 
34*10465441SEvalZero #ifndef SAL_MEBDTLS_BUFFER_LEN
35*10465441SEvalZero #define SAL_MEBDTLS_BUFFER_LEN         1024
36*10465441SEvalZero #endif
37*10465441SEvalZero 
mebdtls_socket(int socket)38*10465441SEvalZero static void *mebdtls_socket(int socket)
39*10465441SEvalZero {
40*10465441SEvalZero     MbedTLSSession *session = RT_NULL;
41*10465441SEvalZero     char *pers = "mbedtls";
42*10465441SEvalZero 
43*10465441SEvalZero     if (socket < 0)
44*10465441SEvalZero     {
45*10465441SEvalZero         return RT_NULL;
46*10465441SEvalZero     }
47*10465441SEvalZero 
48*10465441SEvalZero     session = (MbedTLSSession *) tls_calloc(1, sizeof(MbedTLSSession));
49*10465441SEvalZero     if (session == RT_NULL)
50*10465441SEvalZero     {
51*10465441SEvalZero         return RT_NULL;
52*10465441SEvalZero     }
53*10465441SEvalZero 
54*10465441SEvalZero     session->buffer_len = SAL_MEBDTLS_BUFFER_LEN;
55*10465441SEvalZero     session->buffer = tls_calloc(1, session->buffer_len);
56*10465441SEvalZero     if (session->buffer == RT_NULL)
57*10465441SEvalZero     {
58*10465441SEvalZero         tls_free(session);
59*10465441SEvalZero         session = RT_NULL;
60*10465441SEvalZero 
61*10465441SEvalZero         return RT_NULL;
62*10465441SEvalZero     }
63*10465441SEvalZero 
64*10465441SEvalZero     /* initialize TLS Client sesison */
65*10465441SEvalZero     if (mbedtls_client_init(session, (void *) pers, rt_strlen(pers)) != RT_EOK)
66*10465441SEvalZero     {
67*10465441SEvalZero         mbedtls_client_close(session);
68*10465441SEvalZero         return RT_NULL;
69*10465441SEvalZero     }
70*10465441SEvalZero     session->server_fd.fd = socket;
71*10465441SEvalZero 
72*10465441SEvalZero     return (void *)session;
73*10465441SEvalZero }
74*10465441SEvalZero 
mbedtls_net_send_cb(void * ctx,const unsigned char * buf,size_t len)75*10465441SEvalZero int mbedtls_net_send_cb(void *ctx, const unsigned char *buf, size_t len)
76*10465441SEvalZero {
77*10465441SEvalZero     struct sal_socket *sock;
78*10465441SEvalZero     int socket, ret;
79*10465441SEvalZero 
80*10465441SEvalZero     RT_ASSERT(ctx);
81*10465441SEvalZero     RT_ASSERT(buf);
82*10465441SEvalZero 
83*10465441SEvalZero     socket = ((mbedtls_net_context *) ctx)->fd;
84*10465441SEvalZero     sock = sal_get_socket(socket);
85*10465441SEvalZero     if (sock == RT_NULL)
86*10465441SEvalZero     {
87*10465441SEvalZero         return -1;
88*10465441SEvalZero     }
89*10465441SEvalZero 
90*10465441SEvalZero     /* Register scoket sendto option to TLS send data callback */
91*10465441SEvalZero     ret = sock->ops->sendto((int) sock->user_data, (void *)buf, len, 0, RT_NULL, RT_NULL);
92*10465441SEvalZero     if (ret < 0)
93*10465441SEvalZero     {
94*10465441SEvalZero #ifdef RT_USING_DFS
95*10465441SEvalZero         if ((fcntl(socket, F_GETFL) & O_NONBLOCK) == O_NONBLOCK)
96*10465441SEvalZero             return MBEDTLS_ERR_SSL_WANT_WRITE;
97*10465441SEvalZero #endif
98*10465441SEvalZero         if (errno == ECONNRESET)
99*10465441SEvalZero             return MBEDTLS_ERR_NET_CONN_RESET;
100*10465441SEvalZero         if ( errno == EINTR)
101*10465441SEvalZero             return MBEDTLS_ERR_SSL_WANT_READ;
102*10465441SEvalZero 
103*10465441SEvalZero         return MBEDTLS_ERR_NET_SEND_FAILED ;
104*10465441SEvalZero     }
105*10465441SEvalZero 
106*10465441SEvalZero     return ret;
107*10465441SEvalZero }
108*10465441SEvalZero 
mbedtls_net_recv_cb(void * ctx,unsigned char * buf,size_t len)109*10465441SEvalZero int mbedtls_net_recv_cb( void *ctx, unsigned char *buf, size_t len)
110*10465441SEvalZero {
111*10465441SEvalZero     struct sal_socket *sock;
112*10465441SEvalZero     int socket, ret;
113*10465441SEvalZero 
114*10465441SEvalZero     RT_ASSERT(ctx);
115*10465441SEvalZero     RT_ASSERT(buf);
116*10465441SEvalZero 
117*10465441SEvalZero     socket = ((mbedtls_net_context *) ctx)->fd;
118*10465441SEvalZero     sock = sal_get_socket(socket);
119*10465441SEvalZero     if (sock == RT_NULL)
120*10465441SEvalZero     {
121*10465441SEvalZero         return -1;
122*10465441SEvalZero     }
123*10465441SEvalZero 
124*10465441SEvalZero     /* Register scoket recvfrom option to TLS recv data callback */
125*10465441SEvalZero     ret = sock->ops->recvfrom((int) sock->user_data, (void *)buf, len, 0, RT_NULL, RT_NULL);
126*10465441SEvalZero     if (ret < 0)
127*10465441SEvalZero     {
128*10465441SEvalZero #ifdef RT_USING_DFS
129*10465441SEvalZero         if ((fcntl(socket, F_GETFL) & O_NONBLOCK) == O_NONBLOCK)
130*10465441SEvalZero             return MBEDTLS_ERR_SSL_WANT_WRITE;
131*10465441SEvalZero #endif
132*10465441SEvalZero         if (errno == ECONNRESET)
133*10465441SEvalZero             return MBEDTLS_ERR_NET_CONN_RESET;
134*10465441SEvalZero         if ( errno == EINTR)
135*10465441SEvalZero             return MBEDTLS_ERR_SSL_WANT_READ;
136*10465441SEvalZero 
137*10465441SEvalZero         return MBEDTLS_ERR_NET_RECV_FAILED ;
138*10465441SEvalZero     }
139*10465441SEvalZero 
140*10465441SEvalZero     return ret;
141*10465441SEvalZero }
142*10465441SEvalZero 
mbedtls_connect(void * sock)143*10465441SEvalZero static int mbedtls_connect(void *sock)
144*10465441SEvalZero {
145*10465441SEvalZero     MbedTLSSession *session = RT_NULL;
146*10465441SEvalZero     int ret = 0;
147*10465441SEvalZero 
148*10465441SEvalZero     RT_ASSERT(sock);
149*10465441SEvalZero 
150*10465441SEvalZero     session = (MbedTLSSession *) sock;
151*10465441SEvalZero 
152*10465441SEvalZero     /* Set the SSL Configure infromation */
153*10465441SEvalZero     ret = mbedtls_client_context(session);
154*10465441SEvalZero     if (ret < 0)
155*10465441SEvalZero     {
156*10465441SEvalZero         goto __exit;
157*10465441SEvalZero     }
158*10465441SEvalZero 
159*10465441SEvalZero     /* Set the underlying BIO callbacks for write, read and read-with-timeout.  */
160*10465441SEvalZero     mbedtls_ssl_set_bio(&session->ssl, &session->server_fd, mbedtls_net_send_cb, mbedtls_net_recv_cb, RT_NULL);
161*10465441SEvalZero 
162*10465441SEvalZero     while ((ret = mbedtls_ssl_handshake(&session->ssl)) != 0)
163*10465441SEvalZero     {
164*10465441SEvalZero         if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
165*10465441SEvalZero         {
166*10465441SEvalZero             goto __exit;
167*10465441SEvalZero         }
168*10465441SEvalZero     }
169*10465441SEvalZero 
170*10465441SEvalZero     /* Return the result of the certificate verification */
171*10465441SEvalZero     ret = mbedtls_ssl_get_verify_result(&session->ssl);
172*10465441SEvalZero     if (ret != 0)
173*10465441SEvalZero     {
174*10465441SEvalZero         rt_memset(session->buffer, 0x00, session->buffer_len);
175*10465441SEvalZero         mbedtls_x509_crt_verify_info((char *)session->buffer, session->buffer_len, "  ! ", ret);
176*10465441SEvalZero         goto __exit;
177*10465441SEvalZero     }
178*10465441SEvalZero 
179*10465441SEvalZero     return ret;
180*10465441SEvalZero 
181*10465441SEvalZero __exit:
182*10465441SEvalZero     if (session)
183*10465441SEvalZero     {
184*10465441SEvalZero         mbedtls_client_close(session);
185*10465441SEvalZero     }
186*10465441SEvalZero 
187*10465441SEvalZero     return ret;
188*10465441SEvalZero }
189*10465441SEvalZero 
mbedtls_closesocket(void * sock)190*10465441SEvalZero static int mbedtls_closesocket(void *sock)
191*10465441SEvalZero {
192*10465441SEvalZero     struct sal_socket *ssock;
193*10465441SEvalZero     int socket;
194*10465441SEvalZero 
195*10465441SEvalZero     if (sock == RT_NULL)
196*10465441SEvalZero     {
197*10465441SEvalZero         return 0;
198*10465441SEvalZero     }
199*10465441SEvalZero 
200*10465441SEvalZero     socket = ((MbedTLSSession *) sock)->server_fd.fd;
201*10465441SEvalZero     ssock = sal_get_socket(socket);
202*10465441SEvalZero     if (ssock == RT_NULL)
203*10465441SEvalZero     {
204*10465441SEvalZero         return -1;
205*10465441SEvalZero     }
206*10465441SEvalZero 
207*10465441SEvalZero     /* Close TLS client session, and clean user-data in SAL socket */
208*10465441SEvalZero     mbedtls_client_close((MbedTLSSession *) sock);
209*10465441SEvalZero     ssock->user_data_tls = RT_NULL;
210*10465441SEvalZero 
211*10465441SEvalZero     return 0;
212*10465441SEvalZero }
213*10465441SEvalZero 
214*10465441SEvalZero static const struct sal_proto_tls_ops mbedtls_proto_ops=
215*10465441SEvalZero {
216*10465441SEvalZero     RT_NULL,
217*10465441SEvalZero     mebdtls_socket,
218*10465441SEvalZero     mbedtls_connect,
219*10465441SEvalZero     (int (*)(void *sock, const void *data, size_t size)) mbedtls_client_write,
220*10465441SEvalZero     (int (*)(void *sock, void *mem, size_t len)) mbedtls_client_read,
221*10465441SEvalZero     mbedtls_closesocket,
222*10465441SEvalZero };
223*10465441SEvalZero 
224*10465441SEvalZero static const struct sal_proto_tls mbedtls_proto =
225*10465441SEvalZero {
226*10465441SEvalZero     "mbedtls",
227*10465441SEvalZero     &mbedtls_proto_ops,
228*10465441SEvalZero };
229*10465441SEvalZero 
sal_mbedtls_proto_init(void)230*10465441SEvalZero int sal_mbedtls_proto_init(void)
231*10465441SEvalZero {
232*10465441SEvalZero     /* register MbedTLS protocol options to SAL */
233*10465441SEvalZero     sal_proto_tls_register(&mbedtls_proto);
234*10465441SEvalZero 
235*10465441SEvalZero     return 0;
236*10465441SEvalZero }
237*10465441SEvalZero INIT_COMPONENT_EXPORT(sal_mbedtls_proto_init);
238*10465441SEvalZero 
239*10465441SEvalZero #endif /* SAL_USING_TLS */
240