/* * Copyright (C) 2005, 2006, 2008, 2010 Free Software Foundation, Inc. * * Author: Simon Josefsson * * This file is part of GnuTLS-EXTRA. * * GnuTLS-extra is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * GnuTLS-extra is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see * . * */ #include "gnutls_int.h" #include "gnutls_auth.h" #include "gnutls_errors.h" #include "gnutls_num.h" #include "ext_inner_application.h" #include #define NO 0 #define YES 1 int _gnutls_inner_application_recv_params (gnutls_session_t session, const opaque * data, size_t data_size) { tls_ext_st *ext = &session->security_parameters.extensions; if (data_size != 1) { gnutls_assert (); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } ext->gnutls_ia_peer_enable = 1; ext->gnutls_ia_peer_allowskip = 0; switch ((unsigned char) *data) { case NO: /* Peer's ia_on_resume == no */ ext->gnutls_ia_peer_allowskip = 1; break; case YES: break; default: gnutls_assert (); } return 0; } /* returns data_size or a negative number on failure */ int _gnutls_inner_application_send_params (gnutls_session_t session, opaque * data, size_t data_size) { tls_ext_st *ext = &session->security_parameters.extensions; /* Set ext->gnutls_ia_enable depending on whether we have a TLS/IA credential in the session. */ 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); if (cred) ext->gnutls_ia_enable = 1; } else { gnutls_ia_server_credentials_t cred = (gnutls_ia_server_credentials_t) _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL); if (cred) ext->gnutls_ia_enable = 1; } /* 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; } /* default: require new application phase */ *data = YES; if (session->security_parameters.entity == GNUTLS_CLIENT) { /* 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; }