corrected copyright notices
[gnutls.git] / tests / mini-dtls-srtp.c
blob11bf746275a3db4ea5c57b0b142bf27ba46aa92a
1 /*
2 * Copyright (C) 2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * GnuTLS is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * GnuTLS is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with GnuTLS; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
27 #include <stdio.h>
28 #include <stdlib.h>
30 #if defined(_WIN32) || !defined(ENABLE_DTLS_SRTP)
32 int
33 main (int argc, char** argv)
35 exit (77);
38 #else
40 #include <string.h>
41 #include <sys/types.h>
42 #include <netinet/in.h>
43 #include <sys/socket.h>
44 #include <sys/wait.h>
45 #include <arpa/inet.h>
46 #include <unistd.h>
47 #include <gnutls/gnutls.h>
48 #include <gnutls/dtls.h>
50 #include "utils.h"
52 static void terminate (void);
54 /* This program tests the rehandshake in DTLS
57 static void
58 server_log_func (int level, const char *str)
60 fprintf (stderr, "server|<%d>| %s", level, str);
63 static void
64 client_log_func (int level, const char *str)
66 fprintf (stderr, "client|<%d>| %s", level, str);
69 /* These are global */
70 static pid_t child;
72 #define MAX_KEY_MATERIAL 64*4
73 /* A very basic DTLS client, with anonymous authentication, that negotiates SRTP
76 static void
77 client (int fd, int profile)
79 gnutls_session_t session;
80 int ret;
81 gnutls_anon_client_credentials_t anoncred;
82 uint8_t km[MAX_KEY_MATERIAL];
83 char buf[2*MAX_KEY_MATERIAL];
84 gnutls_datum_t cli_key, cli_salt, server_key, server_salt;
85 /* Need to enable anonymous KX specifically. */
87 gnutls_global_init ();
89 if (debug)
91 gnutls_global_set_log_function (client_log_func);
92 gnutls_global_set_log_level (4711);
95 gnutls_anon_allocate_client_credentials (&anoncred);
97 /* Initialize TLS session
99 gnutls_init (&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM);
100 gnutls_heartbeat_enable (session, GNUTLS_HB_PEER_ALLOWED_TO_SEND);
101 gnutls_dtls_set_mtu (session, 1500);
103 /* Use default priorities */
104 gnutls_priority_set_direct (session,
105 "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL",
106 NULL);
107 if (profile)
108 ret = gnutls_srtp_set_profile_direct(session, "SRTP_AES128_CM_HMAC_SHA1_80",
109 NULL);
110 else
111 ret = gnutls_srtp_set_profile_direct(session, "SRTP_NULL_HMAC_SHA1_80",
112 NULL);
113 if (ret < 0)
115 gnutls_perror(ret);
116 exit(1);
120 /* put the anonymous credentials to the current session
122 gnutls_credentials_set (session, GNUTLS_CRD_ANON, anoncred);
124 gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) fd);
126 /* Perform the TLS handshake
130 ret = gnutls_handshake (session);
132 while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
134 if (ret < 0)
136 fail ("client: Handshake failed\n");
137 gnutls_perror (ret);
138 exit (1);
140 else
142 if (debug)
143 success ("client: Handshake was completed\n");
146 if (debug)
147 success ("client: DTLS version is: %s\n",
148 gnutls_protocol_get_name (gnutls_protocol_get_version
149 (session)));
151 ret = gnutls_srtp_get_keys (session, km, sizeof(km), &cli_key, &cli_salt, &server_key, &server_salt);
152 if (ret < 0)
154 gnutls_perror(ret);
155 exit(1);
158 if (debug)
160 size_t size = sizeof(buf);
161 gnutls_hex_encode(&cli_key, buf, &size);
162 success ("Client key: %s\n", buf);
164 size = sizeof(buf);
165 gnutls_hex_encode(&cli_salt, buf, &size);
166 success ("Client salt: %s\n", buf);
168 size = sizeof(buf);
169 gnutls_hex_encode(&server_key, buf, &size);
170 success ("Server key: %s\n", buf);
172 size = sizeof(buf);
173 gnutls_hex_encode(&server_salt, buf, &size);
174 success ("Server salt: %s\n", buf);
178 gnutls_bye (session, GNUTLS_SHUT_WR);
180 close (fd);
182 gnutls_deinit (session);
184 gnutls_anon_free_client_credentials (anoncred);
186 gnutls_global_deinit ();
189 static void
190 terminate (void)
192 int status;
194 kill (child, SIGTERM);
195 wait (&status);
196 exit (1);
199 static void
200 server (int fd, int profile)
202 int ret;
203 gnutls_session_t session;
204 gnutls_anon_server_credentials_t anoncred;
205 uint8_t km[MAX_KEY_MATERIAL];
206 char buf[2*MAX_KEY_MATERIAL];
207 gnutls_datum_t cli_key, cli_salt, server_key, server_salt;
209 /* this must be called once in the program
211 gnutls_global_init ();
213 if (debug)
215 gnutls_global_set_log_function (server_log_func);
216 gnutls_global_set_log_level (4711);
219 gnutls_anon_allocate_server_credentials (&anoncred);
221 gnutls_init (&session, GNUTLS_SERVER | GNUTLS_DATAGRAM);
222 gnutls_heartbeat_enable (session, GNUTLS_HB_PEER_ALLOWED_TO_SEND);
223 gnutls_dtls_set_mtu (session, 1500);
225 /* avoid calling all the priority functions, since the defaults
226 * are adequate.
228 gnutls_priority_set_direct (session,
229 "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL",
230 NULL);
232 if (profile)
233 ret = gnutls_srtp_set_profile_direct(session, "SRTP_AES128_CM_HMAC_SHA1_80",
234 NULL);
235 else
236 ret = gnutls_srtp_set_profile_direct(session, "SRTP_NULL_HMAC_SHA1_80",
237 NULL);
238 if (ret < 0)
240 gnutls_perror(ret);
241 exit(1);
244 gnutls_credentials_set (session, GNUTLS_CRD_ANON, anoncred);
246 gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) fd);
250 ret = gnutls_handshake (session);
252 while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
253 if (ret < 0)
255 close (fd);
256 gnutls_deinit (session);
257 fail ("server: Handshake has failed (%s)\n\n",
258 gnutls_strerror (ret));
259 terminate ();
261 if (debug)
262 success ("server: Handshake was completed\n");
264 if (debug)
265 success ("server: TLS version is: %s\n",
266 gnutls_protocol_get_name (gnutls_protocol_get_version
267 (session)));
269 ret = gnutls_srtp_get_keys (session, km, sizeof(km), &cli_key, &cli_salt, &server_key, &server_salt);
270 if (ret < 0)
272 gnutls_perror(ret);
273 exit(1);
276 if (debug)
278 size_t size = sizeof(buf);
279 gnutls_hex_encode(&cli_key, buf, &size);
280 success ("Client key: %s\n", buf);
282 size = sizeof(buf);
283 gnutls_hex_encode(&cli_salt, buf, &size);
284 success ("Client salt: %s\n", buf);
286 size = sizeof(buf);
287 gnutls_hex_encode(&server_key, buf, &size);
288 success ("Server key: %s\n", buf);
290 size = sizeof(buf);
291 gnutls_hex_encode(&server_salt, buf, &size);
292 success ("Server salt: %s\n", buf);
295 /* do not wait for the peer to close the connection.
297 gnutls_bye (session, GNUTLS_SHUT_WR);
299 close (fd);
300 gnutls_deinit (session);
302 gnutls_anon_free_server_credentials (anoncred);
304 gnutls_global_deinit ();
306 if (debug)
307 success ("server: finished\n");
310 static void
311 start (int profile)
313 int fd[2];
314 int ret;
316 ret = socketpair (AF_UNIX, SOCK_DGRAM, 0, fd);
317 if (ret < 0)
319 perror ("socketpair");
320 exit (1);
323 child = fork ();
324 if (child < 0)
326 perror ("fork");
327 fail ("fork");
328 exit (1);
331 if (child)
333 int status;
334 /* parent */
336 server (fd[0], profile);
337 wait (&status);
338 if (WEXITSTATUS (status) != 0)
339 fail ("Child died with status %d\n", WEXITSTATUS (status));
341 else
343 close (fd[0]);
344 client (fd[1], profile);
345 exit (0);
349 void
350 doit (void)
352 start (0);
353 start (1);
356 #endif /* _WIN32 */