src/sock_gnutls.c
author Tero Marttila <terom@fixme.fi>
Sun, 22 Feb 2009 06:52:55 +0200
changeset 4 a3ca0f97a075
parent 3 cc94ae754e2a
child 5 a09a0797f6f0
permissions -rw-r--r--
change ERROR_* to use pointers again, and implement error_info for sock_init
2
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
#include "sock_gnutls.h"
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
#include <stdlib.h>
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
#include <err.h>
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
static void _sock_gnutls_error (struct sock_gnutls *sock, const char *func, int _err) {
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
    if (_err == GNUTLS_E_FATAL_ALERT_RECEIVED)
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
        errx(1, "%s: %s: %s", func, gnutls_strerror(_err), gnutls_alert_get_name(gnutls_alert_get(sock->session)));
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
    else
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
        errx(1, "%s: %s", func, gnutls_strerror(_err));
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
}
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    15
static err_t sock_gnutls_read (struct sock_stream *base_sock, void *buf, size_t len)
2
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
{
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
    struct sock_gnutls *sock = SOCK_FROM_BASE(base_sock, struct sock_gnutls);
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
    
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
    // just map to gnutls_record_recv
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
    return gnutls_record_recv(sock->session, buf, len);
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
}
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    22
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    23
static err_t sock_gnutls_write (struct sock_stream *base_sock, const void *buf, size_t len)
2
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
{
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
    struct sock_gnutls *sock = SOCK_FROM_BASE(base_sock, struct sock_gnutls);
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
    
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
    // just map to gnutls_record_send
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
    return gnutls_record_send(sock->session, buf, len);
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    29
}
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    30
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
/*
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
 * Our sock_stream_Type
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    33
 */
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    34
struct sock_stream_type sock_gnutls_type = {
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    35
    .methods.read   = &sock_gnutls_read,
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    36
    .methods.write  = &sock_gnutls_write,
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
};
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    38
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    39
/*
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    40
 * XXX: global shared sock_gnutls_ctx
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
 */
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
struct sock_gnutls_client_ctx _sock_gnutls_client_ctx;
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
/*
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
 * Configure the given gnutls socket context to use simple anonymous client credentials
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
 */
4
a3ca0f97a075 change ERROR_* to use pointers again, and implement error_info for sock_init
Tero Marttila <terom@fixme.fi>
parents: 3
diff changeset
    47
static err_t sock_gnutls_client_ctx_anon (struct sock_gnutls_client_ctx *ctx, struct error_info *err)
2
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
{
4
a3ca0f97a075 change ERROR_* to use pointers again, and implement error_info for sock_init
Tero Marttila <terom@fixme.fi>
parents: 3
diff changeset
    49
    // init to use anonymous x509 cert
a3ca0f97a075 change ERROR_* to use pointers again, and implement error_info for sock_init
Tero Marttila <terom@fixme.fi>
parents: 3
diff changeset
    50
    if ((ERROR_EXTRA(err) = gnutls_certificate_allocate_credentials(&ctx->xcred)) < 0)
a3ca0f97a075 change ERROR_* to use pointers again, and implement error_info for sock_init
Tero Marttila <terom@fixme.fi>
parents: 3
diff changeset
    51
        return SET_ERROR(err, ERR_GNUTLS_CERT_ALLOC_CRED);
a3ca0f97a075 change ERROR_* to use pointers again, and implement error_info for sock_init
Tero Marttila <terom@fixme.fi>
parents: 3
diff changeset
    52
a3ca0f97a075 change ERROR_* to use pointers again, and implement error_info for sock_init
Tero Marttila <terom@fixme.fi>
parents: 3
diff changeset
    53
    // done
a3ca0f97a075 change ERROR_* to use pointers again, and implement error_info for sock_init
Tero Marttila <terom@fixme.fi>
parents: 3
diff changeset
    54
    return SUCCESS;
2
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
}
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
4
a3ca0f97a075 change ERROR_* to use pointers again, and implement error_info for sock_init
Tero Marttila <terom@fixme.fi>
parents: 3
diff changeset
    57
err_t sock_gnutls_init (struct error_info *err)
2
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
{
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
    // global init
4
a3ca0f97a075 change ERROR_* to use pointers again, and implement error_info for sock_init
Tero Marttila <terom@fixme.fi>
parents: 3
diff changeset
    60
    if ((ERROR_EXTRA(err) = gnutls_global_init()) < 0)
a3ca0f97a075 change ERROR_* to use pointers again, and implement error_info for sock_init
Tero Marttila <terom@fixme.fi>
parents: 3
diff changeset
    61
        return SET_ERROR(err, ERR_GNUTLS_GLOBAL_INIT);
2
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
    // init _sock_gnutls_ctx
4
a3ca0f97a075 change ERROR_* to use pointers again, and implement error_info for sock_init
Tero Marttila <terom@fixme.fi>
parents: 3
diff changeset
    64
    if (sock_gnutls_client_ctx_anon(&_sock_gnutls_client_ctx, err))
a3ca0f97a075 change ERROR_* to use pointers again, and implement error_info for sock_init
Tero Marttila <terom@fixme.fi>
parents: 3
diff changeset
    65
        return ERROR_CODE(err);
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    66
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    67
    // done
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    68
    return SUCCESS;
2
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
}
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    72
// XXX: errors
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
struct sock_stream *sock_ssl_connect (const char *host, const char *service)
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
{
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
    int _err;
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
    struct sock_gnutls *sock;
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
    struct sock_gnutls_client_ctx *ctx = &_sock_gnutls_client_ctx;
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    79
    // alloc
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
    if ((sock = calloc(1, sizeof(*sock))) == NULL)
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
        errx(1, "calloc");
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
    // initialize
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
    sock->base_tcp.base.type = &sock_gnutls_type;
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
    // initialize client session
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
    if ((_err = gnutls_init(&sock->session, GNUTLS_CLIENT)) < 0)
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
        errx(1, "gnutls_init: %s", gnutls_strerror(_err));
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
    // ...default priority stuff
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    91
    gnutls_set_default_priority(sock->session);
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
    // bind anon credentials
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
    gnutls_credentials_set(sock->session, GNUTLS_CRD_CERTIFICATE, ctx->xcred);
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
    // TCP connect
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
    sock_tcp_init_connect(SOCK_GNUTLS_TCP(sock), host, service);
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
    // bind default transport functions (recv/send) to use the TCP fd
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
    gnutls_transport_set_ptr(sock->session, (gnutls_transport_ptr_t) sock->base_tcp.fd);
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
    // perform the handshake
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
    if ((_err = gnutls_handshake(sock->session)) < 0)
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
        _sock_gnutls_error(sock, "gnutls_handshake", _err);
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
    // done
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
    return SOCK_GNUTLS_BASE(sock);
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
}
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109