Tizen 2.0 Release
[external/libgnutls26.git] / tests / anonself.c
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
3  * Foundation, Inc.
4  *
5  * Author: Simon Josefsson
6  *
7  * This file is part of GnuTLS.
8  *
9  * GnuTLS is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * GnuTLS is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with GnuTLS; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23
24 /* Parts copied from GnuTLS example programs. */
25
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sys/types.h>
34 #include <netinet/in.h>
35 #include <sys/socket.h>
36 #if !defined(_WIN32)
37 #include <sys/wait.h>
38 #include <arpa/inet.h>
39 #endif
40 #include <unistd.h>
41 #include <gnutls/gnutls.h>
42
43 #include "tcp.c"
44
45 #include "utils.h"
46
47 static void
48 tls_log_func (int level, const char *str)
49 {
50   fprintf (stderr, "|<%d>| %s", level, str);
51 }
52
53 /* A very basic TLS client, with anonymous authentication.
54  */
55
56 #define MAX_BUF 1024
57 #define MSG "Hello TLS"
58
59 static void
60 client (void)
61 {
62   int ret, sd, ii;
63   gnutls_session_t session;
64   char buffer[MAX_BUF + 1];
65   gnutls_anon_client_credentials_t anoncred;
66   /* Need to enable anonymous KX specifically. */
67
68   gnutls_global_init ();
69
70   gnutls_global_set_log_function (tls_log_func);
71   if (debug)
72     gnutls_global_set_log_level (4711);
73
74   gnutls_anon_allocate_client_credentials (&anoncred);
75
76   /* Initialize TLS session
77    */
78   gnutls_init (&session, GNUTLS_CLIENT);
79
80   /* Use default priorities */
81   gnutls_priority_set_direct (session, "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL);
82
83   /* put the anonymous credentials to the current session
84    */
85   gnutls_credentials_set (session, GNUTLS_CRD_ANON, anoncred);
86
87   /* connect to the peer
88    */
89   sd = tcp_connect ();
90
91   gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
92
93   /* Perform the TLS handshake
94    */
95   ret = gnutls_handshake (session);
96
97   if (ret < 0)
98     {
99       fail ("client: Handshake failed\n");
100       gnutls_perror (ret);
101       goto end;
102     }
103   else
104     {
105       if (debug)
106         success ("client: Handshake was completed\n");
107     }
108
109   if (debug)
110     success ("client: TLS version is: %s\n",
111              gnutls_protocol_get_name (gnutls_protocol_get_version
112                                        (session)));
113
114   gnutls_record_send (session, MSG, strlen (MSG));
115
116   ret = gnutls_record_recv (session, buffer, MAX_BUF);
117   if (ret == 0)
118     {
119       if (debug)
120         success ("client: Peer has closed the TLS connection\n");
121       goto end;
122     }
123   else if (ret < 0)
124     {
125       fail ("client: Error: %s\n", gnutls_strerror (ret));
126       goto end;
127     }
128
129   if (debug)
130     {
131       printf ("- Received %d bytes: ", ret);
132       for (ii = 0; ii < ret; ii++)
133         {
134           fputc (buffer[ii], stdout);
135         }
136       fputs ("\n", stdout);
137     }
138
139   gnutls_bye (session, GNUTLS_SHUT_RDWR);
140
141 end:
142
143   tcp_close (sd);
144
145   gnutls_deinit (session);
146
147   gnutls_anon_free_client_credentials (anoncred);
148
149   gnutls_global_deinit ();
150 }
151
152 /* This is a sample TLS 1.0 echo server, for anonymous authentication only.
153  */
154
155 #define SA struct sockaddr
156 #define MAX_BUF 1024
157 #define PORT 5556               /* listen to 5556 port */
158 #define DH_BITS 1024
159
160 /* These are global */
161 gnutls_anon_server_credentials_t anoncred;
162
163 static gnutls_session_t
164 initialize_tls_session (void)
165 {
166   gnutls_session_t session;
167
168   gnutls_init (&session, GNUTLS_SERVER);
169
170   /* avoid calling all the priority functions, since the defaults
171    * are adequate.
172    */
173   gnutls_priority_set_direct (session, "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL);
174
175   gnutls_credentials_set (session, GNUTLS_CRD_ANON, anoncred);
176
177   gnutls_dh_set_prime_bits (session, DH_BITS);
178
179   return session;
180 }
181
182 static gnutls_dh_params_t dh_params;
183
184 static int
185 generate_dh_params (void)
186 {
187   const gnutls_datum_t p3 = { (char *) pkcs3, strlen (pkcs3) };
188   /* Generate Diffie-Hellman parameters - for use with DHE
189    * kx algorithms. These should be discarded and regenerated
190    * once a day, once a week or once a month. Depending on the
191    * security requirements.
192    */
193   gnutls_dh_params_init (&dh_params);
194   return gnutls_dh_params_import_pkcs3 (dh_params, &p3, GNUTLS_X509_FMT_PEM);
195 }
196
197 int err, listen_sd, i;
198 int sd, ret;
199 struct sockaddr_in sa_serv;
200 struct sockaddr_in sa_cli;
201 int client_len;
202 char topbuf[512];
203 gnutls_session_t session;
204 char buffer[MAX_BUF + 1];
205 int optval = 1;
206
207 static void
208 server_start (void)
209 {
210   /* Socket operations
211    */
212   listen_sd = socket (AF_INET, SOCK_STREAM, 0);
213   if (err == -1)
214     {
215       perror ("socket");
216       fail ("server: socket failed\n");
217       return;
218     }
219
220   memset (&sa_serv, '\0', sizeof (sa_serv));
221   sa_serv.sin_family = AF_INET;
222   sa_serv.sin_addr.s_addr = INADDR_ANY;
223   sa_serv.sin_port = htons (PORT);      /* Server Port number */
224
225   setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval,
226               sizeof (int));
227
228   err = bind (listen_sd, (SA *) & sa_serv, sizeof (sa_serv));
229   if (err == -1)
230     {
231       perror ("bind");
232       fail ("server: bind failed\n");
233       return;
234     }
235
236   err = listen (listen_sd, 1024);
237   if (err == -1)
238     {
239       perror ("listen");
240       fail ("server: listen failed\n");
241       return;
242     }
243
244   if (debug)
245     success ("server: ready. Listening to port '%d'.\n", PORT);
246 }
247
248 static void
249 server (void)
250 {
251   /* this must be called once in the program
252    */
253   gnutls_global_init ();
254
255   gnutls_global_set_log_function (tls_log_func);
256   if (debug)
257     gnutls_global_set_log_level (4711);
258
259   gnutls_anon_allocate_server_credentials (&anoncred);
260
261   if (debug)
262     success ("Launched, generating DH parameters...\n");
263
264   generate_dh_params ();
265
266   gnutls_anon_set_server_dh_params (anoncred, dh_params);
267
268   client_len = sizeof (sa_cli);
269
270   session = initialize_tls_session ();
271
272   sd = accept (listen_sd, (SA *) & sa_cli, &client_len);
273
274   if (debug)
275     success ("server: connection from %s, port %d\n",
276              inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf,
277                         sizeof (topbuf)), ntohs (sa_cli.sin_port));
278
279   gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
280   ret = gnutls_handshake (session);
281   if (ret < 0)
282     {
283       close (sd);
284       gnutls_deinit (session);
285       fail ("server: Handshake has failed (%s)\n\n", gnutls_strerror (ret));
286       return;
287     }
288   if (debug)
289     success ("server: Handshake was completed\n");
290
291   if (debug)
292     success ("server: TLS version is: %s\n",
293              gnutls_protocol_get_name (gnutls_protocol_get_version
294                                        (session)));
295
296   /* see the Getting peer's information example */
297   /* print_info(session); */
298
299   i = 0;
300   for (;;)
301     {
302       memset (buffer, 0, MAX_BUF + 1);
303       ret = gnutls_record_recv (session, buffer, MAX_BUF);
304
305       if (ret == 0)
306         {
307           if (debug)
308             success ("server: Peer has closed the GnuTLS connection\n");
309           break;
310         }
311       else if (ret < 0)
312         {
313           fail ("server: Received corrupted data(%d). Closing...\n", ret);
314           break;
315         }
316       else if (ret > 0)
317         {
318           /* echo data back to the client
319            */
320           gnutls_record_send (session, buffer, strlen (buffer));
321         }
322     }
323   /* do not wait for the peer to close the connection.
324    */
325   gnutls_bye (session, GNUTLS_SHUT_WR);
326
327   close (sd);
328   gnutls_deinit (session);
329
330   close (listen_sd);
331
332   gnutls_anon_free_server_credentials (anoncred);
333
334   gnutls_dh_params_deinit (dh_params);
335
336   gnutls_global_deinit ();
337
338   if (debug)
339     success ("server: finished\n");
340 }
341
342 void
343 doit (void)
344 {
345   pid_t child;
346
347   server_start ();
348   if (error_count)
349     return;
350
351   child = fork ();
352   if (child < 0)
353     {
354       perror ("fork");
355       fail ("fork");
356       return;
357     }
358
359   if (child)
360     {
361       int status;
362       /* parent */
363       server ();
364       wait (&status);
365     }
366   else
367     client ();
368 }