~ubuntu-branches/ubuntu/quantal/gnutls26/quantal-security

« back to all changes in this revision

Viewing changes to libextra/ext_inner_application.c

  • Committer: Package Import Robot
  • Author(s): Andreas Metzler
  • Date: 2011-10-01 15:28:13 UTC
  • mfrom: (12.1.20 sid)
  • Revision ID: package-import@ubuntu.com-20111001152813-yygm1c4cxonfxhzy
Tags: 2.12.11-1
* New upstream version.
  + Allow CA importing of 0 certificates to succeed. Closes: #640639
* Add libp11-kit-dev to libgnutls-dev dependencies. (see #643811)
* [20_guiledocstring.diff] guile: Fix docstring extraction with CPP 4.5+.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#define NO 0
32
32
#define YES 1
33
33
 
34
 
int
 
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);
 
42
 
 
43
extension_entry_st ext_mod_ia = {
 
44
  .name = "INNER APPLICATION",
 
45
  .type = GNUTLS_EXTENSION_INNER_APPLICATION,
 
46
  .parse_type = GNUTLS_EXT_TLS,
 
47
 
 
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,
 
53
};
 
54
 
 
55
static int
35
56
_gnutls_inner_application_recv_params (gnutls_session_t session,
36
 
                                       const opaque * data, size_t data_size)
 
57
                                       const opaque * data, size_t data_size)
37
58
{
38
 
  tls_ext_st *ext = &session->security_parameters.extensions;
 
59
  extension_priv_data_t epriv;
 
60
  ia_ext_st *priv;
 
61
  int ret;
39
62
 
40
63
  if (data_size != 1)
41
64
    {
43
66
      return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
44
67
    }
45
68
 
46
 
  ext->gnutls_ia_peer_enable = 1;
47
 
  ext->gnutls_ia_peer_allowskip = 0;
 
69
  ret =
 
70
    _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_INNER_APPLICATION,
 
71
                                  &epriv);
 
72
  if (ret < 0)
 
73
    {
 
74
      priv = gnutls_calloc (1, sizeof (*priv));
 
75
      if (priv == NULL)
 
76
        {
 
77
          gnutls_assert ();
 
78
          return GNUTLS_E_MEMORY_ERROR;
 
79
        }
 
80
 
 
81
      epriv.ptr = priv;
 
82
      _gnutls_ext_set_session_data (session,
 
83
                                    GNUTLS_EXTENSION_INNER_APPLICATION,
 
84
                                    epriv);
 
85
    }
 
86
  else
 
87
    priv = epriv.ptr;
 
88
 
 
89
  priv->flags |= IA_PEER_ENABLE;
 
90
  priv->flags &= ~IA_PEER_ALLOW_SKIP;
48
91
 
49
92
  switch ((unsigned char) *data)
50
93
    {
51
 
    case NO:                    /* Peer's ia_on_resume == no */
52
 
      ext->gnutls_ia_peer_allowskip = 1;
 
94
    case NO:                   /* Peer's ia_on_resume == no */
 
95
      priv->flags |= IA_PEER_ALLOW_SKIP;
53
96
      break;
54
97
 
55
98
    case YES:
59
102
      gnutls_assert ();
60
103
    }
61
104
 
 
105
 
62
106
  return 0;
63
107
}
64
108
 
65
109
 
66
110
/* returns data_size or a negative number on failure
67
111
 */
68
 
int
 
112
static int
69
113
_gnutls_inner_application_send_params (gnutls_session_t session,
70
 
                                       opaque * data, size_t data_size)
 
114
                                       opaque * data, size_t data_size)
71
115
{
72
 
  tls_ext_st *ext = &session->security_parameters.extensions;
 
116
  extension_priv_data_t epriv;
 
117
  ia_ext_st *priv = NULL;
 
118
  int ret;
 
119
 
 
120
  ret =
 
121
    _gnutls_ext_get_session_data (session, GNUTLS_EXTENSION_INNER_APPLICATION,
 
122
                                  &epriv);
 
123
  if (ret < 0)
 
124
    {
 
125
      priv = gnutls_calloc (1, sizeof (*priv));
 
126
      if (priv == NULL)
 
127
        {
 
128
          gnutls_assert ();
 
129
          return GNUTLS_E_MEMORY_ERROR;
 
130
        }
 
131
 
 
132
      epriv.ptr = priv;
 
133
      _gnutls_ext_set_session_data (session,
 
134
                                    GNUTLS_EXTENSION_INNER_APPLICATION,
 
135
                                    epriv);
 
136
    }
 
137
  else
 
138
    priv = epriv.ptr;
73
139
 
74
140
  /* Set ext->gnutls_ia_enable depending on whether we have a TLS/IA
75
141
     credential in the session. */
77
143
  if (session->security_parameters.entity == GNUTLS_CLIENT)
78
144
    {
79
145
      gnutls_ia_client_credentials_t cred = (gnutls_ia_client_credentials_t)
80
 
        _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
 
146
        _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
81
147
 
82
148
      if (cred)
83
 
        ext->gnutls_ia_enable = 1;
 
149
        priv->flags |= IA_ENABLE;
84
150
    }
85
 
  else
 
151
  else                          /* SERVER */
86
152
    {
87
 
      gnutls_ia_server_credentials_t cred = (gnutls_ia_server_credentials_t)
88
 
        _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
 
153
      gnutls_ia_server_credentials_t cred;
 
154
 
 
155
      cred = (gnutls_ia_server_credentials_t)
 
156
        _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
89
157
 
90
158
      if (cred)
91
 
        ext->gnutls_ia_enable = 1;
 
159
        priv->flags |= IA_PEER_ENABLE;
92
160
    }
93
161
 
94
162
  /* If we don't want gnutls_ia locally, or we are a server and the
95
163
   * client doesn't want it, don't advertise TLS/IA support at all, as
96
164
   * required. */
97
165
 
98
 
  if (!ext->gnutls_ia_enable)
 
166
  if (!(priv->flags & IA_ENABLE))
99
167
    return 0;
100
168
 
101
169
  if (session->security_parameters.entity == GNUTLS_SERVER &&
102
 
      !ext->gnutls_ia_peer_enable)
 
170
      !(priv->flags & IA_PEER_ENABLE))
103
171
    return 0;
104
172
 
105
173
  /* We'll advertise. Check if there's room in the hello buffer. */
119
187
 
120
188
      /* Client: value follows local setting */
121
189
 
122
 
      if (ext->gnutls_ia_allowskip)
123
 
        *data = NO;
 
190
      if (priv->flags & IA_ALLOW_SKIP)
 
191
        *data = NO;
124
192
    }
125
193
  else
126
194
    {
137
205
       * always skip IA on resumption, because recv_ext isn't even called
138
206
       * to record the peer's support for IA at all. Simon? */
139
207
 
140
 
      if (ext->gnutls_ia_allowskip &&
141
 
          ext->gnutls_ia_peer_allowskip &&
142
 
          session->internals.resumed == RESUME_TRUE)
143
 
        *data = NO;
 
208
      if ((priv->flags & IA_ALLOW_SKIP) &&
 
209
          (priv->flags & IA_PEER_ALLOW_SKIP) &&
 
210
          session->internals.resumed == RESUME_TRUE)
 
211
        *data = NO;
144
212
    }
145
213
 
146
214
  return 1;
147
215
}
 
216
 
 
217
static void
 
218
ia_deinit_data (extension_priv_data_t priv)
 
219
{
 
220
  gnutls_free (priv.ptr);
 
221
}
 
222
 
 
223
static int
 
224
ia_pack (extension_priv_data_t epriv, gnutls_buffer_st * ps)
 
225
{
 
226
  ia_ext_st *priv = epriv.ptr;
 
227
  int ret;
 
228
 
 
229
  BUFFER_APPEND_NUM (ps, priv->flags);
 
230
  BUFFER_APPEND_PFX (ps, priv->inner_secret, GNUTLS_MASTER_SIZE);
 
231
 
 
232
  return 0;
 
233
}
 
234
 
 
235
static int
 
236
ia_unpack (gnutls_buffer_st * ps, extension_priv_data_t * _priv)
 
237
{
 
238
  ia_ext_st *priv;
 
239
  int size, ret;
 
240
  extension_priv_data_t epriv;
 
241
 
 
242
  priv = gnutls_calloc (1, sizeof (*priv));
 
243
  if (priv == NULL)
 
244
    {
 
245
      gnutls_assert ();
 
246
      return GNUTLS_E_MEMORY_ERROR;
 
247
    }
 
248
 
 
249
  BUFFER_POP_NUM (ps, priv->flags);
 
250
  BUFFER_POP_NUM (ps, size);
 
251
  if (size != GNUTLS_MASTER_SIZE)
 
252
    {
 
253
      gnutls_assert ();
 
254
      return GNUTLS_E_PARSING_ERROR;
 
255
    }
 
256
  BUFFER_POP (ps, priv->inner_secret, GNUTLS_MASTER_SIZE);
 
257
 
 
258
  epriv.ptr = priv;
 
259
  *_priv = epriv;
 
260
 
 
261
  return 0;
 
262
 
 
263
error:
 
264
  gnutls_free (priv);
 
265
  return ret;
 
266
}