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
41 #include <sys/types.h>
42 #include <netinet/in.h>
43 #include <sys/socket.h>
45 #include <arpa/inet.h>
47 #include <gnutls/gnutls.h>
48 #include <gnutls/dtls.h>
52 static void terminate (void);
54 /* This program tests the rehandshake in DTLS
58 server_log_func (int level
, const char *str
)
60 fprintf (stderr
, "server|<%d>| %s", level
, str
);
64 client_log_func (int level
, const char *str
)
66 fprintf (stderr
, "client|<%d>| %s", level
, str
);
69 /* These are global */
72 /* A very basic DTLS client, with anonymous authentication, that exchanges heartbeats.
79 client (int fd
, int server_init
)
81 gnutls_session_t session
;
83 char buffer
[MAX_BUF
+ 1];
84 gnutls_anon_client_credentials_t anoncred
;
85 /* Need to enable anonymous KX specifically. */
87 gnutls_global_init ();
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",
108 /* put the anonymous credentials to the current session
110 gnutls_credentials_set (session
, GNUTLS_CRD_ANON
, anoncred
);
112 gnutls_transport_set_ptr (session
, (gnutls_transport_ptr_t
) fd
);
114 /* Perform the TLS handshake
118 ret
= gnutls_handshake (session
);
120 while (ret
< 0 && gnutls_error_is_fatal (ret
) == 0);
124 fail ("client: Handshake failed\n");
131 success ("client: Handshake was completed\n");
135 success ("client: DTLS version is: %s\n",
136 gnutls_protocol_get_name (gnutls_protocol_get_version
144 gnutls_record_recv (session
, buffer
, sizeof (buffer
));
146 if (ret
== GNUTLS_E_HEARTBEAT_PING_RECEIVED
)
149 success ("Ping received. Replying with pong.\n");
150 ret2
= gnutls_heartbeat_pong (session
, 0);
153 fail ("pong: %s\n", gnutls_strerror (ret
));
158 while (ret
== GNUTLS_E_AGAIN
|| ret
== GNUTLS_E_INTERRUPTED
159 || ret
== GNUTLS_E_HEARTBEAT_PING_RECEIVED
);
166 gnutls_heartbeat_ping (session
, 256, 5,
167 GNUTLS_HEARTBEAT_WAIT
);
170 success ("Ping sent.\n");
172 while (ret
== GNUTLS_E_AGAIN
|| ret
== GNUTLS_E_INTERRUPTED
);
176 fail ("ping: %s\n", gnutls_strerror (ret
));
181 gnutls_bye (session
, GNUTLS_SHUT_WR
);
185 gnutls_deinit (session
);
187 gnutls_anon_free_client_credentials (anoncred
);
189 gnutls_global_deinit ();
194 static gnutls_session_t
195 initialize_tls_session (void)
197 gnutls_session_t session
;
199 gnutls_init (&session
, GNUTLS_SERVER
| GNUTLS_DATAGRAM
);
200 gnutls_heartbeat_enable (session
, GNUTLS_HB_PEER_ALLOWED_TO_SEND
);
201 gnutls_dtls_set_mtu (session
, 1500);
203 /* avoid calling all the priority functions, since the defaults
206 gnutls_priority_set_direct (session
,
207 "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL",
218 kill (child
, SIGTERM
);
224 server (int fd
, int server_init
)
227 char buffer
[MAX_BUF
+ 1];
228 gnutls_session_t session
;
229 gnutls_anon_server_credentials_t anoncred
;
230 /* this must be called once in the program
232 gnutls_global_init ();
236 gnutls_global_set_log_function (server_log_func
);
237 gnutls_global_set_log_level (4711);
240 gnutls_anon_allocate_server_credentials (&anoncred
);
242 session
= initialize_tls_session ();
243 gnutls_credentials_set (session
, GNUTLS_CRD_ANON
, anoncred
);
245 gnutls_transport_set_ptr (session
, (gnutls_transport_ptr_t
) fd
);
249 ret
= gnutls_handshake (session
);
251 while (ret
< 0 && gnutls_error_is_fatal (ret
) == 0);
255 gnutls_deinit (session
);
256 fail ("server: Handshake has failed (%s)\n\n",
257 gnutls_strerror (ret
));
261 success ("server: Handshake was completed\n");
264 success ("server: TLS version is: %s\n",
265 gnutls_protocol_get_name (gnutls_protocol_get_version
268 /* see the Getting peer's information example */
269 /* print_info(session); */
276 gnutls_record_recv (session
, buffer
, sizeof (buffer
));
278 if (ret
== GNUTLS_E_HEARTBEAT_PING_RECEIVED
)
281 success ("Ping received. Replying with pong.\n");
282 ret2
= gnutls_heartbeat_pong (session
, 0);
285 fail ("pong: %s\n", gnutls_strerror (ret
));
290 while (ret
== GNUTLS_E_AGAIN
|| ret
== GNUTLS_E_INTERRUPTED
291 || ret
== GNUTLS_E_HEARTBEAT_PING_RECEIVED
);
298 gnutls_heartbeat_ping (session
, 256, 5,
299 GNUTLS_HEARTBEAT_WAIT
);
302 success ("Ping sent.\n");
304 while (ret
== GNUTLS_E_AGAIN
|| ret
== GNUTLS_E_INTERRUPTED
);
308 fail ("ping: %s\n", gnutls_strerror (ret
));
313 /* do not wait for the peer to close the connection.
315 gnutls_bye (session
, GNUTLS_SHUT_WR
);
318 gnutls_deinit (session
);
320 gnutls_anon_free_server_credentials (anoncred
);
322 gnutls_global_deinit ();
325 success ("server: finished\n");
329 start (int server_initiated
)
334 ret
= socketpair (AF_UNIX
, SOCK_DGRAM
, 0, fd
);
337 perror ("socketpair");
354 server (fd
[0], server_initiated
);
356 if (WEXITSTATUS (status
) != 0)
357 fail ("Child died with status %d\n", WEXITSTATUS (status
));
362 client (fd
[1], server_initiated
);