From 533664903aa27e611c4af3181e3172ace231e733 Mon Sep 17 00:00:00 2001 From: Dmitry Podgorny Date: Sun, 11 Oct 2015 16:30:50 +0300 Subject: [PATCH] tls: fixed GnuTLS implementation --- src/tls_gnutls.c | 59 +++++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/src/tls_gnutls.c b/src/tls_gnutls.c index d838ffd..e94a983 100644 --- a/src/tls_gnutls.c +++ b/src/tls_gnutls.c @@ -19,11 +19,15 @@ #include "tls.h" #include "sock.h" +/* FIXME this shouldn't be a constant string */ +#define CAFILE "/etc/ssl/certs/ca-certificates.crt" + struct _tls { xmpp_ctx_t *ctx; /* do we need this? */ sock_t sock; gnutls_session_t session; gnutls_certificate_credentials_t cred; + int lasterror; }; void tls_initialize(void) @@ -45,22 +49,19 @@ void tls_shutdown(void) tls_t *tls_new(xmpp_ctx_t *ctx, sock_t sock) { tls_t *tls = xmpp_alloc(ctx, sizeof(tls_t)); - const int cert_type_priority[3] = { GNUTLS_CRT_X509, - GNUTLS_CRT_OPENPGP, 0 }; if (tls) { - tls->ctx = ctx; - tls->sock = sock; - gnutls_init(&tls->session, GNUTLS_CLIENT); + tls->ctx = ctx; + tls->sock = sock; + gnutls_init(&tls->session, GNUTLS_CLIENT); - gnutls_certificate_allocate_credentials(&tls->cred); + gnutls_certificate_allocate_credentials(&tls->cred); + tls_set_credentials(tls, CAFILE); - gnutls_set_default_priority(tls->session); - gnutls_certificate_type_set_priority(tls->session, cert_type_priority); + gnutls_set_default_priority(tls->session); - /* fixme: this may require setting a callback on win32? */ - gnutls_transport_set_ptr(tls->session, - (gnutls_transport_ptr_t)sock); + /* fixme: this may require setting a callback on win32? */ + gnutls_transport_set_int(tls->session, sock); } return tls; @@ -79,29 +80,39 @@ int tls_set_credentials(tls_t *tls, const char *cafilename) /* set trusted credentials -- takes a .pem filename */ err = gnutls_certificate_set_x509_trust_file(tls->cred, - cafilename, GNUTLS_X509_FMT_PEM); - if (err < 0) return err; + cafilename, GNUTLS_X509_FMT_PEM); + if (err >= 0) { + err = gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE, + tls->cred); + } + tls->lasterror = err; - err = gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE, - tls->cred); - - return err; + return err == GNUTLS_E_SUCCESS; } int tls_start(tls_t *tls) { - return gnutls_handshake(tls->session); + sock_set_blocking(tls->sock); + tls->lasterror = gnutls_handshake(tls->session); + sock_set_nonblocking(tls->sock); + + return tls->lasterror == GNUTLS_E_SUCCESS; } int tls_stop(tls_t *tls) { - return gnutls_bye(tls->session, GNUTLS_SHUT_RDWR); + tls->lasterror = gnutls_bye(tls->session, GNUTLS_SHUT_RDWR); + return tls->lasterror == GNUTLS_E_SUCCESS; } int tls_error(tls_t *tls) { - /* todo: some kind of error polling/dump */ - return 0; + return tls->lasterror; +} + +int tls_is_recoverable(int error) +{ + return !gnutls_error_is_fatal(error); } int tls_pending(tls_t *tls) @@ -114,6 +125,7 @@ int tls_read(tls_t *tls, void * const buff, const size_t len) int ret; ret = gnutls_record_recv(tls->session, buff, len); + tls->lasterror = ret < 0 ? ret : 0; return ret; } @@ -123,7 +135,12 @@ int tls_write(tls_t *tls, const void * const buff, const size_t len) int ret; ret = gnutls_record_send(tls->session, buff, len); + tls->lasterror = ret < 0 ? ret : 0; return ret; } +int tls_clear_pending_write(tls_t *tls) +{ + return 0; +}