int print_info (gnutls_session_t session, int print_cert) { const char *tmp; gnutls_credentials_type_t cred; gnutls_kx_algorithm_t kx; unsigned char session_id[33]; size_t session_id_size = sizeof (session_id); /* print session ID */ gnutls_session_get_id (session, session_id, &session_id_size); printf ("- Session ID: %s\n", raw_to_string (session_id, session_id_size)); /* print the key exchange's algorithm name */ kx = gnutls_kx_get (session); cred = gnutls_auth_get_type (session); switch (cred) { #ifdef ENABLE_ANON case GNUTLS_CRD_ANON: if (kx == GNUTLS_KX_ANON_ECDH) print_ecdh_info (session, "Anonymous "); else print_dh_info (session, "Anonymous ", verbose); break; #endif #ifdef ENABLE_SRP case GNUTLS_CRD_SRP: /* This should be only called in server * side. */ if (gnutls_srp_server_get_username (session) != NULL) printf ("- SRP authentication. Connected as '%s'\n", gnutls_srp_server_get_username (session)); break; #endif #ifdef ENABLE_PSK case GNUTLS_CRD_PSK: /* This returns NULL in server side. */ if (gnutls_psk_client_get_hint (session) != NULL) printf ("- PSK authentication. PSK hint '%s'\n", gnutls_psk_client_get_hint (session)); /* This returns NULL in client side. */ if (gnutls_psk_server_get_username (session) != NULL) printf ("- PSK authentication. Connected as '%s'\n", gnutls_psk_server_get_username (session)); if (kx == GNUTLS_KX_DHE_PSK) print_dh_info (session, "Ephemeral ", verbose); if (kx == GNUTLS_KX_ECDHE_PSK) print_ecdh_info (session, "Ephemeral "); break; #endif case GNUTLS_CRD_IA: printf ("- TLS/IA authentication\n"); break; case GNUTLS_CRD_CERTIFICATE: { char dns[256]; size_t dns_size = sizeof (dns); unsigned int type; /* This fails in client side */ if (gnutls_server_name_get (session, dns, &dns_size, &type, 0) == 0) { printf ("- Given server name[%d]: %s\n", type, dns); } } print_cert_info (session, verbose?GNUTLS_CRT_PRINT_FULL:GNUTLS_CRT_PRINT_COMPACT, print_cert); if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) print_dh_info (session, "Ephemeral ", verbose); else if (kx == GNUTLS_KX_ECDHE_RSA || kx == GNUTLS_KX_ECDHE_ECDSA) print_ecdh_info (session, "Ephemeral "); } tmp = SU (gnutls_protocol_get_name (gnutls_protocol_get_version (session))); printf ("- Version: %s\n", tmp); tmp = SU (gnutls_kx_get_name (kx)); printf ("- Key Exchange: %s\n", tmp); tmp = SU (gnutls_cipher_get_name (gnutls_cipher_get (session))); printf ("- Cipher: %s\n", tmp); tmp = SU (gnutls_mac_get_name (gnutls_mac_get (session))); printf ("- MAC: %s\n", tmp); tmp = SU (gnutls_compression_get_name (gnutls_compression_get (session))); printf ("- Compression: %s\n", tmp); if (verbose) { gnutls_datum_t cb; int rc; rc = gnutls_session_channel_binding (session, GNUTLS_CB_TLS_UNIQUE, &cb); if (rc) fprintf (stderr, "Channel binding error: %s\n", gnutls_strerror (rc)); else { size_t i; printf ("- Channel binding 'tls-unique': "); for (i = 0; i < cb.size; i++) printf ("%02x", cb.data[i]); printf ("\n"); } } /* Warning: Do not print anything more here. The 'Compression:' output MUST be the last non-verbose output. This is used by Emacs starttls.el code. */ fflush (stdout); return 0; }
static int psk_callback (gnutls_session_t session, char **username, gnutls_datum_t * key) { const char *hint = gnutls_psk_client_get_hint (session); char *passwd; int ret; printf ("- PSK client callback. "); if (hint) printf ("PSK hint '%s'\n", hint); else printf ("No PSK hint\n"); if (info.psk_username) *username = gnutls_strdup (info.psk_username); else { char *tmp = NULL; size_t n; ssize_t len; printf ("Enter PSK identity: "); fflush (stdout); len = getline (&tmp, &n, stdin); if (tmp == NULL) { fprintf (stderr, "No username given, aborting...\n"); return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } if (tmp[strlen (tmp) - 1] == '\n') tmp[strlen (tmp) - 1] = '\0'; if (tmp[strlen (tmp) - 1] == '\r') tmp[strlen (tmp) - 1] = '\0'; *username = gnutls_strdup (tmp); free (tmp); } if (!*username) return GNUTLS_E_MEMORY_ERROR; passwd = getpass ("Enter password: "******"No password given, aborting...\n"); return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } ret = gnutls_psk_netconf_derive_key (passwd, *username, hint ? hint : "", key); if (ret < 0) { fprintf (stderr, "Error deriving password: %s\n", gnutls_strerror (ret)); gnutls_free (*username); return ret; } if (info.debug) { char hexkey[41]; size_t res_size = sizeof (hexkey); gnutls_hex_encode (key, hexkey, &res_size); fprintf (stderr, "PSK username: %s\n", *username); fprintf (stderr, "PSK hint: %s\n", hint); fprintf (stderr, "PSK key: %s\n", hexkey); } return 0; }
/* This function will print some details of the * given session. */ int print_info (gnutls_session_t session) { const char *tmp; gnutls_credentials_type_t cred; gnutls_kx_algorithm_t kx; /* print the key exchange's algorithm name */ kx = gnutls_kx_get (session); tmp = gnutls_kx_get_name (kx); printf ("- Key Exchange: %s\n", tmp); /* Check the authentication type used and switch * to the appropriate. */ cred = gnutls_auth_get_type (session); switch (cred) { case GNUTLS_CRD_IA: printf ("- TLS/IA session\n"); break; #ifdef ENABLE_SRP case GNUTLS_CRD_SRP: printf ("- SRP session with username %s\n", gnutls_srp_server_get_username (session)); break; #endif case GNUTLS_CRD_PSK: /* This returns NULL in server side. */ if (gnutls_psk_client_get_hint (session) != NULL) printf ("- PSK authentication. PSK hint '%s'\n", gnutls_psk_client_get_hint (session)); /* This returns NULL in client side. */ if (gnutls_psk_server_get_username (session) != NULL) printf ("- PSK authentication. Connected as '%s'\n", gnutls_psk_server_get_username (session)); break; case GNUTLS_CRD_ANON: /* anonymous authentication */ printf ("- Anonymous DH using prime of %d bits\n", gnutls_dh_get_prime_bits (session)); break; case GNUTLS_CRD_CERTIFICATE: /* certificate authentication */ /* Check if we have been using ephemeral Diffie-Hellman. */ if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) { printf ("\n- Ephemeral DH using prime of %d bits\n", gnutls_dh_get_prime_bits (session)); } /* if the certificate list is available, then * print some information about it. */ print_x509_certificate_info (session); } /* switch */ /* print the protocol's name (ie TLS 1.0) */ tmp = gnutls_protocol_get_name (gnutls_protocol_get_version (session)); printf ("- Protocol: %s\n", tmp); /* print the certificate type of the peer. * ie X.509 */ tmp = gnutls_certificate_type_get_name (gnutls_certificate_type_get (session)); printf ("- Certificate Type: %s\n", tmp); /* print the compression algorithm (if any) */ tmp = gnutls_compression_get_name (gnutls_compression_get (session)); printf ("- Compression: %s\n", tmp); /* print the name of the cipher used. * ie 3DES. */ tmp = gnutls_cipher_get_name (gnutls_cipher_get (session)); printf ("- Cipher: %s\n", tmp); /* Print the MAC algorithms name. * ie SHA1 */ tmp = gnutls_mac_get_name (gnutls_mac_get (session)); printf ("- MAC: %s\n", tmp); return 0; }
static int psk_callback (gnutls_session_t session, char **username, gnutls_datum_t * key) { const char *hint = gnutls_psk_client_get_hint (session); unsigned char *rawkey; char *passwd; int ret; size_t res_size; gnutls_datum_t tmp; printf ("- PSK client callback. "); if (hint) printf ("PSK hint '%s'\n", hint); else printf ("No PSK hint\n"); if (info.psk_username) *username = gnutls_strdup (info.psk_username); else { char *tmp = NULL; size_t n; printf ("Enter PSK identity: "); fflush (stdout); getline (&tmp, &n, stdin); if (tmp == NULL) { fprintf (stderr, "No username given, aborting...\n"); return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } if (tmp[strlen (tmp) - 1] == '\n') tmp[strlen (tmp) - 1] = '\0'; if (tmp[strlen (tmp) - 1] == '\r') tmp[strlen (tmp) - 1] = '\0'; *username = gnutls_strdup (tmp); free (tmp); } if (!*username) return GNUTLS_E_MEMORY_ERROR; passwd = getpass ("Enter key: "); if (passwd == NULL) { fprintf (stderr, "No key given, aborting...\n"); return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } tmp.data = passwd; tmp.size = strlen (passwd); res_size = tmp.size / 2 + 1; rawkey = gnutls_malloc (res_size); if (rawkey == NULL) return GNUTLS_E_MEMORY_ERROR; ret = gnutls_hex_decode (&tmp, rawkey, &res_size); if (ret < 0) { fprintf (stderr, "Error deriving password: %s\n", gnutls_strerror (ret)); gnutls_free (*username); return ret; } key->data = rawkey; key->size = res_size; if (info.debug) { char hexkey[41]; res_size = sizeof (hexkey); gnutls_hex_encode (key, hexkey, &res_size); fprintf (stderr, "PSK username: %s\n", *username); fprintf (stderr, "PSK hint: %s\n", hint); fprintf (stderr, "PSK key: %s\n", hexkey); } return 0; }
static void client(int sd, const char *prio) { int ret, ii; gnutls_session_t session; char buffer[MAX_BUF + 1]; gnutls_psk_client_credentials_t pskcred; /* Need to enable anonymous KX specifically. */ const gnutls_datum_t key = { (void *) "DEADBEEF", 8 }; const char *hint; global_init(); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(4711); side = "client"; gnutls_psk_allocate_client_credentials(&pskcred); gnutls_psk_set_client_credentials(pskcred, "test", &key, GNUTLS_PSK_KEY_HEX); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT); /* Use default priorities */ gnutls_priority_set_direct(session, prio, NULL); /* put the anonymous credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_PSK, pskcred); gnutls_transport_set_int(session, sd); /* Perform the TLS handshake */ ret = gnutls_handshake(session); if (ret < 0) { fail("client: Handshake failed\n"); gnutls_perror(ret); goto end; } else { if (debug) success("client: Handshake was completed\n"); } /* check the hint */ hint = gnutls_psk_client_get_hint(session); if (hint == NULL || strcmp(hint, "hint") != 0) { fail("client: hint is not the expected: %s\n", gnutls_psk_client_get_hint(session)); goto end; } gnutls_record_send(session, MSG, strlen(MSG)); ret = gnutls_record_recv(session, buffer, MAX_BUF); if (ret == 0) { if (debug) success ("client: Peer has closed the TLS connection\n"); goto end; } else if (ret < 0) { fail("client: Error: %s\n", gnutls_strerror(ret)); goto end; } if (debug) { 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: close(sd); gnutls_deinit(session); gnutls_psk_free_client_credentials(pskcred); gnutls_global_deinit(); }
int print_info (gnutls_session_t session, const char *hostname, int insecure) { const char *tmp; gnutls_credentials_type_t cred; gnutls_kx_algorithm_t kx; /* print the key exchange's algorithm name */ kx = gnutls_kx_get (session); cred = gnutls_auth_get_type (session); switch (cred) { #ifdef ENABLE_ANON case GNUTLS_CRD_ANON: print_dh_info (session, "Anonymous "); break; #endif #ifdef ENABLE_SRP case GNUTLS_CRD_SRP: /* This should be only called in server * side. */ if (gnutls_srp_server_get_username (session) != NULL) printf ("- SRP authentication. Connected as '%s'\n", gnutls_srp_server_get_username (session)); break; #endif #ifdef ENABLE_PSK case GNUTLS_CRD_PSK: /* This returns NULL in server side. */ if (gnutls_psk_client_get_hint (session) != NULL) printf ("- PSK authentication. PSK hint '%s'\n", gnutls_psk_client_get_hint (session)); /* This returns NULL in client side. */ if (gnutls_psk_server_get_username (session) != NULL) printf ("- PSK authentication. Connected as '%s'\n", gnutls_psk_server_get_username (session)); if (kx == GNUTLS_KX_DHE_PSK) print_dh_info (session, "Ephemeral "); break; #endif case GNUTLS_CRD_IA: printf ("- TLS/IA authentication\n"); break; case GNUTLS_CRD_CERTIFICATE: { char dns[256]; size_t dns_size = sizeof (dns); unsigned int type; /* This fails in client side */ if (gnutls_server_name_get (session, dns, &dns_size, &type, 0) == 0) { printf ("- Given server name[%d]: %s\n", type, dns); } } if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) print_dh_info (session, "Ephemeral "); print_cert_info (session, hostname, insecure); print_cert_vrfy (session); } tmp = SU (gnutls_protocol_get_name (gnutls_protocol_get_version (session))); printf ("- Version: %s\n", tmp); tmp = SU (gnutls_kx_get_name (kx)); printf ("- Key Exchange: %s\n", tmp); tmp = SU (gnutls_cipher_get_name (gnutls_cipher_get (session))); printf ("- Cipher: %s\n", tmp); tmp = SU (gnutls_mac_get_name (gnutls_mac_get (session))); printf ("- MAC: %s\n", tmp); tmp = SU (gnutls_compression_get_name (gnutls_compression_get (session))); printf ("- Compression: %s\n", tmp); if (verbose) { char id[32]; size_t id_size = sizeof (id); gnutls_session_get_id (session, id, &id_size); printf ("- Session ID: %s\n", raw_to_string (id, id_size)); } fflush (stdout); return 0; }