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>
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
)
48 if (packed_session
==NULL
) {
50 return GNUTLS_E_UNIMPLEMENTED_FEATURE
;
54 switch (gnutls_auth_get_type(state
)) {
57 SRP_SERVER_AUTH_INFO info
=
58 _gnutls_get_auth_info(state
);
61 if (info
== NULL
&& state
->gnutls_key
->auth_info_size
!=0) {
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
,
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
);
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) {
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
,
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
);
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) {
112 return GNUTLS_E_INVALID_PARAMETERS
;
116 _gnutls_pack_certificate_auth_info(info
,
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
));
142 /* Returns the size needed to hold the current session.
144 int _gnutls_session_size( GNUTLS_STATE state
)
148 pack_size
= PACK_HEADER_SIZE
+ sizeof(uint32
);
150 switch ( gnutls_auth_get_type(state
)) {
152 case GNUTLS_CRD_ANON
:
153 pack_size
+= state
->gnutls_key
->auth_info_size
;
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
);
164 /* Auth_info structures copied. Now copy SecurityParameters.
166 pack_size
+= sizeof(SecurityParameters
) + sizeof(uint32
);
171 int _gnutls_session_unpack(GNUTLS_STATE state
,
172 const gnutls_datum
* packed_session
)
176 uint32 timestamp
= time(0);
177 SecurityParameters sp
;
179 if (packed_session
==NULL
|| packed_session
->size
== 0) {
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]) {
190 case GNUTLS_CRD_SRP
:{
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
)) {
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
) {
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
+
220 case GNUTLS_CRD_ANON
:{
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
)) {
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
) {
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
)],
246 case GNUTLS_CRD_CERTIFICATE
:{
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;
256 if (pack_size
< sizeof(CERTIFICATE_AUTH_INFO_INT
)) {
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
) {
266 return GNUTLS_E_MEMORY_ERROR
;
268 state
->gnutls_key
->auth_info_size
=
269 sizeof(CERTIFICATE_AUTH_INFO_INT
);
272 _gnutls_unpack_certificate_auth_info(state
->
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.
294 _gnutls_read_uint32(&packed_session
->
295 data
[PACK_HEADER_SIZE
+ sizeof(uint32
) +
298 if (ret
!= sizeof(SecurityParameters
)) {
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
));
311 _gnutls_free_auth_info( state
);
313 return GNUTLS_E_EXPIRED
;
320 int _gnutls_pack_certificate_auth_info( CERTIFICATE_AUTH_INFO info
,
321 gnutls_datum
* packed_session
)
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
]);
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
;
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
;
354 static int _gnutls_pack_certificate_auth_info_size( CERTIFICATE_AUTH_INFO info
)
356 uint32 pack_size
= sizeof(CERTIFICATE_AUTH_INFO_INT
);
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
)
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
) {
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
);
405 gnutls_free_datum( &info
->raw_certificate_list
[j
]);
407 gnutls_free( info
->raw_certificate_list
);
408 return GNUTLS_E_MEMORY_ERROR
;