From f9f46ac68653694d3e4675f4be22fdb6baa6d5a6 Mon Sep 17 00:00:00 2001 From: Simon Josefsson Date: Fri, 5 May 2006 09:07:17 +0000 Subject: TLS/IA fixes from Emile. --- libextra/gnutls_ia.c | 79 +++++++++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 35 deletions(-) (limited to 'libextra') diff --git a/libextra/gnutls_ia.c b/libextra/gnutls_ia.c index adf821a882..a98c65fd98 100644 --- a/libextra/gnutls_ia.c +++ b/libextra/gnutls_ia.c @@ -383,7 +383,9 @@ gnutls_ia_verify_endphase (gnutls_session_t session, const char *checksum) * * To finish an application phase in the server, use * gnutls_ia_endphase_send(). The client cannot end an application - * phase. + * phase unilaterally; rather, a client is required to respond with + * an endphase of its own if gnutls_ia_recv indicates that the server + * has sent one. * * If the EINTR is returned by the internal push function (the default * is send()} then %GNUTLS_E_INTERRUPTED will be returned. If @@ -418,7 +420,8 @@ gnutls_ia_send (gnutls_session_t session, const char *data, size_t sizeofdata) * If the server attempt to finish an application phase, this function * will return %GNUTLS_E_WARNING_IA_IPHF_RECEIVED or * %GNUTLS_E_WARNING_IA_FPHF_RECEIVED. The caller should then invoke - * gnutls_ia_verify_endphase(). + * gnutls_ia_verify_endphase(), and if it runs the client side, also + * send an endphase message of its own using gnutls_ia_endphase_send. * * If EINTR is returned by the internal push function (the default is * @code{recv()}) then GNUTLS_E_INTERRUPTED will be returned. If @@ -607,23 +610,23 @@ gnutls_ia_handshake_p (gnutls_session_t session) { tls_ext_st *ext = &session->security_parameters.extensions; - /* The other side didn't advertise TLS/IA. */ - if (ext->peer_mode == GNUTLS_IA_DISABLED) - return 0; + /* Either local side or peer doesn't do TLS/IA: don't do IA */ - /* We don't consider the inner phase optional. */ - if (!ext->inner_phase_optional) - return 1; + if (!ext->gnutls_ia_enable || !ext->gnutls_ia_peer_enable) + return 0; - /* This is not a resumed session. always require an inner - application. */ - if (!gnutls_session_is_resumed (session)) - return 1; + /* Not resuming or we don't allow skipping on resumption locally: do IA */ - /* Require an inner phase if the other end requested it. */ - return ext->peer_mode == GNUTLS_IA_APP_PHASE_ON_RESUMPTION_YES; + if (!ext->gnutls_ia_allowskip || !gnutls_session_is_resumed (session)) + return 1; + + /* If we're resuming and we and the peer both allow skipping on resumption: + * don't do IA */ + + return !ext->gnutls_ia_peer_allowskip; } + /** * gnutls_ia_handshake: * @session: is a #gnutls_session_t structure. @@ -872,29 +875,35 @@ gnutls_ia_get_server_avp_ptr (gnutls_ia_server_credentials_t cred) } /** - * gnutls_ia_require_inner_phase - Set if a TLS/IA inner phase is required + * gnutls_ia_enable - Call this to indicate the application's willingness + * to execute one or more TLS/IA application phases + * in the handshake. * @session: is a #gnutls_session_t structure. - * @require: non-zero if an inner application phase should be required. - * - * Specify whether a TLS/IA Inner Application Phase will be required - * or not. If the TLS session is resumed, it is possibly to optimize - * away the inner application phase by calling this function and - * specify a zero value for @require. - * - * For this function to have any effect, it must be called before - * gnutls_handshake(). - * - * Whether to invoke the TLS/IA handshake will also depend on whether - * the client supports or requested TLS/IA. A server should thus use - * gnutls_ia_handshake_p() to decide whether to call - * gnutls_ia_handshake() or not. + * @allow_skip_on_resume: non-zero if local party allows to skip the + * TLS/IA application phases for a resumed session. + * + * Specify whether we must advertise support for the TLS/IA extension + * during the handshake. + * + * At the client side, we always advertise TLS/IA if gnutls_ia_enable was + * called before the handshake; at the server side, we also require that + * the client has advertised that it wants to run TLS/IA before including + * the advertisement, as required by the protocol. + * + * Similarly, at the client side we always advertise that we allow TLS/IA to be + * skipped for resumed sessions if @allow_skip_on_resume is non-zero; at the + * server side, we also require that the session is indeed resumable and that + * the client has also advertised that it allows TLS/IA to be skipped for + * resumed sessions. + * + * After the TLS handshake, call gnutls_ia_handshake_p() to find out + * whether both parties agreed to do a TLS/IA handshake, before calling + * gnutls_ia_handshake() or one of the lower level gnutls_ia_* functions. **/ void -gnutls_ia_require_inner_phase (gnutls_session_t session, int require) +gnutls_ia_enable (gnutls_session_t session, int allow_skip_on_resume) { - /* XXX. This function should ideally take a TLS/IA credential, but - we can't do that, since we don't want the LGPL'd - lib/ext_inner_applicaiton.c to call/inspect GPL'd - functions/structures. */ - session->security_parameters.extensions.inner_phase_optional = !require; + session->security_parameters.extensions.gnutls_ia_enable = 1; + session->security_parameters.extensions.gnutls_ia_allowskip = + allow_skip_on_resume; } -- cgit v1.2.1