static void session_init(int sock, int server) { gnutls_init(&session, GNUTLS_DATAGRAM | (server ? GNUTLS_SERVER : GNUTLS_CLIENT) | GNUTLS_NONBLOCK * nonblock); gnutls_priority_set_direct(session, "+CTYPE-OPENPGP:+CIPHER-ALL:+MAC-ALL:+ECDHE-RSA:+ANON-ECDH", 0); gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t) (intptr_t) sock); if (full) { gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred); if (server) { gnutls_certificate_server_set_request(session, GNUTLS_CERT_REQUIRE); } } else if (server) { gnutls_anon_server_credentials_t cred; gnutls_anon_allocate_server_credentials(&cred); gnutls_credentials_set(session, GNUTLS_CRD_ANON, cred); } else { gnutls_anon_client_credentials_t cred; gnutls_anon_allocate_client_credentials(&cred); gnutls_credentials_set(session, GNUTLS_CRD_ANON, cred); } gnutls_transport_set_push_function(session, writefn); gnutls_dtls_set_mtu(session, 1400); gnutls_dtls_set_timeouts(session, retransmit_milliseconds, timeout_seconds * 1000); }
gnutls_session_t session(int sock, int server) { gnutls_session_t r; gnutls_init(&r, GNUTLS_DATAGRAM | (server ? GNUTLS_SERVER : GNUTLS_CLIENT) | GNUTLS_NONBLOCK * nonblock); gnutls_priority_set_direct(r, "NORMAL:+ANON-ECDH", 0); gnutls_transport_set_ptr(r, (gnutls_transport_ptr_t) sock); if (server) { gnutls_anon_server_credentials_t cred; gnutls_anon_allocate_server_credentials(&cred); gnutls_credentials_set(r, GNUTLS_CRD_ANON, cred); } else { gnutls_anon_client_credentials_t cred; gnutls_anon_allocate_client_credentials(&cred); gnutls_credentials_set(r, GNUTLS_CRD_ANON, cred); } gnutls_transport_set_push_function(r, writefn); gnutls_dtls_set_mtu(r, 1400); gnutls_dtls_set_timeouts(r, 100, 60000); return r; }
static void client(int sds[], struct params_res *params) { int ret, ii; gnutls_session_t session; char buffer[MAX_BUF + 1]; gnutls_anon_client_credentials_t anoncred; /* Need to enable anonymous KX specifically. */ /* variables used in session resuming */ int t; gnutls_datum_t session_data; if (debug) { gnutls_global_set_log_function(tls_log_func); gnutls_global_set_log_level(3); } global_init(); gnutls_anon_allocate_client_credentials(&anoncred); for (t = 0; t < SESSIONS; t++) { int sd = sds[t]; /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM); /* Use default priorities */ if (params->enable_session_ticket_client) gnutls_priority_set_direct(session, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL); else gnutls_priority_set_direct(session, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH:%NO_TICKETS", NULL); /* put the anonymous credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); if (t > 0) { /* if this is not the first time we connect */ gnutls_session_set_data(session, session_data.data, session_data.size); gnutls_free(session_data.data); } gnutls_transport_set_int(session, sd); /* Perform the TLS handshake */ gnutls_dtls_set_timeouts(session, 3*1000, 240 * 1000); do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { gnutls_perror(ret); fail("client: Handshake failed\n"); goto end; } else { if (debug) success ("client: Handshake was completed\n"); } if (t == 0) { /* the first time we connect */ /* get the session data size */ ret = gnutls_session_get_data2(session, &session_data); if (ret < 0) fail("Getting resume data failed\n"); } else { /* the second time we connect */ /* check if we actually resumed the previous session */ if (gnutls_session_is_resumed(session) != 0) { if (params->expect_resume) { if (debug) success ("- Previous session was resumed\n"); } else fail("- Previous session was resumed\n"); } else { if (params->expect_resume) { fail("*** Previous session was NOT resumed\n"); } else { if (debug) success ("*** Previous session was NOT resumed (expected)\n"); } } } 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); close(sd); gnutls_deinit(session); } end: gnutls_anon_free_client_credentials(anoncred); }
static void server(int sds[], struct params_res *params) { gnutls_anon_server_credentials_t anoncred; static gnutls_datum_t session_ticket_key = { NULL, 0 }; int ret; size_t t; gnutls_session_t session; /* this must be called once in the program, it is mostly for the server. */ if (debug) { gnutls_global_set_log_function(tls_log_func); gnutls_global_set_log_level(3); } global_init(); gnutls_anon_allocate_server_credentials(&anoncred); if (debug) success("Launched, generating DH parameters...\n"); gnutls_anon_set_server_dh_params(anoncred, dh_params); if (params->enable_db) { wrap_db_init(); } if (params->enable_session_ticket_server) gnutls_session_ticket_key_generate(&session_ticket_key); for (t = 0; t < SESSIONS; t++) { int sd = sds[t]; gnutls_init(&session, GNUTLS_SERVER | GNUTLS_DATAGRAM); gnutls_priority_set_direct(session, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL); gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); gnutls_dh_set_prime_bits(session, DH_BITS); if (params->enable_db) { gnutls_db_set_retrieve_function(session, wrap_db_fetch); gnutls_db_set_remove_function(session, wrap_db_delete); gnutls_db_set_store_function(session, wrap_db_store); gnutls_db_set_ptr(session, NULL); } if (params->enable_session_ticket_server) gnutls_session_ticket_enable_server(session, &session_ticket_key); gnutls_transport_set_int(session, sd); gnutls_dtls_set_timeouts(session, 3*1000, 240 * 1000); do { ret = gnutls_handshake(session); } while (ret < 0 && (ret == GNUTLS_E_INTERRUPTED||ret == GNUTLS_E_AGAIN)); if (ret < 0) { close(sd); gnutls_deinit(session); kill(child, SIGTERM); fail("server: Handshake has failed (%s)\n\n", gnutls_strerror(ret)); return; } if (debug) success("server: Handshake was completed\n"); /* see the Getting peer's information example */ /* print_info(session); */ for (;;) { memset(buffer, 0, MAX_BUF + 1); ret = gnutls_record_recv(session, buffer, MAX_BUF); if (ret == 0) { if (debug) success ("server: Peer has closed the GnuTLS connection\n"); break; } else if (ret < 0) { kill(child, SIGTERM); fail("server: Received corrupted data(%d). Closing...\n", ret); break; } else if (ret > 0) { /* echo data back to the client */ gnutls_record_send(session, buffer, strlen(buffer)); } } /* do not wait for the peer to close the connection. */ gnutls_bye(session, GNUTLS_SHUT_WR); close(sd); gnutls_deinit(session); } if (params->enable_db) { wrap_db_deinit(); } gnutls_free(session_ticket_key.data); session_ticket_key.data = NULL; gnutls_anon_free_server_credentials(anoncred); if (debug) success("server: finished\n"); }
static void server(int fd) { int ret; gnutls_session_t session; gnutls_anon_server_credentials_t anoncred; char c; global_init(); if (debug) { gnutls_global_set_log_function(server_log_func); gnutls_global_set_log_level(2); } gnutls_anon_allocate_server_credentials(&anoncred); gnutls_init(&session, GNUTLS_SERVER | GNUTLS_DATAGRAM); gnutls_dtls_set_timeouts(session, 50 * 1000, 600 * 1000); gnutls_transport_set_push_function(session, odd_push); gnutls_heartbeat_enable(session, GNUTLS_HB_PEER_ALLOWED_TO_SEND); gnutls_dtls_set_mtu(session, 1500); /* avoid calling all the priority functions, since the defaults * are adequate. */ gnutls_priority_set_direct(session, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL", NULL); gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); gnutls_transport_set_int(session, fd); do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { close(fd); gnutls_deinit(session); fail("server: Handshake has failed (%s)\n\n", gnutls_strerror(ret)); terminate(); } if (debug) success("server: Handshake was completed\n"); if (debug) success("server: TLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); gnutls_record_recv(session, &c, 1); do { do { ret = gnutls_record_send(session, &c, 1); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); if (ret < 0) { fail("send: %s\n", gnutls_strerror(ret)); terminate(); } } while (test_finished == 0); gnutls_transport_set_push_function(session, n_push); do { ret = gnutls_bye(session, GNUTLS_SHUT_WR); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); close(fd); gnutls_deinit(session); gnutls_anon_free_server_credentials(anoncred); gnutls_global_deinit(); if (debug) success("server: finished\n"); }
static void client(int fd) { gnutls_session_t session; int ret; char buffer[MAX_BUF + 1]; gnutls_anon_client_credentials_t anoncred; unsigned char seq[8]; uint32_t useq; memset(buffer, 0, sizeof(buffer)); /* Need to enable anonymous KX specifically. */ /* gnutls_global_set_audit_log_function (tls_audit_log_func); */ global_init(); if (debug) { gnutls_global_set_log_function(client_log_func); gnutls_global_set_log_level(2); } gnutls_anon_allocate_client_credentials(&anoncred); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM); gnutls_dtls_set_timeouts(session, 50 * 1000, 600 * 1000); gnutls_heartbeat_enable(session, GNUTLS_HB_PEER_ALLOWED_TO_SEND); gnutls_dtls_set_mtu(session, 1500); /* Use default priorities */ gnutls_priority_set_direct(session, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL", NULL); /* put the anonymous credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); gnutls_transport_set_int(session, fd); /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { fail("client: Handshake failed\n"); gnutls_perror(ret); exit(1); } else { if (debug) success("client: Handshake was completed\n"); } gnutls_record_send(session, buffer, 1); if (debug) success("client: DTLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); do { ret = gnutls_record_recv_seq(session, buffer, sizeof(buffer), seq); if (ret > 0) { useq = seq[7] | (seq[6] << 8) | (seq[5] << 16) | (seq[4] << 24); if (debug) success("received %u\n", (unsigned int)useq); if (recv_msg_seq[current] == -1) { fail("received message sequence differs\n"); terminate(); } if (((uint32_t)recv_msg_seq[current]) != useq) { fail("received message sequence differs (current: %u, got: %u, expected: %u)\n", (unsigned)current, (unsigned)useq, (unsigned)recv_msg_seq[current]); terminate(); } current++; } } while ((ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED || ret > 0)); gnutls_bye(session, GNUTLS_SHUT_WR); close(fd); gnutls_deinit(session); gnutls_anon_free_client_credentials(anoncred); gnutls_global_deinit(); }
/** * gnutls_init: * @session: is a pointer to a #gnutls_session_t type. * @flags: indicate if this session is to be used for server or client. * * This function initializes the provided session. Every * session must be initialized before use, and must be deinitialized * after used by calling gnutls_deinit(). * * @flags can be any combination of flags from %gnutls_init_flags_t. * * Note that since version 3.1.2 this function enables some common * TLS extensions such as session tickets and OCSP certificate status * request in client side by default. To prevent that use the %GNUTLS_NO_EXTENSIONS * flag. * * Returns: %GNUTLS_E_SUCCESS on success, or an error code. **/ int gnutls_init(gnutls_session_t * session, unsigned int flags) { int ret; record_parameters_st *epoch; FAIL_IF_LIB_ERROR; *session = gnutls_calloc(1, sizeof(struct gnutls_session_int)); if (*session == NULL) return GNUTLS_E_MEMORY_ERROR; ret = _gnutls_epoch_alloc(*session, 0, &epoch); if (ret < 0) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } /* Set all NULL algos on epoch 0 */ _gnutls_epoch_set_null_algos(*session, epoch); (*session)->security_parameters.epoch_next = 1; (*session)->security_parameters.entity = (flags & GNUTLS_SERVER ? GNUTLS_SERVER : GNUTLS_CLIENT); /* the default certificate type for TLS */ (*session)->security_parameters.cert_type = DEFAULT_CERT_TYPE; /* Initialize buffers */ _gnutls_buffer_init(&(*session)->internals.handshake_hash_buffer); _gnutls_buffer_init(&(*session)->internals.hb_remote_data); _gnutls_buffer_init(&(*session)->internals.hb_local_data); _gnutls_buffer_init(&(*session)->internals.record_presend_buffer); _mbuffer_head_init(&(*session)->internals.record_buffer); _mbuffer_head_init(&(*session)->internals.record_send_buffer); _mbuffer_head_init(&(*session)->internals.record_recv_buffer); _mbuffer_head_init(&(*session)->internals.handshake_send_buffer); _gnutls_handshake_recv_buffer_init(*session); (*session)->internals.expire_time = DEFAULT_EXPIRE_TIME; /* one hour default */ gnutls_handshake_set_max_packet_length((*session), MAX_HANDSHAKE_PACKET_SIZE); /* set the socket pointers to -1; */ (*session)->internals.transport_recv_ptr = (gnutls_transport_ptr_t) - 1; (*session)->internals.transport_send_ptr = (gnutls_transport_ptr_t) - 1; /* set the default maximum record size for TLS */ (*session)->security_parameters.max_record_recv_size = DEFAULT_MAX_RECORD_SIZE; (*session)->security_parameters.max_record_send_size = DEFAULT_MAX_RECORD_SIZE; /* everything else not initialized here is initialized * as NULL or 0. This is why calloc is used. */ _gnutls_handshake_internal_state_init(*session); (*session)->internals.extensions_sent_size = 0; /* emulate old gnutls behavior for old applications that do not use the priority_* * functions. */ (*session)->internals.priorities.sr = SR_PARTIAL; #ifdef HAVE_WRITEV #ifdef MSG_NOSIGNAL if (flags & GNUTLS_NO_SIGNAL) gnutls_transport_set_vec_push_function(*session, system_writev_nosignal); else #endif gnutls_transport_set_vec_push_function(*session, system_writev); #else gnutls_transport_set_push_function(*session, system_write); #endif (*session)->internals.pull_timeout_func = gnutls_system_recv_timeout; (*session)->internals.pull_func = system_read; (*session)->internals.errno_func = system_errno; /* heartbeat timeouts */ (*session)->internals.hb_retrans_timeout_ms = 1000; (*session)->internals.hb_total_timeout_ms = 60000; if (flags & GNUTLS_DATAGRAM) { (*session)->internals.dtls.mtu = DTLS_DEFAULT_MTU; (*session)->internals.transport = GNUTLS_DGRAM; gnutls_dtls_set_timeouts(*session, DTLS_RETRANS_TIMEOUT, 60000); } else { (*session)->internals.transport = GNUTLS_STREAM; } /* Enable useful extensions */ if ((flags & GNUTLS_CLIENT) && !(flags & GNUTLS_NO_EXTENSIONS)) { #ifdef ENABLE_SESSION_TICKETS if (!(flags & GNUTLS_NO_TICKETS)) gnutls_session_ticket_enable_client(*session); #endif #ifdef ENABLE_OCSP gnutls_ocsp_status_request_enable_client(*session, NULL, 0, NULL); #endif } (*session)->internals.flags = flags; return 0; }
static void server(int fd, unsigned do_thread) { int ret; gnutls_certificate_credentials_t x509_cred; gnutls_session_t session; /* this must be called once in the program */ global_init(); #if 0 if (debug) { side = "server"; gnutls_global_set_log_function(tls_log_func); gnutls_global_set_log_level(4711); } #endif gnutls_certificate_allocate_credentials(&x509_cred); gnutls_certificate_set_x509_key_mem(x509_cred, &server_cert, &server_key, GNUTLS_X509_FMT_PEM); gnutls_init(&session, GNUTLS_SERVER | GNUTLS_DATAGRAM); gnutls_dtls_set_timeouts(session, 5 * 1000, 60 * 1000); gnutls_dtls_set_mtu(session, 400); /* avoid calling all the priority functions, since the defaults * are adequate. */ gnutls_priority_set_direct(session, "NONE:+VERS-DTLS1.2:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ECDHE-ECDSA:+CURVE-ALL", NULL); gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_transport_set_int(session, fd); do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { close(fd); gnutls_deinit(session); fail("server: Handshake has failed (%s)\n\n", gnutls_strerror(ret)); terminate(); } if (debug) success("server: Handshake was completed\n"); if (debug) success("server: TLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); if (do_thread) do_thread_stuff(session); else do_reflect_stuff(session); close(fd); gnutls_deinit(session); gnutls_certificate_free_credentials(x509_cred); gnutls_global_deinit(); if (debug) success("server: finished\n"); }
static void client(int fd, unsigned do_thread) { int ret; gnutls_certificate_credentials_t x509_cred; gnutls_session_t session; /* Need to enable anonymous KX specifically. */ global_init(); if (debug) { side = "client"; gnutls_global_set_log_function(tls_log_func); gnutls_global_set_log_level(4711); } gnutls_certificate_allocate_credentials(&x509_cred); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM); gnutls_dtls_set_mtu(session, 1500); gnutls_dtls_set_timeouts(session, 6 * 1000, 60 * 1000); //gnutls_transport_set_push_function(session, push); /* Use default priorities */ gnutls_priority_set_direct(session, "NONE:+VERS-DTLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ECDHE-ECDSA:+CURVE-ALL", NULL); /* put the anonymous credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_transport_set_int(session, fd); /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { fail("client: Handshake failed\n"); gnutls_perror(ret); exit(1); } else { if (debug) success("client: Handshake was completed\n"); } if (do_thread) do_thread_stuff(session); else do_reflect_stuff(session); close(fd); gnutls_deinit(session); gnutls_certificate_free_credentials(x509_cred); gnutls_global_deinit(); exit(0); }
static void client(int fd) { int ret; char buffer[MAX_BUF + 1]; gnutls_certificate_credentials_t clientx509cred; gnutls_anon_client_credentials_t anoncred; gnutls_session_t session; global_init(); if (debug) { gnutls_global_set_log_function(client_log_func); gnutls_global_set_log_level(4711); } assert(gnutls_anon_allocate_client_credentials(&anoncred) >= 0); assert(gnutls_certificate_allocate_credentials(&clientx509cred) >= 0); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM); gnutls_dtls_set_mtu(session, MTU); assert(gnutls_priority_set_direct(session, "NONE:+VERS-DTLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL", NULL) >= 0); gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, clientx509cred); gnutls_transport_set_int(session, fd); gnutls_transport_set_push_function(session, push); gnutls_dtls_set_timeouts(session, 2000, 30 * 1000); /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { fail("client: Handshake failed\n"); gnutls_perror(ret); exit(1); } else { if (debug) success("client: Handshake was completed\n"); } if (debug) success("client: TLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); /* update priorities to allow cert auth */ assert(gnutls_priority_set_direct(session, "NONE:+VERS-DTLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ECDHE-RSA:+CURVE-ALL", NULL) >= 0); do { ret = gnutls_record_recv(session, buffer, MAX_BUF); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); if (ret == 0) { if (debug) success("client: Peer has closed the TLS connection\n"); goto end; } else if (ret < 0) { if (ret == GNUTLS_E_REHANDSHAKE) { if (debug) success ("Initiating rehandshake due to server request\n"); do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); } if (ret != 0) { fail("client: Error: %s\n", gnutls_strerror(ret)); exit(1); } } do { ret = gnutls_record_send(session, MSG, strlen(MSG)); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); gnutls_bye(session, GNUTLS_SHUT_WR); end: close(fd); gnutls_deinit(session); gnutls_certificate_free_credentials(clientx509cred); gnutls_anon_free_client_credentials(anoncred); gnutls_global_deinit(); }