/[hydra]/hydra/src/ssl.c
ViewVC logotype

Annotation of /hydra/src/ssl.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.20 - (hide annotations)
Thu Mar 9 18:26:30 2006 UTC (18 years ago) by nmav
Branch: MAIN
CVS Tags: hydra_0_1_8, HEAD
Changes since 1.19: +3 -1 lines
File MIME type: text/plain
--disable-smp option now works.

1 nmav 1.1 /*
2 nmav 1.17 * Copyright (C) 2002,2003 Nikos Mavroyanopoulos
3 nmav 1.1 *
4 nmav 1.5 * This file is part of Hydra webserver.
5 nmav 1.1 *
6 nmav 1.5 * Hydra is free software; you can redistribute it and/or modify
7 nmav 1.1 * 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.
10     *
11 nmav 1.5 * Hydra is distributed in the hope that it will be useful,
12 nmav 1.1 * 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.
15     *
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
19     */
20 nmav 1.6
21 nmav 1.1 #include <stdio.h>
22     #include <stdlib.h>
23     #include <string.h>
24     #include "boa.h"
25    
26     #ifdef ENABLE_SSL
27    
28 nmav 1.7 #include "ssl.h"
29    
30 nmav 1.1 #include <gnutls/gnutls.h>
31 nmav 1.17 #include <gnutls/x509.h>
32 nmav 1.18 #include <gcrypt.h>
33 nmav 1.20 #ifdef ENABLE_SMP
34 nmav 1.18 GCRY_THREAD_OPTION_PTHREAD_IMPL;
35 nmav 1.1
36 nmav 1.3 pthread_mutex_t ssl_session_cache_lock = PTHREAD_MUTEX_INITIALIZER;
37     #endif
38    
39 nmav 1.1 extern int ssl_session_cache;
40     extern int ssl_session_timeout;
41    
42     extern char* ssl_ciphers;
43     extern char* ssl_kx;
44     extern char* ssl_mac;
45     extern char* ssl_comp;
46     extern char* ssl_protocol;
47 nmav 1.7 extern int ssl_verify; /* 0 no verify, 1 request certificate, and validate
48     * if sent, 2 require certificate and validate.
49 nmav 1.8 * 3 is request one, and try to verify it. Does not fail in
50     * any case.
51 nmav 1.7 */
52 nmav 1.1
53     static void wrap_db_init(void);
54     static int wrap_db_store(void *dbf, gnutls_datum key, gnutls_datum data);
55     static gnutls_datum wrap_db_fetch(void *dbf, gnutls_datum key);
56     static int wrap_db_delete(void *dbf, gnutls_datum key);
57    
58 nmav 1.2 static int cur = 0; /* points to the credentials structure used */
59 nmav 1.10 static gnutls_certificate_credentials credentials[2] = { NULL, NULL };
60 nmav 1.1
61     static int need_dh_params = 0; /* whether we need to generate DHE
62     * parameters. Depend on the chosen ciphersuites.
63     */
64     static int need_rsa_params = 0;
65    
66    
67     /* we use primes up to 1024 in this server.
68     * otherwise we should add them here.
69     */
70     extern int ssl_dh_bits;
71    
72 nmav 1.2 gnutls_dh_params _dh_params[2];
73     gnutls_rsa_params _rsa_params[2];
74 nmav 1.1
75 nmav 1.2 static int generate_dh_primes( gnutls_dh_params* dh_params)
76 nmav 1.1 {
77 nmav 1.2 if (gnutls_dh_params_init( dh_params) < 0) {
78 nmav 1.1 log_error_time();
79 nmav 1.15 fprintf(stderr, "tls: Error in dh parameter initialization\n");
80 nmav 1.1 exit(1);
81     }
82    
83     /* Generate Diffie Hellman parameters - for use with DHE
84     * kx algorithms. These should be discarded and regenerated
85     * once a day, once a week or once a month. Depends on the
86     * security requirements.
87     */
88    
89 nmav 1.17 if (gnutls_dh_params_generate2( *dh_params, ssl_dh_bits) < 0) {
90 nmav 1.1 log_error_time();
91 nmav 1.15 fprintf(stderr, "tls: Error in prime generation\n");
92 nmav 1.1 exit(1);
93     }
94    
95     log_error_time();
96     fprintf
97     (stderr,
98     "tls: Generated Diffie Hellman parameters [%d bits].\n",
99     ssl_dh_bits);
100    
101 nmav 1.17 return 0;
102 nmav 1.1 }
103    
104 nmav 1.2 static int generate_rsa_params( gnutls_rsa_params* rsa_params)
105 nmav 1.1 {
106 nmav 1.2 if (gnutls_rsa_params_init( rsa_params) < 0) {
107 nmav 1.1 log_error_time();
108 nmav 1.15 fprintf(stderr, "tls: Error in rsa parameter initialization\n");
109 nmav 1.1 exit(1);
110     }
111    
112     /* Generate RSA parameters - for use with RSA-export
113     * cipher suites. These should be discarded and regenerated
114     * once a day, once every 500 transactions etc. Depends on the
115     * security requirements.
116     */
117    
118 nmav 1.17 if (gnutls_rsa_params_generate2( *rsa_params, 512) < 0) {
119 nmav 1.1 log_error_time();
120 nmav 1.15 fprintf(stderr, "tls: Error in rsa parameter generation\n");
121 nmav 1.1 exit(1);
122     }
123    
124     log_error_time();
125     fprintf
126     (stderr, "tls: Generated temporary RSA parameters.\n");
127    
128     return 0;
129     }
130    
131     static int protocol_priority[16];
132     static int kx_priority[16];
133     static int cipher_priority[16];
134     static int mac_priority[16];
135     static int comp_priority[16];
136    
137     /* Parses a string in the form:
138 nmav 1.10 * CIPHER1, CIPHER2, ... and tries to find the given algorithm.
139     * This is inefficient. Returns true or false.
140 nmav 1.1 */
141     static int parse_cs_string( const char* string, const char* algo)
142     {
143 nmav 1.10 char *broken_list[MAX_COMMA_SEP_ELEMENTS];
144     int broken_list_size, i;
145     char list[64];
146    
147 nmav 1.1 if (string == NULL || algo == NULL) return 0;
148 nmav 1.10
149     if (strlen( string) > sizeof(list)-1) return 0;
150 nmav 1.1
151 nmav 1.10 strcpy( list, string);
152    
153     break_comma_list( list, broken_list, &broken_list_size);
154    
155     for (i=0;i<broken_list_size;i++) {
156     if (strcmp( broken_list[i], algo) == 0) {
157 nmav 1.1 return 1;
158 nmav 1.10 }
159     }
160 nmav 1.1
161     return 0;
162    
163     }
164    
165 nmav 1.10 /* Initializes a single SSL/TLS session. That is set the algorithm,
166     * the db backend, whether to request certificates etc.
167     */
168 nmav 1.1 gnutls_session initialize_ssl_session(void)
169     {
170 nmav 1.16 gnutls_session state;
171 nmav 1.1
172     gnutls_init(&state, GNUTLS_SERVER);
173    
174     gnutls_cipher_set_priority(state, cipher_priority);
175     gnutls_compression_set_priority(state, comp_priority);
176     gnutls_kx_set_priority(state, kx_priority);
177     gnutls_protocol_set_priority(state, protocol_priority);
178     gnutls_mac_set_priority(state, mac_priority);
179    
180 nmav 1.16 gnutls_credentials_set(state, GNUTLS_CRD_CERTIFICATE, credentials[ cur]);
181 nmav 1.1
182     gnutls_certificate_server_set_request(state, GNUTLS_CERT_IGNORE);
183    
184     if (ssl_session_cache != 0) {
185     gnutls_db_set_retrieve_function(state, wrap_db_fetch);
186     gnutls_db_set_remove_function(state, wrap_db_delete);
187     gnutls_db_set_store_function(state, wrap_db_store);
188     gnutls_db_set_ptr(state, NULL);
189     }
190     gnutls_db_set_cache_expiration( state, ssl_session_timeout);
191    
192 nmav 1.9 /* gnutls_handshake_set_private_extensions( state, 1); */
193 nmav 1.1
194 nmav 1.8 if (ssl_verify == 1 || ssl_verify == 3) {
195 nmav 1.7 gnutls_certificate_server_set_request( state, GNUTLS_CERT_REQUEST);
196     } else if (ssl_verify == 2) {
197     gnutls_certificate_server_set_request( state, GNUTLS_CERT_REQUIRE);
198 nmav 1.10 } else { /* default */
199     gnutls_certificate_server_set_request(state, GNUTLS_CERT_IGNORE);
200 nmav 1.7 }
201    
202 nmav 1.10
203 nmav 1.1 return state;
204     }
205    
206 nmav 1.7 extern char *ca_cert;
207 nmav 1.1 extern char *server_cert;
208     extern char *server_key;
209    
210     /* Initialization of gnutls' global state
211     */
212     int initialize_ssl(void)
213     {
214     int i;
215    
216 nmav 1.15 log_error_time();
217     fprintf(stderr, "tls: Initializing GnuTLS/%s.\n", gnutls_check_version(NULL));
218 nmav 1.20 #ifdef ENABLE_SMP
219 nmav 1.18 gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
220 nmav 1.20 #endif
221 nmav 1.1 gnutls_global_init();
222    
223 nmav 1.2 if (gnutls_certificate_allocate_credentials( &credentials[0]) < 0) {
224 nmav 1.1 log_error_time();
225 nmav 1.15 fprintf(stderr, "tls: certificate allocation error\n");
226 nmav 1.1 exit(1);
227     }
228    
229     if (gnutls_certificate_set_x509_key_file
230 nmav 1.2 ( credentials[0], server_cert, server_key, GNUTLS_X509_FMT_PEM) < 0) {
231 nmav 1.1 log_error_time();
232 nmav 1.15 fprintf(stderr, "tls: could not find '%s' or '%s'.\n", server_cert,
233 nmav 1.1 server_key);
234     exit(1);
235     }
236    
237 nmav 1.7 if (ca_cert != NULL && gnutls_certificate_set_x509_trust_file
238     ( credentials[0], ca_cert, GNUTLS_X509_FMT_PEM) < 0) {
239     log_error_time();
240 nmav 1.15 fprintf(stderr, "tls: could not find '%s'.\n", ca_cert);
241 nmav 1.7 exit(1);
242     }
243    
244 nmav 1.1 if (ssl_session_cache != 0)
245     wrap_db_init();
246    
247     /* Add ciphers
248     */
249     i = 0;
250     if ( parse_cs_string( ssl_ciphers, "AES") != 0)
251     cipher_priority[i++] = GNUTLS_CIPHER_RIJNDAEL_128_CBC;
252     if ( parse_cs_string( ssl_ciphers, "ARCFOUR-128") != 0)
253     cipher_priority[i++] = GNUTLS_CIPHER_ARCFOUR_128;
254     if ( parse_cs_string( ssl_ciphers, "3DES") != 0)
255     cipher_priority[i++] = GNUTLS_CIPHER_3DES_CBC;
256     if ( parse_cs_string( ssl_ciphers, "ARCFOUR-40") != 0)
257     cipher_priority[i++] = GNUTLS_CIPHER_ARCFOUR_40;
258     cipher_priority[i] = 0;
259    
260     /* Add key exchange methods
261     */
262     i = 0;
263     if ( parse_cs_string( ssl_kx, "RSA") != 0)
264     kx_priority[i++] = GNUTLS_KX_RSA;
265     if ( parse_cs_string( ssl_kx, "RSA-EXPORT") != 0) {
266     kx_priority[i++] = GNUTLS_KX_RSA_EXPORT;
267     need_rsa_params = 1;
268     }
269     if ( parse_cs_string( ssl_kx, "DHE-RSA") != 0) {
270     kx_priority[i++] = GNUTLS_KX_DHE_RSA;
271     need_dh_params = 1; /* generate DH parameters */
272     }
273     if ( parse_cs_string( ssl_kx, "DHE-DSS") != 0) {
274     kx_priority[i++] = GNUTLS_KX_DHE_DSS;
275     need_dh_params = 1;
276     }
277     kx_priority[i] = 0;
278    
279     /* Add MAC Algorithms
280     */
281     i = 0;
282     if ( parse_cs_string( ssl_mac, "MD5") != 0)
283     mac_priority[i++] = GNUTLS_MAC_MD5;
284 nmav 1.11 if ( parse_cs_string( ssl_mac, "SHA1") != 0)
285 nmav 1.1 mac_priority[i++] = GNUTLS_MAC_SHA;
286 nmav 1.19 if ( parse_cs_string( ssl_mac, "RMD160") != 0)
287     mac_priority[i++] = GNUTLS_MAC_RMD160;
288 nmav 1.1 mac_priority[i] = 0;
289    
290     /* Add Compression algorithms
291     */
292     i = 0;
293     if ( parse_cs_string( ssl_comp, "NULL") != 0)
294     comp_priority[i++] = GNUTLS_COMP_NULL;
295     if ( parse_cs_string( ssl_comp, "ZLIB") != 0)
296     comp_priority[i++] = GNUTLS_COMP_ZLIB;
297     if ( parse_cs_string( ssl_comp, "LZO") != 0)
298     comp_priority[i++] = GNUTLS_COMP_LZO;
299     comp_priority[i] = 0;
300    
301     /* Add protocols
302     */
303     i = 0;
304 nmav 1.10 if ( parse_cs_string( ssl_protocol, "TLS1.0") != 0)
305 nmav 1.1 protocol_priority[i++] = GNUTLS_TLS1;
306 nmav 1.19 if ( parse_cs_string( ssl_protocol, "TLS1.1") != 0)
307     protocol_priority[i++] = GNUTLS_TLS1_1;
308 nmav 1.10 if ( parse_cs_string( ssl_protocol, "SSL3.0") != 0)
309 nmav 1.1 protocol_priority[i++] = GNUTLS_SSL3;
310     protocol_priority[i] = 0;
311    
312     /* Generate temporary parameters -- if needed.
313     */
314     if (need_rsa_params) {
315 nmav 1.2 generate_rsa_params( &_rsa_params[0]);
316 nmav 1.19 gnutls_certificate_set_rsa_export_params(credentials[0], _rsa_params[0]);
317 nmav 1.1 }
318    
319     if (need_dh_params) {
320 nmav 1.2 generate_dh_primes( &_dh_params[0]);
321     gnutls_certificate_set_dh_params(credentials[0], _dh_params[0]);
322 nmav 1.1 }
323    
324     return 0;
325     }
326    
327     /* This function will regenerate the SSL parameters (RSA and DH) without
328     * any need for downtime.
329     */
330 nmav 1.10
331 nmav 1.1 void ssl_regenerate_params(void)
332     {
333 nmav 1.10 static int already_here; /* static so the default value == 0 */
334 nmav 1.2 int _cur = (cur + 1) % 2;
335    
336 nmav 1.10 /* There is a rare situation where we have been here, because of
337     * a SIGHUP signal, and the process receives a SIGALRM as well.
338     * We try to avoid messing everything up.
339     */
340     if (already_here != 0) return;
341     already_here = 1;
342    
343 nmav 1.2 /* The hint here, is that we keep a copy of 2 certificate credentials.
344     * When we come here, we free the unused copy and allocate new
345     * parameters to it. Then we make the current copy to be this copy.
346     *
347     * We don't free the previous copy because we don't know if anyone
348     * is using it. (this has to be fixed)
349     */
350 nmav 1.1
351     time(&current_time);
352    
353 nmav 1.2 if ( !credentials[_cur]) {
354     if (gnutls_certificate_allocate_credentials( &credentials[ _cur]) < 0) {
355     log_error_time();
356 nmav 1.15 fprintf(stderr, "tls: certificate allocation error\n");
357 nmav 1.2 exit(1);
358     }
359    
360     if (gnutls_certificate_set_x509_key_file
361     ( credentials[_cur], server_cert, server_key, GNUTLS_X509_FMT_PEM) < 0) {
362     log_error_time();
363 nmav 1.15 fprintf(stderr, "tls: could not find '%s' or '%s'.", server_cert,
364 nmav 1.2 server_key);
365     exit(1);
366     }
367 nmav 1.7
368     if (ca_cert!=NULL && gnutls_certificate_set_x509_trust_file
369     ( credentials[_cur], ca_cert, GNUTLS_X509_FMT_PEM) < 0) {
370     log_error_time();
371 nmav 1.15 fprintf(stderr, "tls: could not find '%s'.\n", ca_cert);
372 nmav 1.7 exit(1);
373     }
374 nmav 1.2 }
375    
376 nmav 1.1 if (need_rsa_params) {
377 nmav 1.2 gnutls_rsa_params_deinit( _rsa_params[ _cur]);
378     generate_rsa_params( &_rsa_params[ _cur]);
379 nmav 1.19 gnutls_certificate_set_rsa_export_params(credentials[_cur], _rsa_params[ _cur]);
380 nmav 1.1 }
381    
382     if (need_dh_params) {
383 nmav 1.2 gnutls_dh_params_deinit( _dh_params[ _cur]);
384     generate_dh_primes( &_dh_params[ _cur]);
385     gnutls_certificate_set_dh_params(credentials[_cur], _dh_params[ _cur]);
386 nmav 1.1 }
387 nmav 1.2
388     cur = _cur;
389 nmav 1.1
390 nmav 1.10 already_here = 0;
391 nmav 1.1 return;
392     }
393    
394    
395     /* Session resuming:
396     */
397    
398     #define SESSION_ID_SIZE 32
399 nmav 1.14 #define SESSION_DATA_SIZE 1024
400 nmav 1.1
401     typedef struct {
402     char session_id[SESSION_ID_SIZE];
403     int session_id_size;
404    
405     char session_data[SESSION_DATA_SIZE];
406     int session_data_size;
407     } CACHE;
408    
409     static CACHE *cache_db;
410 nmav 1.3 static int cache_db_ptr;
411 nmav 1.1
412     static void wrap_db_init(void)
413     {
414    
415     /* allocate cache_db */
416     cache_db = calloc(1, ssl_session_cache * sizeof(CACHE));
417     }
418    
419     static int wrap_db_store(void *dbf, gnutls_datum key, gnutls_datum data)
420     {
421    
422     if (cache_db == NULL)
423     return -1;
424    
425     if (key.size > SESSION_ID_SIZE)
426     return -1;
427     if (data.size > SESSION_DATA_SIZE)
428     return -1;
429    
430 nmav 1.3 #ifdef ENABLE_SMP
431     pthread_mutex_lock( &ssl_session_cache_lock);
432     #endif
433    
434 nmav 1.1 memcpy(cache_db[cache_db_ptr].session_id, key.data, key.size);
435     cache_db[cache_db_ptr].session_id_size = key.size;
436    
437     memcpy(cache_db[cache_db_ptr].session_data, data.data, data.size);
438     cache_db[cache_db_ptr].session_data_size = data.size;
439    
440 nmav 1.4 cache_db_ptr++;
441     cache_db_ptr %= ssl_session_cache;
442 nmav 1.3
443     #ifdef ENABLE_SMP
444     pthread_mutex_unlock( &ssl_session_cache_lock);
445     #endif
446 nmav 1.1
447     return 0;
448     }
449    
450     static gnutls_datum wrap_db_fetch(void *dbf, gnutls_datum key)
451     {
452     gnutls_datum res = { NULL, 0 };
453     int i;
454    
455     if (cache_db == NULL)
456     return res;
457    
458 nmav 1.3 #ifdef ENABLE_SMP
459     pthread_mutex_lock( &ssl_session_cache_lock);
460     #endif
461    
462 nmav 1.1 for (i = 0; i < ssl_session_cache; i++) {
463     if (key.size == cache_db[i].session_id_size &&
464     memcmp(key.data, cache_db[i].session_id, key.size) == 0) {
465    
466     res.size = cache_db[i].session_data_size;
467    
468     res.data = malloc(res.size);
469 nmav 1.3 if (res.data == NULL) {
470     #ifdef ENABLE_SMP
471     pthread_mutex_unlock( &ssl_session_cache_lock);
472     #endif
473 nmav 1.1 return res;
474 nmav 1.3 }
475 nmav 1.1
476     memcpy(res.data, cache_db[i].session_data, res.size);
477    
478 nmav 1.3 #ifdef ENABLE_SMP
479     pthread_mutex_unlock( &ssl_session_cache_lock);
480     #endif
481 nmav 1.1 return res;
482     }
483     }
484 nmav 1.3
485     #ifdef ENABLE_SMP
486     pthread_mutex_unlock( &ssl_session_cache_lock);
487     #endif
488    
489 nmav 1.1 return res;
490     }
491    
492     static int wrap_db_delete(void *dbf, gnutls_datum key)
493     {
494     int i;
495    
496     if (cache_db == NULL)
497     return -1;
498    
499 nmav 1.3 #ifdef ENABLE_SMP
500     pthread_mutex_lock( &ssl_session_cache_lock);
501     #endif
502    
503 nmav 1.1 for (i = 0; i < ssl_session_cache; i++) {
504     if (key.size == cache_db[i].session_id_size &&
505     memcmp(key.data, cache_db[i].session_id, key.size) == 0) {
506    
507     cache_db[i].session_id_size = 0;
508     cache_db[i].session_data_size = 0;
509    
510 nmav 1.3 #ifdef ENABLE_SMP
511     pthread_mutex_unlock( &ssl_session_cache_lock);
512     #endif
513    
514 nmav 1.1 return 0;
515     }
516     }
517 nmav 1.3
518     #ifdef ENABLE_SMP
519     pthread_mutex_unlock( &ssl_session_cache_lock);
520     #endif
521 nmav 1.1 return -1;
522    
523     }
524    
525     void check_ssl_alert( request* req, int ret)
526     {
527     int last_alert;
528    
529     if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED || ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
530     {
531     last_alert = gnutls_alert_get(req->ssl_state);
532     log_error_doc(req);
533 nmav 1.16 fprintf(stderr, "tls: Received alert %d '%s'.\n", last_alert, gnutls_alert_get_name(last_alert));
534 nmav 1.1 }
535     }
536    
537     int finish_handshake(request * current)
538     {
539     int retval;
540    
541     retval = gnutls_handshake(current->ssl_state);
542    
543     if (retval == GNUTLS_E_AGAIN)
544     retval = -1;
545     else if (retval == GNUTLS_E_INTERRUPTED)
546     retval = 1;
547     else if (retval < 0) {
548     if (gnutls_error_is_fatal(retval) != 0) {
549     log_error_doc(current);
550 nmav 1.15 fprintf(stderr, "tls: Handshake error '%s'.\n", gnutls_strerror(retval));
551 nmav 1.1 check_ssl_alert( current, retval);
552    
553     /* we ignore the level of the alert, since we always
554     * send fatal alerts.
555     */
556     current->alert_to_send = gnutls_error_to_alert( retval, NULL);
557 nmav 1.11 if (current->alert_to_send == GNUTLS_E_INVALID_REQUEST)
558     current->alert_to_send = GNUTLS_A_HANDSHAKE_FAILURE;
559    
560     current->status = SEND_ALERT;
561 nmav 1.1 retval = 1;
562     } else {
563     check_ssl_alert( current, retval);
564     retval = 1;
565     }
566     } else if (retval == 0) {
567 nmav 1.7
568 nmav 1.8 if (ssl_verify >= 1) {
569 nmav 1.17 size_t size;
570     int verify, ret, valid;
571 nmav 1.7 char name[128];
572     const gnutls_datum *cert_list;
573     int cert_list_size;
574 nmav 1.17 gnutls_x509_crt crt = NULL;
575    
576     ret = gnutls_x509_crt_init( &crt);
577     if (ret < 0) {
578     log_error_time();
579     fprintf( stderr, "tls: Error in crt_init(): %s\n", gnutls_strerror(ret));
580     current->alert_to_send = GNUTLS_A_INTERNAL_ERROR;
581     current->status = SEND_ALERT;
582     return 1;
583     }
584    
585     cert_list =
586     gnutls_certificate_get_peers(current->ssl_state, &cert_list_size);
587    
588     if (cert_list) {
589     ret = gnutls_x509_crt_import( crt, &cert_list[0], GNUTLS_X509_FMT_DER);
590     if (ret < 0) {
591     log_error_time();
592     fprintf( stderr, "tls: Could not import X.509 certificate: %s\n", gnutls_strerror(ret));
593     current->alert_to_send = GNUTLS_A_INTERNAL_ERROR;
594     current->status = SEND_ALERT;
595     return 1;
596     }
597    
598     size = sizeof(name);
599     if (gnutls_x509_crt_get_dn(crt, name, &size) < 0)
600     strcpy(name, "Unknown");
601     }
602    
603 nmav 1.7
604     verify = gnutls_certificate_verify_peers( current->ssl_state);
605 nmav 1.8 current->certificate_verified = "NONE";
606    
607 nmav 1.17 if (cert_list == NULL) {
608     log_error_time();
609     fprintf( stderr, "tls: Peer did not send a certificate.\n");
610     if (ssl_verify == 2) {
611     current->alert_to_send = GNUTLS_A_ACCESS_DENIED;
612     current->status = SEND_ALERT;
613     return 1;
614     }
615     } else { /* cert_list */
616     log_error_time();
617     valid = 0;
618     fprintf( stderr, "tls: X.509 Certificate by '%s' is ", name);
619    
620     if (gnutls_x509_crt_get_expiration_time( crt) < current_time) {
621     fprintf(stderr, "Expired");
622     valid = 1;
623     }
624    
625     if (gnutls_x509_crt_get_activation_time( crt) > current_time) {
626     if (!valid) fprintf(stderr, "Not yet activated");
627     valid = 1;
628     }
629 nmav 1.7
630 nmav 1.17 if (valid || verify & GNUTLS_CERT_INVALID || verify & GNUTLS_CERT_REVOKED)
631 nmav 1.7 {
632 nmav 1.8 current->certificate_verified = "FAILED";
633 nmav 1.17 fprintf( stderr, ", NOT trusted");
634     if (verify & GNUTLS_CERT_REVOKED)
635     fprintf( stderr, ", Revoked");
636     if (verify & GNUTLS_CERT_SIGNER_NOT_FOUND)
637     fprintf( stderr, ", Issuer not known");
638     if (verify & GNUTLS_CERT_SIGNER_NOT_CA)
639     fprintf( stderr, ", Issuer is not a CA");
640     fprintf( stderr, ".\n");
641 nmav 1.8
642     if (ssl_verify == 2 || ssl_verify == 1) {
643     current->alert_to_send = GNUTLS_A_BAD_CERTIFICATE;
644     current->status = SEND_ALERT;
645 nmav 1.17 gnutls_x509_crt_deinit(crt);
646 nmav 1.8 return 1;
647     }
648     } else {
649     current->certificate_verified = "SUCCESS";
650 nmav 1.17 fprintf( stderr, "trusted.\n");
651 nmav 1.7 }
652     }
653    
654 nmav 1.17 gnutls_x509_crt_deinit(crt);
655 nmav 1.7 }
656 nmav 1.1 retval = 1;
657     current->status = READ_HEADER;
658     }
659    
660     return retval;
661     }
662    
663     int send_alert(request * current)
664     {
665     int retval;
666    
667     retval = gnutls_alert_send( current->ssl_state,
668     GNUTLS_AL_FATAL, current->alert_to_send);
669    
670     if (retval == GNUTLS_E_AGAIN)
671     retval = -1;
672     else if (retval == GNUTLS_E_INTERRUPTED)
673     retval = 1;
674     else if (retval <= 0) {
675     retval = 0;
676     current->status = DEAD;
677     }
678    
679     return retval;
680     }
681    
682 nmav 1.10 /* This will parse the ciphers given and set the new ciphers.
683     * If required it will regenerate RSA and DHE parameters.
684     */
685     void ssl_reinit()
686     {
687     int i;
688    
689     need_dh_params = 0;
690     need_rsa_params = 0;
691    
692     /* Add ciphers
693     */
694     i = 0;
695     if ( parse_cs_string( ssl_ciphers, "AES") != 0)
696     cipher_priority[i++] = GNUTLS_CIPHER_RIJNDAEL_128_CBC;
697     if ( parse_cs_string( ssl_ciphers, "ARCFOUR-128") != 0)
698     cipher_priority[i++] = GNUTLS_CIPHER_ARCFOUR_128;
699     if ( parse_cs_string( ssl_ciphers, "3DES") != 0)
700     cipher_priority[i++] = GNUTLS_CIPHER_3DES_CBC;
701     if ( parse_cs_string( ssl_ciphers, "ARCFOUR-40") != 0)
702     cipher_priority[i++] = GNUTLS_CIPHER_ARCFOUR_40;
703     cipher_priority[i] = 0;
704    
705     /* Add key exchange methods
706     */
707     i = 0;
708     if ( parse_cs_string( ssl_kx, "RSA") != 0)
709     kx_priority[i++] = GNUTLS_KX_RSA;
710     if ( parse_cs_string( ssl_kx, "RSA-EXPORT") != 0) {
711     kx_priority[i++] = GNUTLS_KX_RSA_EXPORT;
712     need_rsa_params = 1;
713     }
714     if ( parse_cs_string( ssl_kx, "DHE-RSA") != 0) {
715     kx_priority[i++] = GNUTLS_KX_DHE_RSA;
716     need_dh_params = 1; /* generate DH parameters */
717     }
718     if ( parse_cs_string( ssl_kx, "DHE-DSS") != 0) {
719     kx_priority[i++] = GNUTLS_KX_DHE_DSS;
720     need_dh_params = 1;
721     }
722     kx_priority[i] = 0;
723    
724     /* Add MAC Algorithms
725     */
726     i = 0;
727     if ( parse_cs_string( ssl_mac, "MD5") != 0)
728     mac_priority[i++] = GNUTLS_MAC_MD5;
729 nmav 1.11 if ( parse_cs_string( ssl_mac, "SHA1") != 0)
730 nmav 1.10 mac_priority[i++] = GNUTLS_MAC_SHA;
731     mac_priority[i] = 0;
732    
733     /* Add Compression algorithms
734     */
735     i = 0;
736     if ( parse_cs_string( ssl_comp, "NULL") != 0)
737     comp_priority[i++] = GNUTLS_COMP_NULL;
738     if ( parse_cs_string( ssl_comp, "ZLIB") != 0)
739     comp_priority[i++] = GNUTLS_COMP_ZLIB;
740     if ( parse_cs_string( ssl_comp, "LZO") != 0)
741     comp_priority[i++] = GNUTLS_COMP_LZO;
742     comp_priority[i] = 0;
743    
744     /* Add protocols
745     */
746     i = 0;
747     if ( parse_cs_string( ssl_protocol, "TLS1.0") != 0)
748     protocol_priority[i++] = GNUTLS_TLS1;
749     if ( parse_cs_string( ssl_protocol, "SSL3.0") != 0)
750     protocol_priority[i++] = GNUTLS_SSL3;
751     protocol_priority[i] = 0;
752    
753    
754     /* Generate temporary parameters -- if needed.
755     */
756     ssl_regenerate_params();
757    
758     return;
759     }
760    
761 nmav 1.1 #else /* a stub for initialize_ssl */
762    
763     int initialize_ssl(void)
764     {
765     log_error_time();
766 nmav 1.15 fprintf(stderr, "tls: SSL is not available in this build. Disable SSL in Hydra's configuration file.\n");
767 nmav 1.1 exit(1);
768 nmav 1.10 }
769    
770     void ssl_reinit() {
771     return;
772 nmav 1.1 }
773    
774     #endif

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26