1
/* Copyright 2007 Free Software Foundation
3
* Copying and distribution of this file, with or without modification,
4
* are permitted in any medium without royalty provided the copyright
5
* notice and this notice are preserved.
15
#include <sys/types.h>
16
#include <sys/socket.h>
17
#include <arpa/inet.h>
18
#include <netinet/in.h>
21
#include <gnutls/gnutls.h>
22
/* Must be linked against gnutls-extra.
24
#include <gnutls/extra.h>
26
#define KEYFILE "secret.asc"
27
#define CERTFILE "public.asc"
28
#define RINGFILE "ring.gpg"
30
/* This is a sample TLS 1.0-OpenPGP echo server.
34
#define SA struct sockaddr
35
#define SOCKET_ERR(err,s) if(err==-1) {perror(s);return(1);}
37
#define PORT 5556 /* listen to 5556 port */
40
/* These are global */
41
gnutls_certificate_credentials_t cred;
42
gnutls_dh_params_t dh_params;
45
generate_dh_params (void)
48
/* Generate Diffie Hellman parameters - for use with DHE
49
* kx algorithms. These should be discarded and regenerated
50
* once a day, once a week or once a month. Depending on the
51
* security requirements.
53
gnutls_dh_params_init (&dh_params);
54
gnutls_dh_params_generate2 (dh_params, DH_BITS);
60
initialize_tls_session (void)
62
gnutls_session_t session;
64
gnutls_init (&session, GNUTLS_SERVER);
66
gnutls_priority_set_direct(session, "NORMAL", NULL);
68
/* request client certificate if any.
70
gnutls_certificate_server_set_request (session, GNUTLS_CERT_REQUEST);
72
gnutls_dh_set_prime_bits (session, DH_BITS);
80
int err, listen_sd, i;
82
struct sockaddr_in sa_serv;
83
struct sockaddr_in sa_cli;
86
gnutls_session_t session;
87
char buffer[MAX_BUF + 1];
91
strcpy (name, "Echo Server");
93
/* this must be called once in the program
95
gnutls_global_init ();
97
gnutls_certificate_allocate_credentials (&cred);
98
gnutls_certificate_set_openpgp_keyring_file (cred, RINGFILE, GNUTLS_OPENPGP_FMT_BASE64);
100
gnutls_certificate_set_openpgp_key_file (cred, CERTFILE, KEYFILE, GNUTLS_OPENPGP_FMT_BASE64);
102
generate_dh_params ();
104
gnutls_certificate_set_dh_params (cred, dh_params);
108
listen_sd = socket (AF_INET, SOCK_STREAM, 0);
109
SOCKET_ERR (listen_sd, "socket");
111
memset (&sa_serv, '\0', sizeof (sa_serv));
112
sa_serv.sin_family = AF_INET;
113
sa_serv.sin_addr.s_addr = INADDR_ANY;
114
sa_serv.sin_port = htons (PORT); /* Server Port number */
116
setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (int));
118
err = bind (listen_sd, (SA *) & sa_serv, sizeof (sa_serv));
119
SOCKET_ERR (err, "bind");
120
err = listen (listen_sd, 1024);
121
SOCKET_ERR (err, "listen");
123
printf ("%s ready. Listening to port '%d'.\n\n", name, PORT);
125
client_len = sizeof (sa_cli);
128
session = initialize_tls_session ();
130
sd = accept (listen_sd, (SA *) & sa_cli, &client_len);
132
printf ("- connection from %s, port %d\n",
133
inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf,
134
sizeof (topbuf)), ntohs (sa_cli.sin_port));
136
gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
137
ret = gnutls_handshake (session);
141
gnutls_deinit (session);
142
fprintf (stderr, "*** Handshake has failed (%s)\n\n",
143
gnutls_strerror (ret));
146
printf ("- Handshake was completed\n");
148
/* see the Getting peer's information example */
149
/* print_info(session); */
154
memset (buffer, 0, MAX_BUF + 1);
155
ret = gnutls_record_recv (session, buffer, MAX_BUF);
159
printf ("\n- Peer has closed the GNUTLS connection\n");
164
fprintf (stderr, "\n*** Received corrupted "
165
"data(%d). Closing the connection.\n\n", ret);
170
/* echo data back to the client
172
gnutls_record_send (session, buffer, strlen (buffer));
176
/* do not wait for the peer to close the connection.
178
gnutls_bye (session, GNUTLS_SHUT_WR);
181
gnutls_deinit (session);
186
gnutls_certificate_free_credentials (cred);
188
gnutls_global_deinit ();