Next: Using a callback to select the certificate to use, Up: More advanced client and servers [Contents][Index]
The simplest client using TLS is the one that doesn’t do any authentication. This means no external certificates or passwords are needed to set up the connection. As could be expected, the connection is vulnerable to man-in-the-middle (active or redirection) attacks. However, the data are integrity protected and encrypted from passive eavesdroppers.
Note that due to the vulnerable nature of this method very few public servers support it.
/* This example code is placed in the public domain. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include <assert.h> #include <gnutls/gnutls.h> /* A very basic TLS client, with anonymous authentication. */ #define LOOP_CHECK(rval, cmd) \ do { \ rval = cmd; \ } while (rval == GNUTLS_E_AGAIN || rval == GNUTLS_E_INTERRUPTED); \ assert(rval >= 0) #define MAX_BUF 1024 #define MSG "GET / HTTP/1.0\r\n\r\n" extern int tcp_connect(void); extern void tcp_close(int sd); int main(void) { int ret, sd, ii; gnutls_session_t session; char buffer[MAX_BUF + 1]; gnutls_anon_client_credentials_t anoncred; /* Need to enable anonymous KX specifically. */ gnutls_global_init(); gnutls_anon_allocate_client_credentials(&anoncred); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT); /* Use default priorities */ gnutls_priority_set_direct(session, "PERFORMANCE:+ANON-ECDH:+ANON-DH", NULL); /* put the anonymous credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); /* connect to the peer */ sd = tcp_connect(); gnutls_transport_set_int(session, sd); gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { fprintf(stderr, "*** Handshake failed\n"); gnutls_perror(ret); goto end; } else { char *desc; desc = gnutls_session_get_desc(session); printf("- Session info: %s\n", desc); gnutls_free(desc); } LOOP_CHECK(ret, gnutls_record_send(session, MSG, strlen(MSG))); LOOP_CHECK(ret, gnutls_record_recv(session, buffer, MAX_BUF)); if (ret == 0) { printf("- Peer has closed the TLS connection\n"); goto end; } else if (ret < 0 && gnutls_error_is_fatal(ret) == 0) { fprintf(stderr, "*** Warning: %s\n", gnutls_strerror(ret)); } else if (ret < 0) { fprintf(stderr, "*** Error: %s\n", gnutls_strerror(ret)); goto end; } if (ret > 0) { printf("- Received %d bytes: ", ret); for (ii = 0; ii < ret; ii++) { fputc(buffer[ii], stdout); } fputs("\n", stdout); } LOOP_CHECK(ret, gnutls_bye(session, GNUTLS_SHUT_RDWR)); end: tcp_close(sd); gnutls_deinit(session); gnutls_anon_free_client_credentials(anoncred); gnutls_global_deinit(); return 0; }