#include #include #include #include #include #include #include #include #include #include void nonblock(int sockfd) { /* most recent unix versions */ int flags; flags = fcntl(sockfd, F_GETFL, 0); fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); } #define MAX_BUF 1024 #define SA struct sockaddr #define MSG "GET / HTTP/1.0\r\n\r\n" /* Connects to the peer and returns a socket * descriptor. */ int tcp_connect(void) { #if 0 const char *PORT = "443"; const char *SERVER = "66.35.250.203"; /* www.sourceforge.net */ #else const char *PORT = "8999"; const char *SERVER = "127.0.0.1"; #endif 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); } nonblock(sd); return sd; } static void tls_log_func(int level, const char *str) { fprintf(stderr, "|<%d>| %s", level, str); } /* 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; gnutls_anon_client_credentials cred; char buffer[MAX_BUF + 1]; char *cafile="doesntexist"; const int cert_type_priority[3] = { GNUTLS_CRT_X509, 0 }; int rc; /* connect to the peer */ sd = tcp_connect(); fprintf(stderr, "gnutls: %s\n", gnutls_check_version(NULL)); gnutls_global_init(); gnutls_global_set_log_function(tls_log_func); gnutls_global_set_log_level(2); rc = gnutls_certificate_allocate_credentials(&cred); fprintf(stderr, "==> Before SET CA\n"); rc = gnutls_certificate_set_x509_trust_file(cred, cafile, GNUTLS_X509_FMT_PEM); fprintf(stderr, "==> After SET CA\n"); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT); /* Use default priorities */ gnutls_set_default_priority(session); rc = gnutls_certificate_type_set_priority(session, cert_type_priority); rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred); gnutls_transport_set_ptr(session, (gnutls_transport_ptr) sd); fprintf(stderr, "==> Before Handshake\n"); /* Perform the TLS handshake */ while(1) { fd_set fds_read; fd_set fds_write; struct timeval timeout={1,0}; ret = gnutls_handshake(session); if((ret != GNUTLS_E_AGAIN) && (ret != GNUTLS_E_INTERRUPTED)) break; FD_ZERO(&fds_read); FD_ZERO(&fds_write); FD_SET(sd, &fds_read); FD_SET(sd, &fds_write); select(sd+1, &fds_read, &fds_write, NULL, &timeout); } if (ret < 0) { fprintf(stderr, "*** Handshake failed\n"); gnutls_perror(ret); } else { printf("- Handshake was completed\n"); } tcp_close(sd); gnutls_deinit(session); gnutls_global_deinit(); return 0; }