/* This example code is placed in the public domain. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* for getpass() */ /* A TLS client that loads the certificate and key. */ #define MAX_BUF 1024 #define MSG "GET / HTTP/1.0\r\n\r\n" #define MIN(x,y) (((x)<(y))?(x):(y)) #define CAFILE "/etc/ssl/certs/ca-certificates.crt" /* The URLs of the objects can be obtained * using p11tool --list-all --login */ #define KEY_URL "pkcs11:manufacturer=SomeManufacturer;object=Private%20Key" \ ";objecttype=private;id=%db%5b%3e%b5%72%33" #define CERT_URL "pkcs11:manufacturer=SomeManufacturer;object=Certificate;" \ "objecttype=cert;id=db%5b%3e%b5%72%33" extern int tcp_connect (void); extern void tcp_close (int sd); static int pin_callback (void *user, int attempt, const char *token_url, const char *token_label, unsigned int flags, char *pin, size_t pin_max) { const char *password; int len; printf ("PIN required for token '%s' with URL '%s'\n", token_label, token_url); if (flags & GNUTLS_PIN_FINAL_TRY) printf ("*** This is the final try before locking!\n"); if (flags & GNUTLS_PIN_COUNT_LOW) printf ("*** Only few tries left before locking!\n"); if (flags & GNUTLS_PIN_WRONG) printf ("*** Wrong PIN\n"); password = getpass ("Enter pin: "); if (password == NULL || password[0] == 0) { fprintf (stderr, "No password given\n"); exit (1); } len = MIN (pin_max-1, strlen (password)); memcpy (pin, password, len); pin[len] = 0; return 0; } int main (void) { int ret, sd, ii; gnutls_session_t session; gnutls_priority_t priorities_cache; char buffer[MAX_BUF + 1]; gnutls_certificate_credentials_t xcred; /* Allow connections to servers that have OpenPGP keys as well. */ gnutls_global_init (); /* PKCS11 private key operations might require PIN. * Register a callback. */ gnutls_pkcs11_set_pin_function (pin_callback, NULL); /* X509 stuff */ gnutls_certificate_allocate_credentials (&xcred); /* priorities */ gnutls_priority_init (&priorities_cache, "NORMAL", NULL); /* sets the trusted cas file */ gnutls_certificate_set_x509_trust_file (xcred, CAFILE, GNUTLS_X509_FMT_PEM); gnutls_certificate_set_x509_key_file (xcred, CERT_URL, KEY_URL, GNUTLS_X509_FMT_DER); /* Initialize TLS session */ gnutls_init (&session, GNUTLS_CLIENT); /* Use default priorities */ gnutls_priority_set (session, priorities_cache); /* 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_int (session, sd); /* Perform the TLS handshake */ ret = gnutls_handshake (session); 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); } gnutls_record_send (session, MSG, strlen (MSG)); 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) { fprintf (stderr, "*** Error: %s\n", gnutls_strerror (ret)); goto end; } printf ("- Received %d bytes: ", ret); for (ii = 0; ii < ret; ii++) { fputc (buffer[ii], stdout); } fputs ("\n", stdout); gnutls_bye (session, GNUTLS_SHUT_RDWR); end: tcp_close (sd); gnutls_deinit (session); gnutls_certificate_free_credentials (xcred); gnutls_priority_deinit (priorities_cache); gnutls_global_deinit (); return 0; }