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