summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2013-05-05 13:39:43 +0300
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2013-05-05 13:39:43 +0300
commit12529701fe93452705675e6933ea40076480d872 (patch)
tree1ac503b04acfcc64fb946a7fe68752ce19e6e14b
parentb61a0d3d582c2e76f7407f1c1fd64a4bcdc74292 (diff)
downloadgnutls-12529701fe93452705675e6933ea40076480d872.tar.gz
Added support for the NO_APPLICATION_PROTOCOL alert for ALPN.
-rw-r--r--lib/ext/alpn.c11
-rw-r--r--lib/ext/alpn.h1
-rw-r--r--lib/gnutls_alert.c6
-rw-r--r--lib/gnutls_errors.c2
-rw-r--r--lib/includes/gnutls/gnutls.h.in7
5 files changed, 24 insertions, 3 deletions
diff --git a/lib/ext/alpn.c b/lib/ext/alpn.c
index 4f19f0752e..939266e15a 100644
--- a/lib/ext/alpn.c
+++ b/lib/ext/alpn.c
@@ -112,6 +112,9 @@ _gnutls_alpn_recv_params (gnutls_session_t session,
p += len1;
}
+ if (priv->selected_protocol == NULL && (priv->flags & GNUTLS_ALPN_MAND))
+ return gnutls_assert_val(GNUTLS_E_NO_APPLICATION_PROTOCOL);
+
return 0;
}
@@ -224,10 +227,14 @@ gnutls_alpn_get_selected_protocol (gnutls_session_t session,
* @session: is a #gnutls_session_t structure.
* @protocols: is the protocol names to add.
* @protocols_size: the number of protocols to add.
+ * @flags: one of %GNUTLS_ALPN_*
*
* This function is to be used by both clients and servers, to declare
* the supported ALPN protocols, which are used during peer negotiation.
*
+ * If %GNUTLS_ALPN_MAND is specified the connection will be aborted
+ * if no matching ALPN protocol is found.
+ *
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
* otherwise a negative error code is returned.
*
@@ -235,7 +242,8 @@ gnutls_alpn_get_selected_protocol (gnutls_session_t session,
**/
int
gnutls_alpn_set_protocols (gnutls_session_t session,
- const gnutls_datum_t * protocols, unsigned protocols_size)
+ const gnutls_datum_t * protocols, unsigned protocols_size,
+ unsigned int flags)
{
int ret;
alpn_ext_st *priv;
@@ -272,6 +280,7 @@ gnutls_alpn_set_protocols (gnutls_session_t session,
priv->protocol_size[i] = protocols[i].size;
priv->size++;
}
+ priv->flags = flags;
return 0;
}
diff --git a/lib/ext/alpn.h b/lib/ext/alpn.h
index 541bcaeb21..5784f1de9c 100644
--- a/lib/ext/alpn.h
+++ b/lib/ext/alpn.h
@@ -32,6 +32,7 @@ typedef struct
unsigned size;
uint8_t *selected_protocol;
unsigned selected_protocol_size;
+ unsigned flags;
} alpn_ext_st;
extern extension_entry_st ext_mod_alpn;
diff --git a/lib/gnutls_alert.c b/lib/gnutls_alert.c
index 995782ff0e..c7932eb472 100644
--- a/lib/gnutls_alert.c
+++ b/lib/gnutls_alert.c
@@ -72,6 +72,8 @@ static const gnutls_alert_entry sup_alerts[] = {
N_("The server name sent was not recognized")),
ALERT_ENTRY(GNUTLS_A_UNKNOWN_PSK_IDENTITY,
N_("The SRP/PSK username is missing or not known")),
+ ALERT_ENTRY(GNUTLS_A_NO_APPLICATION_PROTOCOL,
+ N_("No supported application protocol could be negotiated")),
{0, NULL, NULL}
};
@@ -279,6 +281,10 @@ gnutls_error_to_alert (int err, int *level)
ret = GNUTLS_A_INSUFFICIENT_SECURITY;
_level = GNUTLS_AL_FATAL;
break;
+ case GNUTLS_E_NO_APPLICATION_PROTOCOL:
+ ret = GNUTLS_A_NO_APPLICATION_PROTOCOL;
+ _level = GNUTLS_AL_FATAL;
+ break;
default:
ret = GNUTLS_A_INTERNAL_ERROR;
_level = GNUTLS_AL_FATAL;
diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c
index 2397e9b632..25bd0ca2ff 100644
--- a/lib/gnutls_errors.c
+++ b/lib/gnutls_errors.c
@@ -355,6 +355,8 @@ static const gnutls_error_entry error_algorithms[] = {
GNUTLS_E_NO_CERTIFICATE_STATUS, 1),
ERROR_ENTRY (N_("Error in the system's randomness device."),
GNUTLS_E_RANDOM_DEVICE_ERROR, 1),
+ ERROR_ENTRY (N_("No common application protocol could be negotiated."),
+ GNUTLS_E_NO_APPLICATION_PROTOCOL, 1),
{NULL, NULL, 0, 0}
};
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 185187de24..5cb6f7ea84 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -388,6 +388,7 @@ extern "C"
GNUTLS_A_CERTIFICATE_UNOBTAINABLE = 111,
GNUTLS_A_UNRECOGNIZED_NAME = 112,
GNUTLS_A_UNKNOWN_PSK_IDENTITY = 115,
+ GNUTLS_A_NO_APPLICATION_PROTOCOL = 120,
} gnutls_alert_description_t;
/**
@@ -1047,11 +1048,12 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session);
int gnutls_srtp_get_mki (gnutls_session_t session, gnutls_datum_t *mki);
/* ALPN TLS extension */
+#define GNUTLS_ALPN_MAND 1
int gnutls_alpn_get_selected_protocol (gnutls_session_t session,
gnutls_datum_t * protocol);
int gnutls_alpn_set_protocols (gnutls_session_t session,
- const gnutls_datum_t * protocols, unsigned protocols_size);
-
+ const gnutls_datum_t * protocols, unsigned protocols_size,
+ unsigned flags);
int gnutls_key_generate (gnutls_datum_t * key, unsigned int key_size);
@@ -2199,6 +2201,7 @@ typedef int (*gnutls_pin_callback_t) (void *userdata, int attempt,
#define GNUTLS_E_OCSP_RESPONSE_ERROR -341
#define GNUTLS_E_RANDOM_DEVICE_ERROR -342
#define GNUTLS_E_AUTH_ERROR -343
+#define GNUTLS_E_NO_APPLICATION_PROTOCOL -344
#define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250