*** empty log message ***
[gnutls.git] / lib / gnutls_session_pack.c
bloba8e5a71228b9739555c718072c582defccc51729
1 /*
2 * Copyright (C) 2000 Nikos Mavroyanopoulos
4 * This file is part of GNUTLS.
6 * The GNUTLS library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <gnutls_int.h>
22 #include <auth_srp.h>
23 #include <auth_anon.h>
24 #include <auth_cert.h>
25 #include <gnutls_errors.h>
26 #include <gnutls_auth_int.h>
27 #include <gnutls_session_pack.h>
28 #include <gnutls_datum.h>
29 #include <gnutls_num.h>
31 #define PACK_HEADER_SIZE 1
32 int _gnutls_pack_certificate_auth_info( CERTIFICATE_AUTH_INFO info,
33 gnutls_datum * packed_session);
34 int _gnutls_unpack_certificate_auth_info(CERTIFICATE_AUTH_INFO info,
35 const gnutls_datum * packed_session);
36 static int _gnutls_pack_certificate_auth_info_size( CERTIFICATE_AUTH_INFO info);
39 /* Since auth_info structures contain malloced data, this function
40 * is required in order to pack these structures in a vector in
41 * order to store them to the DB.
43 int _gnutls_session_pack(GNUTLS_STATE state, gnutls_datum * packed_session)
45 uint32 pack_size;
46 int ret;
48 if (packed_session==NULL) {
49 gnutls_assert();
50 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
54 switch (gnutls_auth_get_type(state)) {
55 #ifdef ENABLE_SRP
56 case GNUTLS_CRD_SRP:{
57 SRP_SERVER_AUTH_INFO info =
58 _gnutls_get_auth_info(state);
61 if (info == NULL && state->gnutls_key->auth_info_size!=0) {
62 gnutls_assert();
63 return GNUTLS_E_INVALID_PARAMETERS;
66 pack_size = state->gnutls_key->auth_info_size;
67 packed_session->size =
68 PACK_HEADER_SIZE + pack_size + sizeof(uint32);
70 packed_session->data[0] = GNUTLS_CRD_SRP;
71 _gnutls_write_uint32(pack_size,
72 &packed_session->
73 data[PACK_HEADER_SIZE]);
75 if (state->gnutls_key->auth_info_size > 0)
76 memcpy(&packed_session->
77 data[PACK_HEADER_SIZE + sizeof(uint32)],
78 info, state->gnutls_key->auth_info_size);
82 break;
83 #endif
84 case GNUTLS_CRD_ANON:{
85 ANON_CLIENT_AUTH_INFO info =
86 _gnutls_get_auth_info(state);
87 if (info == NULL && state->gnutls_key->auth_info_size!=0) {
88 gnutls_assert();
89 return GNUTLS_E_INVALID_PARAMETERS;
92 packed_session->size =
93 PACK_HEADER_SIZE + state->gnutls_key->auth_info_size + sizeof(uint32);
95 packed_session->data[0] = GNUTLS_CRD_ANON;
96 _gnutls_write_uint32(state->gnutls_key->auth_info_size,
97 &packed_session->
98 data[PACK_HEADER_SIZE]);
100 if (state->gnutls_key->auth_info_size > 0)
101 memcpy(&packed_session->
102 data[PACK_HEADER_SIZE + sizeof(uint32)],
103 info, state->gnutls_key->auth_info_size);
106 break;
107 case GNUTLS_CRD_CERTIFICATE:{
108 CERTIFICATE_AUTH_INFO info =
109 _gnutls_get_auth_info(state);
110 if (info == NULL && state->gnutls_key->auth_info_size!=0) {
111 gnutls_assert();
112 return GNUTLS_E_INVALID_PARAMETERS;
115 ret =
116 _gnutls_pack_certificate_auth_info(info,
117 packed_session);
118 if (ret < 0) {
119 gnutls_assert();
120 return ret;
123 break;
124 default:
125 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
129 /* Auth_info structures copied. Now copy SecurityParameters.
131 packed_session->size += sizeof(SecurityParameters)+sizeof(uint32);
133 _gnutls_write_uint32( sizeof(SecurityParameters), &packed_session->data[packed_session->size - sizeof(SecurityParameters) - sizeof(uint32)]);
134 memcpy(&packed_session->
135 data[packed_session->size - sizeof(SecurityParameters)],
136 &state->security_parameters, sizeof(SecurityParameters));
139 return 0;
142 /* Returns the size needed to hold the current session.
144 int _gnutls_session_size( GNUTLS_STATE state)
146 uint32 pack_size;
148 pack_size = PACK_HEADER_SIZE + sizeof(uint32);
150 switch ( gnutls_auth_get_type(state)) {
151 case GNUTLS_CRD_SRP:
152 case GNUTLS_CRD_ANON:
153 pack_size += state->gnutls_key->auth_info_size;
154 break;
155 case GNUTLS_CRD_CERTIFICATE: {
156 CERTIFICATE_AUTH_INFO info =
157 _gnutls_get_auth_info(state);
159 pack_size += _gnutls_pack_certificate_auth_info_size( info);
161 break;
164 /* Auth_info structures copied. Now copy SecurityParameters.
166 pack_size += sizeof(SecurityParameters) + sizeof(uint32);
168 return pack_size;
171 int _gnutls_session_unpack(GNUTLS_STATE state,
172 const gnutls_datum * packed_session)
174 uint32 pack_size;
175 int ret;
176 uint32 timestamp = time(0);
177 SecurityParameters sp;
179 if (packed_session==NULL || packed_session->size == 0) {
180 gnutls_assert();
181 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
184 if (state->gnutls_key->auth_info != NULL) {
185 _gnutls_free_auth_info( state);
188 switch ( packed_session->data[0]) {
189 #ifdef ENABLE_SRP
190 case GNUTLS_CRD_SRP:{
192 pack_size =
193 _gnutls_read_uint32(&packed_session->
194 data[PACK_HEADER_SIZE]);
196 if (pack_size == 0) break;
197 if (pack_size != sizeof(SRP_SERVER_AUTH_INFO_INT)) {
198 gnutls_assert();
199 return GNUTLS_E_DB_ERROR;
202 state->gnutls_key->auth_info =
203 gnutls_malloc( pack_size);
205 if (state->gnutls_key->auth_info == NULL) {
206 gnutls_assert();
207 return GNUTLS_E_MEMORY_ERROR;
209 state->gnutls_key->auth_info_size =
210 sizeof(SRP_SERVER_AUTH_INFO_INT);
213 memcpy(state->gnutls_key->auth_info,
214 &packed_session->data[PACK_HEADER_SIZE +
215 sizeof(uint32)],
216 pack_size);
218 break;
219 #endif
220 case GNUTLS_CRD_ANON:{
221 pack_size =
222 _gnutls_read_uint32(&packed_session->
223 data[PACK_HEADER_SIZE]);
225 if (pack_size == 0) break;
227 if (pack_size != sizeof(ANON_CLIENT_AUTH_INFO_INT)) {
228 gnutls_assert();
229 return GNUTLS_E_DB_ERROR;
232 state->gnutls_key->auth_info =
233 gnutls_malloc( pack_size);
235 if (state->gnutls_key->auth_info == NULL) {
236 gnutls_assert();
237 return GNUTLS_E_MEMORY_ERROR;
239 state->gnutls_key->auth_info_size = pack_size;
241 memcpy(state->gnutls_key->auth_info,
242 &packed_session->data[PACK_HEADER_SIZE + sizeof(uint32)],
243 pack_size);
245 break;
246 case GNUTLS_CRD_CERTIFICATE:{
247 pack_size =
248 _gnutls_read_uint32(&packed_session->
249 data[PACK_HEADER_SIZE]);
251 if (pack_size == 0) {
252 state->gnutls_key->auth_info = NULL;
253 state->gnutls_key->auth_info_size = 0;
254 break;
256 if (pack_size < sizeof(CERTIFICATE_AUTH_INFO_INT)) {
257 gnutls_assert();
258 return GNUTLS_E_DB_ERROR;
261 state->gnutls_key->auth_info =
262 gnutls_malloc( sizeof(CERTIFICATE_AUTH_INFO_INT));
264 if (state->gnutls_key->auth_info == NULL) {
265 gnutls_assert();
266 return GNUTLS_E_MEMORY_ERROR;
268 state->gnutls_key->auth_info_size =
269 sizeof(CERTIFICATE_AUTH_INFO_INT);
271 ret =
272 _gnutls_unpack_certificate_auth_info(state->
273 gnutls_key->
274 auth_info,
275 packed_session);
276 if (ret < 0) {
277 gnutls_assert();
278 return ret;
282 break;
283 default:
284 gnutls_assert();
285 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
289 state->gnutls_key->auth_info_type = packed_session->data[0];
291 /* Auth_info structures copied. Now copy SecurityParameters.
293 ret =
294 _gnutls_read_uint32(&packed_session->
295 data[PACK_HEADER_SIZE + sizeof(uint32) +
296 pack_size]);
298 if (ret != sizeof(SecurityParameters)) {
299 gnutls_assert();
300 return GNUTLS_E_DB_ERROR;
302 memcpy(&sp, &packed_session->data[PACK_HEADER_SIZE +
303 2 * sizeof(uint32) + pack_size],
304 sizeof(SecurityParameters));
306 if ( timestamp - sp.timestamp <= state->gnutls_internals.expire_time
307 && sp.timestamp <= timestamp) {
309 memcpy( &state->gnutls_internals.resumed_security_parameters, &sp, sizeof(SecurityParameters));
310 } else {
311 _gnutls_free_auth_info( state);
312 gnutls_assert();
313 return GNUTLS_E_EXPIRED;
317 return 0;
320 int _gnutls_pack_certificate_auth_info( CERTIFICATE_AUTH_INFO info,
321 gnutls_datum * packed_session)
323 uint32 pos, i;
324 int info_size;
326 packed_session->size = _gnutls_pack_certificate_auth_info_size( info);
328 if (info==NULL) info_size = 0;
329 else info_size = sizeof(CERTIFICATE_AUTH_INFO_INT);
331 packed_session->data[0] = GNUTLS_CRD_CERTIFICATE;
332 _gnutls_write_uint32( packed_session->size-PACK_HEADER_SIZE-sizeof(uint32), &packed_session->data[PACK_HEADER_SIZE]);
334 if (info!=NULL) {
335 memcpy(&packed_session->data[PACK_HEADER_SIZE + sizeof(uint32)],
336 info, sizeof(CERTIFICATE_AUTH_INFO_INT));
339 pos = PACK_HEADER_SIZE + sizeof(uint32) + info_size;
341 if (info!=NULL) {
342 for (i=0;i<info->ncerts;i++) {
343 _gnutls_write_uint32( info->raw_certificate_list[i].size, &packed_session->data[pos]);
344 pos += sizeof(uint32);
346 memcpy(&packed_session->data[pos], info->raw_certificate_list[i].data, info->raw_certificate_list[i].size);
347 pos += info->raw_certificate_list[i].size;
351 return 0;
354 static int _gnutls_pack_certificate_auth_info_size( CERTIFICATE_AUTH_INFO info)
356 uint32 pack_size = sizeof(CERTIFICATE_AUTH_INFO_INT);
357 int i;
359 if (info == NULL)
360 return sizeof(uint32) + PACK_HEADER_SIZE;
362 for (i=0;i<info->ncerts;i++) {
363 pack_size += sizeof(uint32) + info->raw_certificate_list[i].size;
366 return pack_size + PACK_HEADER_SIZE + sizeof(uint32);
370 int _gnutls_unpack_certificate_auth_info(CERTIFICATE_AUTH_INFO info,
371 const gnutls_datum * packed_session)
373 int ret, i, pos, j;
374 uint32 size;
376 memcpy(info,
377 &packed_session->data[PACK_HEADER_SIZE + sizeof(uint32)],
378 sizeof(CERTIFICATE_AUTH_INFO_INT));
380 pos = PACK_HEADER_SIZE + sizeof(uint32) + sizeof(CERTIFICATE_AUTH_INFO_INT);
381 if (info->ncerts > 0) {
382 info->raw_certificate_list = gnutls_calloc( 1, info->ncerts * sizeof( gnutls_datum));
383 if (info->raw_certificate_list == NULL) {
384 gnutls_assert();
385 return GNUTLS_E_MEMORY_ERROR;
388 for (i=0;i<info->ncerts;i++) {
389 size = _gnutls_read_uint32( &packed_session->data[ pos]);
390 pos += sizeof(uint32);
392 ret = gnutls_set_datum( &info->raw_certificate_list[i], &packed_session->data[ pos], size);
393 pos += size;
395 if (ret < 0) {
396 gnutls_assert();
397 goto clear;
401 return 0;
403 clear:
404 for (j=0;j<i;j++)
405 gnutls_free_datum( &info->raw_certificate_list[j]);
407 gnutls_free( info->raw_certificate_list);
408 return GNUTLS_E_MEMORY_ERROR;