This patch fixes following kind of issue with automake 1.12
[gnutls.git] / libextra / ext_inner_application.c
blob329e4ec9a719c4737ea33c7bf684d69ac071ebf3
1 /*
2 * Copyright (C) 2005, 2006, 2008, 2010 Free Software Foundation, Inc.
4 * Author: Simon Josefsson
6 * This file is part of GnuTLS-EXTRA.
8 * GnuTLS-extra is free software: you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation, either version 3 of the
11 * License, or (at your option) any later version.
13 * GnuTLS-extra is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see
20 * <http://www.gnu.org/licenses/>.
24 #include "gnutls_int.h"
25 #include "gnutls_auth.h"
26 #include "gnutls_errors.h"
27 #include "gnutls_num.h"
28 #include "ext_inner_application.h"
29 #include <gnutls/extra.h>
31 #define NO 0
32 #define YES 1
34 static int _gnutls_inner_application_recv_params (gnutls_session_t session,
35 const opaque * data,
36 size_t data_size);
37 static int _gnutls_inner_application_send_params (gnutls_session_t session,
38 opaque * data, size_t);
39 static int ia_unpack (gnutls_buffer_st * ps, extension_priv_data_t * _priv);
40 static int ia_pack (extension_priv_data_t _priv, gnutls_buffer_st * ps);
41 static void ia_deinit_data (extension_priv_data_t priv);
43 extension_entry_st ext_mod_ia = {
44 .name = "INNER APPLICATION",
45 .type = GNUTLS_EXTENSION_INNER_APPLICATION,
46 .parse_type = GNUTLS_EXT_TLS,
48 .recv_func = _gnutls_inner_application_recv_params,
49 .send_func = _gnutls_inner_application_send_params,
50 .pack_func = ia_pack,
51 .unpack_func = ia_unpack,
52 .deinit_func = ia_deinit_data,
55 static int
56 _gnutls_inner_application_recv_params (gnutls_session_t session,
57 const opaque * data, size_t data_size)
59 extension_priv_data_t epriv;
60 ia_ext_st *priv;
61 int ret;
63 if (data_size != 1)
65 gnutls_assert ();
66 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
69 ret =
70 _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_INNER_APPLICATION,
71 &epriv);
72 if (ret < 0)
74 priv = gnutls_calloc (1, sizeof (*priv));
75 if (priv == NULL)
77 gnutls_assert ();
78 return GNUTLS_E_MEMORY_ERROR;
81 epriv.ptr = priv;
82 _gnutls_ext_set_session_data (session,
83 GNUTLS_EXTENSION_INNER_APPLICATION,
84 epriv);
86 else
87 priv = epriv.ptr;
89 priv->flags |= IA_PEER_ENABLE;
90 priv->flags &= ~IA_PEER_ALLOW_SKIP;
92 switch ((unsigned char) *data)
94 case NO: /* Peer's ia_on_resume == no */
95 priv->flags |= IA_PEER_ALLOW_SKIP;
96 break;
98 case YES:
99 break;
101 default:
102 gnutls_assert ();
106 return 0;
110 /* returns data_size or a negative number on failure
112 static int
113 _gnutls_inner_application_send_params (gnutls_session_t session,
114 opaque * data, size_t data_size)
116 extension_priv_data_t epriv;
117 ia_ext_st *priv = NULL;
118 int ret;
120 ret =
121 _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_INNER_APPLICATION,
122 &epriv);
123 if (ret < 0)
125 priv = gnutls_calloc (1, sizeof (*priv));
126 if (priv == NULL)
128 gnutls_assert ();
129 return GNUTLS_E_MEMORY_ERROR;
132 epriv.ptr = priv;
133 _gnutls_ext_set_session_data (session,
134 GNUTLS_EXTENSION_INNER_APPLICATION,
135 epriv);
137 else
138 priv = epriv.ptr;
140 /* Set ext->gnutls_ia_enable depending on whether we have a TLS/IA
141 credential in the session. */
143 if (session->security_parameters.entity == GNUTLS_CLIENT)
145 gnutls_ia_client_credentials_t cred = (gnutls_ia_client_credentials_t)
146 _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
148 if (cred)
149 priv->flags |= IA_ENABLE;
151 else /* SERVER */
153 gnutls_ia_server_credentials_t cred;
155 cred = (gnutls_ia_server_credentials_t)
156 _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
158 if (cred)
159 priv->flags |= IA_PEER_ENABLE;
162 /* If we don't want gnutls_ia locally, or we are a server and the
163 * client doesn't want it, don't advertise TLS/IA support at all, as
164 * required. */
166 if (!(priv->flags & IA_ENABLE))
167 return 0;
169 if (session->security_parameters.entity == GNUTLS_SERVER &&
170 !(priv->flags & IA_PEER_ENABLE))
171 return 0;
173 /* We'll advertise. Check if there's room in the hello buffer. */
175 if (data_size < 1)
177 gnutls_assert ();
178 return GNUTLS_E_SHORT_MEMORY_BUFFER;
181 /* default: require new application phase */
183 *data = YES;
185 if (session->security_parameters.entity == GNUTLS_CLIENT)
188 /* Client: value follows local setting */
190 if (priv->flags & IA_ALLOW_SKIP)
191 *data = NO;
193 else
196 /* Server: value follows local setting and client's setting, but only
197 * if we are resuming.
199 * XXX Can server test for resumption at this stage?
201 * Ai! It seems that read_client_hello only calls parse_extensions if
202 * we're NOT resuming! That would make us automatically violate the IA
203 * draft; if we're resuming, we must first learn what the client wants
204 * -- IA or no IA -- and then prepare our response. Right now we'll
205 * always skip IA on resumption, because recv_ext isn't even called
206 * to record the peer's support for IA at all. Simon? */
208 if ((priv->flags & IA_ALLOW_SKIP) &&
209 (priv->flags & IA_PEER_ALLOW_SKIP) &&
210 session->internals.resumed == RESUME_TRUE)
211 *data = NO;
214 return 1;
217 static void
218 ia_deinit_data (extension_priv_data_t priv)
220 gnutls_free (priv.ptr);
223 static int
224 ia_pack (extension_priv_data_t epriv, gnutls_buffer_st * ps)
226 ia_ext_st *priv = epriv.ptr;
227 int ret;
229 BUFFER_APPEND_NUM (ps, priv->flags);
230 BUFFER_APPEND_PFX (ps, priv->inner_secret, GNUTLS_MASTER_SIZE);
232 return 0;
235 static int
236 ia_unpack (gnutls_buffer_st * ps, extension_priv_data_t * _priv)
238 ia_ext_st *priv;
239 int size, ret;
240 extension_priv_data_t epriv;
242 priv = gnutls_calloc (1, sizeof (*priv));
243 if (priv == NULL)
245 gnutls_assert ();
246 return GNUTLS_E_MEMORY_ERROR;
249 BUFFER_POP_NUM (ps, priv->flags);
250 BUFFER_POP_NUM (ps, size);
251 if (size != GNUTLS_MASTER_SIZE)
253 gnutls_assert ();
254 return GNUTLS_E_PARSING_ERROR;
256 BUFFER_POP (ps, priv->inner_secret, GNUTLS_MASTER_SIZE);
258 epriv.ptr = priv;
259 *_priv = epriv;
261 return 0;
263 error:
264 gnutls_free (priv);
265 return ret;