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