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