Line data Source code
1 : /*
2 : * Copyright (C) 2000-2012 Free Software Foundation, Inc.
3 : * Copyright (C) 2017 Red Hat, Inc.
4 : *
5 : * Author: Nikos Mavrogiannopoulos
6 : *
7 : * This file is part of GnuTLS.
8 : *
9 : * The GnuTLS is free software; you can redistribute it and/or
10 : * modify it under the terms of the GNU Lesser General Public License
11 : * as published by the Free Software Foundation; either version 2.1 of
12 : * the License, or (at your option) any later version.
13 : *
14 : * This library is distributed in the hope that it will be useful, but
15 : * WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : * Lesser General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU Lesser General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>
21 : *
22 : */
23 :
24 : /* Contains functions that are supposed to pack and unpack session data,
25 : * before and after they are sent to the database backend.
26 : */
27 :
28 : #include "gnutls_int.h"
29 : #ifdef ENABLE_SRP
30 : #include <auth/srp_kx.h>
31 : #endif
32 : #ifdef ENABLE_PSK
33 : #include <auth/psk.h>
34 : #endif
35 : #include <auth/anon.h>
36 : #include <auth/cert.h>
37 : #include "errors.h"
38 : #include <auth.h>
39 : #include <session_pack.h>
40 : #include <datum.h>
41 : #include <num.h>
42 : #include <hello_ext.h>
43 : #include <constate.h>
44 : #include <algorithms.h>
45 : #include <state.h>
46 : #include <db.h>
47 : #include "tls13/session_ticket.h"
48 :
49 : static int pack_certificate_auth_info(gnutls_session_t,
50 : gnutls_buffer_st * packed_session);
51 : static int unpack_certificate_auth_info(gnutls_session_t,
52 : gnutls_buffer_st * packed_session);
53 :
54 : static int unpack_srp_auth_info(gnutls_session_t session,
55 : gnutls_buffer_st * packed_session);
56 : static int pack_srp_auth_info(gnutls_session_t session,
57 : gnutls_buffer_st * packed_session);
58 :
59 : static int unpack_psk_auth_info(gnutls_session_t session,
60 : gnutls_buffer_st * packed_session);
61 : static int pack_psk_auth_info(gnutls_session_t session,
62 : gnutls_buffer_st * packed_session);
63 :
64 : static int unpack_anon_auth_info(gnutls_session_t session,
65 : gnutls_buffer_st * packed_session);
66 : static int pack_anon_auth_info(gnutls_session_t session,
67 : gnutls_buffer_st * packed_session);
68 :
69 : static int unpack_security_parameters(gnutls_session_t session,
70 : gnutls_buffer_st * packed_session);
71 : static int pack_security_parameters(gnutls_session_t session,
72 : gnutls_buffer_st * packed_session);
73 : static int tls13_unpack_security_parameters(gnutls_session_t session,
74 : gnutls_buffer_st * packed_session);
75 : static int tls13_pack_security_parameters(gnutls_session_t session,
76 : gnutls_buffer_st * packed_session);
77 :
78 :
79 : /* Since auth_info structures contain malloced data, this function
80 : * is required in order to pack these structures in a vector in
81 : * order to store them to the DB.
82 : *
83 : * packed_session will contain the session data.
84 : *
85 : * The data will be in a platform independent format.
86 : */
87 : int
88 13942 : _gnutls_session_pack(gnutls_session_t session,
89 : gnutls_datum_t * packed_session)
90 : {
91 13942 : int ret;
92 13942 : gnutls_buffer_st sb;
93 13942 : uint8_t id;
94 :
95 13942 : if (packed_session == NULL) {
96 0 : gnutls_assert();
97 0 : return GNUTLS_E_INTERNAL_ERROR;
98 : }
99 :
100 13942 : _gnutls_buffer_init(&sb);
101 :
102 :
103 13942 : id = gnutls_auth_get_type(session);
104 :
105 13942 : BUFFER_APPEND_NUM(&sb, PACKED_SESSION_MAGIC);
106 13942 : BUFFER_APPEND_NUM(&sb, session->security_parameters.timestamp);
107 13942 : BUFFER_APPEND_NUM(&sb, session->internals.expire_time);
108 13942 : BUFFER_APPEND(&sb, &id, 1);
109 :
110 13942 : switch (id) {
111 : #ifdef ENABLE_SRP
112 29 : case GNUTLS_CRD_SRP:
113 29 : ret = pack_srp_auth_info(session, &sb);
114 29 : if (ret < 0) {
115 0 : gnutls_assert();
116 0 : goto fail;
117 : }
118 : break;
119 : #endif
120 : #ifdef ENABLE_PSK
121 1703 : case GNUTLS_CRD_PSK:
122 1703 : ret = pack_psk_auth_info(session, &sb);
123 1703 : if (ret < 0) {
124 0 : gnutls_assert();
125 0 : goto fail;
126 : }
127 : break;
128 : #endif
129 : #ifdef ENABLE_ANON
130 635 : case GNUTLS_CRD_ANON:
131 635 : ret = pack_anon_auth_info(session, &sb);
132 635 : if (ret < 0) {
133 0 : gnutls_assert();
134 0 : goto fail;
135 : }
136 : break;
137 : #endif
138 11106 : case GNUTLS_CRD_CERTIFICATE:
139 11106 : ret = pack_certificate_auth_info(session, &sb);
140 11106 : if (ret < 0) {
141 0 : gnutls_assert();
142 0 : goto fail;
143 : }
144 : break;
145 : default:
146 469 : ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
147 469 : goto fail;
148 :
149 : }
150 :
151 : /* Auth_info structures copied. Now copy security_parameters_st.
152 : * packed_session must have allocated space for the security parameters.
153 : */
154 13473 : ret = pack_security_parameters(session, &sb);
155 13473 : if (ret < 0) {
156 1 : gnutls_assert();
157 1 : goto fail;
158 : }
159 :
160 :
161 13472 : if (session->security_parameters.pversion->tls13_sem) {
162 6907 : ret = tls13_pack_security_parameters(session, &sb);
163 6907 : if (ret < 0) {
164 0 : gnutls_assert();
165 0 : goto fail;
166 : }
167 : }
168 :
169 : /* Extensions are re-negotiated in a resumed session under TLS 1.3 */
170 13472 : if (!session->security_parameters.pversion->tls13_sem) {
171 6565 : ret = _gnutls_hello_ext_pack(session, &sb);
172 6565 : if (ret < 0) {
173 0 : gnutls_assert();
174 0 : goto fail;
175 : }
176 : }
177 :
178 13472 : return _gnutls_buffer_to_datum(&sb, packed_session, 0);
179 :
180 470 : fail:
181 470 : _gnutls_buffer_clear(&sb);
182 470 : return ret;
183 : }
184 :
185 :
186 : /* Load session data from a buffer.
187 : */
188 : int
189 1582 : _gnutls_session_unpack(gnutls_session_t session,
190 : const gnutls_datum_t * packed_session)
191 : {
192 1582 : int ret;
193 1582 : gnutls_buffer_st sb;
194 1582 : uint32_t magic;
195 1582 : uint32_t expire_time;
196 1582 : uint8_t id;
197 :
198 1582 : _gnutls_buffer_init(&sb);
199 :
200 1582 : if (packed_session == NULL || packed_session->size == 0) {
201 0 : gnutls_assert();
202 0 : return GNUTLS_E_INTERNAL_ERROR;
203 : }
204 :
205 1582 : ret =
206 1582 : _gnutls_buffer_append_data(&sb, packed_session->data,
207 : packed_session->size);
208 1582 : if (ret < 0) {
209 0 : gnutls_assert();
210 0 : return ret;
211 : }
212 :
213 1582 : if (session->key.auth_info != NULL) {
214 4 : _gnutls_free_auth_info(session);
215 : }
216 :
217 1582 : BUFFER_POP_NUM(&sb, magic);
218 1582 : if (magic != PACKED_SESSION_MAGIC) {
219 12 : ret = gnutls_assert_val(GNUTLS_E_DB_ERROR);
220 12 : goto error;
221 : }
222 :
223 1570 : BUFFER_POP_NUM(&sb,
224 : session->internals.resumed_security_parameters.
225 1570 : timestamp);
226 1570 : BUFFER_POP_NUM(&sb, expire_time);
227 1570 : (void) expire_time;
228 1570 : BUFFER_POP(&sb, &id, 1);
229 :
230 1570 : switch (id) {
231 : #ifdef ENABLE_SRP
232 0 : case GNUTLS_CRD_SRP:
233 0 : ret = unpack_srp_auth_info(session, &sb);
234 0 : if (ret < 0) {
235 0 : gnutls_assert();
236 0 : goto error;
237 : }
238 : break;
239 : #endif
240 : #ifdef ENABLE_PSK
241 480 : case GNUTLS_CRD_PSK:
242 480 : ret = unpack_psk_auth_info(session, &sb);
243 480 : if (ret < 0) {
244 0 : gnutls_assert();
245 0 : goto error;
246 : }
247 : break;
248 : #endif
249 : #ifdef ENABLE_ANON
250 431 : case GNUTLS_CRD_ANON:
251 431 : ret = unpack_anon_auth_info(session, &sb);
252 431 : if (ret < 0) {
253 0 : gnutls_assert();
254 0 : return ret;
255 : }
256 : break;
257 : #endif
258 659 : case GNUTLS_CRD_CERTIFICATE:
259 659 : ret = unpack_certificate_auth_info(session, &sb);
260 659 : if (ret < 0) {
261 0 : gnutls_assert();
262 0 : goto error;
263 : }
264 : break;
265 0 : default:
266 0 : gnutls_assert();
267 0 : ret = GNUTLS_E_INTERNAL_ERROR;
268 0 : goto error;
269 :
270 : }
271 :
272 : /* Auth_info structures copied. Now copy security_parameters_st.
273 : * packed_session must have allocated space for the security parameters.
274 : */
275 1570 : ret = unpack_security_parameters(session, &sb);
276 1570 : if (ret < 0) {
277 0 : gnutls_assert();
278 0 : goto error;
279 : }
280 :
281 1570 : if (session->internals.resumed_security_parameters.pversion->tls13_sem) {
282 : /* 'prf' will not be NULL at this point, else unpack_security_parameters() would have failed */
283 247 : ret = tls13_unpack_security_parameters(session, &sb);
284 247 : if (ret < 0) {
285 0 : gnutls_assert();
286 0 : goto error;
287 : }
288 : }
289 :
290 1570 : if (!session->internals.resumed_security_parameters.pversion->tls13_sem) {
291 1323 : ret = _gnutls_hello_ext_unpack(session, &sb);
292 1323 : if (ret < 0) {
293 0 : gnutls_assert();
294 0 : goto error;
295 : }
296 : }
297 :
298 : ret = 0;
299 :
300 1582 : error:
301 1582 : _gnutls_buffer_clear(&sb);
302 :
303 1582 : return ret;
304 : }
305 :
306 : /*
307 : * If we're using TLS 1.3 semantics, we might have TLS 1.3-specific data.
308 : * Format:
309 : * 4 bytes the total length
310 : * 4 bytes the ticket lifetime
311 : * 4 bytes the ticket age add value
312 : * 1 byte the ticket nonce length
313 : * x bytes the ticket nonce
314 : * 4 bytes the ticket length
315 : * x bytes the ticket
316 : * 1 bytes the resumption master secret length
317 : * x bytes the resumption master secret
318 : * 12 bytes the ticket arrival time
319 : * 4 bytes the max early data size
320 : *
321 : * We only store that info if we received a TLS 1.3 NewSessionTicket at some point.
322 : * If we didn't receive any NST then we cannot resume a TLS 1.3 session and hence
323 : * its nonsense to store all that info.
324 : */
325 : static int
326 6907 : tls13_pack_security_parameters(gnutls_session_t session, gnutls_buffer_st *ps)
327 : {
328 6907 : int ret = 0;
329 6907 : uint32_t length = 0;
330 6907 : size_t length_pos;
331 6907 : tls13_ticket_st *ticket = &session->internals.tls13_ticket;
332 :
333 6907 : length_pos = ps->length;
334 6907 : BUFFER_APPEND_NUM(ps, 0);
335 :
336 6907 : if (ticket->ticket.data != NULL) {
337 52 : BUFFER_APPEND_NUM(ps, ticket->lifetime);
338 52 : length += 4;
339 52 : BUFFER_APPEND_NUM(ps, ticket->age_add);
340 52 : length += 4;
341 52 : BUFFER_APPEND_PFX1(ps,
342 : ticket->nonce,
343 52 : ticket->nonce_size);
344 52 : length += (1 + ticket->nonce_size);
345 52 : BUFFER_APPEND_PFX4(ps,
346 : ticket->ticket.data,
347 52 : ticket->ticket.size);
348 52 : length += (4 + ticket->ticket.size);
349 52 : BUFFER_APPEND_PFX1(ps,
350 : ticket->resumption_master_secret,
351 52 : ticket->prf->output_size);
352 52 : length += (1 + ticket->prf->output_size);
353 52 : BUFFER_APPEND_TS(ps, ticket->arrival_time);
354 52 : length += 12;
355 52 : BUFFER_APPEND_NUM(ps,
356 : session->security_parameters.
357 52 : max_early_data_size);
358 52 : length += 4;
359 :
360 : /* Overwrite the length field */
361 52 : _gnutls_write_uint32(length, ps->data + length_pos);
362 : }
363 :
364 : return ret;
365 : }
366 :
367 : static int
368 247 : tls13_unpack_security_parameters(gnutls_session_t session, gnutls_buffer_st *ps)
369 : {
370 247 : uint32_t ttl_len;
371 247 : tls13_ticket_st *ticket = &session->internals.tls13_ticket;
372 247 : gnutls_datum_t t;
373 247 : int ret = 0;
374 :
375 247 : BUFFER_POP_NUM(ps, ttl_len);
376 :
377 247 : if (ttl_len > 0) {
378 59 : BUFFER_POP_NUM(ps, ticket->lifetime);
379 59 : BUFFER_POP_NUM(ps, ticket->age_add);
380 :
381 59 : ret = _gnutls_buffer_pop_datum_prefix8(ps, &t);
382 59 : if (ret < 0 || t.size > sizeof(ticket->nonce)) {
383 0 : ret = GNUTLS_E_PARSING_ERROR;
384 0 : gnutls_assert();
385 0 : goto error;
386 : }
387 59 : ticket->nonce_size = t.size;
388 59 : memcpy(ticket->nonce, t.data, t.size);
389 :
390 59 : BUFFER_POP_DATUM(ps, &ticket->ticket);
391 :
392 59 : ret = _gnutls_buffer_pop_datum_prefix8(ps, &t);
393 59 : if (ret < 0 || t.size > sizeof(ticket->resumption_master_secret)) {
394 0 : ret = GNUTLS_E_PARSING_ERROR;
395 0 : gnutls_assert();
396 0 : goto error;
397 : }
398 59 : memcpy(ticket->resumption_master_secret, t.data, t.size);
399 :
400 59 : if (unlikely(session->internals.resumed_security_parameters.prf == NULL ||
401 : session->internals.resumed_security_parameters.prf->output_size != t.size))
402 0 : return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
403 :
404 59 : ticket->prf = session->internals.resumed_security_parameters.prf;
405 :
406 59 : BUFFER_POP_TS(ps, ticket->arrival_time);
407 59 : BUFFER_POP_NUM(ps,
408 : session->security_parameters.
409 : max_early_data_size);
410 : }
411 :
412 188 : error:
413 : return ret;
414 : }
415 :
416 : /* Format:
417 : * 1 byte the credentials type
418 : * 4 bytes the size of the whole structure
419 : * DH stuff
420 : * 2 bytes the size of secret key in bits
421 : * 4 bytes the size of the prime
422 : * x bytes the prime
423 : * 4 bytes the size of the generator
424 : * x bytes the generator
425 : * 4 bytes the size of the public key
426 : * x bytes the public key
427 : * RSA stuff
428 : * 4 bytes the size of the modulus
429 : * x bytes the modulus
430 : * 4 bytes the size of the exponent
431 : * x bytes the exponent
432 : * CERTIFICATES
433 : * 4 bytes the length of the certificate list
434 : * 4 bytes the size of first certificate
435 : * x bytes the certificate
436 : * and so on...
437 : */
438 : static int
439 11106 : pack_certificate_auth_info(gnutls_session_t session, gnutls_buffer_st * ps)
440 : {
441 11106 : unsigned int i;
442 11106 : int cur_size, ret;
443 11106 : cert_auth_info_t info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
444 11106 : int size_offset;
445 :
446 11106 : size_offset = ps->length;
447 11106 : BUFFER_APPEND_NUM(ps, 0);
448 11106 : cur_size = ps->length;
449 :
450 11106 : if (info) {
451 :
452 3438 : BUFFER_APPEND_NUM(ps, info->dh.secret_bits);
453 3438 : BUFFER_APPEND_PFX4(ps, info->dh.prime.data,
454 3438 : info->dh.prime.size);
455 3438 : BUFFER_APPEND_PFX4(ps, info->dh.generator.data,
456 3438 : info->dh.generator.size);
457 3438 : BUFFER_APPEND_PFX4(ps, info->dh.public_key.data,
458 3438 : info->dh.public_key.size);
459 :
460 3438 : BUFFER_APPEND_NUM(ps, info->ncerts);
461 :
462 4390 : for (i = 0; i < info->ncerts; i++) {
463 952 : BUFFER_APPEND_PFX4(ps,
464 : info->raw_certificate_list[i].
465 : data,
466 : info->raw_certificate_list[i].
467 952 : size);
468 : }
469 :
470 3438 : BUFFER_APPEND_NUM(ps, info->nocsp);
471 :
472 3611 : for (i = 0; i < info->nocsp; i++) {
473 173 : BUFFER_APPEND_PFX4(ps,
474 : info->raw_ocsp_list[i].
475 : data,
476 : info->raw_ocsp_list[i].
477 173 : size);
478 : }
479 : }
480 :
481 : /* write the real size */
482 11106 : _gnutls_write_uint32(ps->length - cur_size,
483 11106 : ps->data + size_offset);
484 :
485 11106 : return 0;
486 : }
487 :
488 :
489 : /* Upack certificate info.
490 : */
491 : static int
492 659 : unpack_certificate_auth_info(gnutls_session_t session,
493 : gnutls_buffer_st * ps)
494 : {
495 659 : int ret;
496 659 : unsigned int i = 0, j = 0;
497 659 : size_t pack_size;
498 659 : cert_auth_info_t info = NULL;
499 659 : unsigned cur_ncerts = 0;
500 659 : unsigned cur_nocsp = 0;
501 :
502 659 : BUFFER_POP_NUM(ps, pack_size);
503 :
504 659 : if (pack_size == 0)
505 : return 0; /* nothing to be done */
506 :
507 : /* client and server have the same auth_info here
508 : */
509 556 : ret =
510 556 : _gnutls_auth_info_init(session, GNUTLS_CRD_CERTIFICATE,
511 : sizeof(cert_auth_info_st), 1);
512 556 : if (ret < 0) {
513 0 : gnutls_assert();
514 0 : return ret;
515 : }
516 :
517 556 : info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
518 556 : if (info == NULL)
519 0 : return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
520 :
521 556 : BUFFER_POP_NUM(ps, info->dh.secret_bits);
522 :
523 556 : BUFFER_POP_DATUM(ps, &info->dh.prime);
524 556 : BUFFER_POP_DATUM(ps, &info->dh.generator);
525 556 : BUFFER_POP_DATUM(ps, &info->dh.public_key);
526 :
527 556 : BUFFER_POP_NUM(ps, info->ncerts);
528 :
529 556 : if (info->ncerts > 0) {
530 350 : info->raw_certificate_list =
531 175 : gnutls_calloc(info->ncerts, sizeof(gnutls_datum_t));
532 175 : if (info->raw_certificate_list == NULL) {
533 0 : gnutls_assert();
534 0 : ret = GNUTLS_E_MEMORY_ERROR;
535 0 : goto error;
536 : }
537 : }
538 :
539 836 : for (i = 0; i < info->ncerts; i++) {
540 280 : BUFFER_POP_DATUM(ps, &info->raw_certificate_list[i]);
541 280 : cur_ncerts++;
542 : }
543 :
544 : /* read OCSP responses */
545 556 : BUFFER_POP_NUM(ps, info->nocsp);
546 :
547 556 : if (info->nocsp > 0) {
548 102 : info->raw_ocsp_list =
549 51 : gnutls_calloc(info->nocsp, sizeof(gnutls_datum_t));
550 51 : if (info->raw_ocsp_list == NULL) {
551 0 : gnutls_assert();
552 0 : ret = GNUTLS_E_MEMORY_ERROR;
553 0 : goto error;
554 : }
555 : }
556 :
557 637 : for (i = 0; i < info->nocsp; i++) {
558 81 : BUFFER_POP_DATUM(ps, &info->raw_ocsp_list[i]);
559 81 : cur_nocsp++;
560 : }
561 :
562 : return 0;
563 :
564 0 : error:
565 0 : if (info) {
566 0 : _gnutls_free_datum(&info->dh.prime);
567 0 : _gnutls_free_datum(&info->dh.generator);
568 0 : _gnutls_free_datum(&info->dh.public_key);
569 :
570 0 : for (j = 0; j < cur_ncerts; j++)
571 0 : _gnutls_free_datum(&info->raw_certificate_list[j]);
572 :
573 0 : for (j = 0; j < cur_nocsp; j++)
574 0 : _gnutls_free_datum(&info->raw_ocsp_list[j]);
575 :
576 0 : gnutls_free(info->raw_certificate_list);
577 0 : gnutls_free(info->raw_ocsp_list);
578 : }
579 :
580 : return ret;
581 :
582 : }
583 :
584 : #ifdef ENABLE_SRP
585 : /* Packs the SRP session authentication data.
586 : */
587 :
588 : /* Format:
589 : * 1 byte the credentials type
590 : * 4 bytes the size of the SRP username (x)
591 : * x bytes the SRP username
592 : */
593 : static int
594 29 : pack_srp_auth_info(gnutls_session_t session, gnutls_buffer_st * ps)
595 : {
596 29 : srp_server_auth_info_t info = _gnutls_get_auth_info(session, GNUTLS_CRD_SRP);
597 29 : int len, ret;
598 29 : int size_offset;
599 29 : size_t cur_size;
600 29 : const char *username = NULL;
601 :
602 29 : if (info) {
603 29 : username = info->username;
604 29 : len = strlen(info->username) + 1; /* include the terminating null */
605 : } else
606 : len = 0;
607 :
608 29 : size_offset = ps->length;
609 29 : BUFFER_APPEND_NUM(ps, 0);
610 29 : cur_size = ps->length;
611 :
612 29 : BUFFER_APPEND_PFX4(ps, username, len);
613 :
614 : /* write the real size */
615 29 : _gnutls_write_uint32(ps->length - cur_size,
616 29 : ps->data + size_offset);
617 :
618 29 : return 0;
619 : }
620 :
621 :
622 : static int
623 0 : unpack_srp_auth_info(gnutls_session_t session, gnutls_buffer_st * ps)
624 : {
625 0 : size_t username_size;
626 0 : int ret;
627 0 : srp_server_auth_info_t info;
628 :
629 0 : BUFFER_POP_NUM(ps, username_size);
630 0 : if (username_size > sizeof(info->username)) {
631 0 : gnutls_assert();
632 0 : return GNUTLS_E_INTERNAL_ERROR;
633 : }
634 :
635 0 : ret =
636 0 : _gnutls_auth_info_init(session, GNUTLS_CRD_SRP,
637 : sizeof(srp_server_auth_info_st), 1);
638 0 : if (ret < 0) {
639 0 : gnutls_assert();
640 0 : return ret;
641 : }
642 :
643 0 : info = _gnutls_get_auth_info(session, GNUTLS_CRD_SRP);
644 0 : if (info == NULL)
645 0 : return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
646 :
647 0 : BUFFER_POP(ps, info->username, username_size);
648 0 : if (username_size == 0)
649 0 : info->username[0] = 0;
650 :
651 : ret = 0;
652 :
653 : error:
654 : return ret;
655 : }
656 : #endif
657 :
658 :
659 : #ifdef ENABLE_ANON
660 : /* Packs the ANON session authentication data.
661 : */
662 :
663 : /* Format:
664 : * 1 byte the credentials type
665 : * 4 bytes the size of the whole structure
666 : * 2 bytes the size of secret key in bits
667 : * 4 bytes the size of the prime
668 : * x bytes the prime
669 : * 4 bytes the size of the generator
670 : * x bytes the generator
671 : * 4 bytes the size of the public key
672 : * x bytes the public key
673 : */
674 : static int
675 635 : pack_anon_auth_info(gnutls_session_t session, gnutls_buffer_st * ps)
676 : {
677 635 : int cur_size, ret;
678 635 : anon_auth_info_t info = _gnutls_get_auth_info(session, GNUTLS_CRD_ANON);
679 635 : int size_offset;
680 :
681 635 : size_offset = ps->length;
682 635 : BUFFER_APPEND_NUM(ps, 0);
683 635 : cur_size = ps->length;
684 :
685 635 : if (info) {
686 635 : BUFFER_APPEND_NUM(ps, info->dh.secret_bits);
687 635 : BUFFER_APPEND_PFX4(ps, info->dh.prime.data,
688 635 : info->dh.prime.size);
689 635 : BUFFER_APPEND_PFX4(ps, info->dh.generator.data,
690 635 : info->dh.generator.size);
691 635 : BUFFER_APPEND_PFX4(ps, info->dh.public_key.data,
692 635 : info->dh.public_key.size);
693 : }
694 :
695 : /* write the real size */
696 635 : _gnutls_write_uint32(ps->length - cur_size,
697 635 : ps->data + size_offset);
698 :
699 635 : return 0;
700 : }
701 :
702 :
703 : static int
704 431 : unpack_anon_auth_info(gnutls_session_t session, gnutls_buffer_st * ps)
705 : {
706 431 : int ret;
707 431 : size_t pack_size;
708 431 : anon_auth_info_t info = NULL;
709 :
710 431 : BUFFER_POP_NUM(ps, pack_size);
711 :
712 431 : if (pack_size == 0)
713 : return 0; /* nothing to be done */
714 :
715 : /* client and server have the same auth_info here
716 : */
717 431 : ret =
718 431 : _gnutls_auth_info_init(session, GNUTLS_CRD_ANON,
719 : sizeof(anon_auth_info_st), 1);
720 431 : if (ret < 0) {
721 0 : gnutls_assert();
722 0 : return ret;
723 : }
724 :
725 431 : info = _gnutls_get_auth_info(session, GNUTLS_CRD_ANON);
726 431 : if (info == NULL)
727 0 : return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
728 :
729 431 : BUFFER_POP_NUM(ps, info->dh.secret_bits);
730 :
731 431 : BUFFER_POP_DATUM(ps, &info->dh.prime);
732 431 : BUFFER_POP_DATUM(ps, &info->dh.generator);
733 431 : BUFFER_POP_DATUM(ps, &info->dh.public_key);
734 :
735 431 : return 0;
736 :
737 0 : error:
738 0 : if (info) {
739 0 : _gnutls_free_datum(&info->dh.prime);
740 0 : _gnutls_free_datum(&info->dh.generator);
741 0 : _gnutls_free_datum(&info->dh.public_key);
742 : }
743 :
744 : return ret;
745 : }
746 : #endif /* ANON */
747 :
748 : #ifdef ENABLE_PSK
749 : /* Packs the PSK session authentication data.
750 : */
751 :
752 : /* Format:
753 : * 1 byte the credentials type
754 : * 4 bytes the size of the whole structure
755 : *
756 : * 4 bytes the size of the PSK username (x)
757 : * x bytes the PSK username
758 : * 2 bytes the size of secret key in bits
759 : * 4 bytes the size of the prime
760 : * x bytes the prime
761 : * 4 bytes the size of the generator
762 : * x bytes the generator
763 : * 4 bytes the size of the public key
764 : * x bytes the public key
765 : */
766 : static int
767 1703 : pack_psk_auth_info(gnutls_session_t session, gnutls_buffer_st * ps)
768 : {
769 1703 : psk_auth_info_t info;
770 1703 : int username_len;
771 1703 : int hint_len, ret;
772 1703 : int size_offset;
773 1703 : size_t cur_size;
774 :
775 1703 : info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
776 1703 : if (info == NULL)
777 0 : return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
778 :
779 1703 : username_len = info->username_len;
780 1703 : hint_len = strlen(info->hint) + 1; /* include the terminating null */
781 :
782 1703 : size_offset = ps->length;
783 1703 : BUFFER_APPEND_NUM(ps, 0);
784 1703 : cur_size = ps->length;
785 :
786 1703 : BUFFER_APPEND_PFX4(ps, info->username, username_len);
787 1703 : BUFFER_APPEND_PFX4(ps, info->hint, hint_len);
788 :
789 1703 : BUFFER_APPEND_NUM(ps, info->dh.secret_bits);
790 1703 : BUFFER_APPEND_PFX4(ps, info->dh.prime.data, info->dh.prime.size);
791 1703 : BUFFER_APPEND_PFX4(ps, info->dh.generator.data,
792 1703 : info->dh.generator.size);
793 1703 : BUFFER_APPEND_PFX4(ps, info->dh.public_key.data,
794 1703 : info->dh.public_key.size);
795 :
796 : /* write the real size */
797 1703 : _gnutls_write_uint32(ps->length - cur_size,
798 1703 : ps->data + size_offset);
799 1703 : return 0;
800 : }
801 :
802 : static int
803 480 : unpack_psk_auth_info(gnutls_session_t session, gnutls_buffer_st * ps)
804 : {
805 480 : size_t username_size, hint_size;
806 480 : int ret;
807 480 : psk_auth_info_t info;
808 480 : unsigned pack_size;
809 :
810 480 : ret =
811 480 : _gnutls_auth_info_init(session, GNUTLS_CRD_PSK,
812 : sizeof(psk_auth_info_st), 1);
813 480 : if (ret < 0) {
814 0 : gnutls_assert();
815 0 : return ret;
816 : }
817 :
818 480 : info = _gnutls_get_auth_info(session, GNUTLS_CRD_PSK);
819 480 : if (info == NULL)
820 0 : return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
821 :
822 480 : BUFFER_POP_NUM(ps, pack_size);
823 480 : if (pack_size == 0)
824 : return GNUTLS_E_INVALID_REQUEST;
825 :
826 480 : BUFFER_POP_NUM(ps, username_size);
827 480 : if (username_size > (sizeof(info->username) - 1)) {
828 0 : gnutls_assert();
829 0 : return GNUTLS_E_INTERNAL_ERROR;
830 : }
831 :
832 480 : BUFFER_POP(ps, info->username, username_size);
833 480 : if (username_size == 0)
834 0 : info->username[0] = 0;
835 :
836 : /* append a null terminator and set length */
837 480 : info->username[username_size] = 0;
838 480 : info->username_len = username_size;
839 :
840 480 : BUFFER_POP_NUM(ps, hint_size);
841 480 : if (hint_size > sizeof(info->hint)) {
842 0 : gnutls_assert();
843 0 : return GNUTLS_E_INTERNAL_ERROR;
844 : }
845 480 : BUFFER_POP(ps, info->hint, hint_size);
846 480 : if (hint_size == 0)
847 0 : info->hint[0] = 0;
848 :
849 480 : BUFFER_POP_NUM(ps, info->dh.secret_bits);
850 :
851 480 : BUFFER_POP_DATUM(ps, &info->dh.prime);
852 480 : BUFFER_POP_DATUM(ps, &info->dh.generator);
853 480 : BUFFER_POP_DATUM(ps, &info->dh.public_key);
854 :
855 480 : ret = 0;
856 :
857 480 : error:
858 480 : _gnutls_free_datum(&info->dh.prime);
859 480 : _gnutls_free_datum(&info->dh.generator);
860 480 : _gnutls_free_datum(&info->dh.public_key);
861 :
862 : return ret;
863 : }
864 : #endif
865 :
866 :
867 : /* Packs the security parameters.
868 : */
869 : static int
870 13473 : pack_security_parameters(gnutls_session_t session, gnutls_buffer_st * ps)
871 : {
872 :
873 13473 : int ret;
874 13473 : int size_offset;
875 13473 : size_t cur_size;
876 :
877 13473 : if (session->security_parameters.epoch_read
878 13473 : != session->security_parameters.epoch_write &&
879 6207 : !(session->internals.hsk_flags & HSK_EARLY_START_USED)) {
880 1 : gnutls_assert();
881 1 : return GNUTLS_E_UNAVAILABLE_DURING_HANDSHAKE;
882 : }
883 :
884 13472 : ret = _gnutls_epoch_get(session, EPOCH_READ_CURRENT, NULL);
885 13472 : if (ret < 0) {
886 0 : gnutls_assert();
887 0 : return ret;
888 : }
889 :
890 : /* move after the auth info stuff.
891 : */
892 13472 : size_offset = ps->length;
893 13472 : BUFFER_APPEND_NUM(ps, 0);
894 13472 : cur_size = ps->length;
895 :
896 13472 : BUFFER_APPEND_NUM(ps, session->security_parameters.entity);
897 13472 : BUFFER_APPEND_NUM(ps, session->security_parameters.prf->id);
898 :
899 13472 : BUFFER_APPEND_NUM(ps,
900 13472 : session->security_parameters.client_auth_type);
901 13472 : BUFFER_APPEND_NUM(ps,
902 13472 : session->security_parameters.server_auth_type);
903 :
904 13472 : BUFFER_APPEND(ps, &session->security_parameters.session_id_size,
905 13472 : 1);
906 13472 : BUFFER_APPEND(ps, session->security_parameters.session_id,
907 13472 : session->security_parameters.session_id_size);
908 :
909 13472 : BUFFER_APPEND_NUM(ps, session->security_parameters.pversion->id);
910 :
911 13472 : BUFFER_APPEND_NUM(ps, session->security_parameters.client_ctype);
912 13472 : BUFFER_APPEND_NUM(ps, session->security_parameters.server_ctype);
913 :
914 : /* if we are under TLS 1.3 do not pack keys or params negotiated using an extension
915 : * they are not necessary */
916 13472 : if (!session->security_parameters.pversion->tls13_sem) {
917 6565 : BUFFER_APPEND(ps, session->security_parameters.cs->id, 2);
918 :
919 6565 : BUFFER_APPEND_PFX1(ps, session->security_parameters.master_secret,
920 6565 : GNUTLS_MASTER_SIZE);
921 6565 : BUFFER_APPEND_PFX1(ps, session->security_parameters.client_random,
922 6565 : GNUTLS_RANDOM_SIZE);
923 6565 : BUFFER_APPEND_PFX1(ps, session->security_parameters.server_random,
924 6565 : GNUTLS_RANDOM_SIZE);
925 :
926 : /* reset max_record_recv_size if it was negotiated
927 : * using the record_size_limit extension */
928 6565 : if (session->internals.hsk_flags & HSK_RECORD_SIZE_LIMIT_NEGOTIATED) {
929 3910 : BUFFER_APPEND_NUM(ps,
930 : session->security_parameters.
931 3910 : max_user_record_send_size);
932 3910 : BUFFER_APPEND_NUM(ps,
933 : session->security_parameters.
934 : max_user_record_recv_size);
935 : } else {
936 2655 : BUFFER_APPEND_NUM(ps,
937 : session->security_parameters.
938 2655 : max_record_recv_size);
939 2655 : BUFFER_APPEND_NUM(ps,
940 : session->security_parameters.
941 6565 : max_record_send_size);
942 : }
943 :
944 6565 : if (session->security_parameters.grp) {
945 3012 : BUFFER_APPEND_NUM(ps, session->security_parameters.grp->id);
946 : } else {
947 3553 : BUFFER_APPEND_NUM(ps, 0);
948 : }
949 :
950 6565 : BUFFER_APPEND_NUM(ps,
951 6565 : session->security_parameters.server_sign_algo);
952 6565 : BUFFER_APPEND_NUM(ps,
953 6565 : session->security_parameters.client_sign_algo);
954 6565 : BUFFER_APPEND_NUM(ps,
955 6565 : session->security_parameters.ext_master_secret);
956 6565 : BUFFER_APPEND_NUM(ps,
957 13472 : session->security_parameters.etm);
958 : }
959 :
960 :
961 13472 : _gnutls_write_uint32(ps->length - cur_size,
962 13472 : ps->data + size_offset);
963 :
964 13472 : return 0;
965 : }
966 :
967 : static int
968 1570 : unpack_security_parameters(gnutls_session_t session, gnutls_buffer_st * ps)
969 : {
970 1570 : size_t pack_size;
971 1570 : int ret;
972 1570 : unsigned version;
973 1570 : gnutls_datum_t t;
974 1570 : time_t timestamp;
975 1570 : uint8_t cs[2];
976 :
977 1570 : BUFFER_POP_NUM(ps, pack_size);
978 :
979 1570 : if (pack_size == 0)
980 : return GNUTLS_E_INVALID_REQUEST;
981 :
982 1570 : timestamp =
983 : session->internals.resumed_security_parameters.timestamp;
984 1570 : memset(&session->internals.resumed_security_parameters, 0,
985 : sizeof(session->internals.resumed_security_parameters));
986 1570 : session->internals.resumed_security_parameters.timestamp =
987 : timestamp;
988 :
989 1570 : BUFFER_POP_NUM(ps,
990 : session->internals.resumed_security_parameters.
991 1570 : entity);
992 :
993 1570 : BUFFER_POP_NUM(ps, version);
994 1570 : session->internals.resumed_security_parameters.prf = mac_to_entry(version);
995 1570 : if (session->internals.resumed_security_parameters.prf == NULL)
996 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
997 :
998 1570 : BUFFER_POP_NUM(ps,
999 : session->internals.resumed_security_parameters.
1000 1570 : client_auth_type);
1001 1570 : BUFFER_POP_NUM(ps,
1002 : session->internals.resumed_security_parameters.
1003 1570 : server_auth_type);
1004 :
1005 1570 : BUFFER_POP(ps,
1006 : &session->internals.resumed_security_parameters.
1007 1570 : session_id_size, 1);
1008 :
1009 1570 : BUFFER_POP(ps,
1010 : session->internals.resumed_security_parameters.
1011 : session_id,
1012 : session->internals.resumed_security_parameters.
1013 1570 : session_id_size);
1014 :
1015 1570 : BUFFER_POP_NUM(ps, version);
1016 3140 : session->internals.resumed_security_parameters.pversion =
1017 1570 : version_to_entry(version);
1018 1570 : if (session->internals.resumed_security_parameters.pversion ==
1019 : NULL)
1020 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1021 :
1022 1570 : BUFFER_POP_NUM(ps,
1023 : session->internals.resumed_security_parameters.
1024 1570 : client_ctype);
1025 1570 : BUFFER_POP_NUM(ps,
1026 : session->internals.resumed_security_parameters.
1027 1570 : server_ctype);
1028 :
1029 1570 : if (!session->internals.resumed_security_parameters.pversion->tls13_sem) {
1030 1323 : BUFFER_POP(ps, cs, 2);
1031 1323 : session->internals.resumed_security_parameters.cs = ciphersuite_to_entry(cs);
1032 1323 : if (session->internals.resumed_security_parameters.cs == NULL)
1033 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1034 :
1035 : /* master secret */
1036 1323 : ret = _gnutls_buffer_pop_datum_prefix8(ps, &t);
1037 1323 : if (ret < 0) {
1038 0 : ret = GNUTLS_E_PARSING_ERROR;
1039 0 : gnutls_assert();
1040 0 : goto error;
1041 : }
1042 1323 : if (t.size == GNUTLS_MASTER_SIZE)
1043 1323 : memcpy(session->internals.resumed_security_parameters.master_secret, t.data, t.size);
1044 :
1045 : /* client random */
1046 1323 : ret = _gnutls_buffer_pop_datum_prefix8(ps, &t);
1047 1323 : if (ret < 0) {
1048 0 : ret = GNUTLS_E_PARSING_ERROR;
1049 0 : gnutls_assert();
1050 0 : goto error;
1051 : }
1052 1323 : if (t.size == GNUTLS_RANDOM_SIZE)
1053 1323 : memcpy(session->internals.resumed_security_parameters.client_random, t.data, t.size);
1054 :
1055 : /* server random */
1056 1323 : ret = _gnutls_buffer_pop_datum_prefix8(ps, &t);
1057 1323 : if (ret < 0) {
1058 0 : ret = GNUTLS_E_PARSING_ERROR;
1059 0 : gnutls_assert();
1060 0 : goto error;
1061 : }
1062 1323 : if (t.size == GNUTLS_RANDOM_SIZE)
1063 1323 : memcpy(session->internals.resumed_security_parameters.server_random, t.data, t.size);
1064 :
1065 :
1066 1323 : BUFFER_POP_NUM(ps,
1067 : session->internals.resumed_security_parameters.
1068 1323 : max_record_send_size);
1069 1323 : BUFFER_POP_NUM(ps,
1070 : session->internals.resumed_security_parameters.
1071 1323 : max_record_recv_size);
1072 :
1073 1323 : BUFFER_POP_NUM(ps, ret);
1074 1323 : session->internals.resumed_security_parameters.grp = _gnutls_id_to_group(ret);
1075 : /* it can be null */
1076 :
1077 1323 : BUFFER_POP_NUM(ps,
1078 : session->internals.resumed_security_parameters.
1079 1323 : server_sign_algo);
1080 1323 : BUFFER_POP_NUM(ps,
1081 : session->internals.resumed_security_parameters.
1082 1323 : client_sign_algo);
1083 1323 : BUFFER_POP_NUM(ps,
1084 : session->internals.resumed_security_parameters.
1085 1323 : ext_master_secret);
1086 1323 : BUFFER_POP_NUM(ps,
1087 : session->internals.resumed_security_parameters.
1088 1323 : etm);
1089 :
1090 1323 : if (session->internals.resumed_security_parameters.
1091 : max_record_recv_size == 0
1092 1323 : || session->internals.resumed_security_parameters.
1093 : max_record_send_size == 0) {
1094 0 : return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1095 : }
1096 : }
1097 :
1098 : ret = 0;
1099 :
1100 : error:
1101 : return ret;
1102 : }
1103 :
1104 : /**
1105 : * gnutls_session_set_premaster:
1106 : * @session: is a #gnutls_session_t type.
1107 : * @entity: GNUTLS_SERVER or GNUTLS_CLIENT
1108 : * @version: the TLS protocol version
1109 : * @kx: the key exchange method
1110 : * @cipher: the cipher
1111 : * @mac: the MAC algorithm
1112 : * @comp: the compression method (ignored)
1113 : * @master: the master key to use
1114 : * @session_id: the session identifier
1115 : *
1116 : * This function sets the premaster secret in a session. This is
1117 : * a function intended for exceptional uses. Do not use this
1118 : * function unless you are implementing a legacy protocol.
1119 : * Use gnutls_session_set_data() instead.
1120 : *
1121 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
1122 : * an error code is returned.
1123 : **/
1124 : int
1125 21 : gnutls_session_set_premaster(gnutls_session_t session, unsigned int entity,
1126 : gnutls_protocol_t version,
1127 : gnutls_kx_algorithm_t kx,
1128 : gnutls_cipher_algorithm_t cipher,
1129 : gnutls_mac_algorithm_t mac,
1130 : gnutls_compression_method_t comp,
1131 : const gnutls_datum_t * master,
1132 : const gnutls_datum_t * session_id)
1133 : {
1134 21 : int ret;
1135 21 : uint8_t cs[2];
1136 :
1137 21 : memset(&session->internals.resumed_security_parameters, 0,
1138 : sizeof(session->internals.resumed_security_parameters));
1139 :
1140 21 : session->internals.resumed_security_parameters.entity = entity;
1141 :
1142 21 : ret =
1143 21 : _gnutls_cipher_suite_get_id(kx, cipher, mac, cs);
1144 21 : if (ret < 0)
1145 0 : return gnutls_assert_val(ret);
1146 :
1147 21 : session->internals.resumed_security_parameters.cs = ciphersuite_to_entry(cs);
1148 21 : if (session->internals.resumed_security_parameters.cs == NULL)
1149 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1150 :
1151 21 : session->internals.resumed_security_parameters.client_ctype =
1152 : DEFAULT_CERT_TYPE;
1153 21 : session->internals.resumed_security_parameters.server_ctype =
1154 : DEFAULT_CERT_TYPE;
1155 42 : session->internals.resumed_security_parameters.pversion =
1156 21 : version_to_entry(version);
1157 21 : if (session->internals.resumed_security_parameters.pversion ==
1158 : NULL)
1159 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1160 :
1161 21 : if (session->internals.resumed_security_parameters.pversion->selectable_prf)
1162 14 : session->internals.resumed_security_parameters.prf = mac_to_entry(session->internals.resumed_security_parameters.cs->prf);
1163 : else
1164 7 : session->internals.resumed_security_parameters.prf = mac_to_entry(GNUTLS_MAC_MD5_SHA1);
1165 21 : if (session->internals.resumed_security_parameters.prf == NULL)
1166 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1167 :
1168 21 : if (master->size != GNUTLS_MASTER_SIZE)
1169 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1170 :
1171 21 : memcpy(session->internals.resumed_security_parameters.
1172 21 : master_secret, master->data, master->size);
1173 :
1174 21 : if (session_id->size > GNUTLS_MAX_SESSION_ID)
1175 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1176 :
1177 21 : session->internals.resumed_security_parameters.session_id_size =
1178 : session_id->size;
1179 21 : memcpy(session->internals.resumed_security_parameters.session_id,
1180 21 : session_id->data, session_id->size);
1181 :
1182 21 : session->internals.resumed_security_parameters.
1183 21 : max_record_send_size =
1184 : session->internals.resumed_security_parameters.
1185 21 : max_record_recv_size = DEFAULT_MAX_RECORD_SIZE;
1186 :
1187 42 : session->internals.resumed_security_parameters.timestamp =
1188 21 : gnutls_time(0);
1189 :
1190 21 : session->internals.resumed_security_parameters.grp = 0;
1191 :
1192 21 : session->internals.resumed_security_parameters.post_handshake_auth = 0;
1193 :
1194 21 : session->internals.premaster_set = 1;
1195 :
1196 21 : return 0;
1197 : }
|