doc update: document that session_get_data() must be used in non-resumed sessions
[gnutls:gnutls.git] / lib / gnutls_session.c
1 /*
2  * Copyright (C) 2000-2012 Free Software Foundation, Inc.
3  *
4  * Author: Nikos Mavrogiannopoulos
5  *
6  * This file is part of GnuTLS.
7  *
8  * The GnuTLS 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.
12  *
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.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>
20  *
21  */
22 #include "gnutls_int.h"
23 #include "gnutls_errors.h"
24 #include "debug.h"
25 #include <gnutls_session_pack.h>
26 #include <gnutls_datum.h>
27
28 /**
29  * gnutls_session_get_data:
30  * @session: is a #gnutls_session_t structure.
31  * @session_data: is a pointer to space to hold the session.
32  * @session_data_size: is the session_data's size, or it will be set by the function.
33  *
34  * Returns all session parameters needed to be stored to support resumption.
35  * The client should call this, and store the returned session data. A session
36  * may be resumed later by calling gnutls_session_set_data().  
37  * This function must be called after a successful (full) handshake. It should
38  * not be used in resumed sessions --see gnutls_session_is_resumed().
39  *
40  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
41  *   an error code is returned.
42  **/
43 int
44 gnutls_session_get_data(gnutls_session_t session,
45                         void *session_data, size_t * session_data_size)
46 {
47
48         gnutls_datum_t psession;
49         int ret;
50
51         if (session->internals.resumable == RESUME_FALSE)
52                 return GNUTLS_E_INVALID_SESSION;
53
54         psession.data = session_data;
55
56         ret = _gnutls_session_pack(session, &psession);
57         if (ret < 0) {
58                 gnutls_assert();
59                 return ret;
60         }
61
62         if (psession.size > *session_data_size) {
63                 *session_data_size = psession.size;
64                 ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
65                 goto error;
66         }
67         *session_data_size = psession.size;
68
69         if (session_data != NULL)
70                 memcpy(session_data, psession.data, psession.size);
71
72         ret = 0;
73
74       error:
75         _gnutls_free_datum(&psession);
76         return ret;
77 }
78
79 /**
80  * gnutls_session_get_data2:
81  * @session: is a #gnutls_session_t structure.
82  * @data: is a pointer to a datum that will hold the session.
83  *
84  * Returns all session parameters needed to be stored to support resumption.
85  * The client should call this, and store the returned session data. A session
86  * may be resumed later by calling gnutls_session_set_data().  
87  * This function must be called after a successful (full) handshake. It should
88  * not be used in resumed sessions --see gnutls_session_is_resumed().
89  *
90  * The returned @data are allocated and must be released using gnutls_free().
91  *
92  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
93  *   an error code is returned.
94  **/
95 int
96 gnutls_session_get_data2(gnutls_session_t session, gnutls_datum_t * data)
97 {
98
99         int ret;
100
101         if (data == NULL) {
102                 return GNUTLS_E_INVALID_REQUEST;
103         }
104
105         if (session->internals.resumable == RESUME_FALSE)
106                 return GNUTLS_E_INVALID_SESSION;
107
108         ret = _gnutls_session_pack(session, data);
109         if (ret < 0) {
110                 gnutls_assert();
111                 return ret;
112         }
113
114         return 0;
115 }
116
117
118 /**
119  * gnutls_session_get_id:
120  * @session: is a #gnutls_session_t structure.
121  * @session_id: is a pointer to space to hold the session id.
122  * @session_id_size: initially should contain the maximum @session_id size and will be updated.
123  *
124  * Returns the current session ID. This can be used if you want to
125  * check if the next session you tried to resume was actually
126  * resumed.  That is because resumed sessions share the same session ID
127  * with the original session.
128  *
129  * The session ID is selected by the server, that identify the
130  * current session.  In all supported TLS protocols, the session id
131  * is less than %GNUTLS_MAX_SESSION_ID_SIZE.
132  *
133  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
134  *   an error code is returned.
135  **/
136 int
137 gnutls_session_get_id(gnutls_session_t session,
138                       void *session_id, size_t * session_id_size)
139 {
140         size_t given_session_id_size = *session_id_size;
141
142         *session_id_size = session->security_parameters.session_id_size;
143
144         /* just return the session size */
145         if (session_id == NULL) {
146                 return 0;
147         }
148
149         if (given_session_id_size <
150             session->security_parameters.session_id_size) {
151                 return GNUTLS_E_SHORT_MEMORY_BUFFER;
152         }
153
154         memcpy(session_id, &session->security_parameters.session_id,
155                *session_id_size);
156
157         return 0;
158 }
159
160 /**
161  * gnutls_session_get_id2:
162  * @session: is a #gnutls_session_t structure.
163  * @session_id: will point to the session ID.
164  *
165  * Returns the current session ID. The returned data should be
166  * treated as constant.
167  *
168  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
169  *   an error code is returned.
170  *
171  * Since: 3.1.4
172  **/
173 int
174 gnutls_session_get_id2(gnutls_session_t session,
175                        gnutls_datum_t * session_id)
176 {
177         session_id->size = session->security_parameters.session_id_size;
178         session_id->data = session->security_parameters.session_id;
179
180         return 0;
181 }
182
183 /**
184  * gnutls_session_set_data:
185  * @session: is a #gnutls_session_t structure.
186  * @session_data: is a pointer to space to hold the session.
187  * @session_data_size: is the session's size
188  *
189  * Sets all session parameters, in order to resume a previously
190  * established session.  The session data given must be the one
191  * returned by gnutls_session_get_data().  This function should be
192  * called before gnutls_handshake().
193  *
194  * Keep in mind that session resuming is advisory. The server may
195  * choose not to resume the session, thus a full handshake will be
196  * performed.
197  *
198  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
199  *   an error code is returned.
200  **/
201 int
202 gnutls_session_set_data(gnutls_session_t session,
203                         const void *session_data, size_t session_data_size)
204 {
205         int ret;
206         gnutls_datum_t psession;
207
208         psession.data = (uint8_t *) session_data;
209         psession.size = session_data_size;
210
211         if (session_data == NULL || session_data_size == 0) {
212                 gnutls_assert();
213                 return GNUTLS_E_INVALID_REQUEST;
214         }
215         ret = _gnutls_session_unpack(session, &psession);
216         if (ret < 0) {
217                 gnutls_assert();
218                 return ret;
219         }
220
221         session->internals.resumption_requested = 1;
222
223         return 0;
224 }
225
226 /**
227  * gnutls_session_force_valid:
228  * @session: is a #gnutls_session_t structure.
229  *
230  * Clears the invalid flag in a session. That means
231  * that sessions were corrupt or invalid data were received 
232  * can be re-used. Use only when debugging or experimenting
233  * with the TLS protocol. Should not be used in typical
234  * applications.
235  *
236  **/
237 void gnutls_session_force_valid(gnutls_session_t session)
238 {
239         session->internals.invalid_connection = 0;
240 }