TCPStream::TCPStream(int sd, gnutls_session_t* session, struct sockaddr_in* address): m_sd(sd) { char ip[50]; inet_ntop(PF_INET, (struct in_addr*)&(address->sin_addr.s_addr), ip, sizeof(ip)-1); m_peerIP = ip; m_peerPort = ntohs(address->sin_port); secure = true; char *desc1; desc1 = gnutls_session_get_desc(*session); printf("- Session info: %s\n", desc1); gnutls_free(desc1); std::cout<<"Session addresss "<<session<<std::endl; m_session = session; char *desc2; desc2 = gnutls_session_get_desc(*m_session); printf("- Session info: %s\n", desc2); gnutls_free(desc2); std::cout<<"m_session addresss "<<m_session<<std::endl; /*m_session = (gnutls_session_t*) malloc(sizeof(gnutls_session_t)+1); memcpy(m_session, session, sizeof(gnutls_session_t)); char *desc2; desc2 = gnutls_session_get_desc(*m_session); printf("- Session info: %s\n", desc2); gnutls_free(desc2); std::cout<<"m_session addresss "<<m_session<<std::endl;*/ }
extern int xlibgnutls_tls_handshake(gnutls_session_t *session, int tcp_sd, unsigned verbose_level) { int ret, ii; /* Need to enable anonymous KX specifically. */ gnutls_global_init(); gnutls_anon_allocate_client_credentials(&anoncred); gnutls_init(session, GNUTLS_CLIENT); gnutls_priority_set_direct(*session, "NORMAL:+ANON-ECDH:+ANON-DH", NULL); gnutls_credentials_set(*session, GNUTLS_CRD_ANON, anoncred); gnutls_transport_set_int(*session, tcp_sd); gnutls_handshake_set_timeout(*session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); do { ret = gnutls_handshake(*session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { print_error("handshake failed"); gnutls_perror(ret); } else { char *desc; desc = gnutls_session_get_desc(*session); print_info("- Session info: %s\n", desc); gnutls_free(desc); } return ret; }
void ssl_get_info(http_t *client) { #ifndef gnutls_session_get_desc (void)client; #else char *info; /* Available since 3.1.10 */ info = gnutls_session_get_desc(client->ssl); logit(LOG_INFO, "SSL connection using: %s", info); gnutls_free(info); #endif }
int main(void) { int ret, sd, ii; gnutls_session_t session; char buffer[MAX_BUF + 1]; const char *err; gnutls_certificate_credentials_t xcred; if (gnutls_check_version("3.1.4") == NULL) { fprintf(stderr, "GnuTLS 3.1.4 or later is required for this example\n"); exit(1); } /* for backwards compatibility with gnutls < 3.3.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); gnutls_certificate_set_verify_function(xcred, verify_certificate_callback); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM); /* Use default priorities */ ret = gnutls_priority_set_direct(session, "NORMAL", &err); if (ret < 0) { if (ret == GNUTLS_E_INVALID_REQUEST) { fprintf(stderr, "Syntax error at: %s\n", err); } exit(1); } /* put the x509 credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); gnutls_server_name_set(session, GNUTLS_NAME_DNS, "my_host_name", strlen("my_host_name")); /* connect to the peer */ sd = udp_connect(); gnutls_transport_set_int(session, sd); /* set the connection MTU */ gnutls_dtls_set_mtu(session, 1000); gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); /* Note that DTLS may also receive GNUTLS_E_LARGE_PACKET */ 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 && gnutls_error_is_fatal(ret) == 0) { fprintf(stderr, "*** Warning: %s\n", gnutls_strerror(ret)); } else if (ret < 0) { fprintf(stderr, "*** Error: %s\n", gnutls_strerror(ret)); goto end; } if (ret > 0) { printf("- Received %d bytes: ", ret); for (ii = 0; ii < ret; ii++) { fputc(buffer[ii], stdout); } fputs("\n", stdout); } /* It is suggested not to use GNUTLS_SHUT_RDWR in DTLS * connections because the peer's closure message might * be lost */ gnutls_bye(session, GNUTLS_SHUT_WR); end: udp_close(sd); gnutls_deinit(session); gnutls_certificate_free_credentials(xcred); gnutls_global_deinit(); return 0; }
int main(void) { int ret, sd, ii; gnutls_session_t session; char buffer[MAX_BUF + 1]; const char *err; gnutls_certificate_credentials_t xcred; if (gnutls_check_version("3.1.4") == NULL) { fprintf(stderr, "GnuTLS 3.1.4 or later is required for this example\n"); exit(1); } /* for backwards compatibility with gnutls < 3.3.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); gnutls_certificate_set_verify_function(xcred, _verify_certificate_callback); /* If client holds a certificate it can be set using the following: * gnutls_certificate_set_x509_key_file (xcred, "cert.pem", "key.pem", GNUTLS_X509_FMT_PEM); */ /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT); gnutls_session_set_ptr(session, (void *) "my_host_name"); gnutls_server_name_set(session, GNUTLS_NAME_DNS, "my_host_name", strlen("my_host_name")); /* use default priorities */ gnutls_set_default_priority(session); #if 0 /* if more fine-graned control is required */ ret = gnutls_priority_set_direct(session, "NORMAL", &err); if (ret < 0) { if (ret == GNUTLS_E_INVALID_REQUEST) { fprintf(stderr, "Syntax error at: %s\n", err); } exit(1); } #endif /* 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); gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); 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 && gnutls_error_is_fatal(ret) == 0) { fprintf(stderr, "*** Warning: %s\n", gnutls_strerror(ret)); } else if (ret < 0) { fprintf(stderr, "*** Error: %s\n", gnutls_strerror(ret)); goto end; } if (ret > 0) { 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_global_deinit(); return 0; }
void TLSClient::connect (const std::string& host, const std::string& port) { _host = host; _port = port; // Store the TLSClient instance, so that the verification callback can access // it during the handshake below and call the verifcation method. gnutls_session_set_ptr (_session, (void*) this); // use IPv4 or IPv6, does not matter. struct addrinfo hints {}; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // use my IP struct addrinfo* res; int ret = ::getaddrinfo (host.c_str (), port.c_str (), &hints, &res); if (ret != 0) throw std::string (::gai_strerror (ret)); // Try them all, stop on success. struct addrinfo* p; for (p = res; p != NULL; p = p->ai_next) { if ((_socket = ::socket (p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) continue; // When a socket is closed, it remains unavailable for a while (netstat -an). // Setting SO_REUSEADDR allows this program to assume control of a closed, // but unavailable socket. int on = 1; if (::setsockopt (_socket, SOL_SOCKET, SO_REUSEADDR, (const void*) &on, sizeof (on)) == -1) throw std::string (::strerror (errno)); if (::connect (_socket, p->ai_addr, p->ai_addrlen) == -1) continue; break; } free (res); if (p == NULL) throw format (STRING_CMD_SYNC_CONNECT, host, port); #if GNUTLS_VERSION_NUMBER >= 0x030109 gnutls_transport_set_int (_session, _socket); #else gnutls_transport_set_ptr (_session, (gnutls_transport_ptr_t) (intptr_t) _socket); #endif // Perform the TLS handshake do { ret = gnutls_handshake (_session); } while (ret < 0 && gnutls_error_is_fatal (ret) == 0); if (ret < 0) throw format (STRING_CMD_SYNC_HANDSHAKE, gnutls_strerror (ret)); #if GNUTLS_VERSION_NUMBER < 0x02090a // The automatic verification for the server certificate with // gnutls_certificate_set_verify_function does only work with gnutls // >=2.9.10. So with older versions we should call the verify function // manually after the gnutls handshake. ret = verify_certificate (); if (ret < 0) { if (_debug) std::cout << "c: ERROR Certificate verification failed.\n"; throw format (STRING_TLS_INIT_FAIL, gnutls_strerror (ret)); } #endif if (_debug) { #if GNUTLS_VERSION_NUMBER >= 0x03010a char* desc = gnutls_session_get_desc (_session); std::cout << "c: INFO Handshake was completed: " << desc << "\n"; gnutls_free (desc); #else std::cout << "c: INFO Handshake was completed.\n"; #endif } }
extern int xlibgnutls_dtls_handshake(gnutls_session_t *session, int udp_sd, unsigned verbose_level) { const char *CAFILE = "ca-cert.pem"; // TODO: use anoncred int ret; const char *err; if (gnutls_check_version("3.1.4") == NULL) { print_error("GnuTLS 3.1.4 or later is required"); return -1; } /* for backwards compatibility with gnutls < 3.3.0 */ gnutls_global_init(); if (verbose_level >= VERBOSE_LEVEL_GNUTLS) { gnutls_global_set_log_level(9999); gnutls_global_set_log_function(gnutls_log); } /* X509 stuff */ gnutls_certificate_allocate_credentials(&xcred); /* sets the trusted cas file */ gnutls_certificate_set_x509_trust_file(xcred, CAFILE, GNUTLS_X509_FMT_PEM); gnutls_certificate_set_verify_function(xcred, verify_certificate_callback); /* Initialize TLS session */ gnutls_init(session, GNUTLS_CLIENT | GNUTLS_DATAGRAM); /* put the x509 credentials to the current session */ gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE, xcred); gnutls_server_name_set(*session, GNUTLS_NAME_DNS, "my_host_name", strlen("my_host_name")); if (verbose_level >= VERBOSE_LEVEL_PACKETS) { gnutls_transport_set_push_function(*session, gnutls_push_func_custom); //gnutls_transport_set_pull_function(*session, gnutls_pull_func_custom); //gnutls_transport_set_pull_timeout_function(*session, gnutls_pull_timeout_func_custom); } gnutls_dtls_set_mtu(*session, 1 << 14); gnutls_set_default_priority(*session); /* if more fine-graned control is required */ ret = gnutls_priority_set_direct(*session, "NORMAL", &err); if (ret < 0) { if (ret == GNUTLS_E_INVALID_REQUEST) print_error("syntax error at: %d", err); goto end; } gnutls_transport_set_int(*session, udp_sd); gnutls_handshake_set_timeout(*session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); if (verbose_level >= VERBOSE_LEVEL_CLIENT) print_info("handshake started"); do { ret = gnutls_handshake(*session); } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); /* Note that DTLS may also receive GNUTLS_E_LARGE_PACKET */ if (verbose_level >= VERBOSE_LEVEL_CLIENT) print_info("handshake finished"); if (ret < 0) { print_error("handshake failed with return code %d", ret); gnutls_perror(ret); goto end; } else { char *desc; desc = gnutls_session_get_desc(*session); if (verbose_level >= VERBOSE_LEVEL_CLIENT) print_info("session info: %s", desc); gnutls_free(desc); } ret = 0; end: return ret; }
int print_info(gnutls_session_t session, int verbose, 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); gnutls_srtp_profile_t srtp_profile; gnutls_datum_t p; char *desc; int rc; desc = gnutls_session_get_desc(session); printf("- Description: %s\n", desc); gnutls_free(desc); /* 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); } } if (print_cert) print_cert_info(session, verbose, 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); if (gnutls_sign_algorithm_get(session) != GNUTLS_SIGN_UNKNOWN) { tmp = SU(gnutls_sign_get_name (gnutls_sign_algorithm_get(session))); printf("- Server Signature: %s\n", tmp); } if (gnutls_sign_algorithm_get_client(session) != GNUTLS_SIGN_UNKNOWN) { tmp = SU(gnutls_sign_get_name (gnutls_sign_algorithm_get_client(session))); printf("- Client Signature: %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); #ifdef ENABLE_DTLS_SRTP rc = gnutls_srtp_get_selected_profile(session, &srtp_profile); if (rc == 0) printf("- SRTP profile: %s\n", gnutls_srtp_get_profile_name(srtp_profile)); #endif #ifdef ENABLE_ALPN rc = gnutls_alpn_get_selected_protocol(session, &p); if (rc == 0) printf("- Application protocol: %.*s\n", p.size, p.data); #endif if (verbose) { gnutls_datum_t cb; 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; }
int main(void) { int ret, sd, ii; gnutls_session_t session; char buffer[MAX_BUF + 1]; const char *err; gnutls_psk_client_credentials_t pskcred; const gnutls_datum_t key = { (void *) "DEADBEEF", 8 }; CHECK(gnutls_global_init()); CHECK(gnutls_psk_allocate_client_credentials(&pskcred)); CHECK(gnutls_psk_set_client_credentials(pskcred, "test", &key, GNUTLS_PSK_KEY_HEX)); /* Initialize TLS session */ CHECK(gnutls_init(&session, GNUTLS_CLIENT)); /* Use default priorities */ ret = gnutls_priority_set_direct(session, "PERFORMANCE:+ECDHE-PSK:+DHE-PSK:+PSK", &err); if (ret < 0) { if (ret == GNUTLS_E_INVALID_REQUEST) { fprintf(stderr, "Syntax error at: %s\n", err); } exit(1); } /* put the x509 credentials to the current session */ CHECK(gnutls_credentials_set(session, GNUTLS_CRD_PSK, pskcred)); /* connect to the peer */ sd = tcp_connect(); gnutls_transport_set_int(session, sd); gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); 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); } CHECK(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 && gnutls_error_is_fatal(ret) == 0) { fprintf(stderr, "*** Warning: %s\n", gnutls_strerror(ret)); } else if (ret < 0) { fprintf(stderr, "*** Error: %s\n", gnutls_strerror(ret)); goto end; } if (ret > 0) { printf("- Received %d bytes: ", ret); for (ii = 0; ii < ret; ii++) { fputc(buffer[ii], stdout); } fputs("\n", stdout); } CHECK(gnutls_bye(session, GNUTLS_SHUT_RDWR)); end: tcp_close(sd); gnutls_deinit(session); gnutls_psk_free_client_credentials(pskcred); gnutls_global_deinit(); 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; }
static void test_ciphersuite_kx(const char *cipher_prio, unsigned pk) { /* Server stuff. */ gnutls_anon_server_credentials_t s_anoncred; gnutls_session_t server; int sret, cret; const char *str; char *suite = NULL; /* Client stuff. */ gnutls_anon_client_credentials_t c_anoncred; gnutls_certificate_credentials_t c_certcred, s_certcred; gnutls_session_t client; /* Need to enable anonymous KX specifically. */ int ret; struct benchmark_st st; struct timespec tr_start, tr_stop; double avg, sstddev; gnutls_priority_t priority_cache; total_diffs_size = 0; /* Init server */ gnutls_certificate_allocate_credentials(&s_certcred); gnutls_anon_allocate_server_credentials(&s_anoncred); ret = 0; if (pk == GNUTLS_PK_RSA_PSS) ret = gnutls_certificate_set_x509_key_mem(s_certcred, &server_rsa_pss_cert, &server_key, GNUTLS_X509_FMT_PEM); else if (pk == GNUTLS_PK_RSA) ret = gnutls_certificate_set_x509_key_mem(s_certcred, &server_cert, &server_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf(stderr, "Error in %d: %s\n", __LINE__, gnutls_strerror(ret)); exit(1); } ret = 0; if (pk == GNUTLS_PK_ECDSA) ret = gnutls_certificate_set_x509_key_mem(s_certcred, &server_ecc_cert, &server_ecc_key, GNUTLS_X509_FMT_PEM); else if (pk == GNUTLS_PK_EDDSA_ED25519) ret = gnutls_certificate_set_x509_key_mem(s_certcred, &server_ed25519_cert, &server_ed25519_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf(stderr, "Error in %d: %s\n", __LINE__, gnutls_strerror(ret)); exit(1); } /* Init client */ gnutls_anon_allocate_client_credentials(&c_anoncred); gnutls_certificate_allocate_credentials(&c_certcred); start_benchmark(&st); ret = gnutls_priority_init(&priority_cache, cipher_prio, &str); if (ret < 0) { fprintf(stderr, "Error in %s\n", str); exit(1); } do { gnutls_init(&server, GNUTLS_SERVER); ret = gnutls_priority_set(server, priority_cache); if (ret < 0) { fprintf(stderr, "Error in setting priority: %s\n", gnutls_strerror(ret)); exit(1); } gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred); gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, s_certcred); gnutls_transport_set_push_function(server, server_push); gnutls_transport_set_pull_function(server, server_pull); gnutls_transport_set_ptr(server, (gnutls_transport_ptr_t) server); reset_buffers(); gnutls_init(&client, GNUTLS_CLIENT); ret = gnutls_priority_set(client, priority_cache); if (ret < 0) { fprintf(stderr, "Error in setting priority: %s\n", gnutls_strerror(ret)); exit(1); } gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred); gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, c_certcred); gnutls_transport_set_push_function(client, client_push); gnutls_transport_set_pull_function(client, client_pull); gnutls_transport_set_ptr(client, (gnutls_transport_ptr_t) client); gettime(&tr_start); HANDSHAKE(client, server); gettime(&tr_stop); if (suite == NULL) suite = gnutls_session_get_desc(server); gnutls_deinit(client); gnutls_deinit(server); total_diffs[total_diffs_size++] = timespec_sub_ms(&tr_stop, &tr_start); if (total_diffs_size > sizeof(total_diffs)/sizeof(total_diffs[0])) abort(); st.size += 1; } while (benchmark_must_finish == 0); fprintf(stdout, "%38s ", suite); gnutls_free(suite); stop_benchmark(&st, "transactions", 1); gnutls_priority_deinit(priority_cache); avg = calc_avg(total_diffs, total_diffs_size); sstddev = calc_sstdev(total_diffs, total_diffs_size, avg); printf("%32s %.2f ms, sample variance: %.2f)\n", "(avg. handshake time:", avg, sstddev); gnutls_anon_free_client_credentials(c_anoncred); gnutls_anon_free_server_credentials(s_anoncred); }
void TLSClient::connect (const std::string& host, const std::string& port) { // Store the host name, so the verification callback can access it during the // handshake below. gnutls_session_set_ptr (_session, (void*) host.c_str ()); // use IPv4 or IPv6, does not matter. struct addrinfo hints = {0}; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // use my IP struct addrinfo* res; if (::getaddrinfo (host.c_str (), port.c_str (), &hints, &res) != 0) throw std::string (::gai_strerror (errno)); // Try them all, stop on success. struct addrinfo* p; for (p = res; p != NULL; p = p->ai_next) { if ((_socket = ::socket (p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) continue; // When a socket is closed, it remains unavailable for a while (netstat -an). // Setting SO_REUSEADDR allows this program to assume control of a closed, // but unavailable socket. int on = 1; if (::setsockopt (_socket, SOL_SOCKET, SO_REUSEADDR, (const void*) &on, sizeof (on)) == -1) throw std::string (::strerror (errno)); if (::connect (_socket, p->ai_addr, p->ai_addrlen) == -1) continue; break; } free (res); if (p == NULL) throw std::string ("Could not connect to ") + host + " " + port; #if GNUTLS_VERSION_NUMBER >= 0x030109 gnutls_transport_set_int (_session, _socket); #else gnutls_transport_set_ptr (_session, (gnutls_transport_ptr_t) (long) _socket); #endif // Perform the TLS handshake int ret; do { ret = gnutls_handshake (_session); } while (ret < 0 && gnutls_error_is_fatal (ret) == 0); if (ret < 0) throw std::string ("Handshake failed. ") + gnutls_strerror (ret); if (_debug) { #if GNUTLS_VERSION_NUMBER >= 0x03010a char* desc = gnutls_session_get_desc (_session); std::cout << "c: INFO Handshake was completed: " << desc << "\n"; gnutls_free (desc); #else std::cout << "c: INFO Handshake was completed.\n"; #endif } }
int main(void) { int ret, sd, ii; gnutls_session_t session; char buffer[MAX_BUF + 1]; gnutls_certificate_credentials_t xcred; if (gnutls_check_version("3.1.4") == NULL) { fprintf(stderr, "GnuTLS 3.1.4 or later is required for this example\n"); exit(1); } /* for backwards compatibility with gnutls < 3.3.0 */ CHECK(gnutls_global_init()); /* X509 stuff */ CHECK(gnutls_certificate_allocate_credentials(&xcred)); /* sets the system trusted CAs for Internet PKI */ CHECK(gnutls_certificate_set_x509_system_trust(xcred)); /* Initialize TLS session */ CHECK(gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM)); /* Use default priorities */ CHECK(gnutls_set_default_priority(session)); /* put the x509 credentials to the current session */ CHECK(gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred)); CHECK(gnutls_server_name_set(session, GNUTLS_NAME_DNS, "www.example.com", strlen("www.example.com"))); gnutls_session_set_verify_cert(session, "www.example.com", 0); /* connect to the peer */ sd = udp_connect(); gnutls_transport_set_int(session, sd); /* set the connection MTU */ gnutls_dtls_set_mtu(session, 1000); /* gnutls_dtls_set_timeouts(session, 1000, 60000); */ /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); /* Note that DTLS may also receive GNUTLS_E_LARGE_PACKET */ 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); } LOOP_CHECK(ret, gnutls_record_send(session, MSG, strlen(MSG))); LOOP_CHECK(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 && gnutls_error_is_fatal(ret) == 0) { fprintf(stderr, "*** Warning: %s\n", gnutls_strerror(ret)); } else if (ret < 0) { fprintf(stderr, "*** Error: %s\n", gnutls_strerror(ret)); goto end; } if (ret > 0) { printf("- Received %d bytes: ", ret); for (ii = 0; ii < ret; ii++) { fputc(buffer[ii], stdout); } fputs("\n", stdout); } /* It is suggested not to use GNUTLS_SHUT_RDWR in DTLS * connections because the peer's closure message might * be lost */ CHECK(gnutls_bye(session, GNUTLS_SHUT_WR)); end: udp_close(sd); gnutls_deinit(session); gnutls_certificate_free_credentials(xcred); gnutls_global_deinit(); return 0; }
struct wpabuf * tls_connection_handshake(void *tls_ctx, struct tls_connection *conn, const struct wpabuf *in_data, struct wpabuf **appl_data) { struct tls_global *global = tls_ctx; struct wpabuf *out_data; int ret; if (appl_data) *appl_data = NULL; if (in_data && wpabuf_len(in_data) > 0) { if (conn->pull_buf) { wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in " "pull_buf", __func__, (unsigned long) wpabuf_len(conn->pull_buf)); wpabuf_free(conn->pull_buf); } conn->pull_buf = wpabuf_dup(in_data); if (conn->pull_buf == NULL) return NULL; conn->pull_buf_offset = wpabuf_head(conn->pull_buf); } ret = gnutls_handshake(conn->session); if (ret < 0) { gnutls_alert_description_t alert; switch (ret) { case GNUTLS_E_AGAIN: if (global->server && conn->established && conn->push_buf == NULL) { /* Need to return something to trigger * completion of EAP-TLS. */ conn->push_buf = wpabuf_alloc(0); } break; case GNUTLS_E_FATAL_ALERT_RECEIVED: alert = gnutls_alert_get(conn->session); wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert", __func__, gnutls_alert_get_name(alert)); conn->read_alerts++; if (conn->global->event_cb != NULL) { union tls_event_data ev; os_memset(&ev, 0, sizeof(ev)); ev.alert.is_local = 0; ev.alert.type = gnutls_alert_get_name(alert); ev.alert.description = ev.alert.type; conn->global->event_cb(conn->global->cb_ctx, TLS_ALERT, &ev); } /* continue */ default: wpa_printf(MSG_DEBUG, "%s - gnutls_handshake failed " "-> %s", __func__, gnutls_strerror(ret)); conn->failed++; } } else { size_t size; wpa_printf(MSG_DEBUG, "TLS: Handshake completed successfully"); #if GNUTLS_VERSION_NUMBER >= 0x03010a { char *desc; desc = gnutls_session_get_desc(conn->session); if (desc) { wpa_printf(MSG_DEBUG, "GnuTLS: %s", desc); gnutls_free(desc); } } #endif /* GnuTLS 3.1.10 or newer */ conn->established = 1; if (conn->push_buf == NULL) { /* Need to return something to get final TLS ACK. */ conn->push_buf = wpabuf_alloc(0); } gnutls_session_get_data(conn->session, NULL, &size); if (global->session_data == NULL || global->session_data_size < size) { os_free(global->session_data); global->session_data = os_malloc(size); } if (global->session_data) { global->session_data_size = size; gnutls_session_get_data(conn->session, global->session_data, &global->session_data_size); } if (conn->pull_buf && appl_data) *appl_data = gnutls_get_appl_data(conn); } out_data = conn->push_buf; conn->push_buf = NULL; return out_data; }
void TLSTransaction::init (TLSServer& server) { int ret = gnutls_init (&_session, GNUTLS_SERVER); if (ret < 0) throw format ("TLS server init error. {1}", gnutls_strerror (ret)); ret = gnutls_priority_set (_session, server._priorities); if (ret < 0) throw format ("Error initializing TLS. {1}", gnutls_strerror (ret)); // Apply the x509 credentials to the current session. ret = gnutls_credentials_set (_session, GNUTLS_CRD_CERTIFICATE, server._credentials); if (ret < 0) throw format ("TLS credentials error. {1}", gnutls_strerror (ret)); // Store the TLSTransaction instance, so that the verification callback can // access it during the handshake below and call the verifcation method. gnutls_session_set_ptr (_session, (void*) this); // Require client certificate. gnutls_certificate_server_set_request (_session, GNUTLS_CERT_REQUIRE); /* // Set maximum compatibility mode. This is only suggested on public // webservers that need to trade security for compatibility gnutls_session_enable_compatibility_mode (_session); */ struct sockaddr_in sa_cli = {0}; socklen_t client_len = sizeof sa_cli; do { _socket = accept (server._socket, (struct sockaddr *) &sa_cli, &client_len); } while (errno == EINTR); if (_socket < 0) throw std::string (::strerror (errno)); // Obtain client info. char topbuf[512]; _address = inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf, sizeof (topbuf)); _port = ntohs (sa_cli.sin_port); if (_debug) std::cout << "s: INFO connection from " << _address << " port " << _port << "\n"; #if GNUTLS_VERSION_NUMBER >= 0x030109 gnutls_transport_set_int (_session, _socket); #else gnutls_transport_set_ptr (_session, (gnutls_transport_ptr_t) (intptr_t) _socket); #endif // Perform the TLS handshake do { ret = gnutls_handshake (_session); } while (ret < 0 && gnutls_error_is_fatal (ret) == 0); if (ret < 0) throw std::string ("Handshake has failed (") + gnutls_strerror (ret) + ")"; #if GNUTLS_VERSION_NUMBER < 0x02090a // The automatic verification for the server certificate with // gnutls_certificate_set_verify_function does only work with gnutls // >=2.9.10. So with older versions we should call the verify function // manually after the gnutls handshake. ret = verify_certificate (); if (ret < 0) { if (_debug) std::cout << "s: ERROR Certificate verification failed.\n"; throw std::string ("Error initializing TLS."); } #endif if (_debug) { #if GNUTLS_VERSION_NUMBER >= 0x03010a char* desc = gnutls_session_get_desc (_session); std::cout << "s: INFO Handshake was completed: " << desc << "\n"; gnutls_free (desc); #else std::cout << "s: INFO Handshake was completed.\n"; #endif } }