static void server(int fd, int profile) { int ret; gnutls_session_t session; gnutls_anon_server_credentials_t anoncred; uint8_t km[MAX_KEY_MATERIAL]; char buf[2 * MAX_KEY_MATERIAL]; gnutls_datum_t cli_key, cli_salt, server_key, server_salt; /* this must be called once in the program */ global_init(); if (debug) { gnutls_global_set_log_function(server_log_func); gnutls_global_set_log_level(4711); } gnutls_anon_allocate_server_credentials(&anoncred); gnutls_init(&session, GNUTLS_SERVER | GNUTLS_DATAGRAM); 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); if (profile) ret = gnutls_srtp_set_profile_direct(session, "SRTP_AES128_CM_HMAC_SHA1_80", NULL); else ret = gnutls_srtp_set_profile_direct(session, "SRTP_NULL_HMAC_SHA1_80", NULL); if (ret < 0) { gnutls_perror(ret); exit(1); } 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))); ret = gnutls_srtp_get_keys(session, km, sizeof(km), &cli_key, &cli_salt, &server_key, &server_salt); if (ret < 0) { gnutls_perror(ret); exit(1); } if (debug) { size_t size = sizeof(buf); gnutls_hex_encode(&cli_key, buf, &size); success("Client key: %s\n", buf); size = sizeof(buf); gnutls_hex_encode(&cli_salt, buf, &size); success("Client salt: %s\n", buf); size = sizeof(buf); gnutls_hex_encode(&server_key, buf, &size); success("Server key: %s\n", buf); size = sizeof(buf); gnutls_hex_encode(&server_salt, buf, &size); success("Server salt: %s\n", buf); } /* do not wait for the peer to close the connection. */ gnutls_bye(session, GNUTLS_SHUT_WR); 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, int profile) { gnutls_session_t session; int ret; gnutls_anon_client_credentials_t anoncred; uint8_t km[MAX_KEY_MATERIAL]; char buf[2 * MAX_KEY_MATERIAL]; gnutls_datum_t cli_key, cli_salt, server_key, server_salt; /* Need to enable anonymous KX specifically. */ global_init(); if (debug) { gnutls_global_set_log_function(client_log_func); gnutls_global_set_log_level(4711); } gnutls_anon_allocate_client_credentials(&anoncred); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM); 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); if (profile) ret = gnutls_srtp_set_profile_direct(session, "SRTP_AES128_CM_HMAC_SHA1_80", NULL); else ret = gnutls_srtp_set_profile_direct(session, "SRTP_NULL_HMAC_SHA1_80", NULL); if (ret < 0) { gnutls_perror(ret); exit(1); } /* 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"); } if (debug) success("client: DTLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); ret = gnutls_srtp_get_keys(session, km, sizeof(km), &cli_key, &cli_salt, &server_key, &server_salt); if (ret < 0) { gnutls_perror(ret); exit(1); } if (debug) { size_t size = sizeof(buf); gnutls_hex_encode(&cli_key, buf, &size); success("Client key: %s\n", buf); size = sizeof(buf); gnutls_hex_encode(&cli_salt, buf, &size); success("Client salt: %s\n", buf); size = sizeof(buf); gnutls_hex_encode(&server_key, buf, &size); success("Server key: %s\n", buf); size = sizeof(buf); gnutls_hex_encode(&server_salt, buf, &size); success("Server salt: %s\n", buf); } gnutls_bye(session, GNUTLS_SHUT_WR); close(fd); gnutls_deinit(session); gnutls_anon_free_client_credentials(anoncred); gnutls_global_deinit(); }
/* initializes a gnutls_session_t with some defaults. */ static gnutls_session_t init_tls_session (const char *hostname) { const char *err; int ret; gnutls_session_t session; if (priorities == NULL) priorities = "NORMAL"; if (udp) { gnutls_init (&session, GNUTLS_DATAGRAM|init_flags); if (mtu) gnutls_dtls_set_mtu(session, mtu); } else gnutls_init (&session, init_flags); if ((ret = gnutls_priority_set_direct (session, priorities, &err)) < 0) { if (ret == GNUTLS_E_INVALID_REQUEST) fprintf (stderr, "Syntax error at: %s\n", err); else fprintf(stderr, "Error in priorities: %s\n", gnutls_strerror(ret)); exit (1); } /* allow the use of private ciphersuites. */ if (disable_extensions == 0) { if (!isdigit(hostname[0]) && strchr(hostname, ':') == 0) gnutls_server_name_set (session, GNUTLS_NAME_DNS, hostname, strlen (hostname)); } if (HAVE_OPT(DH_BITS)) gnutls_dh_set_prime_bits( session, OPT_VALUE_DH_BITS); gnutls_credentials_set (session, GNUTLS_CRD_ANON, anon_cred); if (srp_cred) gnutls_credentials_set (session, GNUTLS_CRD_SRP, srp_cred); if (psk_cred) gnutls_credentials_set (session, GNUTLS_CRD_PSK, psk_cred); gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); gnutls_certificate_set_retrieve_function2 (xcred, cert_callback); gnutls_certificate_set_verify_function (xcred, cert_verify_callback); /* send the fingerprint */ #ifdef ENABLE_OPENPGP if (fingerprint != 0) gnutls_openpgp_send_cert (session, GNUTLS_OPENPGP_CERT_FINGERPRINT); #endif /* use the max record size extension */ if (record_max_size > 0 && disable_extensions == 0) { if (gnutls_record_set_max_size (session, record_max_size) < 0) { fprintf (stderr, "Cannot set the maximum record size to %d.\n", record_max_size); fprintf (stderr, "Possible values: 512, 1024, 2048, 4096.\n"); exit (1); } } if (HAVE_OPT(HEARTBEAT)) gnutls_heartbeat_enable (session, GNUTLS_HB_PEER_ALLOWED_TO_SEND); #ifdef ENABLE_DTLS_SRTP if (HAVE_OPT(SRTP_PROFILES)) { ret = gnutls_srtp_set_profile_direct (session, OPT_ARG(SRTP_PROFILES), &err); if (ret == GNUTLS_E_INVALID_REQUEST) fprintf (stderr, "Syntax error at: %s\n", err); else fprintf(stderr, "Error in profiles: %s\n", gnutls_strerror(ret)); exit (1); } #endif return session; }