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
23/* This file contains functions which are wrappers for the key exchange
24 * part of TLS. They are called by the handshake functions (gnutls_handshake)
25 */
26
27#include "gnutls_int.h"
28#include "gnutls_handshake.h"
29#include "gnutls_kx.h"
30#include "gnutls_dh.h"
31#include "gnutls_errors.h"
32#include "algorithms.h"
33#include "debug.h"
34#include "gnutls_mpi.h"
35#include <gnutls_state.h>
36#include <gnutls_datum.h>
37#include <gnutls_mbuffers.h>
38
39/* This is a temporary function to be used before the generate_*
40 internal API is changed to use mbuffers. For now we don't avoid the
41 extra alloc + memcpy. */
42static inline int
43send_handshake (gnutls_session_t session, uint8_t * data, size_t size,
44 gnutls_handshake_description_t type)
45{
46 mbuffer_st *bufel;
47
48 if (data == NULL && size == 0)
49 return _gnutls_send_handshake (session, NULL, type);
50
51 if (data == NULL && size > 0)
52 {
53 gnutls_assert ();
54 return GNUTLS_E_INVALID_REQUEST;
55 }
56
57 bufel = _gnutls_handshake_alloc(session, size, size);
58 if (bufel == NULL)
59 {
60 gnutls_assert ();
61 return GNUTLS_E_MEMORY_ERROR;
62 }
63
64 _mbuffer_set_udata (bufel, data, size);
65
66 return _gnutls_send_handshake (session, bufel, type);
67}
68
69
70/* This file contains important thing for the TLS handshake procedure.
71 */
72
73#define MASTER_SECRET "master secret"
74#define MASTER_SECRET_SIZE (sizeof(MASTER_SECRET)-1)
75static int generate_normal_master (gnutls_session_t session, gnutls_datum_t*, int);
76
77int
78_gnutls_generate_master (gnutls_session_t session, int keep_premaster)
79{
80 if (session->internals.resumed == RESUME_FALSE)
81 return generate_normal_master (session, &session->key.key, keep_premaster);
82 else if (session->internals.premaster_set)
83 {
84 gnutls_datum_t premaster;
85 premaster.size = sizeof(session->internals.resumed_security_parameters.master_secret);
86 premaster.data = session->internals.resumed_security_parameters.master_secret;
87 return generate_normal_master(session, &premaster, 1);
88 }
89 return 0;
90}
91
92/* here we generate the TLS Master secret.
93 */
94static int
95generate_normal_master (gnutls_session_t session, gnutls_datum_t *premaster,
96 int keep_premaster)
97{
98 int ret = 0;
99 char buf[512];
100
101 _gnutls_hard_log ("INT: PREMASTER SECRET[%d]: %s\n", premaster->size,
102 _gnutls_bin2hex (premaster->data, premaster->size, buf,
103 sizeof (buf), NULL));
104 _gnutls_hard_log ("INT: CLIENT RANDOM[%d]: %s\n", 32,
105 _gnutls_bin2hex (session->
106 security_parameters.client_random, 32,
107 buf, sizeof (buf), NULL));
108 _gnutls_hard_log ("INT: SERVER RANDOM[%d]: %s\n", 32,
109 _gnutls_bin2hex (session->
110 security_parameters.server_random, 32,
111 buf, sizeof (buf), NULL));
112
113 if (get_num_version (session) == GNUTLS_SSL3)
114 {
115 uint8_t rnd[2 * GNUTLS_RANDOM_SIZE + 1];
116
117 memcpy (rnd, session->security_parameters.client_random,
118 GNUTLS_RANDOM_SIZE);
119 memcpy (&rnd[GNUTLS_RANDOM_SIZE],
120 session->security_parameters.server_random, GNUTLS_RANDOM_SIZE);
121
122 ret =
123 _gnutls_ssl3_generate_random (premaster->data, premaster->size,
124 rnd, 2 * GNUTLS_RANDOM_SIZE,
125 GNUTLS_MASTER_SIZE,
126 session->
127 security_parameters.master_secret);
128
129 }
130 else
131 {
132 uint8_t rnd[2 * GNUTLS_RANDOM_SIZE + 1];
133
134 memcpy (rnd, session->security_parameters.client_random,
135 GNUTLS_RANDOM_SIZE);
136 memcpy (&rnd[GNUTLS_RANDOM_SIZE],
137 session->security_parameters.server_random, GNUTLS_RANDOM_SIZE);
138
139 ret =
140 _gnutls_PRF (session, premaster->data, premaster->size,
141 MASTER_SECRET, MASTER_SECRET_SIZE,
142 rnd, 2 * GNUTLS_RANDOM_SIZE, GNUTLS_MASTER_SIZE,
143 session->security_parameters.master_secret);
144 }
145
146 if (!keep_premaster)
147 _gnutls_free_datum (premaster);
148
149 if (ret < 0)
150 return ret;
151
152 _gnutls_hard_log ("INT: MASTER SECRET: %s\n",
153 _gnutls_bin2hex (session->
154 security_parameters.master_secret,
155 GNUTLS_MASTER_SIZE, buf, sizeof (buf),
156 NULL));
157
158 return ret;
159}
160
161
162/* This is called when we want to receive the key exchange message of the
163 * server. It does nothing if this type of message is not required
164 * by the selected ciphersuite.
165 */
166int
167_gnutls_send_server_kx_message (gnutls_session_t session, int again)
168{
169 gnutls_buffer_st data;
170 int ret = 0;
171
172 if (session->internals.auth_struct->gnutls_generate_server_kx == NULL)
173 return 0;
174
175 _gnutls_buffer_init( &data);
176
177 if (again == 0)
178 {
179 ret =
180 session->internals.auth_struct->gnutls_generate_server_kx (session,
181 &data);
182
183 if (ret == GNUTLS_E_INT_RET_0)
184 {
185 gnutls_assert ();
186 ret = 0;
187 goto cleanup;
188 }
189
190 if (ret < 0)
191 {
192 gnutls_assert ();
193 goto cleanup;
194 }
195 }
196
197 ret = send_handshake (session, data.data, data.length,
198 GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE);
199 if (ret < 0)
200 {
201 gnutls_assert ();
202 }
203
204cleanup:
205 _gnutls_buffer_clear (&data);
206 return ret;
207}
208
209/* This function sends a certificate request message to the
210 * client.
211 */
212int
213_gnutls_send_server_crt_request (gnutls_session_t session, int again)
214{
215 gnutls_buffer_st data;
216 int ret = 0;
217
218 if (session->internals.
219 auth_struct->gnutls_generate_server_crt_request == NULL)
220 return 0;
221
222 if (session->internals.send_cert_req <= 0)
223 return 0;
224
225 _gnutls_buffer_init( &data);
226
227 if (again == 0)
228 {
229 ret =
230 session->internals.
231 auth_struct->gnutls_generate_server_crt_request (session,
232 &data);
233
234 if (ret < 0)
235 {
236 gnutls_assert ();
237 goto cleanup;
238 }
239 }
240
241 ret = send_handshake (session, data.data, data.length,
242 GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST);
243 if (ret < 0)
244 {
245 gnutls_assert ();
246 }
247
248cleanup:
249 _gnutls_buffer_clear (&data);
250 return ret;
251}
252
253
254/* This is the function for the client to send the key
255 * exchange message
256 */
257int
258_gnutls_send_client_kx_message (gnutls_session_t session, int again)
259{
260 gnutls_buffer_st data;
261 int ret = 0;
262
263 if (session->internals.auth_struct->gnutls_generate_client_kx == NULL)
264 return 0;
265
266 _gnutls_buffer_init( &data);
267
268 if (again == 0)
269 {
270 ret =
271 session->internals.auth_struct->gnutls_generate_client_kx (session,
272 &data);
273 if (ret < 0)
274 {
275 gnutls_assert();
276 goto cleanup;
277 }
278 }
279 ret = send_handshake (session, data.data, data.length,
280 GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE);
281 if (ret < 0)
282 {
283 gnutls_assert ();
284 }
285
286cleanup:
287 _gnutls_buffer_clear (&data);
288 return ret;
289}
290
291
292/* This is the function for the client to send the certificate
293 * verify message
294 */
295int
296_gnutls_send_client_certificate_verify (gnutls_session_t session, int again)
297{
298 gnutls_buffer_st data;
299 int ret = 0;
300
301 /* This is a packet that is only sent by the client
302 */
303 if (session->security_parameters.entity == GNUTLS_SERVER)
304 return 0;
305
306 /* if certificate verify is not needed just exit
307 */
308 if (session->key.crt_requested == 0)
309 return 0;
310
311
312 if (session->internals.auth_struct->gnutls_generate_client_crt_vrfy ==
313 NULL)
314 {
315 gnutls_assert ();
316 return 0; /* this algorithm does not support cli_crt_vrfy
317 */
318 }
319
320 _gnutls_buffer_init( &data);
321
322 if (again == 0)
323 {
324 ret =
325 session->internals.
326 auth_struct->gnutls_generate_client_crt_vrfy (session, &data);
327 if (ret < 0)
328 {
329 gnutls_assert();
330 goto cleanup;
331 }
332
333 if (ret == 0)
334 goto cleanup;
335
336 }
337 ret = send_handshake (session, data.data, data.length,
338 GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY);
339
340 if (ret < 0)
341 {
342 gnutls_assert ();
343 }
344
345cleanup:
346 _gnutls_buffer_clear (&data);
347 return ret;
348}
349
350/* This is called when we want send our certificate
351 */
352int
353_gnutls_send_client_certificate (gnutls_session_t session, int again)
354{
355 gnutls_buffer_st data;
356 int ret = 0;
357
358
359 if (session->key.crt_requested == 0)
360 return 0;
361
362 if (session->internals.auth_struct->gnutls_generate_client_certificate ==
363 NULL)
364 return 0;
365
366 _gnutls_buffer_init( &data);
367
368 if (again == 0)
369 {
370 if (get_num_version (session) != GNUTLS_SSL3 ||
371 session->internals.selected_cert_list_length > 0)
372 {
373 /* TLS 1.0 or SSL 3.0 with a valid certificate
374 */
375 ret =
376 session->internals.
377 auth_struct->gnutls_generate_client_certificate (session, &data);
378
379 if (ret < 0)
380 {
381 gnutls_assert();
382 goto cleanup;
383 }
384 }
385 }
386
387 /* In the SSL 3.0 protocol we need to send a
388 * no certificate alert instead of an
389 * empty certificate.
390 */
391 if (get_num_version (session) == GNUTLS_SSL3 &&
392 session->internals.selected_cert_list_length == 0)
393 {
394 ret =
395 gnutls_alert_send (session, GNUTLS_AL_WARNING,
396 GNUTLS_A_SSL3_NO_CERTIFICATE);
397
398 }
399 else
400 { /* TLS 1.0 or SSL 3.0 with a valid certificate
401 */
402 ret = send_handshake (session, data.data, data.length,
403 GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
404 }
405
406cleanup:
407 _gnutls_buffer_clear (&data);
408 return ret;
409}
410
411
412/* This is called when we want send our certificate
413 */
414int
415_gnutls_send_server_certificate (gnutls_session_t session, int again)
416{
417 gnutls_buffer_st data;
418 int ret = 0;
419
420
421 if (session->internals.auth_struct->gnutls_generate_server_certificate ==
422 NULL)
423 return 0;
424
425 _gnutls_buffer_init( &data);
426
427 if (again == 0)
428 {
429 ret =
430 session->internals.
431 auth_struct->gnutls_generate_server_certificate (session, &data);
432
433 if (ret < 0)
434 {
435 gnutls_assert();
436 goto cleanup;
437 }
438 }
439 ret = send_handshake (session, data.data, data.length,
440 GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
441 if (ret < 0)
442 {
443 gnutls_assert ();
444 }
445
446cleanup:
447 _gnutls_buffer_clear (&data);
448 return ret;
449}
450
451
452int
453_gnutls_recv_server_kx_message (gnutls_session_t session)
454{
455 gnutls_buffer_st buf;
456 int ret = 0;
457 unsigned int optflag = 0;
458
459 if (session->internals.auth_struct->gnutls_process_server_kx != NULL)
460 {
461 /* Server key exchange packet is optional for PSK. */
462 if (_gnutls_session_is_psk (session))
463 optflag = 1;
464
465 ret =
466 _gnutls_recv_handshake (session,
467 GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE,
468 optflag, &buf);
469 if (ret < 0)
470 {
471 gnutls_assert ();
472 return ret;
473 }
474
475 ret =
476 session->internals.auth_struct->gnutls_process_server_kx (session,
477 buf.data,
478 buf.length);
479 _gnutls_buffer_clear(&buf);
480
481 if (ret < 0)
482 {
483 gnutls_assert ();
484 return ret;
485 }
486
487 }
488 return ret;
489}
490
491int
492_gnutls_recv_server_crt_request (gnutls_session_t session)
493{
494 gnutls_buffer_st buf;
495 int ret = 0;
496
497 if (session->internals.
498 auth_struct->gnutls_process_server_crt_request != NULL)
499 {
500
501 ret =
502 _gnutls_recv_handshake (session,
503 GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST,
504 1, &buf);
505 if (ret < 0)
506 return ret;
507
508 if (ret == 0 && buf.length == 0)
509 {
510 _gnutls_buffer_clear(&buf);
511 return 0; /* ignored */
512 }
513
514 ret =
515 session->internals.
516 auth_struct->gnutls_process_server_crt_request (session, buf.data,
517 buf.length);
518 _gnutls_buffer_clear (&buf);
519 if (ret < 0)
520 return ret;
521
522 }
523 return ret;
524}
525
526int
527_gnutls_recv_client_kx_message (gnutls_session_t session)
528{
529 gnutls_buffer_st buf;
530 int ret = 0;
531
532
533 /* Do key exchange only if the algorithm permits it */
534 if (session->internals.auth_struct->gnutls_process_client_kx != NULL)
535 {
536
537 ret =
538 _gnutls_recv_handshake (session,
539 GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE,
540 0, &buf);
541 if (ret < 0)
542 return ret;
543
544 ret =
545 session->internals.auth_struct->gnutls_process_client_kx (session,
546 buf.data,
547 buf.length);
548 _gnutls_buffer_clear (&buf);
549 if (ret < 0)
550 return ret;
551
552 }
553
554 return ret;
555}
556
557
558int
559_gnutls_recv_client_certificate (gnutls_session_t session)
560{
561 gnutls_buffer_st buf;
562 int ret = 0;
563 int optional;
564
565 if (session->internals.auth_struct->gnutls_process_client_certificate ==
566 NULL)
567 return 0;
568
569 /* if we have not requested a certificate then just return
570 */
571 if (session->internals.send_cert_req == 0)
572 {
573 return 0;
574 }
575
576 if (session->internals.send_cert_req == GNUTLS_CERT_REQUIRE)
577 optional = 0;
578 else
579 optional = 1;
580
581 ret =
582 _gnutls_recv_handshake (session, GNUTLS_HANDSHAKE_CERTIFICATE_PKT,
583 optional, &buf);
584
585 if (ret < 0)
586 {
587 /* Handle the case of old SSL3 clients who send
588 * a warning alert instead of an empty certificate to indicate
589 * no certificate.
590 */
591 if (optional != 0 &&
592 ret == GNUTLS_E_WARNING_ALERT_RECEIVED &&
593 get_num_version (session) == GNUTLS_SSL3 &&
594 gnutls_alert_get (session) == GNUTLS_A_SSL3_NO_CERTIFICATE)
595 {
596
597 /* SSL3 does not send an empty certificate,
598 * but this alert. So we just ignore it.
599 */
600 gnutls_assert ();
601 return 0;
602 }
603
604 /* certificate was required
605 */
606 if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED
607 || ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
608 && optional == 0)
609 {
610 gnutls_assert ();
611 return GNUTLS_E_NO_CERTIFICATE_FOUND;
612 }
613
614 return ret;
615 }
616
617 if (ret == 0 && buf.length == 0 && optional != 0)
618 {
619 /* Client has not sent the certificate message.
620 * well I'm not sure we should accept this
621 * behaviour.
622 */
623 gnutls_assert ();
624 ret = 0;
625 goto cleanup;
626 }
627 ret =
628 session->internals.
629 auth_struct->gnutls_process_client_certificate (session, buf.data,
630 buf.length);
631
632 if (ret < 0 && ret != GNUTLS_E_NO_CERTIFICATE_FOUND)
633 {
634 gnutls_assert ();
635 goto cleanup;
636 }
637
638 /* ok we should expect a certificate verify message now
639 */
640 if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND && optional != 0)
641 ret = 0;
642 else
643 session->key.crt_requested = 1;
644
645cleanup:
646 _gnutls_buffer_clear(&buf);
647 return ret;
648}
649
650int
651_gnutls_recv_server_certificate (gnutls_session_t session)
652{
653 gnutls_buffer_st buf;
654 int ret = 0;
655
656 if (session->internals.auth_struct->gnutls_process_server_certificate !=
657 NULL)
658 {
659
660 ret =
661 _gnutls_recv_handshake (session,
662 GNUTLS_HANDSHAKE_CERTIFICATE_PKT,
663 0, &buf);
664 if (ret < 0)
665 {
666 gnutls_assert ();
667 return ret;
668 }
669
670 ret =
671 session->internals.
672 auth_struct->gnutls_process_server_certificate (session, buf.data,
673 buf.length);
674 _gnutls_buffer_clear(&buf);
675 if (ret < 0)
676 {
677 gnutls_assert ();
678 return ret;
679 }
680 }
681
682 return ret;
683}
684
685
686/* Recv the client certificate verify. This packet may not
687 * arrive if the peer did not send us a certificate.
688 */
689int
690_gnutls_recv_client_certificate_verify_message (gnutls_session_t session)
691{
692 gnutls_buffer_st buf;
693 int ret = 0;
694
695
696 if (session->internals.auth_struct->gnutls_process_client_crt_vrfy == NULL)
697 return 0;
698
699 if (session->internals.send_cert_req == 0 ||
700 session->key.crt_requested == 0)
701 {
702 return 0;
703 }
704
705 ret =
706 _gnutls_recv_handshake (session,
707 GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY,
708 1, &buf);
709 if (ret < 0)
710 return ret;
711
712 if (ret == 0 && buf.length == 0
713 && session->internals.send_cert_req == GNUTLS_CERT_REQUIRE)
714 {
715 /* certificate was required */
716 gnutls_assert ();
717 ret = GNUTLS_E_NO_CERTIFICATE_FOUND;
718 goto cleanup;
719 }
720
721 ret =
722 session->internals.
723 auth_struct->gnutls_process_client_crt_vrfy (session, buf.data,
724 buf.length);
725
726cleanup:
727 _gnutls_buffer_clear(&buf);
728 return ret;
729}
730