aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant/tls_gnutls.c
diff options
context:
space:
mode:
Diffstat (limited to 'wpa_supplicant/tls_gnutls.c')
-rw-r--r--wpa_supplicant/tls_gnutls.c47
1 files changed, 45 insertions, 2 deletions
diff --git a/wpa_supplicant/tls_gnutls.c b/wpa_supplicant/tls_gnutls.c
index ff10a11..b669caf 100644
--- a/wpa_supplicant/tls_gnutls.c
+++ b/wpa_supplicant/tls_gnutls.c
@@ -20,6 +20,18 @@
#include "tls.h"
+#define TLS_RANDOM_SIZE 32
+
+#if LIBGNUTLS_VERSION_NUMBER < 0x010302
+/* GnuTLS 1.3.2 added functions for using master secret. Older versions require
+ * use of internal structures to get the master_secret and
+ * {server,client}_random.
+ */
+#define GNUTLS_INTERNAL_STRUCTURE_HACK
+#endif /* LIBGNUTLS_VERSION_NUMBER < 0x010302 */
+
+
+#ifdef GNUTLS_INTERNAL_STRUCTURE_HACK
/*
* It looks like gnutls does not provide access to client/server_random and
* master_key. This is somewhat unfortunate since these are needed for key
@@ -29,7 +41,6 @@
*/
typedef u8 uint8;
-#define TLS_RANDOM_SIZE 32
#define TLS_MASTER_SIZE 48
typedef unsigned char opaque;
typedef struct {
@@ -56,6 +67,7 @@ struct gnutls_session_int {
security_parameters_st security_parameters;
/* followed by things we are not interested in */
};
+#endif /* LIBGNUTLS_VERSION_NUMBER < 0x010302 */
struct tls_connection {
@@ -105,18 +117,22 @@ extern int wpa_debug_show_keys;
void * tls_init(const struct tls_config *conf)
{
+#ifdef GNUTLS_INTERNAL_STRUCTURE_HACK
/* Because of the horrible hack to get master_secret and client/server
* random, we need to make sure that the gnutls version is something
* that is expected to have same structure definition for the session
* data.. */
const char *ver;
const char *ok_ver[] = { "1.2.3", "1.2.4", "1.2.5", "1.2.6", "1.2.9",
+ "1.3.2",
NULL };
int i;
+#endif /* GNUTLS_INTERNAL_STRUCTURE_HACK */
if (gnutls_global_init() < 0)
return NULL;
+#ifdef GNUTLS_INTERNAL_STRUCTURE_HACK
ver = gnutls_check_version(NULL);
if (ver == NULL)
return NULL;
@@ -130,6 +146,7 @@ void * tls_init(const struct tls_config *conf)
"to be tested and enabled in tls_gnutls.c", ver);
return NULL;
}
+#endif /* GNUTLS_INTERNAL_STRUCTURE_HACK */
gnutls_global_set_log_function(tls_log_func);
if (wpa_debug_show_keys)
@@ -488,24 +505,50 @@ int tls_global_private_key(void *_ssl_ctx, const char *private_key,
int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn,
struct tls_keys *keys)
{
+#ifdef GNUTLS_INTERNAL_STRUCTURE_HACK
security_parameters_st *sec;
+#endif /* GNUTLS_INTERNAL_STRUCTURE_HACK */
if (conn == NULL || conn->session == NULL || keys == NULL)
return -1;
memset(keys, 0, sizeof(*keys));
+
+#ifdef GNUTLS_INTERNAL_STRUCTURE_HACK
sec = &conn->session->security_parameters;
keys->master_key = sec->master_secret;
keys->master_key_len = TLS_MASTER_SIZE;
keys->client_random = sec->client_random;
- keys->client_random_len = TLS_RANDOM_SIZE;
keys->server_random = sec->server_random;
+#else /* GNUTLS_INTERNAL_STRUCTURE_HACK */
+ keys->client_random = gnutls_session_get_client_random(conn->session);
+ keys->server_random = gnutls_session_get_server_random(conn->session);
+ /* No access to master_secret */
+#endif /* GNUTLS_INTERNAL_STRUCTURE_HACK */
+
+ keys->client_random_len = TLS_RANDOM_SIZE;
keys->server_random_len = TLS_RANDOM_SIZE;
return 0;
}
+int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
+ const char *label, int server_random_first,
+ u8 *out, size_t out_len)
+{
+#if LIBGNUTLS_VERSION_NUMBER >= 0x010302
+ if (conn == NULL || conn->session == NULL)
+ return -1;
+
+ return gnutls_prf(conn->session, strlen(label), label,
+ server_random_first, 0, NULL, out_len, out);
+#else /* LIBGNUTLS_VERSION_NUMBER >= 0x010302 */
+ return -1;
+#endif /* LIBGNUTLS_VERSION_NUMBER >= 0x010302 */
+}
+
+
static int tls_connection_verify_peer(struct tls_connection *conn)
{
unsigned int status, num_certs, i;