dtls_server.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /*
  2. * Simple DTLS server demonstration program
  3. *
  4. * Copyright The Mbed TLS Contributors
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  8. * not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. */
  19. #include "mbedtls/build_info.h"
  20. #include "mbedtls/platform.h"
  21. /* Uncomment out the following line to default to IPv4 and disable IPv6 */
  22. //#define FORCE_IPV4
  23. #ifdef FORCE_IPV4
  24. #define BIND_IP "0.0.0.0" /* Forces IPv4 */
  25. #else
  26. #define BIND_IP "::"
  27. #endif
  28. #if !defined(MBEDTLS_SSL_SRV_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) || \
  29. !defined(MBEDTLS_SSL_COOKIE_C) || !defined(MBEDTLS_NET_C) || \
  30. !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_CTR_DRBG_C) || \
  31. !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_RSA_C) || \
  32. !defined(MBEDTLS_PEM_PARSE_C) || !defined(MBEDTLS_TIMING_C)
  33. int main(void)
  34. {
  35. printf("MBEDTLS_SSL_SRV_C and/or MBEDTLS_SSL_PROTO_DTLS and/or "
  36. "MBEDTLS_SSL_COOKIE_C and/or MBEDTLS_NET_C and/or "
  37. "MBEDTLS_ENTROPY_C and/or MBEDTLS_CTR_DRBG_C and/or "
  38. "MBEDTLS_X509_CRT_PARSE_C and/or MBEDTLS_RSA_C and/or "
  39. "MBEDTLS_PEM_PARSE_C and/or MBEDTLS_TIMING_C not defined.\n");
  40. mbedtls_exit(0);
  41. }
  42. #else
  43. #if defined(_WIN32)
  44. #include <windows.h>
  45. #endif
  46. #include <string.h>
  47. #include <stdlib.h>
  48. #include <stdio.h>
  49. #include "mbedtls/entropy.h"
  50. #include "mbedtls/ctr_drbg.h"
  51. #include "mbedtls/x509.h"
  52. #include "mbedtls/ssl.h"
  53. #include "mbedtls/ssl_cookie.h"
  54. #include "mbedtls/net_sockets.h"
  55. #include "mbedtls/error.h"
  56. #include "mbedtls/debug.h"
  57. #include "mbedtls/timing.h"
  58. #include "test/certs.h"
  59. #if defined(MBEDTLS_SSL_CACHE_C)
  60. #include "mbedtls/ssl_cache.h"
  61. #endif
  62. #define READ_TIMEOUT_MS 10000 /* 10 seconds */
  63. #define DEBUG_LEVEL 0
  64. static void my_debug(void *ctx, int level,
  65. const char *file, int line,
  66. const char *str)
  67. {
  68. ((void) level);
  69. mbedtls_fprintf((FILE *) ctx, "%s:%04d: %s", file, line, str);
  70. fflush((FILE *) ctx);
  71. }
  72. int main(void)
  73. {
  74. int ret, len;
  75. mbedtls_net_context listen_fd, client_fd;
  76. unsigned char buf[1024];
  77. const char *pers = "dtls_server";
  78. unsigned char client_ip[16] = { 0 };
  79. size_t cliip_len;
  80. mbedtls_ssl_cookie_ctx cookie_ctx;
  81. mbedtls_entropy_context entropy;
  82. mbedtls_ctr_drbg_context ctr_drbg;
  83. mbedtls_ssl_context ssl;
  84. mbedtls_ssl_config conf;
  85. mbedtls_x509_crt srvcert;
  86. mbedtls_pk_context pkey;
  87. mbedtls_timing_delay_context timer;
  88. #if defined(MBEDTLS_SSL_CACHE_C)
  89. mbedtls_ssl_cache_context cache;
  90. #endif
  91. mbedtls_net_init(&listen_fd);
  92. mbedtls_net_init(&client_fd);
  93. mbedtls_ssl_init(&ssl);
  94. mbedtls_ssl_config_init(&conf);
  95. mbedtls_ssl_cookie_init(&cookie_ctx);
  96. #if defined(MBEDTLS_SSL_CACHE_C)
  97. mbedtls_ssl_cache_init(&cache);
  98. #endif
  99. mbedtls_x509_crt_init(&srvcert);
  100. mbedtls_pk_init(&pkey);
  101. mbedtls_entropy_init(&entropy);
  102. mbedtls_ctr_drbg_init(&ctr_drbg);
  103. #if defined(MBEDTLS_DEBUG_C)
  104. mbedtls_debug_set_threshold(DEBUG_LEVEL);
  105. #endif
  106. /*
  107. * 1. Seed the RNG
  108. */
  109. printf(" . Seeding the random number generator...");
  110. fflush(stdout);
  111. if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
  112. (const unsigned char *) pers,
  113. strlen(pers))) != 0) {
  114. printf(" failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret);
  115. goto exit;
  116. }
  117. printf(" ok\n");
  118. /*
  119. * 2. Load the certificates and private RSA key
  120. */
  121. printf("\n . Loading the server cert. and key...");
  122. fflush(stdout);
  123. /*
  124. * This demonstration program uses embedded test certificates.
  125. * Instead, you may want to use mbedtls_x509_crt_parse_file() to read the
  126. * server and CA certificates, as well as mbedtls_pk_parse_keyfile().
  127. */
  128. ret = mbedtls_x509_crt_parse(&srvcert, (const unsigned char *) mbedtls_test_srv_crt,
  129. mbedtls_test_srv_crt_len);
  130. if (ret != 0) {
  131. printf(" failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret);
  132. goto exit;
  133. }
  134. ret = mbedtls_x509_crt_parse(&srvcert, (const unsigned char *) mbedtls_test_cas_pem,
  135. mbedtls_test_cas_pem_len);
  136. if (ret != 0) {
  137. printf(" failed\n ! mbedtls_x509_crt_parse returned %d\n\n", ret);
  138. goto exit;
  139. }
  140. ret = mbedtls_pk_parse_key(&pkey,
  141. (const unsigned char *) mbedtls_test_srv_key,
  142. mbedtls_test_srv_key_len,
  143. NULL,
  144. 0,
  145. mbedtls_ctr_drbg_random,
  146. &ctr_drbg);
  147. if (ret != 0) {
  148. printf(" failed\n ! mbedtls_pk_parse_key returned %d\n\n", ret);
  149. goto exit;
  150. }
  151. printf(" ok\n");
  152. /*
  153. * 3. Setup the "listening" UDP socket
  154. */
  155. printf(" . Bind on udp/*/4433 ...");
  156. fflush(stdout);
  157. if ((ret = mbedtls_net_bind(&listen_fd, BIND_IP, "4433", MBEDTLS_NET_PROTO_UDP)) != 0) {
  158. printf(" failed\n ! mbedtls_net_bind returned %d\n\n", ret);
  159. goto exit;
  160. }
  161. printf(" ok\n");
  162. /*
  163. * 4. Setup stuff
  164. */
  165. printf(" . Setting up the DTLS data...");
  166. fflush(stdout);
  167. if ((ret = mbedtls_ssl_config_defaults(&conf,
  168. MBEDTLS_SSL_IS_SERVER,
  169. MBEDTLS_SSL_TRANSPORT_DATAGRAM,
  170. MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
  171. mbedtls_printf(" failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret);
  172. goto exit;
  173. }
  174. mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
  175. mbedtls_ssl_conf_dbg(&conf, my_debug, stdout);
  176. mbedtls_ssl_conf_read_timeout(&conf, READ_TIMEOUT_MS);
  177. #if defined(MBEDTLS_SSL_CACHE_C)
  178. mbedtls_ssl_conf_session_cache(&conf, &cache,
  179. mbedtls_ssl_cache_get,
  180. mbedtls_ssl_cache_set);
  181. #endif
  182. mbedtls_ssl_conf_ca_chain(&conf, srvcert.next, NULL);
  183. if ((ret = mbedtls_ssl_conf_own_cert(&conf, &srvcert, &pkey)) != 0) {
  184. printf(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret);
  185. goto exit;
  186. }
  187. if ((ret = mbedtls_ssl_cookie_setup(&cookie_ctx,
  188. mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) {
  189. printf(" failed\n ! mbedtls_ssl_cookie_setup returned %d\n\n", ret);
  190. goto exit;
  191. }
  192. mbedtls_ssl_conf_dtls_cookies(&conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check,
  193. &cookie_ctx);
  194. if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
  195. printf(" failed\n ! mbedtls_ssl_setup returned %d\n\n", ret);
  196. goto exit;
  197. }
  198. mbedtls_ssl_set_timer_cb(&ssl, &timer, mbedtls_timing_set_delay,
  199. mbedtls_timing_get_delay);
  200. printf(" ok\n");
  201. reset:
  202. #ifdef MBEDTLS_ERROR_C
  203. if (ret != 0) {
  204. char error_buf[100];
  205. mbedtls_strerror(ret, error_buf, 100);
  206. printf("Last error was: %d - %s\n\n", ret, error_buf);
  207. }
  208. #endif
  209. mbedtls_net_free(&client_fd);
  210. mbedtls_ssl_session_reset(&ssl);
  211. /*
  212. * 3. Wait until a client connects
  213. */
  214. printf(" . Waiting for a remote connection ...");
  215. fflush(stdout);
  216. if ((ret = mbedtls_net_accept(&listen_fd, &client_fd,
  217. client_ip, sizeof(client_ip), &cliip_len)) != 0) {
  218. printf(" failed\n ! mbedtls_net_accept returned %d\n\n", ret);
  219. goto exit;
  220. }
  221. /* For HelloVerifyRequest cookies */
  222. if ((ret = mbedtls_ssl_set_client_transport_id(&ssl,
  223. client_ip, cliip_len)) != 0) {
  224. printf(" failed\n ! "
  225. "mbedtls_ssl_set_client_transport_id() returned -0x%x\n\n", (unsigned int) -ret);
  226. goto exit;
  227. }
  228. mbedtls_ssl_set_bio(&ssl, &client_fd,
  229. mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout);
  230. printf(" ok\n");
  231. /*
  232. * 5. Handshake
  233. */
  234. printf(" . Performing the DTLS handshake...");
  235. fflush(stdout);
  236. do {
  237. ret = mbedtls_ssl_handshake(&ssl);
  238. } while (ret == MBEDTLS_ERR_SSL_WANT_READ ||
  239. ret == MBEDTLS_ERR_SSL_WANT_WRITE);
  240. if (ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) {
  241. printf(" hello verification requested\n");
  242. ret = 0;
  243. goto reset;
  244. } else if (ret != 0) {
  245. printf(" failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", (unsigned int) -ret);
  246. goto reset;
  247. }
  248. printf(" ok\n");
  249. /*
  250. * 6. Read the echo Request
  251. */
  252. printf(" < Read from client:");
  253. fflush(stdout);
  254. len = sizeof(buf) - 1;
  255. memset(buf, 0, sizeof(buf));
  256. do {
  257. ret = mbedtls_ssl_read(&ssl, buf, len);
  258. } while (ret == MBEDTLS_ERR_SSL_WANT_READ ||
  259. ret == MBEDTLS_ERR_SSL_WANT_WRITE);
  260. if (ret <= 0) {
  261. switch (ret) {
  262. case MBEDTLS_ERR_SSL_TIMEOUT:
  263. printf(" timeout\n\n");
  264. goto reset;
  265. case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
  266. printf(" connection was closed gracefully\n");
  267. ret = 0;
  268. goto close_notify;
  269. default:
  270. printf(" mbedtls_ssl_read returned -0x%x\n\n", (unsigned int) -ret);
  271. goto reset;
  272. }
  273. }
  274. len = ret;
  275. printf(" %d bytes read\n\n%s\n\n", len, buf);
  276. /*
  277. * 7. Write the 200 Response
  278. */
  279. printf(" > Write to client:");
  280. fflush(stdout);
  281. do {
  282. ret = mbedtls_ssl_write(&ssl, buf, len);
  283. } while (ret == MBEDTLS_ERR_SSL_WANT_READ ||
  284. ret == MBEDTLS_ERR_SSL_WANT_WRITE);
  285. if (ret < 0) {
  286. printf(" failed\n ! mbedtls_ssl_write returned %d\n\n", ret);
  287. goto exit;
  288. }
  289. len = ret;
  290. printf(" %d bytes written\n\n%s\n\n", len, buf);
  291. /*
  292. * 8. Done, cleanly close the connection
  293. */
  294. close_notify:
  295. printf(" . Closing the connection...");
  296. /* No error checking, the connection might be closed already */
  297. do {
  298. ret = mbedtls_ssl_close_notify(&ssl);
  299. } while (ret == MBEDTLS_ERR_SSL_WANT_WRITE);
  300. ret = 0;
  301. printf(" done\n");
  302. goto reset;
  303. /*
  304. * Final clean-ups and exit
  305. */
  306. exit:
  307. #ifdef MBEDTLS_ERROR_C
  308. if (ret != 0) {
  309. char error_buf[100];
  310. mbedtls_strerror(ret, error_buf, 100);
  311. printf("Last error was: %d - %s\n\n", ret, error_buf);
  312. }
  313. #endif
  314. mbedtls_net_free(&client_fd);
  315. mbedtls_net_free(&listen_fd);
  316. mbedtls_x509_crt_free(&srvcert);
  317. mbedtls_pk_free(&pkey);
  318. mbedtls_ssl_free(&ssl);
  319. mbedtls_ssl_config_free(&conf);
  320. mbedtls_ssl_cookie_free(&cookie_ctx);
  321. #if defined(MBEDTLS_SSL_CACHE_C)
  322. mbedtls_ssl_cache_free(&cache);
  323. #endif
  324. mbedtls_ctr_drbg_free(&ctr_drbg);
  325. mbedtls_entropy_free(&entropy);
  326. /* Shell can not handle large exit numbers -> 1 for errors */
  327. if (ret < 0) {
  328. ret = 1;
  329. }
  330. mbedtls_exit(ret);
  331. }
  332. #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_PROTO_DTLS &&
  333. MBEDTLS_SSL_COOKIE_C && MBEDTLS_NET_C && MBEDTLS_ENTROPY_C &&
  334. MBEDTLS_CTR_DRBG_C && MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_RSA_C
  335. && MBEDTLS_PEM_PARSE_C && MBEDTLS_TIMING_C */