tls: fixed GnuTLS implementation
This commit is contained in:
@@ -19,11 +19,15 @@
|
|||||||
#include "tls.h"
|
#include "tls.h"
|
||||||
#include "sock.h"
|
#include "sock.h"
|
||||||
|
|
||||||
|
/* FIXME this shouldn't be a constant string */
|
||||||
|
#define CAFILE "/etc/ssl/certs/ca-certificates.crt"
|
||||||
|
|
||||||
struct _tls {
|
struct _tls {
|
||||||
xmpp_ctx_t *ctx; /* do we need this? */
|
xmpp_ctx_t *ctx; /* do we need this? */
|
||||||
sock_t sock;
|
sock_t sock;
|
||||||
gnutls_session_t session;
|
gnutls_session_t session;
|
||||||
gnutls_certificate_credentials_t cred;
|
gnutls_certificate_credentials_t cred;
|
||||||
|
int lasterror;
|
||||||
};
|
};
|
||||||
|
|
||||||
void tls_initialize(void)
|
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_new(xmpp_ctx_t *ctx, sock_t sock)
|
||||||
{
|
{
|
||||||
tls_t *tls = xmpp_alloc(ctx, sizeof(tls_t));
|
tls_t *tls = xmpp_alloc(ctx, sizeof(tls_t));
|
||||||
const int cert_type_priority[3] = { GNUTLS_CRT_X509,
|
|
||||||
GNUTLS_CRT_OPENPGP, 0 };
|
|
||||||
|
|
||||||
if (tls) {
|
if (tls) {
|
||||||
tls->ctx = ctx;
|
tls->ctx = ctx;
|
||||||
tls->sock = sock;
|
tls->sock = sock;
|
||||||
gnutls_init(&tls->session, GNUTLS_CLIENT);
|
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_set_default_priority(tls->session);
|
||||||
gnutls_certificate_type_set_priority(tls->session, cert_type_priority);
|
|
||||||
|
|
||||||
/* fixme: this may require setting a callback on win32? */
|
/* fixme: this may require setting a callback on win32? */
|
||||||
gnutls_transport_set_ptr(tls->session,
|
gnutls_transport_set_int(tls->session, sock);
|
||||||
(gnutls_transport_ptr_t)sock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tls;
|
return tls;
|
||||||
@@ -79,29 +80,39 @@ int tls_set_credentials(tls_t *tls, const char *cafilename)
|
|||||||
|
|
||||||
/* set trusted credentials -- takes a .pem filename */
|
/* set trusted credentials -- takes a .pem filename */
|
||||||
err = gnutls_certificate_set_x509_trust_file(tls->cred,
|
err = gnutls_certificate_set_x509_trust_file(tls->cred,
|
||||||
cafilename, GNUTLS_X509_FMT_PEM);
|
cafilename, GNUTLS_X509_FMT_PEM);
|
||||||
if (err < 0) return err;
|
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,
|
return err == GNUTLS_E_SUCCESS;
|
||||||
tls->cred);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int tls_start(tls_t *tls)
|
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)
|
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)
|
int tls_error(tls_t *tls)
|
||||||
{
|
{
|
||||||
/* todo: some kind of error polling/dump */
|
return tls->lasterror;
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
int tls_is_recoverable(int error)
|
||||||
|
{
|
||||||
|
return !gnutls_error_is_fatal(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tls_pending(tls_t *tls)
|
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;
|
int ret;
|
||||||
|
|
||||||
ret = gnutls_record_recv(tls->session, buff, len);
|
ret = gnutls_record_recv(tls->session, buff, len);
|
||||||
|
tls->lasterror = ret < 0 ? ret : 0;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -123,7 +135,12 @@ int tls_write(tls_t *tls, const void * const buff, const size_t len)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = gnutls_record_send(tls->session, buff, len);
|
ret = gnutls_record_send(tls->session, buff, len);
|
||||||
|
tls->lasterror = ret < 0 ? ret : 0;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tls_clear_pending_write(tls_t *tls)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user