/** * gnutls_srtp_get_keys: * @session: is a #gnutls_session_t type. * @key_material: Space to hold the generated key material * @key_material_size: The maximum size of the key material * @client_key: The master client write key, pointing inside the key material * @server_key: The master server write key, pointing inside the key material * @client_salt: The master client write salt, pointing inside the key material * @server_salt: The master server write salt, pointing inside the key material * * This is a helper function to generate the keying material for SRTP. * It requires the space of the key material to be pre-allocated (should be at least * 2x the maximum key size and salt size). The @client_key, @client_salt, @server_key * and @server_salt are convenience datums that point inside the key material. They may * be %NULL. * * Returns: On success the size of the key material is returned, * otherwise, %GNUTLS_E_SHORT_MEMORY_BUFFER if the buffer given is not * sufficient, or a negative error code. * * Since 3.1.4 **/ int gnutls_srtp_get_keys(gnutls_session_t session, void *key_material, unsigned int key_material_size, gnutls_datum_t * client_key, gnutls_datum_t * client_salt, gnutls_datum_t * server_key, gnutls_datum_t * server_salt) { int ret; const srtp_profile_st *p; gnutls_srtp_profile_t profile; unsigned int msize; uint8_t *km = key_material; ret = gnutls_srtp_get_selected_profile(session, &profile); if (ret < 0) return gnutls_assert_val(ret); p = get_profile(profile); if (p == NULL) return gnutls_assert_val(GNUTLS_E_UNKNOWN_ALGORITHM); msize = 2 * (p->key_length + p->salt_length); if (msize > key_material_size) return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); if (msize == 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ret = gnutls_prf(session, sizeof("EXTRACTOR-dtls_srtp") - 1, "EXTRACTOR-dtls_srtp", 0, 0, NULL, msize, key_material); if (ret < 0) return gnutls_assert_val(ret); if (client_key) { client_key->data = km; client_key->size = p->key_length; } if (server_key) { server_key->data = km + p->key_length; server_key->size = p->key_length; } if (client_salt) { client_salt->data = km + 2 * p->key_length; client_salt->size = p->salt_length; } if (server_salt) { server_salt->data = km + 2 * p->key_length + p->salt_length; server_salt->size = p->salt_length; } return msize; }
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; }