proto_mbedtls.c 5.3 KB

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