summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSimon Josefsson <simon@josefsson.org>2006-05-05 09:07:17 +0000
committerSimon Josefsson <simon@josefsson.org>2006-05-05 09:07:17 +0000
commitf9f46ac68653694d3e4675f4be22fdb6baa6d5a6 (patch)
treeba2692cfead6551b78c74e2089525cc9c6f4abe0 /lib
parenta30536bec8e4ff37cf89ea187ac9e86d4992d6f5 (diff)
downloadgnutls-f9f46ac68653694d3e4675f4be22fdb6baa6d5a6.tar.gz
TLS/IA fixes from Emile.
Diffstat (limited to 'lib')
-rw-r--r--lib/ext_inner_application.c86
-rw-r--r--lib/gnutls_int.h5
2 files changed, 46 insertions, 45 deletions
diff --git a/lib/ext_inner_application.c b/lib/ext_inner_application.c
index 3cbf77b3ba..ee7b52af27 100644
--- a/lib/ext_inner_application.c
+++ b/lib/ext_inner_application.c
@@ -36,7 +36,6 @@ _gnutls_inner_application_recv_params (gnutls_session_t session,
const opaque * data, size_t data_size)
{
tls_ext_st *ext = &session->security_parameters.extensions;
- gnutls_ia_mode_t state;
if (data_size != 1)
{
@@ -44,26 +43,26 @@ _gnutls_inner_application_recv_params (gnutls_session_t session,
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
+ ext->gnutls_ia_peer_enable = 1;
+ ext->gnutls_ia_peer_allowskip = 0;
+
switch ((unsigned char) *data)
{
- case NO:
- state = GNUTLS_IA_APP_PHASE_ON_RESUMPTION_NO;
+ case NO: /* Peer's ia_on_resume == no */
+ ext->gnutls_ia_peer_allowskip = 1;
break;
case YES:
- state = GNUTLS_IA_APP_PHASE_ON_RESUMPTION_YES;
break;
default:
gnutls_assert ();
- return 0;
}
- ext->peer_mode = state;
-
return 0;
}
+
/* returns data_size or a negative number on failure
*/
int
@@ -72,50 +71,53 @@ _gnutls_inner_application_send_params (gnutls_session_t session,
{
tls_ext_st *ext = &session->security_parameters.extensions;
+ /* If we don't want gnutls_ia locally, or we are a server and the client
+ * doesn't want it, don't advertise TLS/IA support at all, as required. */
+
+ if (!ext->gnutls_ia_enable) return 0;
+
+ if (session->security_parameters.entity == GNUTLS_SERVER &&
+ !ext->gnutls_ia_peer_enable) return 0;
+
+ /* We'll advertise. Check if there's room in the hello buffer. */
+
if (data_size < 1)
{
gnutls_assert ();
return GNUTLS_E_SHORT_MEMORY_BUFFER;
}
- if (session->security_parameters.entity == GNUTLS_CLIENT)
- {
- gnutls_ia_client_credentials_t cred = (gnutls_ia_client_credentials_t)
- _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
+ /* default: require new application phase */
- if (cred == NULL)
- return 0;
+ *data = YES;
- /* Simple case, just send what the application requested. */
+ if (session->security_parameters.entity == GNUTLS_CLIENT) {
- if (ext->inner_phase_optional)
- *data = NO;
- else
- *data = YES;
- }
- else
- {
- gnutls_ia_server_credentials_t cred = (gnutls_ia_server_credentials_t)
- _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
-
- if (cred == NULL)
- return 0;
-
- /* The server MUST set app_phase_on_resumption to "yes" if the
- client set app_phase_on_resumption to "yes" or if the server
- does not resume the session. */
- if ((ext->peer_mode == GNUTLS_IA_APP_PHASE_ON_RESUMPTION_YES) ||
- !gnutls_session_is_resumed (session))
- *data = YES;
- /* The server MAY set app_phase_on_resumption to "yes" for a
- resumed session even if the client set
- app_phase_on_resumption to "no", as the server may have
- reason to proceed with one or more application phases. */
- else if (!ext->inner_phase_optional)
- *data = YES;
- else
- *data = NO;
- }
+ /* Client: value follows local setting */
+
+ if (ext->gnutls_ia_allowskip)
+ *data = NO;
+ }
+ else {
+
+ /* Server: value follows local setting and client's setting, but only
+ * if we are resuming.
+ *
+ * XXX Can server test for resumption at this stage?
+ *
+ * Ai! It seems that read_client_hello only calls parse_extensions if
+ * we're NOT resuming! That would make us automatically violate the IA
+ * draft; if we're resuming, we must first learn what the client wants
+ * -- IA or no IA -- and then prepare our response. Right now we'll
+ * always skip IA on resumption, because recv_ext isn't even called
+ * to record the peer's support for IA at all. Simon? */
+
+ if (ext->gnutls_ia_allowskip &&
+ ext->gnutls_ia_peer_allowskip &&
+ session->internals.resumed == RESUME_TRUE)
+ *data = NO;
+ }
return 1;
}
+
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 5f54da8a8f..5888cdbfd3 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -260,9 +260,8 @@ typedef struct
/* limit server_name extensions */
unsigned server_names_size;
opaque srp_username[MAX_SRP_USERNAME + 1];
- /* 0 = tls/ia not used, 1 = no, 2 = yes */
- gnutls_ia_mode_t peer_mode;
- int inner_phase_optional;
+ int gnutls_ia_enable, gnutls_ia_peer_enable;
+ int gnutls_ia_allowskip, gnutls_ia_peer_allowskip;
} tls_ext_st;
/* auth_info_t structures now MAY contain malloced