Line data Source code
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 :
55 9411 : int _gnutls_generate_master(gnutls_session_t session, int keep_premaster)
56 : {
57 9411 : if (session->internals.resumed == RESUME_FALSE)
58 8515 : return generate_normal_master(session, &session->key.key,
59 : keep_premaster);
60 896 : else if (session->internals.premaster_set) {
61 21 : gnutls_datum_t premaster;
62 21 : premaster.size =
63 : sizeof(session->internals.resumed_security_parameters.
64 : master_secret);
65 21 : premaster.data =
66 21 : session->internals.resumed_security_parameters.
67 : master_secret;
68 21 : 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
85 1 : gnutls_session_get_keylog_function(const gnutls_session_t session)
86 : {
87 1 : 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
101 23100 : gnutls_session_set_keylog_function(gnutls_session_t session,
102 : gnutls_keylog_func func)
103 : {
104 23100 : session->internals.keylog_func = func;
105 23100 : }
106 :
107 : int
108 41428 : _gnutls_call_keylog_func(gnutls_session_t session,
109 : const char *label,
110 : const uint8_t *data,
111 : unsigned size)
112 : {
113 41428 : if (session->internals.keylog_func) {
114 41428 : gnutls_datum_t secret = {(void*)data, size};
115 41428 : return session->internals.keylog_func(session, label, &secret);
116 : }
117 : return 0;
118 : }
119 :
120 : int
121 41418 : _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 41418 : if (!session->internals.handshake_in_progress)
129 : return 0;
130 :
131 41418 : _gnutls_nss_keylog_write(session, label, secret->data, secret->size);
132 41418 : return 0;
133 : }
134 :
135 41418 : void _gnutls_nss_keylog_write(gnutls_session_t session,
136 : const char *label,
137 : const uint8_t *secret, size_t secret_size)
138 : {
139 41418 : static const char *keylogfile = NULL;
140 41418 : static unsigned checked_env = 0;
141 :
142 41418 : if (!checked_env) {
143 1236 : checked_env = 1;
144 1236 : keylogfile = secure_getenv("SSLKEYLOGFILE");
145 1236 : if (keylogfile != NULL)
146 1 : keylog = fopen(keylogfile, "ae");
147 : }
148 :
149 41418 : if (keylog) {
150 12 : char client_random_hex[2*GNUTLS_RANDOM_SIZE+1];
151 12 : char secret_hex[2*MAX_HASH_SIZE+1];
152 :
153 12 : GNUTLS_STATIC_MUTEX_LOCK(keylog_mutex);
154 24 : fprintf(keylog, "%s %s %s\n",
155 : label,
156 12 : _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 12 : fflush(keylog);
163 12 : GNUTLS_STATIC_MUTEX_UNLOCK(keylog_mutex);
164 : }
165 41418 : }
166 :
167 2185 : void _gnutls_nss_keylog_deinit(void)
168 : {
169 2185 : if (keylog) {
170 1 : fclose(keylog);
171 1 : keylog = NULL;
172 : }
173 2185 : }
174 :
175 : /* here we generate the TLS Master secret.
176 : */
177 : static int
178 8536 : generate_normal_master(gnutls_session_t session,
179 : gnutls_datum_t * premaster, int keep_premaster)
180 : {
181 8536 : int ret = 0;
182 8536 : char buf[512];
183 :
184 8536 : _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 8536 : _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 8536 : _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 8536 : if (session->security_parameters.ext_master_secret == 0) {
199 3386 : uint8_t rnd[2 * GNUTLS_RANDOM_SIZE + 1];
200 3386 : memcpy(rnd, session->security_parameters.client_random,
201 : GNUTLS_RANDOM_SIZE);
202 3386 : memcpy(&rnd[GNUTLS_RANDOM_SIZE],
203 3386 : 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 3386 : ret =
218 3386 : _gnutls_PRF(session, premaster->data, premaster->size,
219 : MASTER_SECRET, MASTER_SECRET_SIZE,
220 : rnd, 2 * GNUTLS_RANDOM_SIZE,
221 : GNUTLS_MASTER_SIZE,
222 3386 : session->security_parameters.
223 : master_secret);
224 : } else {
225 5150 : gnutls_datum_t shash = {NULL, 0};
226 :
227 : /* draft-ietf-tls-session-hash-02 */
228 5150 : ret = _gnutls_handshake_get_session_hash(session, &shash);
229 5150 : if (ret < 0)
230 0 : 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 5150 : ret =
237 10300 : _gnutls_PRF(session, premaster->data, premaster->size,
238 : EXT_MASTER_SECRET, EXT_MASTER_SECRET_SIZE,
239 5150 : shash.data, shash.size,
240 : GNUTLS_MASTER_SIZE,
241 5150 : session->security_parameters.
242 : master_secret);
243 :
244 5150 : gnutls_free(shash.data);
245 : }
246 :
247 8536 : if (!keep_premaster)
248 8515 : _gnutls_free_temp_key_datum(premaster);
249 :
250 8536 : if (ret < 0)
251 : return ret;
252 :
253 17072 : ret = _gnutls_call_keylog_func(session, "CLIENT_RANDOM",
254 8536 : session->security_parameters.master_secret,
255 : GNUTLS_MASTER_SIZE);
256 8536 : if (ret < 0)
257 0 : return gnutls_assert_val(ret);
258 :
259 8536 : _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 : */
272 10019 : int _gnutls_send_server_kx_message(gnutls_session_t session, int again)
273 : {
274 10019 : gnutls_buffer_st buf;
275 10019 : int ret = 0;
276 10019 : mbuffer_st *bufel = NULL;
277 :
278 10019 : if (session->internals.auth_struct->gnutls_generate_server_kx ==
279 : NULL)
280 : return 0;
281 :
282 :
283 6381 : if (again == 0) {
284 12527 : ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
285 6381 : if (ret < 0)
286 0 : return gnutls_assert_val(ret);
287 :
288 6381 : ret =
289 6381 : session->internals.auth_struct->
290 : gnutls_generate_server_kx(session, &buf);
291 :
292 6381 : if (ret == GNUTLS_E_INT_RET_0) {
293 470 : gnutls_assert();
294 470 : ret = 0;
295 470 : goto cleanup;
296 : }
297 :
298 5911 : if (ret < 0) {
299 45 : gnutls_assert();
300 45 : goto cleanup;
301 : }
302 :
303 5866 : bufel = _gnutls_buffer_to_mbuffer(&buf);
304 : }
305 :
306 5866 : return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE);
307 :
308 515 : cleanup:
309 515 : _gnutls_buffer_clear(&buf);
310 515 : return ret;
311 : }
312 :
313 : /* This function sends a certificate request message to the
314 : * client.
315 : */
316 9974 : int _gnutls_send_server_crt_request(gnutls_session_t session, int again)
317 : {
318 9974 : gnutls_buffer_st buf;
319 9974 : int ret = 0;
320 9974 : mbuffer_st *bufel = NULL;
321 :
322 9974 : if (session->internals.auth_struct->
323 : gnutls_generate_server_crt_request == NULL)
324 : return 0;
325 :
326 7127 : if (session->internals.send_cert_req <= 0)
327 : return 0;
328 :
329 :
330 2708 : if (again == 0) {
331 5348 : ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
332 2708 : if (ret < 0)
333 0 : return gnutls_assert_val(ret);
334 :
335 2708 : ret =
336 2708 : session->internals.auth_struct->
337 : gnutls_generate_server_crt_request(session, &buf);
338 :
339 2708 : if (ret < 0) {
340 0 : gnutls_assert();
341 0 : goto cleanup;
342 : }
343 :
344 2708 : bufel = _gnutls_buffer_to_mbuffer(&buf);
345 : }
346 :
347 2708 : return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST);
348 :
349 0 : cleanup:
350 0 : _gnutls_buffer_clear(&buf);
351 0 : return ret;
352 : }
353 :
354 :
355 : /* This is the function for the client to send the key
356 : * exchange message
357 : */
358 1480 : int _gnutls_send_client_kx_message(gnutls_session_t session, int again)
359 : {
360 1480 : gnutls_buffer_st buf;
361 1480 : int ret = 0;
362 1480 : mbuffer_st *bufel = NULL;
363 :
364 1480 : if (session->internals.auth_struct->gnutls_generate_client_kx ==
365 : NULL)
366 : return 0;
367 :
368 1480 : if (again == 0) {
369 2693 : ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
370 1480 : if (ret < 0)
371 0 : return gnutls_assert_val(ret);
372 :
373 1480 : ret =
374 1480 : session->internals.auth_struct->
375 : gnutls_generate_client_kx(session, &buf);
376 1480 : if (ret < 0) {
377 7 : gnutls_assert();
378 7 : goto cleanup;
379 : }
380 :
381 1473 : bufel = _gnutls_buffer_to_mbuffer(&buf);
382 : }
383 :
384 1473 : return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE);
385 :
386 7 : cleanup:
387 7 : _gnutls_buffer_clear(&buf);
388 7 : return ret;
389 : }
390 :
391 :
392 : /* This is the function for the client to send the certificate
393 : * verify message
394 : */
395 : int
396 1473 : _gnutls_send_client_certificate_verify(gnutls_session_t session, int again)
397 : {
398 1473 : gnutls_buffer_st buf;
399 1473 : int ret = 0;
400 1473 : mbuffer_st *bufel = NULL;
401 :
402 : /* This is a packet that is only sent by the client
403 : */
404 1473 : if (session->security_parameters.entity == GNUTLS_SERVER)
405 : return 0;
406 :
407 : /* if certificate verify is not needed just exit
408 : */
409 1473 : if (!(session->internals.hsk_flags & HSK_CRT_ASKED))
410 : return 0;
411 :
412 :
413 396 : if (session->internals.auth_struct->
414 : gnutls_generate_client_crt_vrfy == NULL) {
415 0 : gnutls_assert();
416 0 : return 0; /* this algorithm does not support cli_crt_vrfy
417 : */
418 : }
419 :
420 396 : if (again == 0) {
421 748 : ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
422 396 : if (ret < 0)
423 0 : return gnutls_assert_val(ret);
424 :
425 396 : ret =
426 396 : session->internals.auth_struct->
427 : gnutls_generate_client_crt_vrfy(session, &buf);
428 396 : if (ret < 0) {
429 3 : gnutls_assert();
430 3 : goto cleanup;
431 : }
432 :
433 393 : if (ret == 0)
434 265 : goto cleanup;
435 :
436 :
437 128 : bufel = _gnutls_buffer_to_mbuffer(&buf);
438 : }
439 :
440 128 : return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY);
441 :
442 268 : cleanup:
443 268 : _gnutls_buffer_clear(&buf);
444 268 : return ret;
445 : }
446 :
447 : /* This is called when we want send our certificate
448 : */
449 1480 : int _gnutls_send_client_certificate(gnutls_session_t session, int again)
450 : {
451 1480 : gnutls_buffer_st buf;
452 1480 : int ret = 0;
453 1480 : mbuffer_st *bufel = NULL;
454 :
455 1480 : if (!(session->internals.hsk_flags & HSK_CRT_ASKED))
456 : return 0;
457 :
458 396 : if (session->internals.auth_struct->
459 : gnutls_generate_client_certificate == NULL)
460 : return 0;
461 :
462 396 : if (again == 0) {
463 748 : ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
464 396 : if (ret < 0)
465 0 : 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 396 : ret =
475 396 : session->internals.auth_struct->
476 : gnutls_generate_client_certificate(session,
477 : &buf);
478 :
479 396 : if (ret < 0) {
480 0 : gnutls_assert();
481 0 : goto cleanup;
482 : }
483 : }
484 :
485 396 : 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 396 : return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
504 :
505 0 : cleanup:
506 0 : _gnutls_buffer_clear(&buf);
507 0 : return ret;
508 : }
509 :
510 :
511 : /* This is called when we want send our certificate
512 : */
513 10019 : int _gnutls_send_server_certificate(gnutls_session_t session, int again)
514 : {
515 10019 : gnutls_buffer_st buf;
516 10019 : int ret = 0;
517 10019 : mbuffer_st *bufel = NULL;
518 :
519 10019 : if (session->internals.auth_struct->
520 : gnutls_generate_server_certificate == NULL)
521 : return 0;
522 :
523 7309 : if (again == 0) {
524 14415 : ret = _gnutls_buffer_init_handshake_mbuffer(&buf);
525 7309 : if (ret < 0)
526 0 : return gnutls_assert_val(ret);
527 :
528 7309 : ret =
529 7309 : session->internals.auth_struct->
530 : gnutls_generate_server_certificate(session, &buf);
531 :
532 7309 : if (ret < 0) {
533 0 : gnutls_assert();
534 0 : goto cleanup;
535 : }
536 :
537 7309 : bufel = _gnutls_buffer_to_mbuffer(&buf);
538 : }
539 :
540 7309 : return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
541 :
542 0 : cleanup:
543 0 : _gnutls_buffer_clear(&buf);
544 0 : return ret;
545 : }
546 :
547 :
548 6981440 : int _gnutls_recv_server_kx_message(gnutls_session_t session)
549 : {
550 6981440 : gnutls_buffer_st buf;
551 6981440 : int ret = 0;
552 6981440 : unsigned int optflag = 0;
553 :
554 6981440 : if (session->internals.auth_struct->gnutls_process_server_kx !=
555 : NULL) {
556 : /* Server key exchange packet is optional for PSK. */
557 6981150 : if (_gnutls_session_is_psk(session))
558 150 : optflag = 1;
559 :
560 6981150 : ret =
561 6981150 : _gnutls_recv_handshake(session,
562 : GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE,
563 : optflag, &buf);
564 6981150 : if (ret < 0) {
565 6979800 : gnutls_assert();
566 6979800 : return ret;
567 : }
568 :
569 1346 : ret =
570 1346 : session->internals.auth_struct->
571 : gnutls_process_server_kx(session, buf.data,
572 : buf.length);
573 1346 : _gnutls_buffer_clear(&buf);
574 :
575 1346 : if (ret < 0) {
576 88 : gnutls_assert();
577 88 : return ret;
578 : }
579 :
580 : }
581 : return ret;
582 : }
583 :
584 1821 : int _gnutls_recv_server_crt_request(gnutls_session_t session)
585 : {
586 1821 : gnutls_buffer_st buf;
587 1821 : int ret = 0;
588 :
589 1821 : if (session->internals.auth_struct->
590 : gnutls_process_server_crt_request != NULL) {
591 :
592 1357 : ret =
593 1357 : _gnutls_recv_handshake(session,
594 : GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST,
595 : 1, &buf);
596 1357 : if (ret < 0)
597 : return ret;
598 :
599 1079 : if (ret == 0 && buf.length == 0) {
600 655 : _gnutls_buffer_clear(&buf);
601 655 : return 0; /* ignored */
602 : }
603 :
604 424 : ret =
605 424 : session->internals.auth_struct->
606 : gnutls_process_server_crt_request(session, buf.data,
607 : buf.length);
608 424 : _gnutls_buffer_clear(&buf);
609 424 : if (ret < 0)
610 : return ret;
611 :
612 : }
613 : return ret;
614 : }
615 :
616 11119 : int _gnutls_recv_client_kx_message(gnutls_session_t session)
617 : {
618 11119 : gnutls_buffer_st buf;
619 11119 : int ret = 0;
620 :
621 :
622 : /* Do key exchange only if the algorithm permits it */
623 11119 : if (session->internals.auth_struct->gnutls_process_client_kx !=
624 : NULL) {
625 :
626 11119 : ret =
627 11119 : _gnutls_recv_handshake(session,
628 : GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE,
629 : 0, &buf);
630 11119 : if (ret < 0)
631 : return ret;
632 :
633 7762 : ret =
634 7762 : session->internals.auth_struct->
635 : gnutls_process_client_kx(session, buf.data,
636 : buf.length);
637 7762 : _gnutls_buffer_clear(&buf);
638 7762 : if (ret < 0)
639 : return ret;
640 :
641 : }
642 :
643 : return ret;
644 : }
645 :
646 :
647 10045 : int _gnutls_recv_client_certificate(gnutls_session_t session)
648 : {
649 10045 : gnutls_buffer_st buf;
650 10045 : int ret = 0;
651 10045 : int optional;
652 :
653 10045 : 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 7199 : if (session->internals.send_cert_req == 0) {
660 : return 0;
661 : }
662 :
663 2780 : if (session->internals.send_cert_req == GNUTLS_CERT_REQUIRE)
664 : optional = 0;
665 : else
666 2679 : optional = 1;
667 :
668 2780 : ret =
669 2780 : _gnutls_recv_handshake(session,
670 : GNUTLS_HANDSHAKE_CERTIFICATE_PKT,
671 : optional, &buf);
672 :
673 2780 : 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 83 : if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED
696 83 : || ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
697 5 : && optional == 0) {
698 0 : gnutls_assert();
699 0 : return GNUTLS_E_NO_CERTIFICATE_FOUND;
700 : }
701 :
702 : return ret;
703 : }
704 :
705 2697 : 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 0 : gnutls_assert();
711 0 : ret = 0;
712 0 : goto cleanup;
713 : }
714 2697 : ret =
715 2697 : session->internals.auth_struct->
716 : gnutls_process_client_certificate(session, buf.data,
717 : buf.length);
718 :
719 2697 : if (ret < 0 && ret != GNUTLS_E_NO_CERTIFICATE_FOUND) {
720 1643 : gnutls_assert();
721 1643 : goto cleanup;
722 : }
723 :
724 : /* ok we should expect a certificate verify message now
725 : */
726 1054 : if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND && optional != 0)
727 : ret = 0;
728 : else
729 768 : session->internals.hsk_flags |= HSK_CRT_VRFY_EXPECTED;
730 :
731 2697 : cleanup:
732 2697 : _gnutls_buffer_clear(&buf);
733 2697 : return ret;
734 : }
735 :
736 3107 : int _gnutls_recv_server_certificate(gnutls_session_t session)
737 : {
738 3107 : gnutls_buffer_st buf;
739 3107 : int ret = 0;
740 :
741 3107 : if (session->internals.auth_struct->
742 : gnutls_process_server_certificate != NULL) {
743 :
744 2597 : ret =
745 2597 : _gnutls_recv_handshake(session,
746 : GNUTLS_HANDSHAKE_CERTIFICATE_PKT,
747 : 0, &buf);
748 2597 : if (ret < 0) {
749 1121 : gnutls_assert();
750 1121 : return ret;
751 : }
752 :
753 1476 : ret =
754 1476 : session->internals.auth_struct->
755 : gnutls_process_server_certificate(session, buf.data,
756 : buf.length);
757 1476 : _gnutls_buffer_clear(&buf);
758 1476 : if (ret < 0) {
759 269 : gnutls_assert();
760 269 : 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
772 7602 : _gnutls_recv_client_certificate_verify_message(gnutls_session_t session)
773 : {
774 7602 : gnutls_buffer_st buf;
775 7602 : int ret = 0;
776 :
777 :
778 7602 : if (session->internals.auth_struct->
779 : gnutls_process_client_crt_vrfy == NULL)
780 : return 0;
781 :
782 5135 : if (session->internals.send_cert_req == 0 ||
783 1035 : (!(session->internals.hsk_flags & HSK_CRT_VRFY_EXPECTED))) {
784 : return 0;
785 : }
786 :
787 750 : ret =
788 750 : _gnutls_recv_handshake(session,
789 : GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY,
790 : 1, &buf);
791 750 : if (ret < 0)
792 : return ret;
793 :
794 750 : if (ret == 0 && buf.length == 0
795 1 : && session->internals.send_cert_req == GNUTLS_CERT_REQUIRE) {
796 : /* certificate was required */
797 0 : gnutls_assert();
798 0 : ret = GNUTLS_E_NO_CERTIFICATE_FOUND;
799 0 : goto cleanup;
800 : }
801 :
802 750 : ret =
803 750 : session->internals.auth_struct->
804 : gnutls_process_client_crt_vrfy(session, buf.data, buf.length);
805 :
806 750 : cleanup:
807 750 : _gnutls_buffer_clear(&buf);
808 750 : return ret;
809 : }
|