Loading...
Searching...
No Matches
sock_tls.h
1/*
2 * SPDX-FileCopyrightText: 2019 Daniele Lacamera
3 * SPDX-License-Identifier: LGPL-2.1-only
4 */
5
6#pragma once
7
8/* @defgroup module sock_tls
9 * @ingroup pkg_wolfssl
10 * @brief Sock submodule for TLS/DTLS sessions
11 *
12 * How To Use
13 * ----------
14 * First you need to [include][include-link]
15 * a module that implements this API in your application's Makefile.
16 *
17 * The `sock_tls` module requires the `wolfssl` package.
18 *
19 * The application's Makefile should at lease contain the following:
20 *
21 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {Makefile}
22 *
23 * USEPKG += wolfssl
24 * USEMODULE+=sock_tls
25 *
26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 *
28 *
29 * ### A Simple DTLS Server
30 *
31 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
32 * #include <wolfssl/ssl.h>
33 * #include <sock_tls.h>
34 *
35 * #include <stdio.h>
36 * #include <inttypes.h>
37 *
38 * #include <net/sock/udp.h>
39 *
40 * #include <stdio.h>
41 * #include <stdlib.h>
42 * #include <string.h>
43 *
44 * #define SERVER_PORT 11111
45 * #define DEBUG 1
46 * extern const unsigned char server_cert[788];
47 * extern const unsigned char server_key[121];
48 * extern unsigned int server_cert_len;
49 * extern unsigned int server_key_len;
50 *
51 * static sock_tls_t skv;
52 * static sock_tls_t *sk = &skv;
53 * static const char Test_dtls_string[] = "DTLS OK!";
54 *
55 * int main(void)
56 * {
57 * char buf[64];
58 * int ret;
59 * sock_udp_ep_t local = SOCK_IPV6_EP_ANY;
60 * local.port = SERVER_PORT;
61 *
62 * if (sock_dtls_create(sk, &local, NULL, 0, wolfDTLSv1_2_server_method()) != 0) {
63 * printf("Failed to create DTLS socket context\r\n");
64 * return -1;
65 * }
66 * if (wolfSSL_CTX_use_certificate_buffer(sk->ctx, server_cert,
67 * server_cert_len, SSL_FILETYPE_ASN1 ) != SSL_SUCCESS)
68 * {
69 * printf("Failed to load certificate from memory.\r\n");
70 * return -1;
71 * }
72 *
73 * if (wolfSSL_CTX_use_PrivateKey_buffer(sk->ctx, server_key,
74 * server_key_len, SSL_FILETYPE_ASN1 ) != SSL_SUCCESS)
75 * {
76 * printf("Failed to load private key from memory.\r\n");
77 * return -1;
78 * }
79 * ret = sock_dtls_session_create(sk);
80 * if (ret < 0)
81 * {
82 * printf("Failed to create DTLS session (err: %s)\r\n", strerror(-ret));
83 * return -1;
84 * }
85 * printf("Listening on %d\n", SERVER_PORT);
86 * while(1) {
87 * ret = wolfSSL_accept(sk->ssl);
88 * if (ret != SSL_SUCCESS) {
89 * continue;
90 * }
91 * printf("Connection accepted\r\n");
92 * ret = wolfSSL_read(sk->ssl, buf, 64);
93 * if (ret > 0) {
94 * buf[ret] = (char)0;
95 * printf("Received '%s'\r\n", buf);
96 * }
97 * printf("Sending 'DTLS OK'...\r\n");
98 * wolfSSL_write(sk->ssl, Test_dtls_string, sizeof(Test_dtls_string));
99 * printf("Closing connection.\r\n");
100 * sock_dtls_session_destroy(sk);
101 * sock_dtls_close(sk);
102 * break;
103 * }
104 * return 0;
105 * }
106 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
107 *
108 * Above you see a simple DTLS echo server. It is important to at least
109 * [include][include-link] the IPv6 module of your networking
110 * implementation (e.g. `gnrc_ipv6_default` for @ref net_gnrc GNRC) and at least
111 * one network device.
112 * A separate file should define the buffers used as certificate and private key,
113 * in the variables `server_cert`, `private_key` respectively.
114 *
115 * After including all the needed header files, we use a global object to store
116 * the context for incoming DTLS communication. The object contains the reference
117 * to the wolfSSL context, the SSL session and the underlying transport socket.
118 *
119 * For simplicity, we will refer to the address of the object in the static memory,
120 * through the pointer `sk`.
121 *
122 * A constant test string is used later as a reply to incoming connections.
123 *
124 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
125 * static sock_tls_t skv;
126 * static sock_tls_t *sk = &skv;
127 *
128 * static const char Test_dtls_string[] = "DTLS OK!";
129 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
130 *
131 * In the same way as a normal @ref net_sock_udp "UDP socket", in order to be able to
132 * listen for incoming packets, we bind the `sock` by setting a local endpoint with
133 * a port (`11111` in this case).
134 *
135 * We then proceed to create the `sock`. It is bound to `local` and thus listens
136 * for UDP packets with @ref udp_hdr_t::dst_port "destination port" `12345`.
137 * Since we don't need any further configuration we set the flags to 0.
138 * The method argument determines which kind of wolfSSL context is associated to
139 * the socket.
140*
141 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
142 * sock_udp_ep_t local = SOCK_IPV6_EP_ANY;
143 * local.port = SERVER_PORT;
144 *
145 * if (sock_dtls_create(sk, &local, NULL, 0, wolfDTLSv1_2_server_method()) != 0) {
146 * printf("ERROR: Unable to create DTLS sock\r\n");
147 * return -1;
148 * }
149 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
150 *
151 * By default, all sock_tls operations in a DTLS context are blocking for a
152 * limited amount of time, which depends on the DTLS session timeout. To modify
153 * the timeout, use `wolfSSL_dtls_set_timeout_init(sk->ssl)`.
154 *
155 * Certificate and private key for the server context are loaded from a previously
156 * initialized section in memory:
157 *
158 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
159 * if (wolfSSL_CTX_use_certificate_buffer(sk->ctx, server_cert,
160 * server_cert_len, SSL_FILETYPE_ASN1 ) != SSL_SUCCESS)
161 * {
162 * printf("Failed to load certificate from memory.\r\n");
163 * return -1;
164 * }
165 *
166 * if (wolfSSL_CTX_use_PrivateKey_buffer(sk->ctx, server_key,
167 * server_key_len, SSL_FILETYPE_ASN1 ) != SSL_SUCCESS)
168 * {
169 * printf("Failed to load private key from memory.\r\n");
170 * return -1;
171 * }
172 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
173 *
174 * Once the context is configured, the SSL session can be initialized.
175 *
176 * The listening sock automatically takes care of the DTLS handshake.
177 * When the session is established, `wolfSSL_accept()` will finally return
178 * `SSL_SUCCESS`.
179 *
180 *
181 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
182 * ret = sock_dtls_session_create(sk);
183 * if (ret < 0)
184 * {
185 * printf("Failed to create DTLS session (err: %s)\r\n", strerror(-ret));
186 * return -1;
187 * }
188 * printf("Listening on %d\n", SERVER_PORT);
189 * while(1) {
190 * ret = wolfSSL_accept(sk->ssl);
191 * if (ret != SSL_SUCCESS) {
192 * continue;
193 * }
194 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
195 *
196 * At this point, the session is established, and encrypted data can be exchanged
197 * using `wolfSSL_read()` and `wolfSSL_write()`:
198 *
199 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
200 * ret = wolfSSL_read(sk->ssl, buf, 64);
201 * if (ret > 0) {
202 * buf[ret] = (char)0;
203 * printf("Received '%s'\r\n", buf);
204 * }
205 * printf("Sending 'DTLS OK'...\r\n");
206 * wolfSSL_write(sk->ssl, Test_dtls_string, sizeof(Test_dtls_string));
207 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
208 *
209 * The session is terminated, and the associated socket is closed.
210 *
211 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {.c}
212 * sock_dtls_session_destroy(sk);
213 * sock_dtls_close(sk);
214 * break;
215 * }
216 * return 0;
217 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
218 *
219 * [include-link]: https://guide.riot-os.org/advanced_tutorials/creating_application/#including-modules
220 */
221
222#include <string.h>
223#include <stdlib.h>
224#include <stdio.h>
225
226#include <net/sock.h>
227#include <wolfssl/ssl.h>
228
229#ifdef __cplusplus
230extern "C" {
231#endif
232
283int sock_dtls_create(sock_tls_t *sock, const sock_udp_ep_t *local,
284 const sock_udp_ep_t *remote, uint16_t flags, WOLFSSL_METHOD *method);
285
296void sock_dtls_set_endpoint(sock_tls_t *sk, const sock_udp_ep_t *addr);
297
310int sock_dtls_session_create(sock_tls_t *sk);
311
320void sock_dtls_session_destroy(sock_tls_t *sk);
321
330void sock_dtls_close(sock_tls_t *sk);
331
332#ifdef MODULE_SOCK_TCP
333# error Supports only UDP/IP provided via GNRC stack.
334#endif
335
336#ifdef __cplusplus
337}
338#endif
struct _sock_tl_ep sock_udp_ep_t
An end point for a UDP sock object.
Definition udp.h:292
Common sock API definitions.