#include #include #include #include #include #include #include #include #include /* A very basic TLS client. */ #define MAX_BUF 1024 #define CAFILE "ca.pem" #define SA struct sockaddr #define MSG "GET /~typo/ HTTP/1.0\r\n\r\n" /* Connects to the peer and returns a socket * descriptor. */ int tcp_connect( void) { const char *PORT = "443"; const char *SERVER = "127.0.0.1"; int err, sd; struct sockaddr_in sa; /* connects to server */ sd = socket(AF_INET, SOCK_STREAM, 0); memset(&sa, '\0', sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons(atoi(PORT)); inet_pton(AF_INET, SERVER, &sa.sin_addr); err = connect(sd, (SA *) & sa, sizeof(sa)); if (err < 0) { fprintf(stderr, "Connect error\n"); exit(1); } return sd; } /* closes the given socket descriptor. */ void tcp_close( int sd) { shutdown(sd, SHUT_RDWR); /* no more receptions */ close(sd); } int main() { int ret, sd, ii; gnutls_session session; char buffer[MAX_BUF + 1]; gnutls_certificate_credentials xcred; /* Allow connections to servers that have OpenPGP keys as well. */ const int cert_type_priority[3] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 }; gnutls_global_init(); /* X509 stuff */ gnutls_certificate_allocate_credentials(&xcred); /* sets the trusted cas file */ gnutls_certificate_set_x509_trust_file(xcred, CAFILE, GNUTLS_X509_FMT_PEM); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT); /* Use default priorities */ gnutls_set_default_priority(session); gnutls_certificate_type_set_priority(session, cert_type_priority); /* put the x509 credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); /* connect to the peer */ sd = tcp_connect(); gnutls_transport_set_ptr( session, (gnutls_transport_ptr)sd); /* Perform the TLS handshake */ ret = gnutls_handshake( session); if (ret < 0) { fprintf(stderr, "*** Handshake failed\n"); gnutls_perror(ret); goto end; } else { printf("- Handshake was completed\n"); } gnutls_record_send( session, MSG, strlen(MSG)); while(1) { ret = gnutls_record_recv( session, buffer, MAX_BUF); if (ret == 0) { printf("- Peer has closed the TLS connection\n"); break; } else if (ret < 0) { fprintf(stderr, "*** Error: %s\n", gnutls_strerror(ret)); goto end; } for (ii = 0; ii < ret; ii++) { fputc(buffer[ii], stdout); } } gnutls_bye( session, GNUTLS_SHUT_RDWR); end: tcp_close( sd); gnutls_deinit(session); gnutls_certificate_free_credentials(xcred); gnutls_global_deinit(); return 0; }