Fix use of deprecated types, for now and the future.
[gnutls.git] / lib / ext_server_name.c
blob69413ae9c970de91878143a7ac2d511f44277584
1 /*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2008, 2009 Free Software Foundation
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library 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 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
25 #include "gnutls_int.h"
26 #include "gnutls_auth.h"
27 #include "gnutls_errors.h"
28 #include "gnutls_num.h"
29 #include <ext_server_name.h>
32 * In case of a server: if a NAME_DNS extension type is received then
33 * it stores into the session the value of NAME_DNS. The server may
34 * use gnutls_ext_get_server_name(), in order to access it.
36 * In case of a client: If a proper NAME_DNS extension type is found
37 * in the session then it sends the extension to the peer.
41 int
42 _gnutls_server_name_recv_params (gnutls_session_t session,
43 const opaque * data, size_t _data_size)
45 int i;
46 const unsigned char *p;
47 uint16_t len, type;
48 ssize_t data_size = _data_size;
49 int server_names = 0;
51 if (session->security_parameters.entity == GNUTLS_SERVER)
53 DECR_LENGTH_RET (data_size, 2, 0);
54 len = _gnutls_read_uint16 (data);
56 if (len != data_size)
58 /* This is unexpected packet length, but
59 * just ignore it, for now.
61 gnutls_assert ();
62 return 0;
65 p = data + 2;
67 /* Count all server_names in the packet. */
68 while (data_size > 0)
70 DECR_LENGTH_RET (data_size, 1, 0);
71 p++;
73 DECR_LEN (data_size, 2);
74 len = _gnutls_read_uint16 (p);
75 p += 2;
77 if (len > 0)
79 DECR_LENGTH_RET (data_size, len, 0);
80 server_names++;
81 p += len;
83 else
84 _gnutls_handshake_log
85 ("HSK[%p]: Received zero size server name (under attack?)\n",
86 session);
90 /* we cannot accept more server names.
92 if (server_names > MAX_SERVER_NAME_EXTENSIONS)
94 _gnutls_handshake_log
95 ("HSK[%p]: Too many server names received (under attack?)\n",
96 session);
97 server_names = MAX_SERVER_NAME_EXTENSIONS;
100 session->security_parameters.extensions.server_names_size =
101 server_names;
102 if (server_names == 0)
103 return 0; /* no names found */
106 p = data + 2;
107 for (i = 0; i < server_names; i++)
109 type = *p;
110 p++;
112 len = _gnutls_read_uint16 (p);
113 p += 2;
115 switch (type)
117 case 0: /* NAME_DNS */
118 if (len <= MAX_SERVER_NAME_SIZE)
120 memcpy (session->security_parameters.extensions.
121 server_names[i].name, p, len);
122 session->security_parameters.extensions.
123 server_names[i].name_length = len;
124 session->security_parameters.extensions.
125 server_names[i].type = GNUTLS_NAME_DNS;
126 break;
130 /* move to next record */
131 p += len;
134 return 0;
137 /* returns data_size or a negative number on failure
140 _gnutls_server_name_send_params (gnutls_session_t session,
141 opaque * data, size_t _data_size)
143 uint16_t len;
144 opaque *p;
145 unsigned i;
146 ssize_t data_size = _data_size;
147 int total_size = 0;
149 /* this function sends the client extension data (dnsname)
151 if (session->security_parameters.entity == GNUTLS_CLIENT)
154 if (session->security_parameters.extensions.server_names_size == 0)
155 return 0;
157 /* uint16_t
159 total_size = 2;
160 for (i = 0;
161 i < session->security_parameters.extensions.server_names_size; i++)
163 /* count the total size
165 len =
166 session->security_parameters.extensions.server_names[i].
167 name_length;
169 /* uint8_t + uint16_t + size
171 total_size += 1 + 2 + len;
174 p = data;
176 /* UINT16: write total size of all names
178 DECR_LENGTH_RET (data_size, 2, GNUTLS_E_SHORT_MEMORY_BUFFER);
179 _gnutls_write_uint16 (total_size - 2, p);
180 p += 2;
182 for (i = 0;
183 i < session->security_parameters.extensions.server_names_size; i++)
186 switch (session->security_parameters.extensions.
187 server_names[i].type)
189 case GNUTLS_NAME_DNS:
191 len =
192 session->security_parameters.extensions.
193 server_names[i].name_length;
194 if (len == 0)
195 break;
197 /* UINT8: type of this extension
198 * UINT16: size of the first name
199 * LEN: the actual server name.
201 DECR_LENGTH_RET (data_size, len + 3,
202 GNUTLS_E_SHORT_MEMORY_BUFFER);
204 *p = 0; /* NAME_DNS type */
205 p++;
207 _gnutls_write_uint16 (len, p);
208 p += 2;
210 memcpy (p,
211 session->security_parameters.extensions.
212 server_names[i].name, len);
213 p += len;
214 break;
215 default:
216 gnutls_assert ();
217 return GNUTLS_E_INTERNAL_ERROR;
222 return total_size;
226 * gnutls_server_name_get - Used to get the server name indicator send by a client
227 * @session: is a #gnutls_session_t structure.
228 * @data: will hold the data
229 * @data_length: will hold the data length. Must hold the maximum size of data.
230 * @type: will hold the server name indicator type
231 * @indx: is the index of the server_name
233 * This function will allow you to get the name indication (if any), a
234 * client has sent. The name indication may be any of the enumeration
235 * gnutls_server_name_type_t.
237 * If @type is GNUTLS_NAME_DNS, then this function is to be used by
238 * servers that support virtual hosting, and the data will be a null
239 * terminated UTF-8 string.
241 * If @data has not enough size to hold the server name
242 * GNUTLS_E_SHORT_MEMORY_BUFFER is returned, and @data_length will
243 * hold the required size.
245 * @index is used to retrieve more than one server names (if sent by
246 * the client). The first server name has an index of 0, the second 1
247 * and so on. If no name with the given index exists
248 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
250 * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned,
251 * otherwise an error code is returned.
254 gnutls_server_name_get (gnutls_session_t session, void *data,
255 size_t * data_length,
256 unsigned int *type, unsigned int indx)
258 char *_data = data;
260 if (session->security_parameters.entity == GNUTLS_CLIENT)
262 gnutls_assert ();
263 return GNUTLS_E_INVALID_REQUEST;
266 if (indx + 1 > session->security_parameters.extensions.server_names_size)
268 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
271 *type = session->security_parameters.extensions.server_names[indx].type;
273 if (*data_length > /* greater since we need one extra byte for the null */
274 session->security_parameters.extensions.server_names[indx].name_length)
276 *data_length =
277 session->security_parameters.extensions.server_names[indx].
278 name_length;
279 memcpy (data,
280 session->security_parameters.extensions.server_names[indx].name,
281 *data_length);
283 if (*type == GNUTLS_NAME_DNS) /* null terminate */
284 _data[(*data_length)] = 0;
287 else
289 *data_length =
290 session->security_parameters.extensions.server_names[indx].
291 name_length;
292 return GNUTLS_E_SHORT_MEMORY_BUFFER;
295 return 0;
299 * gnutls_server_name_set - set a name indicator to be sent as an extension
300 * @session: is a #gnutls_session_t structure.
301 * @type: specifies the indicator type
302 * @name: is a string that contains the server name.
303 * @name_length: holds the length of name
305 * This function is to be used by clients that want to inform (via a
306 * TLS extension mechanism) the server of the name they connected to.
307 * This should be used by clients that connect to servers that do
308 * virtual hosting.
310 * The value of @name depends on the @ind type. In case of
311 * GNUTLS_NAME_DNS, an ASCII or UTF-8 null terminated string, without
312 * the trailing dot, is expected. IPv4 or IPv6 addresses are not
313 * permitted.
315 * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned,
316 * otherwise an error code is returned.
319 gnutls_server_name_set (gnutls_session_t session,
320 gnutls_server_name_type_t type,
321 const void *name, size_t name_length)
323 int server_names;
325 if (session->security_parameters.entity == GNUTLS_SERVER)
327 gnutls_assert ();
328 return GNUTLS_E_INVALID_REQUEST;
331 if (name_length > MAX_SERVER_NAME_SIZE)
332 return GNUTLS_E_SHORT_MEMORY_BUFFER;
334 server_names = session->security_parameters.extensions.server_names_size + 1;
336 if (server_names > MAX_SERVER_NAME_EXTENSIONS)
337 server_names = MAX_SERVER_NAME_EXTENSIONS;
339 session->security_parameters.extensions.server_names
340 [server_names - 1].type = type;
341 memcpy (session->security_parameters.extensions.
342 server_names[server_names - 1].name, name, name_length);
343 session->security_parameters.extensions.server_names
344 [server_names - 1].name_length = name_length;
346 session->security_parameters.extensions.server_names_size++;
348 return 0;