remove p11-kit in gnutls.spec file
[platform/upstream/gnutls.git] / tests / anonself.c
1 /*
2  * Copyright (C) 2004-2012 Free Software Foundation, Inc.
3  * Copyright (C) 2013 Adam Sampson <ats@offog.org>
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
33 /* This program tests anonymous authentication as well as the gnutls_record_recv_packet.
34  */
35
36 #if defined(_WIN32)
37
38 /* socketpair isn't supported on Win32. */
39 int main(int argc, char **argv)
40 {
41         exit(77);
42 }
43
44 #else
45
46 #include <string.h>
47 #include <sys/types.h>
48 #include <netinet/in.h>
49 #include <sys/socket.h>
50 #if !defined(_WIN32)
51 #include <sys/wait.h>
52 #endif
53 #include <unistd.h>
54 #include <gnutls/gnutls.h>
55
56 #include "utils.h"
57
58 static void tls_log_func(int level, const char *str)
59 {
60         fprintf(stderr, "|<%d>| %s", level, str);
61 }
62
63 #define MAX_BUF 1024
64 #define MSG "Hello TLS"
65
66 static void client(int sd)
67 {
68         int ret, ii;
69         gnutls_session_t session;
70         char buffer[MAX_BUF + 1];
71         gnutls_anon_client_credentials_t anoncred;
72         /* Need to enable anonymous KX specifically. */
73
74         global_init();
75
76         gnutls_global_set_log_function(tls_log_func);
77         if (debug)
78                 gnutls_global_set_log_level(4711);
79
80         gnutls_anon_allocate_client_credentials(&anoncred);
81
82         /* Initialize TLS session
83          */
84         gnutls_init(&session, GNUTLS_CLIENT);
85
86         /* Use default priorities */
87         gnutls_priority_set_direct(session,
88                                    "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH",
89                                    NULL);
90
91         /* put the anonymous credentials to the current session
92          */
93         gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred);
94
95         gnutls_transport_set_int(session, sd);
96
97         /* Perform the TLS handshake
98          */
99         ret = gnutls_handshake(session);
100
101         if (ret < 0) {
102                 fail("client: Handshake failed\n");
103                 gnutls_perror(ret);
104                 goto end;
105         } else {
106                 if (debug)
107                         success("client: Handshake was completed\n");
108         }
109
110         ret = gnutls_dh_get_prime_bits(session);
111         if (ret < 512) {
112                 fail("server: too small prime size: %d\n", ret);
113         }
114
115         ret = gnutls_dh_get_secret_bits(session);
116         if (ret < 256) {
117                 fail("server: too small secret key size: %d\n", ret);
118         }
119
120         if (debug)
121                 success("client: TLS version is: %s\n",
122                         gnutls_protocol_get_name
123                         (gnutls_protocol_get_version(session)));
124
125         gnutls_record_send(session, MSG, strlen(MSG));
126
127         ret = gnutls_record_recv(session, buffer, MAX_BUF);
128         if (ret == 0) {
129                 if (debug)
130                         success
131                             ("client: Peer has closed the TLS connection\n");
132                 goto end;
133         } else if (ret < 0) {
134                 fail("client: Error: %s\n", gnutls_strerror(ret));
135                 goto end;
136         }
137
138         if (ret != strlen(MSG) || memcmp(buffer, MSG, ret) != 0) {
139                 fail("client: received data of different size! (expected: %d, have: %d)\n", 
140                         (int)strlen(MSG), ret);
141                 goto end;
142         }
143
144         if (debug) {
145                 printf("- Received %d bytes: ", ret);
146                 for (ii = 0; ii < ret; ii++) {
147                         fputc(buffer[ii], stdout);
148                 }
149                 fputs("\n", stdout);
150         }
151
152         gnutls_bye(session, GNUTLS_SHUT_RDWR);
153
154       end:
155
156         close(sd);
157
158         gnutls_deinit(session);
159
160         gnutls_anon_free_client_credentials(anoncred);
161
162         gnutls_global_deinit();
163 }
164
165 /* This is a sample TLS 1.0 echo server, for anonymous authentication only.
166  */
167
168 #define MAX_BUF 1024
169 #define DH_BITS 1024
170
171 /* These are global */
172 gnutls_anon_server_credentials_t anoncred;
173
174 static gnutls_session_t initialize_tls_session(void)
175 {
176         gnutls_session_t session;
177
178         gnutls_init(&session, GNUTLS_SERVER);
179
180         /* avoid calling all the priority functions, since the defaults
181          * are adequate.
182          */
183         gnutls_priority_set_direct(session,
184                                    "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH",
185                                    NULL);
186
187         gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred);
188
189         gnutls_dh_set_prime_bits(session, DH_BITS);
190
191         return session;
192 }
193
194 static gnutls_dh_params_t dh_params;
195
196 static int generate_dh_params(void)
197 {
198         const gnutls_datum_t p3 = { (void *) pkcs3, strlen(pkcs3) };
199         /* Generate Diffie-Hellman parameters - for use with DHE
200          * kx algorithms. These should be discarded and regenerated
201          * once a day, once a week or once a month. Depending on the
202          * security requirements.
203          */
204         gnutls_dh_params_init(&dh_params);
205         return gnutls_dh_params_import_pkcs3(dh_params, &p3,
206                                              GNUTLS_X509_FMT_PEM);
207 }
208
209 int err, ret;
210 char topbuf[512];
211 gnutls_session_t session;
212 char buffer[MAX_BUF + 1];
213 int optval = 1;
214
215 static void server(int sd)
216 {
217         gnutls_packet_t packet;
218
219         /* this must be called once in the program
220          */
221         global_init();
222
223         gnutls_global_set_log_function(tls_log_func);
224         if (debug)
225                 gnutls_global_set_log_level(4711);
226
227         gnutls_anon_allocate_server_credentials(&anoncred);
228
229         if (debug)
230                 success("Launched, generating DH parameters...\n");
231
232         generate_dh_params();
233
234         gnutls_anon_set_server_dh_params(anoncred, dh_params);
235
236         session = initialize_tls_session();
237
238         gnutls_transport_set_int(session, sd);
239         ret = gnutls_handshake(session);
240         if (ret < 0) {
241                 close(sd);
242                 gnutls_deinit(session);
243                 fail("server: Handshake has failed (%s)\n\n",
244                      gnutls_strerror(ret));
245                 return;
246         }
247         if (debug)
248                 success("server: Handshake was completed\n");
249
250         if (debug)
251                 success("server: TLS version is: %s\n",
252                         gnutls_protocol_get_name
253                         (gnutls_protocol_get_version(session)));
254
255         ret = gnutls_dh_get_prime_bits(session);
256         if (ret < 512) {
257                 fail("server: too small prime size: %d\n", ret);
258         }
259
260         ret = gnutls_dh_get_secret_bits(session);
261         if (ret < 256) {
262                 fail("server: too small secret key size: %d\n", ret);
263         }
264
265         /* see the Getting peer's information example */
266         /* print_info(session); */
267
268         for (;;) {
269                 ret = gnutls_record_recv_packet(session, &packet);
270
271                 if (ret == 0) {
272                         gnutls_packet_deinit(packet);
273                         if (debug)
274                                 success
275                                     ("server: Peer has closed the GnuTLS connection\n");
276                         break;
277                 } else if (ret < 0) {
278                         fail("server: Received corrupted data(%d). Closing...\n", ret);
279                         break;
280                 } else if (ret > 0) {
281                         gnutls_datum_t pdata;
282
283                         gnutls_packet_get(packet, &pdata, NULL);
284                         /* echo data back to the client
285                          */
286                         gnutls_record_send(session, pdata.data,
287                                            pdata.size);
288                         gnutls_packet_deinit(packet);
289                 }
290         }
291         /* do not wait for the peer to close the connection.
292          */
293         gnutls_bye(session, GNUTLS_SHUT_WR);
294
295         close(sd);
296         gnutls_deinit(session);
297
298         gnutls_anon_free_server_credentials(anoncred);
299
300         gnutls_dh_params_deinit(dh_params);
301
302         gnutls_global_deinit();
303
304         if (debug)
305                 success("server: finished\n");
306 }
307
308 void doit(void)
309 {
310         pid_t child;
311         int sockets[2];
312
313         err = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);
314         if (err == -1) {
315                 perror("socketpair");
316                 fail("socketpair failed\n");
317                 return;
318         }
319
320         child = fork();
321         if (child < 0) {
322                 perror("fork");
323                 fail("fork");
324                 return;
325         }
326
327         if (child) {
328                 int status;
329                 /* parent */
330                 server(sockets[0]);
331                 wait(&status);
332         } else
333                 client(sockets[1]);
334 }
335
336 #endif                          /* _WIN32 */