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; }
/* 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; }
int connect_ssl(char *host, char *port, int reconnect, int use_sessionid, int use_ticket, int delay, const char *client_cert, const char *client_key) { struct addrinfo* addr; int err, s; char buffer[256]; gnutls_anon_client_credentials_t anoncred; gnutls_certificate_credentials_t xcred; gnutls_session_t session; char *session_data = NULL; size_t session_data_size = 0; char *session_id = NULL; size_t session_id_size = 0; char *session_id_hex = NULL; char *session_id_p = NULL; unsigned session_id_idx; const char *hex = "0123456789ABCDEF"; start("Initialize GNU TLS library"); if ((err = gnutls_global_init())) fail("Unable to initialize GNU TLS:\n%s", gnutls_strerror(err)); if ((err = gnutls_anon_allocate_client_credentials(&anoncred))) fail("Unable to allocate anonymous client credentials:\n%s", gnutls_strerror(err)); if ((err = gnutls_certificate_allocate_credentials(&xcred))) fail("Unable to allocate X509 credentials:\n%s", gnutls_strerror(err)); #ifdef DEBUG gnutls_global_set_log_function(debug); gnutls_global_set_log_level(10); #endif addr = solve(host, port); do { start("Initialize TLS session"); if ((err = gnutls_init(&session, GNUTLS_CLIENT))) fail("Unable to initialize the current session:\n%s", gnutls_strerror(err)); if ((err = gnutls_priority_set_direct(session, "PERFORMANCE:NORMAL:EXPORT", NULL))) fail("Unable to initialize cipher suites:\n%s", gnutls_strerror(err)); gnutls_dh_set_prime_bits(session, 512); if (client_cert == NULL) { if ((err = gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred))) fail("Unable to set anonymous credentials for session:\n%s", gnutls_strerror(err)); } else { if ((err = gnutls_certificate_set_x509_key_file(xcred, client_cert, client_key, GNUTLS_X509_FMT_PEM))) { fail("failed to load x509 certificate from file %s or key from %s: %s",client_cert,client_key,gnutls_strerror(err)); } } if ((err = gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred))) fail("Unable to set credentials for session:\n%s", gnutls_strerror(err)); if (use_ticket) { start("Enable use of session tickets (RFC 5077)"); if (gnutls_session_ticket_enable_client(session)) fail("Unable to enable session tickets:\n%s", gnutls_strerror(err)); } if (session_data) { start("Copy old session"); if ((err = gnutls_session_set_data(session, session_data, session_data_size))) fail("Unable to set session to previous one:\n%s", gnutls_strerror(err)); } s = connect_socket(addr, host, port); start("Start TLS renegotiation"); gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t)(uintptr_t)s); if ((err = gnutls_handshake(session))) { fail("Unable to start TLS renegotiation:\n%s", gnutls_strerror(err)); } start("Check if session was reused"); if (!gnutls_session_is_resumed(session) && session_data) warn("No session was reused."); else if (gnutls_session_is_resumed(session) && !session_data) warn("Session was reused."); else if (gnutls_session_is_resumed(session)) end("SSL session correctly reused"); else end("SSL session was not used"); start("Get current session"); if (session_data) { free(session_data); session_data = NULL; } session_data_size = 8192; if ((err = gnutls_session_get_data(session, NULL, &session_data_size))) warn("No session available:\n%s", gnutls_strerror(err)); else { session_data = malloc(session_data_size); if (!session_data) fail("No memory available"); gnutls_session_get_data(session, session_data, &session_data_size); if ((err = gnutls_session_get_id( session, NULL, &session_id_size))) warn("No session id available:\n%s", gnutls_strerror(err)); session_id = malloc(session_id_size); if (!session_id) fail("No memory available"); else { if ((err = gnutls_session_get_id( session, session_id, &session_id_size))) warn("No session id available:\n%s", gnutls_strerror(err)); session_id_hex = malloc(session_id_size * 2 + 1); if (!session_id_hex) fail("No memory available"); else { for (session_id_p = session_id_hex, session_id_idx = 0; session_id_idx < session_id_size; ++session_id_idx) { *session_id_p++ = hex[ (session_id[session_id_idx] >> 4) & 0xf]; *session_id_p++ = hex[ session_id[session_id_idx] & 0xf]; } *session_id_p = '\0'; end("Session context:\nProtocol : %s\nCipher : %s\nKx : %s\nCompression : %s\nPSK : %s\nID : %s", gnutls_protocol_get_name( gnutls_protocol_get_version(session) ), gnutls_cipher_get_name( gnutls_cipher_get(session) ), gnutls_kx_get_name( gnutls_kx_get(session) ), gnutls_compression_get_name( gnutls_compression_get(session)), gnutls_psk_server_get_username(session), session_id_hex ); free(session_id_hex); } free(session_id); } } if (!use_sessionid && !use_ticket) { free(session_data); session_data = NULL; } start("Send HTTP GET"); err = snprintf(buffer, sizeof(buffer), "GET / HTTP/1.0\r\n" "Host: %s\r\n" "\r\n", host); if (err == -1 || err >= sizeof(buffer)) fail("Unable to build request to send"); if (gnutls_record_send(session, buffer, strlen(buffer)) < 0) fail("SSL write request failed:\n%s", gnutls_strerror(err)); start("Get HTTP answer"); if ((err = gnutls_record_recv(session, buffer, sizeof(buffer) - 1)) <= 0) fail("SSL read request failed:\n%s", gnutls_strerror(err)); buffer[err] = '\0'; if (strchr(buffer, '\r')) *strchr(buffer, '\r') = '\0'; end("%s", buffer); start("End TLS connection"); gnutls_bye(session, GNUTLS_SHUT_RDWR); close(s); gnutls_deinit (session); --reconnect; if (reconnect < 0) break; else { start("waiting %d seconds",delay); sleep(delay); } } while (1); if (session_data) free(session_data); gnutls_anon_free_client_credentials(anoncred); gnutls_global_deinit(); return 0; }
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; }
const char *server_session::get_psk_username () const { return gnutls_psk_server_get_username (s); }
int main(void) { int err, listen_sd; int sd, ret; struct sockaddr_in sa_serv; struct sockaddr_in sa_cli; socklen_t client_len; char topbuf[512]; gnutls_session_t session; gnutls_certificate_credentials_t x509_cred; gnutls_psk_server_credentials_t psk_cred; gnutls_priority_t priority_cache; char buffer[MAX_BUF + 1]; int optval = 1; int kx; if (gnutls_check_version("3.1.4") == NULL) { fprintf(stderr, "GnuTLS 3.1.4 is required for this example\n"); exit(1); } gnutls_global_init(); gnutls_certificate_allocate_credentials(&x509_cred); gnutls_certificate_set_x509_trust_file(x509_cred, CAFILE, GNUTLS_X509_FMT_PEM); gnutls_certificate_set_x509_crl_file(x509_cred, CRLFILE, GNUTLS_X509_FMT_PEM); gnutls_certificate_set_x509_key_file(x509_cred, CERTFILE, KEYFILE, GNUTLS_X509_FMT_PEM); gnutls_psk_allocate_server_credentials(&psk_cred); gnutls_psk_set_server_credentials_function(psk_cred, pskfunc); generate_dh_params(); gnutls_priority_init(&priority_cache, "NORMAL:+PSK:+ECDHE-PSK:+DHE-PSK", NULL); gnutls_certificate_set_dh_params(x509_cred, dh_params); /* Socket operations */ listen_sd = socket(AF_INET, SOCK_STREAM, 0); SOCKET_ERR(listen_sd, "socket"); memset(&sa_serv, '\0', sizeof(sa_serv)); sa_serv.sin_family = AF_INET; sa_serv.sin_addr.s_addr = INADDR_ANY; sa_serv.sin_port = htons(PORT); /* Server Port number */ setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval, sizeof(int)); err = bind(listen_sd, (struct sockaddr *) &sa_serv, sizeof(sa_serv)); SOCKET_ERR(err, "bind"); err = listen(listen_sd, 1024); SOCKET_ERR(err, "listen"); printf("Server ready. Listening to port '%d'.\n\n", PORT); client_len = sizeof(sa_cli); for (;;) { gnutls_init(&session, GNUTLS_SERVER); gnutls_priority_set(session, priority_cache); gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_credentials_set(session, GNUTLS_CRD_PSK, psk_cred); /* request client certificate if any. */ gnutls_certificate_server_set_request(session, GNUTLS_CERT_REQUEST); sd = accept(listen_sd, (struct sockaddr *) &sa_cli, &client_len); printf("- connection from %s, port %d\n", inet_ntop(AF_INET, &sa_cli.sin_addr, topbuf, sizeof(topbuf)), ntohs(sa_cli.sin_port)); gnutls_transport_set_int(session, sd); ret = gnutls_handshake(session); if (ret < 0) { close(sd); gnutls_deinit(session); fprintf(stderr, "*** Handshake has failed (%s)\n\n", gnutls_strerror(ret)); continue; } printf("- Handshake was completed\n"); kx = gnutls_kx_get(session); if (kx == GNUTLS_KX_PSK || kx == GNUTLS_KX_DHE_PSK || kx == GNUTLS_KX_ECDHE_PSK) { printf("- User %s was connected\n", gnutls_psk_server_get_username(session)); } /* see the Getting peer's information example */ /* print_info(session); */ for (;;) { ret = gnutls_record_recv(session, buffer, MAX_BUF); if (ret == 0) { printf ("\n- Peer has closed the GnuTLS connection\n"); break; } else if (ret < 0 && gnutls_error_is_fatal(ret) == 0) { fprintf(stderr, "*** Warning: %s\n", gnutls_strerror(ret)); } else if (ret < 0) { fprintf(stderr, "\n*** Received corrupted " "data(%d). Closing the connection.\n\n", ret); break; } else if (ret > 0) { /* echo data back to the client */ gnutls_record_send(session, buffer, ret); } } printf("\n"); /* do not wait for the peer to close the connection. */ gnutls_bye(session, GNUTLS_SHUT_WR); close(sd); gnutls_deinit(session); } close(listen_sd); gnutls_certificate_free_credentials(x509_cred); gnutls_psk_free_server_credentials(psk_cred); gnutls_priority_deinit(priority_cache); gnutls_global_deinit(); return 0; }