1 |
/* |
/* |
2 |
* Copyright (C) 2002 Nikos Mavroyanopoulos |
* Copyright (C) 2002,2003 Nikos Mavroyanopoulos |
3 |
* |
* |
4 |
* This file is part of Hydra webserver. |
* This file is part of Hydra webserver. |
5 |
* |
* |
28 |
#include "ssl.h" |
#include "ssl.h" |
29 |
|
|
30 |
#include <gnutls/gnutls.h> |
#include <gnutls/gnutls.h> |
31 |
#include <gcrypt.h> |
#include <gnutls/x509.h> |
32 |
|
|
33 |
#ifdef ENABLE_SMP |
#ifdef ENABLE_SMP |
34 |
pthread_mutex_t ssl_session_cache_lock = PTHREAD_MUTEX_INITIALIZER; |
pthread_mutex_t ssl_session_cache_lock = PTHREAD_MUTEX_INITIALIZER; |
72 |
|
|
73 |
static int generate_dh_primes( gnutls_dh_params* dh_params) |
static int generate_dh_primes( gnutls_dh_params* dh_params) |
74 |
{ |
{ |
|
gnutls_datum prime, generator; |
|
|
|
|
75 |
if (gnutls_dh_params_init( dh_params) < 0) { |
if (gnutls_dh_params_init( dh_params) < 0) { |
76 |
log_error_time(); |
log_error_time(); |
77 |
fprintf(stderr, "tls: Error in dh parameter initialization\n"); |
fprintf(stderr, "tls: Error in dh parameter initialization\n"); |
84 |
* security requirements. |
* security requirements. |
85 |
*/ |
*/ |
86 |
|
|
87 |
if (gnutls_dh_params_generate(&prime, &generator, ssl_dh_bits) < |
if (gnutls_dh_params_generate2( *dh_params, ssl_dh_bits) < 0) { |
|
0) { |
|
88 |
log_error_time(); |
log_error_time(); |
89 |
fprintf(stderr, "tls: Error in prime generation\n"); |
fprintf(stderr, "tls: Error in prime generation\n"); |
90 |
exit(1); |
exit(1); |
91 |
} |
} |
92 |
|
|
|
if (gnutls_dh_params_set |
|
|
(*dh_params, prime, generator, ssl_dh_bits) < 0) { |
|
|
log_error_time(); |
|
|
fprintf(stderr, "tls: Error in prime replacement\n"); |
|
|
exit(1); |
|
|
} |
|
|
|
|
93 |
log_error_time(); |
log_error_time(); |
94 |
fprintf |
fprintf |
95 |
(stderr, |
(stderr, |
96 |
"tls: Generated Diffie Hellman parameters [%d bits].\n", |
"tls: Generated Diffie Hellman parameters [%d bits].\n", |
97 |
ssl_dh_bits); |
ssl_dh_bits); |
98 |
|
|
99 |
free(prime.data); |
return 0; |
|
free(generator.data); |
|
|
|
|
|
return 0; |
|
100 |
} |
} |
101 |
|
|
102 |
static int generate_rsa_params( gnutls_rsa_params* rsa_params) |
static int generate_rsa_params( gnutls_rsa_params* rsa_params) |
103 |
{ |
{ |
|
gnutls_datum m, e, d, p, q, u; |
|
|
|
|
104 |
if (gnutls_rsa_params_init( rsa_params) < 0) { |
if (gnutls_rsa_params_init( rsa_params) < 0) { |
105 |
log_error_time(); |
log_error_time(); |
106 |
fprintf(stderr, "tls: Error in rsa parameter initialization\n"); |
fprintf(stderr, "tls: Error in rsa parameter initialization\n"); |
113 |
* security requirements. |
* security requirements. |
114 |
*/ |
*/ |
115 |
|
|
116 |
if (gnutls_rsa_params_generate(&m, &e, &d, &p, &q, &u, 512) < 0) { |
if (gnutls_rsa_params_generate2( *rsa_params, 512) < 0) { |
117 |
log_error_time(); |
log_error_time(); |
118 |
fprintf(stderr, "tls: Error in rsa parameter generation\n"); |
fprintf(stderr, "tls: Error in rsa parameter generation\n"); |
119 |
exit(1); |
exit(1); |
120 |
} |
} |
121 |
|
|
|
if (gnutls_rsa_params_set( *rsa_params, m, e, d, p, q, u, 512) < 0) { |
|
|
log_error_time(); |
|
|
fprintf(stderr, "tls: Error in rsa parameter setting\n"); |
|
|
exit(1); |
|
|
} |
|
|
|
|
|
free(m.data); |
|
|
free(e.data); |
|
|
free(d.data); |
|
|
free(p.data); |
|
|
free(q.data); |
|
|
free(u.data); |
|
|
|
|
122 |
log_error_time(); |
log_error_time(); |
123 |
fprintf |
fprintf |
124 |
(stderr, "tls: Generated temporary RSA parameters.\n"); |
(stderr, "tls: Generated temporary RSA parameters.\n"); |
214 |
log_error_time(); |
log_error_time(); |
215 |
fprintf(stderr, "tls: Initializing GnuTLS/%s.\n", gnutls_check_version(NULL)); |
fprintf(stderr, "tls: Initializing GnuTLS/%s.\n", gnutls_check_version(NULL)); |
216 |
gnutls_global_init(); |
gnutls_global_init(); |
|
/* gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING, NULL, 0); */ |
|
217 |
|
|
218 |
if (gnutls_certificate_allocate_credentials( &credentials[0]) < 0) { |
if (gnutls_certificate_allocate_credentials( &credentials[0]) < 0) { |
219 |
log_error_time(); |
log_error_time(); |
557 |
} else if (retval == 0) { |
} else if (retval == 0) { |
558 |
|
|
559 |
if (ssl_verify >= 1) { |
if (ssl_verify >= 1) { |
560 |
int verify; |
size_t size; |
561 |
|
int verify, ret, valid; |
562 |
char name[128]; |
char name[128]; |
563 |
const gnutls_datum *cert_list; |
const gnutls_datum *cert_list; |
564 |
int cert_list_size; |
int cert_list_size; |
565 |
|
gnutls_x509_crt crt = NULL; |
566 |
|
|
567 |
verify = gnutls_certificate_verify_peers( current->ssl_state); |
ret = gnutls_x509_crt_init( &crt); |
568 |
current->certificate_verified = "NONE"; |
if (ret < 0) { |
569 |
|
log_error_time(); |
570 |
|
fprintf( stderr, "tls: Error in crt_init(): %s\n", gnutls_strerror(ret)); |
571 |
|
current->alert_to_send = GNUTLS_A_INTERNAL_ERROR; |
572 |
|
current->status = SEND_ALERT; |
573 |
|
return 1; |
574 |
|
} |
575 |
|
|
576 |
if (verify != GNUTLS_E_NO_CERTIFICATE_FOUND || ssl_verify == 2) { |
cert_list = |
577 |
cert_list = |
gnutls_certificate_get_peers(current->ssl_state, &cert_list_size); |
|
gnutls_certificate_get_peers(current->ssl_state, &cert_list_size); |
|
578 |
|
|
579 |
if (cert_list) |
if (cert_list) { |
580 |
if (gnutls_x509_extract_certificate_dn_string(name, sizeof(name), |
ret = gnutls_x509_crt_import( crt, &cert_list[0], GNUTLS_X509_FMT_DER); |
581 |
&cert_list[0], 0) < 0) strcpy(name, "Unknown"); |
if (ret < 0) { |
582 |
|
log_error_time(); |
583 |
|
fprintf( stderr, "tls: Could not import X.509 certificate: %s\n", gnutls_strerror(ret)); |
584 |
|
current->alert_to_send = GNUTLS_A_INTERNAL_ERROR; |
585 |
|
current->status = SEND_ALERT; |
586 |
|
return 1; |
587 |
|
} |
588 |
|
|
589 |
|
size = sizeof(name); |
590 |
|
if (gnutls_x509_crt_get_dn(crt, name, &size) < 0) |
591 |
|
strcpy(name, "Unknown"); |
592 |
|
} |
593 |
|
|
594 |
|
|
595 |
|
verify = gnutls_certificate_verify_peers( current->ssl_state); |
596 |
|
current->certificate_verified = "NONE"; |
597 |
|
|
598 |
|
if (cert_list == NULL) { |
599 |
|
log_error_time(); |
600 |
|
fprintf( stderr, "tls: Peer did not send a certificate.\n"); |
601 |
|
if (ssl_verify == 2) { |
602 |
|
current->alert_to_send = GNUTLS_A_ACCESS_DENIED; |
603 |
|
current->status = SEND_ALERT; |
604 |
|
return 1; |
605 |
|
} |
606 |
|
} else { /* cert_list */ |
607 |
log_error_time(); |
log_error_time(); |
608 |
if (verify & GNUTLS_CERT_NOT_TRUSTED || verify & GNUTLS_CERT_INVALID || |
valid = 0; |
609 |
verify & GNUTLS_CERT_CORRUPTED || verify & GNUTLS_CERT_REVOKED) |
fprintf( stderr, "tls: X.509 Certificate by '%s' is ", name); |
610 |
|
|
611 |
|
if (gnutls_x509_crt_get_expiration_time( crt) < current_time) { |
612 |
|
fprintf(stderr, "Expired"); |
613 |
|
valid = 1; |
614 |
|
} |
615 |
|
|
616 |
|
if (gnutls_x509_crt_get_activation_time( crt) > current_time) { |
617 |
|
if (!valid) fprintf(stderr, "Not yet activated"); |
618 |
|
valid = 1; |
619 |
|
} |
620 |
|
|
621 |
|
if (valid || verify & GNUTLS_CERT_INVALID || verify & GNUTLS_CERT_REVOKED) |
622 |
{ |
{ |
623 |
current->certificate_verified = "FAILED"; |
current->certificate_verified = "FAILED"; |
624 |
fprintf( stderr, "tls: X.509 Certificate by '%s' is NOT trusted.\n", name); |
fprintf( stderr, ", NOT trusted"); |
625 |
|
if (verify & GNUTLS_CERT_REVOKED) |
626 |
|
fprintf( stderr, ", Revoked"); |
627 |
|
if (verify & GNUTLS_CERT_SIGNER_NOT_FOUND) |
628 |
|
fprintf( stderr, ", Issuer not known"); |
629 |
|
if (verify & GNUTLS_CERT_SIGNER_NOT_CA) |
630 |
|
fprintf( stderr, ", Issuer is not a CA"); |
631 |
|
fprintf( stderr, ".\n"); |
632 |
|
|
633 |
if (ssl_verify == 2 || ssl_verify == 1) { |
if (ssl_verify == 2 || ssl_verify == 1) { |
634 |
current->alert_to_send = GNUTLS_A_BAD_CERTIFICATE; |
current->alert_to_send = GNUTLS_A_BAD_CERTIFICATE; |
635 |
current->status = SEND_ALERT; |
current->status = SEND_ALERT; |
636 |
|
gnutls_x509_crt_deinit(crt); |
637 |
return 1; |
return 1; |
638 |
} |
} |
639 |
} else { |
} else { |
640 |
current->certificate_verified = "SUCCESS"; |
current->certificate_verified = "SUCCESS"; |
641 |
fprintf( stderr, "tls: X.509 Certificate by '%s' was verified.\n", name); |
fprintf( stderr, "trusted.\n"); |
642 |
} |
} |
643 |
} |
} |
644 |
|
|
645 |
|
gnutls_x509_crt_deinit(crt); |
646 |
} |
} |
647 |
retval = 1; |
retval = 1; |
648 |
current->status = READ_HEADER; |
current->status = READ_HEADER; |