upload -> upload-tarballs
[gnutls.git] / tests / dhepskself.c
blob1c79fcc8734be1e655b0b2d7a35fca2c63fc6f63
1 /*
2 * Copyright (C) 2004-2012 Free Software Foundation, Inc.
4 * Author: Simon Josefsson
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 /* Parts copied from GnuTLS example programs. */
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #if !defined(_WIN32)
35 #include <sys/wait.h>
36 #include <netinet/in.h>
37 #include <arpa/inet.h>
38 #endif
39 #include <unistd.h>
40 #include <gnutls/gnutls.h>
42 #include "tcp.c"
44 #include "utils.h"
46 /* A very basic TLS client, with PSK authentication.
49 #define MAX_BUF 1024
50 #define MSG "Hello TLS"
52 static void
53 tls_log_func (int level, const char *str)
55 fprintf (stderr, "|<%d>| %s", level, str);
58 static void
59 client (void)
61 int ret, sd, ii;
62 gnutls_session_t session;
63 char buffer[MAX_BUF + 1];
64 gnutls_psk_client_credentials_t pskcred;
65 const gnutls_datum_t key = { (void *) "DEADBEEF", 8 };
67 gnutls_global_init ();
69 gnutls_global_set_log_function (tls_log_func);
70 if (debug)
71 gnutls_global_set_log_level (5);
73 gnutls_psk_allocate_client_credentials (&pskcred);
74 gnutls_psk_set_client_credentials (pskcred, "test", &key,
75 GNUTLS_PSK_KEY_HEX);
77 /* Initialize TLS session
79 gnutls_init (&session, GNUTLS_CLIENT);
81 /* Use default priorities */
82 gnutls_priority_set_direct (session, "NORMAL:+DHE-PSK", NULL);
84 /* put the anonymous credentials to the current session
86 gnutls_credentials_set (session, GNUTLS_CRD_PSK, pskcred);
88 /* connect to the peer
90 sd = tcp_connect ();
92 gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
94 /* Perform the TLS handshake
96 ret = gnutls_handshake (session);
98 if (ret < 0)
100 fail ("client: Handshake failed\n");
101 gnutls_perror (ret);
102 goto end;
104 else
106 if (debug)
107 success ("client: Handshake was completed\n");
110 gnutls_record_send (session, MSG, strlen (MSG));
112 ret = gnutls_record_recv (session, buffer, MAX_BUF);
113 if (ret == 0)
115 if (debug)
116 success ("client: Peer has closed the TLS connection\n");
117 goto end;
119 else if (ret < 0)
121 fail ("client: Error: %s\n", gnutls_strerror (ret));
122 goto end;
125 if (debug)
127 printf ("- Received %d bytes: ", ret);
128 for (ii = 0; ii < ret; ii++)
129 fputc (buffer[ii], stdout);
130 fputs ("\n", stdout);
133 gnutls_bye (session, GNUTLS_SHUT_RDWR);
135 end:
137 tcp_close (sd);
139 gnutls_deinit (session);
141 gnutls_psk_free_client_credentials (pskcred);
143 gnutls_global_deinit ();
146 /* This is a sample TLS 1.0 echo server, for PSK authentication.
149 #define SA struct sockaddr
150 #define MAX_BUF 1024
151 #define PORT 5556 /* listen to 5556 port */
153 /* These are global */
154 gnutls_psk_server_credentials_t server_pskcred;
156 static gnutls_session_t
157 initialize_tls_session (void)
159 gnutls_session_t session;
161 gnutls_init (&session, GNUTLS_SERVER);
163 /* avoid calling all the priority functions, since the defaults
164 * are adequate.
166 gnutls_priority_set_direct(session, "NORMAL:+DHE-PSK", NULL);
168 gnutls_credentials_set (session, GNUTLS_CRD_PSK, server_pskcred);
170 return session;
173 static gnutls_dh_params_t dh_params;
175 static int
176 generate_dh_params (void)
178 const gnutls_datum_t p3 = { (void *) pkcs3, strlen (pkcs3) };
179 /* Generate Diffie-Hellman parameters - for use with DHE
180 * kx algorithms. These should be discarded and regenerated
181 * once a day, once a week or once a month. Depending on the
182 * security requirements.
184 gnutls_dh_params_init (&dh_params);
185 return gnutls_dh_params_import_pkcs3 (dh_params, &p3, GNUTLS_X509_FMT_PEM);
188 static int
189 pskfunc (gnutls_session_t session, const char *username, gnutls_datum_t * key)
191 if (debug)
192 printf ("psk callback to get %s's password\n", username);
193 key->data = gnutls_malloc (4);
194 key->data[0] = 0xDE;
195 key->data[1] = 0xAD;
196 key->data[2] = 0xBE;
197 key->data[3] = 0xEF;
198 key->size = 4;
199 return 0;
202 int err, listen_sd, i;
203 int sd, ret;
204 struct sockaddr_in sa_serv;
205 struct sockaddr_in sa_cli;
206 socklen_t client_len;
207 char topbuf[512];
208 gnutls_session_t session;
209 char buffer[MAX_BUF + 1];
210 int optval = 1;
212 static void
213 server_start (void)
215 if (debug)
216 success ("Launched, generating DH parameters...\n");
218 /* Socket operations
220 listen_sd = socket (AF_INET, SOCK_STREAM, 0);
221 if (err == -1)
223 perror ("socket");
224 fail ("server: socket failed\n");
225 return;
228 memset (&sa_serv, '\0', sizeof (sa_serv));
229 sa_serv.sin_family = AF_INET;
230 sa_serv.sin_addr.s_addr = INADDR_ANY;
231 sa_serv.sin_port = htons (PORT); /* Server Port number */
233 setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval,
234 sizeof (int));
236 err = bind (listen_sd, (SA *) & sa_serv, sizeof (sa_serv));
237 if (err == -1)
239 perror ("bind");
240 fail ("server: bind failed\n");
241 return;
244 err = listen (listen_sd, 1024);
245 if (err == -1)
247 perror ("listen");
248 fail ("server: listen failed\n");
249 return;
252 if (debug)
253 success ("server: ready. Listening to port '%d'.\n", PORT);
256 static void
257 server (void)
259 /* this must be called once in the program
261 gnutls_global_init ();
263 gnutls_global_set_log_function (tls_log_func);
264 if (debug)
265 gnutls_global_set_log_level (4711);
267 generate_dh_params ();
269 gnutls_psk_allocate_server_credentials (&server_pskcred);
270 gnutls_psk_set_server_credentials_function (server_pskcred, pskfunc);
271 gnutls_psk_set_server_dh_params (server_pskcred, dh_params);
273 client_len = sizeof (sa_cli);
275 session = initialize_tls_session ();
277 sd = accept (listen_sd, (SA *) & sa_cli, &client_len);
279 if (debug)
280 success ("server: connection from %s, port %d\n",
281 inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf,
282 sizeof (topbuf)), ntohs (sa_cli.sin_port));
284 gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
285 ret = gnutls_handshake (session);
286 if (ret < 0)
288 close (sd);
289 gnutls_deinit (session);
290 fail ("server: Handshake has failed (%s)\n\n", gnutls_strerror (ret));
291 return;
293 if (debug)
294 success ("server: Handshake was completed\n");
296 /* see the Getting peer's information example */
297 /* print_info(session); */
299 i = 0;
300 for (;;)
302 memset (buffer, 0, MAX_BUF + 1);
303 ret = gnutls_record_recv (session, buffer, MAX_BUF);
305 if (ret == 0)
307 if (debug)
308 success ("server: Peer has closed the GnuTLS connection\n");
309 break;
311 else if (ret < 0)
313 fail ("server: Received corrupted data(%d). Closing...\n", ret);
314 break;
316 else if (ret > 0)
318 /* echo data back to the client
320 gnutls_record_send (session, buffer, strlen (buffer));
323 /* do not wait for the peer to close the connection.
325 gnutls_bye (session, GNUTLS_SHUT_WR);
327 close (sd);
328 gnutls_deinit (session);
330 close (listen_sd);
332 gnutls_psk_free_server_credentials (server_pskcred);
334 gnutls_dh_params_deinit (dh_params);
336 gnutls_global_deinit ();
338 if (debug)
339 success ("server: finished\n");
342 void
343 doit (void)
345 pid_t child;
347 server_start ();
348 if (error_count)
349 return;
351 child = fork ();
352 if (child < 0)
354 perror ("fork");
355 fail ("fork");
356 return;
359 if (child)
361 int status;
362 /* parent */
363 server ();
364 wait (&status);
366 else
367 client ();