Fix CVE-2017-6891 in minitasn1 code
[platform/upstream/gnutls.git] / doc / examples / ex-serv-srp.c
1 /* This example code is placed in the public domain. */
2
3 #ifdef HAVE_CONFIG_H
4 #include <config.h>
5 #endif
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <errno.h>
10 #include <sys/types.h>
11 #include <sys/socket.h>
12 #include <arpa/inet.h>
13 #include <netinet/in.h>
14 #include <string.h>
15 #include <unistd.h>
16 #include <gnutls/gnutls.h>
17
18 #define SRP_PASSWD "tpasswd"
19 #define SRP_PASSWD_CONF "tpasswd.conf"
20
21 #define KEYFILE "key.pem"
22 #define CERTFILE "cert.pem"
23 #define CAFILE "/etc/ssl/certs/ca-certificates.crt"
24
25 /* This is a sample TLS-SRP echo server.
26  */
27
28 #define SOCKET_ERR(err,s) if(err==-1) {perror(s);return(1);}
29 #define MAX_BUF 1024
30 #define PORT 5556               /* listen to 5556 port */
31
32 int main(void)
33 {
34         int err, listen_sd;
35         int sd, ret;
36         struct sockaddr_in sa_serv;
37         struct sockaddr_in sa_cli;
38         socklen_t client_len;
39         char topbuf[512];
40         gnutls_session_t session;
41         gnutls_srp_server_credentials_t srp_cred;
42         gnutls_certificate_credentials_t cert_cred;
43         char buffer[MAX_BUF + 1];
44         int optval = 1;
45         char name[256];
46
47         strcpy(name, "Echo Server");
48
49         if (gnutls_check_version("3.1.4") == NULL) {
50                 fprintf(stderr, "GnuTLS 3.1.4 or later is required for this example\n");
51                 exit(1);
52         }
53
54         /* for backwards compatibility with gnutls < 3.3.0 */
55         gnutls_global_init();
56
57         /* SRP_PASSWD a password file (created with the included srptool utility) 
58          */
59         gnutls_srp_allocate_server_credentials(&srp_cred);
60         gnutls_srp_set_server_credentials_file(srp_cred, SRP_PASSWD,
61                                                SRP_PASSWD_CONF);
62
63         gnutls_certificate_allocate_credentials(&cert_cred);
64         gnutls_certificate_set_x509_trust_file(cert_cred, CAFILE,
65                                                GNUTLS_X509_FMT_PEM);
66         gnutls_certificate_set_x509_key_file(cert_cred, CERTFILE, KEYFILE,
67                                              GNUTLS_X509_FMT_PEM);
68
69         /* TCP socket operations
70          */
71         listen_sd = socket(AF_INET, SOCK_STREAM, 0);
72         SOCKET_ERR(listen_sd, "socket");
73
74         memset(&sa_serv, '\0', sizeof(sa_serv));
75         sa_serv.sin_family = AF_INET;
76         sa_serv.sin_addr.s_addr = INADDR_ANY;
77         sa_serv.sin_port = htons(PORT); /* Server Port number */
78
79         setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval,
80                    sizeof(int));
81
82         err =
83             bind(listen_sd, (struct sockaddr *) &sa_serv, sizeof(sa_serv));
84         SOCKET_ERR(err, "bind");
85         err = listen(listen_sd, 1024);
86         SOCKET_ERR(err, "listen");
87
88         printf("%s ready. Listening to port '%d'.\n\n", name, PORT);
89
90         client_len = sizeof(sa_cli);
91         for (;;) {
92                 gnutls_init(&session, GNUTLS_SERVER);
93                 gnutls_priority_set_direct(session,
94                                            "NORMAL"
95                                            ":-KX-ALL:+SRP:+SRP-DSS:+SRP-RSA",
96                                            NULL);
97                 gnutls_credentials_set(session, GNUTLS_CRD_SRP, srp_cred);
98                 /* for the certificate authenticated ciphersuites.
99                  */
100                 gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
101                                        cert_cred);
102
103                 /* We don't request any certificate from the client.
104                  * If we did we would need to verify it. One way of
105                  * doing that is shown in the "Verifying a certificate"
106                  * example.
107                  */
108                 gnutls_certificate_server_set_request(session,
109                                                       GNUTLS_CERT_IGNORE);
110
111                 sd = accept(listen_sd, (struct sockaddr *) &sa_cli,
112                             &client_len);
113
114                 printf("- connection from %s, port %d\n",
115                        inet_ntop(AF_INET, &sa_cli.sin_addr, topbuf,
116                                  sizeof(topbuf)), ntohs(sa_cli.sin_port));
117
118                 gnutls_transport_set_int(session, sd);
119
120                 do {
121                         ret = gnutls_handshake(session);
122                 }
123                 while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
124
125                 if (ret < 0) {
126                         close(sd);
127                         gnutls_deinit(session);
128                         fprintf(stderr,
129                                 "*** Handshake has failed (%s)\n\n",
130                                 gnutls_strerror(ret));
131                         continue;
132                 }
133                 printf("- Handshake was completed\n");
134                 printf("- User %s was connected\n",
135                        gnutls_srp_server_get_username(session));
136
137                 /* print_info(session); */
138
139                 for (;;) {
140                         ret = gnutls_record_recv(session, buffer, MAX_BUF);
141
142                         if (ret == 0) {
143                                 printf
144                                     ("\n- Peer has closed the GnuTLS connection\n");
145                                 break;
146                         } else if (ret < 0
147                                    && gnutls_error_is_fatal(ret) == 0) {
148                                 fprintf(stderr, "*** Warning: %s\n",
149                                         gnutls_strerror(ret));
150                         } else if (ret < 0) {
151                                 fprintf(stderr, "\n*** Received corrupted "
152                                         "data(%d). Closing the connection.\n\n",
153                                         ret);
154                                 break;
155                         } else if (ret > 0) {
156                                 /* echo data back to the client
157                                  */
158                                 gnutls_record_send(session, buffer, ret);
159                         }
160                 }
161                 printf("\n");
162                 /* do not wait for the peer to close the connection. */
163                 gnutls_bye(session, GNUTLS_SHUT_WR);
164
165                 close(sd);
166                 gnutls_deinit(session);
167
168         }
169         close(listen_sd);
170
171         gnutls_srp_free_server_credentials(srp_cred);
172         gnutls_certificate_free_credentials(cert_cred);
173
174         gnutls_global_deinit();
175
176         return 0;
177
178 }