Optimized memory handling in the record protocol.
[gnutls.git] / src / serv.c
blob805be19ed1b956141dfed5f2ef57a00b8e6e14ba
1 /*
2 * Copyright (C) 2000,2001,2002 Nikos Mavroyanopoulos
4 * This file is part of GNUTLS.
6 * GNUTLS is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GNUTLS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <errno.h>
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <netinet/in.h>
27 #include <arpa/inet.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include "../lib/gnutls.h"
31 #include "common.h"
32 #include <signal.h>
33 #include "serv-gaa.h"
36 /* konqueror cannot handle sending the page in multiple
37 * pieces.
39 /* global stuff */
40 static char http_buffer[16 * 1024];
41 static int generate = 0;
42 static int http = 0;
43 static int port = 0;
44 static int x509ctype;
46 char *srp_passwd;
47 char *srp_passwd_conf;
48 char *pgp_keyring;
49 char *pgp_trustdb;
50 char *pgp_keyserver;
51 char *pgp_keyfile;
52 char *pgp_certfile;
53 char *x509_keyfile;
54 char *x509_certfile;
55 char *x509_cafile;
56 char *x509_crlfile = NULL;
58 /* end of globals */
60 /* This is a sample TCP echo server.
61 * This will behave as an http server if any argument in the
62 * command line is present
66 #define SA struct sockaddr
67 #define ERR(err,s) if(err==-1) {perror(s);return(1);}
68 #define MAX_BUF 1024
70 #define HTTP_BEGIN "HTTP/1.0 200 OK\n" \
71 "Content-Type: text/html\n" \
72 "\n" \
73 "<HTML><BODY>\n" \
74 "<CENTER><H1>This is <a href=\"http://www.gnu.org/software/gnutls\">" \
75 "GNUTLS</a></H1>\n\n"
77 #define HTTP_END "</BODY></HTML>\n\n"
79 #define RENEGOTIATE
81 /* These are global */
82 GNUTLS_SRP_SERVER_CREDENTIALS srp_cred;
83 GNUTLS_ANON_SERVER_CREDENTIALS dh_cred;
84 GNUTLS_CERTIFICATE_SERVER_CREDENTIALS cert_cred;
87 #define DEFAULT_PRIME_BITS 1024
89 /* we use primes up to 1024 in this server.
90 * otherwise we should add them here.
92 static int prime_nums[] = { 768, 1024, 0 };
94 GNUTLS_DH_PARAMS dh_params;
96 static int generate_dh_primes(void)
98 gnutls_datum prime, generator;
99 int i = 0;
101 if (gnutls_dh_params_init(&dh_params) < 0) {
102 fprintf(stderr, "Error in dh parameter initialization\n");
103 exit(1);
106 do {
107 /* Generate Diffie Hellman parameters - for use with DHE
108 * kx algorithms. These should be discarded and regenerated
109 * once a day, once a week or once a month. Depends on the
110 * security requirements.
112 printf
113 ("Generating Diffie Hellman parameters [%d]. Please wait...",
114 prime_nums[i]);
115 fflush(stdout);
117 if (gnutls_dh_params_generate(&prime, &generator, prime_nums[i]) < 0) {
118 fprintf(stderr, "Error in prime generation\n");
119 exit(1);
122 if (gnutls_dh_params_set
123 (dh_params, prime, generator, prime_nums[i]) < 0) {
124 fprintf(stderr, "Error in prime replacement\n");
125 exit(1);
127 free(prime.data);
128 free(generator.data);
130 } while (prime_nums[++i] != 0);
132 return 0;
135 int protocol_priority[16] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
136 int kx_priority[16] =
137 { GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP,
138 GNUTLS_KX_ANON_DH, 0
140 int cipher_priority[16] =
141 { GNUTLS_CIPHER_RIJNDAEL_128_CBC, GNUTLS_CIPHER_3DES_CBC,
142 GNUTLS_CIPHER_ARCFOUR, 0
144 int comp_priority[16] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 };
145 int mac_priority[16] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 };
146 int cert_type_priority[16] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 };
148 GNUTLS_STATE initialize_state(void)
150 GNUTLS_STATE state;
151 int ret;
153 gnutls_init(&state, GNUTLS_SERVER);
154 if ((ret = gnutls_db_set_name(state, "gnutls-rsm.db")) < 0)
155 fprintf(stderr,
156 "*** DB error (%d). Resuming will not be possible.\n\n",
157 ret);
159 /* null cipher is here only for debuging
160 * purposes.
162 gnutls_cipher_set_priority(state, cipher_priority);
163 gnutls_compression_set_priority(state, comp_priority);
164 gnutls_kx_set_priority(state, kx_priority);
165 gnutls_protocol_set_priority(state, protocol_priority);
166 gnutls_mac_set_priority(state, mac_priority);
167 gnutls_cert_type_set_priority(state, cert_type_priority);
169 gnutls_dh_set_prime_bits(state, DEFAULT_PRIME_BITS);
171 gnutls_cred_set(state, GNUTLS_CRD_ANON, dh_cred);
172 gnutls_cred_set(state, GNUTLS_CRD_SRP, srp_cred);
173 gnutls_cred_set(state, GNUTLS_CRD_CERTIFICATE, cert_cred);
175 gnutls_mac_set_priority(state, mac_priority);
177 gnutls_certificate_server_set_request(state, GNUTLS_CERT_REQUEST);
179 return state;
182 /* Creates html with the current state information.
184 #define tmp2 &http_buffer[strlen(http_buffer)]
185 void peer_print_info(GNUTLS_STATE state)
187 const char *tmp;
188 unsigned char sesid[32];
189 int sesid_size, i;
191 /* print session_id */
192 gnutls_session_get_id(state, sesid, &sesid_size);
193 sprintf(tmp2, "\n<p>Session ID: <i>");
194 for (i = 0; i < sesid_size; i++)
195 sprintf(tmp2, "%.2X", sesid[i]);
196 sprintf(tmp2, "</i></p>\n");
198 /* Here unlike print_info() we use the kx algorithm to distinguish
199 * the functions to call.
202 /* print srp specific data */
203 if (gnutls_kx_get(state) == GNUTLS_KX_SRP) {
204 sprintf(tmp2, "<p>Connected as user '%s'.</p>\n",
205 gnutls_srp_server_get_username(state));
208 if (gnutls_kx_get(state) == GNUTLS_KX_ANON_DH) {
209 sprintf(tmp2,
210 "<p> Connect using anonymous DH (prime of %d bits)</p>\n",
211 gnutls_dh_get_prime_bits(state));
214 /* print state information */
215 strcat(http_buffer, "<P>\n");
217 tmp = gnutls_protocol_get_name(gnutls_protocol_get_version(state));
218 sprintf(tmp2, "Protocol version: <b>%s</b><br>\n", tmp);
220 if (gnutls_auth_get_type(state) == GNUTLS_CRD_CERTIFICATE) {
221 tmp = gnutls_cert_type_get_name(gnutls_cert_type_get(state));
222 sprintf(tmp2, "Certificate Type: <b>%s</b><br>\n", tmp);
225 tmp = gnutls_kx_get_name(gnutls_kx_get(state));
226 sprintf(tmp2, "Key Exchange: <b>%s</b><br>\n", tmp);
228 if (gnutls_kx_get(state) == GNUTLS_KX_DHE_RSA
229 || gnutls_kx_get(state) == GNUTLS_KX_DHE_DSS) {
230 sprintf(tmp2,
231 "Ephemeral DH using prime of <b>%d</b> bits.<br>\n",
232 gnutls_dh_get_prime_bits(state));
235 tmp = gnutls_compression_get_name(gnutls_compression_get(state));
236 sprintf(tmp2, "Compression: <b>%s</b><br>\n", tmp);
238 tmp = gnutls_cipher_get_name(gnutls_cipher_get(state));
239 sprintf(tmp2, "Cipher: <b>%s</b><br>\n", tmp);
241 tmp = gnutls_mac_get_name(gnutls_mac_get(state));
242 sprintf(tmp2, "MAC: <b>%s</b><br>\n", tmp);
244 strcat(http_buffer, "</P>\n");
246 return;
249 /* actually something like readline.
250 * if rnl!=1 then reads an http request in the form REQ\n\n
252 int read_request(GNUTLS_STATE state, char *data, int data_size, int rnl)
254 int n, rc, nl = 0;
255 char c, *ptr, p1 = 0, p2 = 0;
257 ptr = data;
258 for (n = 1; n < data_size; n++) {
259 do {
260 rc = gnutls_record_recv(state, &c, 1);
261 } while (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN);
263 if (rc == 1) {
264 *ptr++ = c;
265 if (c == '\n' && rnl == 1)
266 break;
268 if (c == '\n' && p1 == '\r' && p2 == '\n') {
269 nl++;
270 if (nl == 1)
271 break;
273 p2 = p1;
274 p1 = c;
276 } else if (rc == 0) {
277 if (n == 1)
278 return 0;
279 else
280 break;
281 } else {
282 return rc;
286 *ptr = 0;
287 return n;
291 void check_alert(GNUTLS_STATE state, int ret)
293 int last_alert;
295 if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED
296 || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) {
297 last_alert = gnutls_alert_get(state);
298 if (last_alert == GNUTLS_A_NO_RENEGOTIATION &&
299 ret == GNUTLS_E_WARNING_ALERT_RECEIVED)
300 printf
301 ("* Received NO_RENEGOTIATION alert. Client Does not support renegotiation.\n");
302 else
303 printf("* Received alert '%d'.\n", ret);
307 static void gaa_parser(int argc, char **argv);
309 int main(int argc, char **argv)
311 int err, listen_sd, i;
312 int sd, ret;
313 struct sockaddr_in sa_serv;
314 struct sockaddr_in sa_cli;
315 int client_len;
316 char topbuf[512];
317 GNUTLS_STATE state;
318 char buffer[MAX_BUF + 1];
319 int optval = 1;
320 char name[256];
322 signal(SIGPIPE, SIG_IGN);
324 gaa_parser(argc, argv);
326 if (http == 1) {
327 strcpy(name, "HTTP Server");
328 } else {
329 strcpy(name, "Echo Server");
332 if (gnutls_global_init() < 0) {
333 fprintf(stderr, "global state initialization error\n");
334 exit(1);
337 /* Note that servers must generate parameters for
338 * Diffie Hellman. See gnutls_dh_params_generate(), and
339 * gnutls_dh_params_set().
341 if (generate != 0)
342 generate_dh_primes();
344 if (gnutls_certificate_allocate_sc(&cert_cred) < 0) {
345 fprintf(stderr, "memory error\n");
346 exit(1);
349 if (x509_cafile != NULL) {
350 if ((ret=gnutls_certificate_set_x509_trust_file
351 (cert_cred, x509_cafile, x509ctype)) < 0) {
352 fprintf(stderr, "Error reading '%s'\n", x509_cafile);
353 exit(1);
354 } else {
355 printf("Processed %d CA certificate(s).\n", ret);
359 if (pgp_keyring != NULL) {
360 ret =
361 gnutls_certificate_set_openpgp_keyring_file(cert_cred, pgp_keyring);
362 if (ret < 0) {
363 fprintf(stderr, "Error setting the OpenPGP keyring file\n");
367 if (pgp_trustdb != NULL) {
368 gnutls_certificate_set_openpgp_trustdb(cert_cred, pgp_trustdb);
371 if (pgp_certfile != NULL)
372 if (gnutls_certificate_set_openpgp_key_file
373 (cert_cred, pgp_certfile, pgp_keyfile) < 0) {
374 fprintf(stderr,
375 "Error while reading the OpenPGP key pair ('%s', '%s')\n",
376 pgp_certfile, pgp_keyfile);
379 gnutls_certificate_set_openpgp_keyserver(cert_cred, pgp_keyserver, 0);
381 if (x509_certfile != NULL)
382 if (gnutls_certificate_set_x509_key_file
383 (cert_cred, x509_certfile, x509_keyfile, x509ctype) < 0) {
384 fprintf(stderr,
385 "Error reading '%s' or '%s'\n", x509_certfile,
386 x509_keyfile);
387 exit(1);
390 if (generate != 0)
391 if (gnutls_certificate_set_dh_params(cert_cred, dh_params) < 0) {
392 fprintf(stderr, "Error while setting DH parameters\n");
393 exit(1);
396 /* this is a password file (created with the included srpcrypt utility)
397 * Read README.crypt prior to using SRP.
399 gnutls_srp_allocate_server_sc(&srp_cred);
401 if (srp_passwd!=NULL)
402 if ((ret=gnutls_srp_set_server_cred_file(srp_cred, srp_passwd, srp_passwd_conf)) < 0) {
403 /* only exit is this function is not disabled
405 fprintf(stderr, "Error while setting SRP parameters\n");
408 gnutls_anon_allocate_server_sc(&dh_cred);
409 if (generate != 0)
410 gnutls_anon_set_server_dh_params(dh_cred, dh_params);
412 listen_sd = socket(AF_INET, SOCK_STREAM, 0);
413 ERR(listen_sd, "socket");
415 memset(&sa_serv, '\0', sizeof(sa_serv));
416 sa_serv.sin_family = AF_INET;
417 sa_serv.sin_addr.s_addr = INADDR_ANY;
418 sa_serv.sin_port = htons(port); /* Server Port number */
420 setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int));
421 err = bind(listen_sd, (SA *) & sa_serv, sizeof(sa_serv));
422 ERR(err, "bind");
423 err = listen(listen_sd, 1024);
424 ERR(err, "listen");
426 printf("%s ready. Listening to port '%d'.\n\n", name, port);
428 client_len = sizeof(sa_cli);
430 for (;;) {
431 state = initialize_state();
433 sd = accept(listen_sd, (SA *) & sa_cli, &client_len);
435 printf("- connection from %s, port %d\n",
436 inet_ntop(AF_INET, &sa_cli.sin_addr, topbuf,
437 sizeof(topbuf)), ntohs(sa_cli.sin_port));
440 gnutls_transport_set_ptr(state, sd);
441 do {
442 ret = gnutls_handshake(state);
443 } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
445 if (ret < 0) {
446 close(sd);
447 gnutls_deinit(state);
448 fprintf(stderr,
449 "*** Handshake has failed (%s)\n\n",
450 gnutls_strerror(ret));
451 check_alert(state, ret);
452 continue;
454 printf("- Handshake was completed\n");
455 if ( gnutls_session_is_resumed( state)!=0)
456 printf("*** This is a resumed session\n");
458 print_info(state);
460 i = 0;
461 for (;;) {
462 bzero(buffer, MAX_BUF + 1);
463 ret = read_request(state, buffer, MAX_BUF, (http == 0) ? 1 : 2);
465 if (gnutls_error_is_fatal(ret) == 1 || ret == 0) {
466 fflush(stdout);
467 if (ret == 0) {
468 printf("\n- Peer has closed the GNUTLS connection\n");
469 fflush(stdout);
470 break;
471 } else {
472 fprintf(stderr,
473 "\n*** Received corrupted data(%d). Closing the connection.\n\n",
474 ret);
475 break;
480 if (ret > 0) {
481 if (http == 0) {
482 printf("* Read %d bytes from client.\n", strlen(buffer));
483 do {
484 ret = gnutls_record_send(state, buffer, strlen(buffer));
485 } while (ret ==
486 GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
487 printf("* Wrote %d bytes to client.\n", ret);
488 } else {
489 strcpy(http_buffer, HTTP_BEGIN);
490 peer_print_info(state);
491 strcat(http_buffer, HTTP_END);
492 do {
493 ret =
494 gnutls_record_send(state,
495 http_buffer, strlen(http_buffer));
496 } while (ret ==
497 GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
499 printf("- Served request. Closing connection.\n");
500 break;
503 i++;
504 #ifdef RENEGOTIATE
505 if (i == 20) {
506 do {
507 ret = gnutls_rehandshake(state);
508 } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
510 printf("* Requesting rehandshake.\n");
511 /* continue handshake proccess */
512 do {
513 ret = gnutls_handshake(state);
514 } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
515 printf("* Rehandshake returned %d\n", ret);
517 #endif
519 check_alert(state, ret);
521 if (http != 0) {
522 break; /* close the connection */
525 printf("\n");
526 do {
527 ret = gnutls_bye(state, GNUTLS_SHUT_WR);
528 } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
529 /* do not wait for
530 * the peer to close the connection.
532 close(sd);
533 gnutls_deinit(state);
536 close(listen_sd);
538 gnutls_certificate_free_sc(cert_cred);
539 gnutls_srp_free_server_sc(srp_cred);
540 gnutls_anon_free_server_sc(dh_cred);
542 gnutls_global_deinit();
544 return 0;
548 #define DEFAULT_X509_KEYFILE "x509/key.pem"
549 #define DEFAULT_X509_CERTFILE "x509/cert.pem"
551 #define DEFAULT_X509_KEYFILE2 "x509/key-dsa.pem"
552 #define DEFAULT_X509_CERTFILE2 "x509/cert-dsa.pem"
554 #define DEFAULT_PGP_KEYFILE "openpgp/sec.asc"
555 #define DEFAULT_PGP_CERTFILE "openpgp/pub.asc"
557 #define DEFAULT_X509_CAFILE "x509/ca.pem"
558 #define DEFAULT_X509_CRLFILE NULL;
560 #define DEFAULT_SRP_PASSWD "srp/tpasswd"
561 #define DEFAULT_SRP_PASSWD_CONF "srp/tpasswd.conf"
563 #undef DEBUG
565 static gaainfo info;
566 void gaa_parser(int argc, char **argv)
568 int i, j;
570 if (gaa(argc, argv, &info) != -1) {
571 fprintf(stderr,
572 "Error in the arguments. Use the --help or -h parameters to get more information.\n");
573 exit(1);
576 if (info.http == 0)
577 http = 0;
578 else
579 http = 1;
581 if (info.fmtder == 0)
582 x509ctype = GNUTLS_X509_FMT_PEM;
583 else
584 x509ctype = GNUTLS_X509_FMT_DER;
586 if (info.generate == 0)
587 generate = 0;
588 else
589 generate = 1;
591 port = info.port;
593 #ifdef DEBUG
594 if (info.x509_certfile != NULL)
595 x509_certfile = info.x509_certfile;
596 else
597 x509_certfile = DEFAULT_X509_CERTFILE;
599 if (info.x509_keyfile != NULL)
600 x509_keyfile = info.x509_keyfile;
601 else
602 x509_keyfile = DEFAULT_X509_KEYFILE;
604 if (info.x509_cafile != NULL)
605 x509_cafile = info.x509_certfile;
606 else
607 x509_cafile = DEFAULT_X509_CAFILE;
609 if (info.pgp_certfile != NULL)
610 pgp_certfile = info.pgp_certfile;
611 else
612 pgp_certfile = DEFAULT_PGP_CERTFILE;
614 if (info.pgp_keyfile != NULL)
615 pgp_keyfile = info.pgp_keyfile;
616 else
617 pgp_keyfile = DEFAULT_PGP_KEYFILE;
619 if (info.srp_passwd != NULL)
620 srp_passwd = info.srp_passwd;
621 else
622 srp_passwd = DEFAULT_SRP_PASSWD;
624 if (info.srp_passwd_conf != NULL)
625 srp_passwd_conf = info.srp_passwd_conf;
626 else
627 srp_passwd_conf = DEFAULT_SRP_PASSWD_CONF;
628 #else
629 x509_certfile = info.x509_certfile;
630 x509_keyfile = info.x509_keyfile;
631 x509_cafile = info.x509_cafile;
632 pgp_certfile = info.pgp_certfile;
633 pgp_keyfile = info.pgp_keyfile;
634 srp_passwd = info.srp_passwd;
635 srp_passwd_conf = info.srp_passwd_conf;
636 #endif
638 pgp_keyserver = info.pgp_keyserver;
639 pgp_keyring = info.pgp_keyring;
640 pgp_trustdb = info.pgp_trustdb;
642 if (info.proto != NULL && info.nproto > 0) {
643 for (j = i = 0; i < info.nproto; i++) {
644 if (strncasecmp(info.proto[i], "SSL", 3) == 0)
645 protocol_priority[j++] = GNUTLS_SSL3;
646 if (strncasecmp(info.proto[i], "TLS", 3) == 0)
647 protocol_priority[j++] = GNUTLS_TLS1;
649 protocol_priority[j] = 0;
652 if (info.ciphers != NULL && info.nciphers > 0) {
653 for (j = i = 0; i < info.nciphers; i++) {
654 if (strncasecmp(info.ciphers[i], "RIJ", 3) == 0)
655 cipher_priority[j++] = GNUTLS_CIPHER_RIJNDAEL_128_CBC;
656 if (strncasecmp(info.ciphers[i], "TWO", 3) == 0)
657 cipher_priority[j++] = GNUTLS_CIPHER_TWOFISH_128_CBC;
658 if (strncasecmp(info.ciphers[i], "3DE", 3) == 0)
659 cipher_priority[j++] = GNUTLS_CIPHER_3DES_CBC;
660 if (strncasecmp(info.ciphers[i], "ARC", 3) == 0)
661 cipher_priority[j++] = GNUTLS_CIPHER_ARCFOUR;
663 cipher_priority[j] = 0;
666 if (info.macs != NULL && info.nmacs > 0) {
667 for (j = i = 0; i < info.nmacs; i++) {
668 if (strncasecmp(info.macs[i], "MD5", 3) == 0)
669 mac_priority[j++] = GNUTLS_MAC_MD5;
670 if (strncasecmp(info.macs[i], "SHA", 3) == 0)
671 mac_priority[j++] = GNUTLS_MAC_SHA;
673 mac_priority[j] = 0;
676 if (info.ctype != NULL && info.nctype > 0) {
677 for (j = i = 0; i < info.nctype; i++) {
678 if (strncasecmp(info.ctype[i], "OPE", 3) == 0)
679 cert_type_priority[j++] = GNUTLS_CRT_OPENPGP;
680 if (strncasecmp(info.ctype[i], "X", 1) == 0)
681 cert_type_priority[j++] = GNUTLS_CRT_X509;
683 cert_type_priority[j] = 0;
686 if (info.kx != NULL && info.nkx > 0) {
687 for (j = i = 0; i < info.nkx; i++) {
688 if (strncasecmp(info.kx[i], "SRP", 3) == 0)
689 kx_priority[j++] = GNUTLS_KX_SRP;
690 if (strncasecmp(info.kx[i], "RSA", 3) == 0)
691 kx_priority[j++] = GNUTLS_KX_RSA;
692 if (strncasecmp(info.kx[i], "DHE_RSA", 7) == 0)
693 kx_priority[j++] = GNUTLS_KX_DHE_RSA;
694 if (strncasecmp(info.kx[i], "DHE_DSS", 7) == 0)
695 kx_priority[j++] = GNUTLS_KX_DHE_DSS;
696 if (strncasecmp(info.kx[i], "ANON", 4) == 0)
697 kx_priority[j++] = GNUTLS_KX_ANON_DH;
699 kx_priority[j] = 0;
702 if (info.comp != NULL && info.ncomp > 0) {
703 for (j = i = 0; i < info.ncomp; i++) {
704 if (strncasecmp(info.comp[i], "NUL", 3) == 0)
705 comp_priority[j++] = GNUTLS_COMP_NULL;
706 if (strncasecmp(info.comp[i], "ZLI", 1) == 0)
707 comp_priority[j++] = GNUTLS_COMP_ZLIB;
709 comp_priority[j] = 0;