Mercurial > hg > freeDiameter
diff freeDiameter/cnxctx.c @ 543:40141acabee7
Fix behavior of TLS/SCTP when only one peer does not accept the remote certificate
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Tue, 14 Sep 2010 13:31:27 +0900 |
parents | 0b6cee362f5d |
children | 88a494357a9d |
line wrap: on
line diff
--- a/freeDiameter/cnxctx.c Mon Sep 13 18:39:22 2010 +0900 +++ b/freeDiameter/cnxctx.c Tue Sep 14 13:31:27 2010 +0900 @@ -994,7 +994,7 @@ /* Verify remote credentials after successful handshake (return 0 if OK, EINVAL otherwise) */ int fd_tls_verify_credentials(gnutls_session_t session, struct cnxctx * conn, int verbose) { - int i; + int i, ret = 0; unsigned int gtret; const gnutls_datum_t *cert_list; unsigned int cert_list_size; @@ -1175,15 +1175,13 @@ CHECK_GNUTLS_DO( gnutls_x509_crt_init (&cert), return EINVAL); CHECK_GNUTLS_DO( gnutls_x509_crt_import (cert, &cert_list[i], GNUTLS_X509_FMT_DER), return EINVAL); - /* When gnutls 2.10.1 is around, we should use gnutls_certificate_set_verify_function */ - GNUTLS_TRACE( deadline = gnutls_x509_crt_get_expiration_time(cert) ); if ((deadline != (time_t)-1) && (deadline < now)) { if (TRACE_BOOL(INFO)) { fd_log_debug("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :\n", conn->cc_socket, conn->cc_remid, conn->cc_id); fd_log_debug(" - The certificate %d in the chain is expired\n", i); } - return EINVAL; + ret = EINVAL; } GNUTLS_TRACE( deadline = gnutls_x509_crt_get_activation_time(cert) ); @@ -1192,7 +1190,7 @@ fd_log_debug("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :\n", conn->cc_socket, conn->cc_remid, conn->cc_id); fd_log_debug(" - The certificate %d in the chain is not yet activated\n", i); } - return EINVAL; + ret = EINVAL; } if ((i == 0) && (conn->cc_tls_para.cn)) { @@ -1201,14 +1199,14 @@ fd_log_debug("TLS: Remote certificate invalid on socket %d (Remote: '%s')(Connection: '%s') :\n", conn->cc_socket, conn->cc_remid, conn->cc_id); fd_log_debug(" - The certificate hostname does not match '%s'\n", conn->cc_tls_para.cn); } - return EINVAL; + ret = EINVAL; } } GNUTLS_TRACE( gnutls_x509_crt_deinit (cert) ); } - return 0; + return ret; } /* TLS handshake a connection; no need to have called start_clear before. Reception is active if handhsake is successful */ @@ -1255,7 +1253,7 @@ { int ret; - /* When gnutls 2.10.1 is around, we should use gnutls_certificate_set_verify_function */ + /* When gnutls 2.10.1 is around, we should use gnutls_certificate_set_verify_function and fd_tls_verify_credentials, so that handshake fails directly. */ CHECK_GNUTLS_DO( ret = gnutls_handshake(conn->cc_tls_para.session), { @@ -1278,11 +1276,14 @@ /* Multi-stream TLS: handshake other streams as well */ if (conn->cc_sctp_para.pairs > 1) { #ifndef DISABLE_SCTP + /* Start reading the messages from the master session. That way, if the remote peer closed, we are not stuck inside handshake */ + CHECK_FCT(fd_sctps_startthreads(conn, 0)); + /* Resume all additional sessions from the master one. */ CHECK_FCT(fd_sctps_handshake_others(conn, priority, alt_creds)); /* Start decrypting the messages from all threads and queuing them in target queue */ - CHECK_FCT(fd_sctps_startthreads(conn)); + CHECK_FCT(fd_sctps_startthreads(conn, 1)); #endif /* DISABLE_SCTP */ } else { /* Start decrypting the data */