Hi, there was an small mistake in the error handling from the first patch.
This is working now correct :-) cu thomas
/* SSL support. Copyright (C) 2000 Free Software Foundation, Inc. Contributed by Christian Fraenkel. This file is part of GNU Wget. GNU Wget is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. GNU Wget is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Wget; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. In addition, as a special exception, the Free Software Foundation gives permission to link the code of its release of Wget with the OpenSSL project's "OpenSSL" library (or with modified versions of it that use the same license as the "OpenSSL" library), and distribute the linked executables. You must obey the GNU General Public License in all respects for all of the code used other than "OpenSSL". If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #include <config.h> #ifdef HAVE_SSL #include <assert.h> #include <errno.h> #ifdef HAVE_UNISTD_H # include <unistd.h> #endif #ifdef HAVE_STRING_H # include <string.h> #else # include <strings.h> #endif #include <gnutls.h> #include "wget.h" #include "utils.h" #include "connect.h" #include "url.h" #ifndef errno extern int errno; #endif void ssl_init_prng (void) { return; } /* pass all ssl errors to DEBUGP returns the number of printed errors TODO: - save in static int last error */ int ssl_printerrors (void) { return 0; } /* GNUTLS_CERTIFICATE_CLIENT_CREDENTIALS is already an pointer */ typedef void SSL_CTX; typedef void SSL; /* Creates a SSL Context and sets some defaults for it */ uerr_t init_ssl (SSL_CTX **ctx) {{{ GNUTLS_CERTIFICATE_CREDENTIALS *xcred = (GNUTLS_CERTIFICATE_CREDENTIALS*)ctx; int x509ctype; if (!opt.sslcerttype) x509ctype = GNUTLS_X509_FMT_PEM; else x509ctype = GNUTLS_X509_FMT_DER; if (gnutls_global_init() < 0) { xcred = NULL; return -1; } if (gnutls_certificate_allocate_sc(xcred) < 0) { xcred = NULL; return -1; } if (opt.sslcafile) { if (0 > gnutls_certificate_set_x509_trust_file(*xcred, opt.sslcafile, x509ctype)) { return -1; } } if (opt.sslcertkey != NULL && opt.sslcertkey != NULL) { if (0 > gnutls_certificate_set_x509_key_file(*xcred, opt.sslcertfile, opt.sslcertkey, x509ctype)) { if (0 > gnutls_anon_allocate_client_sc(xcred)) { return -1; } } } // switch (opt.sslprotocol) // if (!opt.sslcheckcert) return 0; /* Succeded */ }}} void shutdown_ssl (SSL* con) {{{ int ret; GNUTLS_STATE state = (GNUTLS_STATE)con; if (con == NULL) return; do ret = gnutls_bye(state, GNUTLS_SHUT_RDWR); while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); gnutls_deinit(state); }}} static int cipher_priority[16] = { GNUTLS_CIPHER_RIJNDAEL_128_CBC, GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_ARCFOUR, GNUTLS_CIPHER_TWOFISH_128_CBC, 0 }; int kx_priority[16] = { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, GNUTLS_KX_ANON_DH, 0 }; int comp_priority[16] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL , 0 }; int protocol_priority[16] = { GNUTLS_TLS1 , GNUTLS_SSL3 , 0 }; int mac_priority[16] = { GNUTLS_MAC_SHA , GNUTLS_MAC_MD5 , 0 }; /* GNUTLS_CRT_OPENPGP unused in wget currently */ int cert_type_priority[16] = { GNUTLS_CRT_X509 , GNUTLS_CRT_OPENPGP, 0 }; /* Sets up a SSL structure and performs the handshake on fd Returns 0 if everything went right Returns 1 if something went wrong ----- TODO: More exit codes */ int connect_ssl (SSL **con, SSL_CTX *ctx, int fd) {{{ int ret; int alert; GNUTLS_CERTIFICATE_CREDENTIALS xcred = (GNUTLS_CERTIFICATE_CREDENTIALS)ctx; GNUTLS_CERTIFICATE_CREDENTIALS anon_cred; GNUTLS_STATE *state = (GNUTLS_STATE*)con; gnutls_init ( state, GNUTLS_CLIENT); gnutls_cipher_set_priority (*state, cipher_priority); gnutls_compression_set_priority (*state, comp_priority); gnutls_kx_set_priority (*state, kx_priority); gnutls_kx_set_priority (*state, kx_priority); gnutls_protocol_set_priority (*state, protocol_priority); gnutls_mac_set_priority (*state, mac_priority); gnutls_cert_type_set_priority (*state, cert_type_priority); gnutls_dh_set_prime_bits (*state, 1024); gnutls_cred_set (*state, GNUTLS_CRD_CERTIFICATE , xcred); gnutls_anon_allocate_client_sc ( &anon_cred); gnutls_cred_set (*state, GNUTLS_CRD_ANON , anon_cred); //gnutls_openpgp_send_key (*state, GNUTLS_OPENPGP_KEY_FINGERPRINT); gnutls_transport_set_ptr (*state, fd); do ret = gnutls_handshake (*state); while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); if (ret < 0) { if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) { alert = gnutls_alert_get (*state); // printf("*** Received alert [%d]: %s\n", alert, gnutls_alert_get_name(alert)); } // const char* gnutls_strerror( int error); gnutls_deinit (*state); *state = NULL; return -1; } return 0; }}} void free_ssl_ctx (SSL_CTX * ctx) { } /* SSL version of iread. Only exchanged read for SSL_read Read at most LEN bytes from FD, storing them to BUF. */ int ssl_iread (SSL *con, char *buf, int len) {{{ GNUTLS_STATE state = (GNUTLS_STATE)con; int fd = gnutls_transport_get_ptr (state); int ret; int alert; if (fd < 0) return 0; if (len == 0) return 0; #ifdef HAVE_SELECT if (opt.timeout) if ( select_fd (fd, opt.timeout, 0) <= 0) return -1; #endif while (1) { ret = gnutls_record_recv (state, buf, len); if (gnutls_error_is_fatal (ret) == 1) { DEBUGP (("fatal error")); return -1; } switch (ret) { case GNUTLS_E_AGAIN: case GNUTLS_E_INTERRUPTED: continue; case GNUTLS_E_WARNING_ALERT_RECEIVED: case GNUTLS_E_FATAL_ALERT_RECEIVED: alert = gnutls_alert_get (state); DEBUGP (("* Received alert [%d]: %s\n", alert, gnutls_alert_get_name(alert))); return -1; case GNUTLS_E_REHANDSHAKE: /* There is a race condition here. If application data is sent after the rehandshake request, the server thinks we ignored his request. This is a bad design of this client. */ do ret = gnutls_handshake (state); while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); if (ret == 0) /* re handshake ok */ continue; DEBUGP (("re-handshake failed\n")); return -1; default: if (ret < 0) /* Unhandeld error */ { DEBUGP (("unhandled error in ssl read\n")); return -1; } return ret; } } return -1; }}} /* SSL version of iwrite. Only exchanged write for SSL_write Write LEN bytes from BUF to FD. */ int ssl_iwrite (SSL *con, char *buf, int len) {{{ GNUTLS_STATE state = (GNUTLS_STATE)con; int fd = gnutls_transport_get_ptr (state); int ret; if (fd < 0) return 0; while (len > 0) { #ifdef HAVE_SELECT if (opt.timeout) if (select_fd (fd, opt.timeout, 1) <= 0) return -1; #endif do ret = gnutls_record_send(state, buf, len); while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); if (ret <= 0); buf += ret; len -= ret; } return ret; }}} #endif /* HAVE_SSL */
smime.p7s
Description: S/MIME Cryptographic Signature