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