[asterisk-commits] file: branch file/sha256-a-harsh-reality r417585 - /team/file/sha256-a-harsh-...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Jun 28 16:50:13 CDT 2014


Author: file
Date: Sat Jun 28 16:50:01 2014
New Revision: 417585

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=417585
Log:
Commonify some logic.

Modified:
    team/file/sha256-a-harsh-reality/res/res_rtp_asterisk.c

Modified: team/file/sha256-a-harsh-reality/res/res_rtp_asterisk.c
URL: http://svnview.digium.com/svn/asterisk/team/file/sha256-a-harsh-reality/res/res_rtp_asterisk.c?view=diff&rev=417585&r1=417584&r2=417585
==============================================================================
--- team/file/sha256-a-harsh-reality/res/res_rtp_asterisk.c (original)
+++ team/file/sha256-a-harsh-reality/res/res_rtp_asterisk.c Sat Jun 28 16:50:01 2014
@@ -183,6 +183,16 @@
 	int max_seq;	/*!< The highest sequence number received */
 	int packets;	/*!< The number of remaining packets before the source is accepted */
 };
+
+#ifdef HAVE_OPENSSL_SRTP
+struct dtls_details {
+	SSL *ssl;         /*!< SSL session */
+	BIO *read_bio;    /*!< Memory buffer for reading */
+	BIO *write_bio;   /*!< Memory buffer for writing */
+	enum ast_rtp_dtls_setup dtls_setup; /*!< Current setup state */
+	enum ast_rtp_dtls_connection connection; /*!< Whether this is a new or existing connection */
+};
+#endif
 
 /*! \brief RTP session description */
 struct ast_rtp {
@@ -283,21 +293,17 @@
 
 #ifdef HAVE_OPENSSL_SRTP
 	SSL_CTX *ssl_ctx; /*!< SSL context */
-	SSL *ssl;         /*!< SSL session */
-	BIO *read_bio;    /*!< Memory buffer for reading */
-	BIO *write_bio;   /*!< Memory buffer for writing */
 	ast_mutex_t dtls_timer_lock;           /*!< Lock for synchronization purposes */
-	enum ast_rtp_dtls_setup dtls_setup; /*!< Current setup state */
 	enum ast_rtp_dtls_verify dtls_verify; /*!< What to verify */
 	enum ast_srtp_suite suite;   /*!< SRTP crypto suite */
 	enum ast_rtp_dtls_hash local_hash; /*!< Local hash used for the fingerprint */
 	char local_fingerprint[160]; /*!< Fingerprint of our certificate */
 	enum ast_rtp_dtls_hash remote_hash; /*!< Remote hash used for the fingerprint */
 	unsigned char remote_fingerprint[EVP_MAX_MD_SIZE]; /*!< Fingerprint of the peer certificate */
-	enum ast_rtp_dtls_connection connection; /*!< Whether this is a new or existing connection */
 	unsigned int rekey; /*!< Interval at which to renegotiate and rekey */
 	int rekeyid; /*!< Scheduled item id for rekeying */
 	int dtlstimerid; /*!< Scheduled item id for DTLS retransmission for RTP */
+	struct dtls_details dtls; /*!< DTLS state information */
 #endif
 };
 
@@ -362,11 +368,7 @@
 	unsigned int rtt_count;
 
 #ifdef HAVE_OPENSSL_SRTP
-	SSL *ssl;         /*!< SSL session */
-	BIO *read_bio;    /*!< Memory buffer for reading */
-	BIO *write_bio;   /*!< Memory buffer for writing */
-	enum ast_rtp_dtls_setup dtls_setup; /*!< Current setup state */
-	enum ast_rtp_dtls_connection connection; /*!< Whether this is a new or existing connection */
+	struct dtls_details dtls; /*!< DTLS state information */
 #endif
 };
 
@@ -555,7 +557,7 @@
 	int res;
 
 	ast_rtp_ice_stop(instance);
-	
+
 	res = ice_create(instance, &rtp->ice_original_rtp_addr, rtp->ice_port, 1);
 	if (!res) {
 		/* Preserve the role that the old ICE session used */
@@ -823,68 +825,72 @@
 	return 1;
 }
 
+static int dtls_details_initialize(struct dtls_details *dtls, SSL_CTX *ssl_ctx,
+	enum ast_rtp_dtls_setup setup)
+{
+	dtls->dtls_setup = setup;
+
+	if (!(dtls->ssl = SSL_new(ssl_ctx))) {
+		ast_log(LOG_ERROR, "Failed to allocate memory for SSL\n");
+		goto error;
+	}
+
+	if (!(dtls->read_bio = BIO_new(BIO_s_mem()))) {
+		ast_log(LOG_ERROR, "Failed to allocate memory for inbound SSL traffic\n");
+		goto error;
+	}
+	BIO_set_mem_eof_return(dtls->read_bio, -1);
+
+	if (!(dtls->write_bio = BIO_new(BIO_s_mem()))) {
+		ast_log(LOG_ERROR, "Failed to allocate memory for outbound SSL traffic\n");
+		goto error;
+	}
+	BIO_set_mem_eof_return(dtls->write_bio, -1);
+
+	SSL_set_bio(dtls->ssl, dtls->read_bio, dtls->write_bio);
+
+	if (dtls->dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
+		SSL_set_accept_state(dtls->ssl);
+	} else {
+		SSL_set_connect_state(dtls->ssl);
+	}
+	dtls->connection = AST_RTP_DTLS_CONNECTION_NEW;
+
+	return 0;
+
+error:
+	if (dtls->read_bio) {
+		BIO_free(dtls->read_bio);
+		dtls->read_bio = NULL;
+	}
+
+	if (dtls->write_bio) {
+		BIO_free(dtls->write_bio);
+		dtls->write_bio = NULL;
+	}
+
+	if (dtls->ssl) {
+		SSL_free(dtls->ssl);
+		dtls->ssl = NULL;
+	}
+	return -1;
+}
+
 static int dtls_setup_rtcp(struct ast_rtp_instance *instance)
 {
 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
 
-	if (!rtp->ssl_ctx) {
+	if (!rtp->ssl_ctx || !rtp->rtcp) {
 		return 0;
 	}
 
-	rtp->rtcp->dtls_setup = rtp->dtls_setup;
-
-	if (!(rtp->rtcp->ssl = SSL_new(rtp->ssl_ctx))) {
-		ast_log(LOG_ERROR, "Failed to allocate memory for SSL context on RTCP of RTP instance '%p'\n",
-			instance);
-		goto error;
-	}
-
-	if (!(rtp->rtcp->read_bio = BIO_new(BIO_s_mem()))) {
-		ast_log(LOG_ERROR, "Failed to allocate memory for inbound SSL traffic on RTCP of RTP instance '%p'\n",
-			instance);
-		goto error;
-	}
-	BIO_set_mem_eof_return(rtp->rtcp->read_bio, -1);
-
-	if (!(rtp->rtcp->write_bio = BIO_new(BIO_s_mem()))) {
-		ast_log(LOG_ERROR, "Failed to allocate memory for outbound SSL traffic on RTCP of RTP instance '%p'\n",
-			instance);
-		goto error;
-	}
-	BIO_set_mem_eof_return(rtp->rtcp->write_bio, -1);
-
-	SSL_set_bio(rtp->rtcp->ssl, rtp->rtcp->read_bio, rtp->rtcp->write_bio);
-
-	if (rtp->rtcp->dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
-		SSL_set_accept_state(rtp->rtcp->ssl);
-	} else {
-		SSL_set_connect_state(rtp->rtcp->ssl);
-	}
-	rtp->rtcp->connection = AST_RTP_DTLS_CONNECTION_NEW;
-
-	return 0;
-
-error:
-	if (rtp->rtcp->read_bio) {
-		BIO_free(rtp->rtcp->read_bio);
-		rtp->rtcp->read_bio = NULL;
-	}
-
-	if (rtp->rtcp->write_bio) {
-		BIO_free(rtp->rtcp->write_bio);
-		rtp->rtcp->write_bio = NULL;
-	}
-
-	if (rtp->rtcp->ssl) {
-		SSL_free(rtp->rtcp->ssl);
-		rtp->rtcp->ssl = NULL;
-	}
-	return -1;
+	return dtls_details_initialize(&rtp->rtcp->dtls, rtp->ssl_ctx, rtp->dtls.dtls_setup);
 }
 
 static int ast_rtp_dtls_set_configuration(struct ast_rtp_instance *instance, const struct ast_rtp_dtls_cfg *dtls_cfg)
 {
 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
+	int res;
 
 	if (!dtls_cfg->enabled) {
 		return 0;
@@ -910,7 +916,7 @@
 		SSL_CTX_set_tlsext_use_srtp(rtp->ssl_ctx, "SRTP_AES128_CM_SHA1_32");
 	} else {
 		ast_log(LOG_ERROR, "Unsupported suite specified for DTLS-SRTP on RTP instance '%p'\n", instance);
-		goto error;
+		return -1;
 	}
 
 	rtp->local_hash = dtls_cfg->hash;
@@ -927,20 +933,20 @@
 		if (!SSL_CTX_use_certificate_file(rtp->ssl_ctx, dtls_cfg->certfile, SSL_FILETYPE_PEM)) {
 			ast_log(LOG_ERROR, "Specified certificate file '%s' for RTP instance '%p' could not be used\n",
 				dtls_cfg->certfile, instance);
-			goto error;
+			return -1;
 		}
 
 		if (!SSL_CTX_use_PrivateKey_file(rtp->ssl_ctx, private, SSL_FILETYPE_PEM) ||
 		    !SSL_CTX_check_private_key(rtp->ssl_ctx)) {
 			ast_log(LOG_ERROR, "Specified private key file '%s' for RTP instance '%p' could not be used\n",
 				private, instance);
-			goto error;
+			return -1;
 		}
 
 		if (!(certbio = BIO_new(BIO_s_file()))) {
 			ast_log(LOG_ERROR, "Failed to allocate memory for certificate fingerprinting on RTP instance '%p'\n",
 				instance);
-			goto error;
+			return -1;
 		}
 
 		if (rtp->local_hash == AST_RTP_DTLS_HASH_SHA1) {
@@ -950,7 +956,7 @@
 		} else {
 			ast_log(LOG_ERROR, "Unsupported fingerprint hash type on RTP instance '%p'\n",
 				instance);
-			goto error;
+			return -1;
 		}
 
 		if (!BIO_read_filename(certbio, dtls_cfg->certfile) ||
@@ -960,7 +966,7 @@
 			ast_log(LOG_ERROR, "Could not produce fingerprint from certificate '%s' for RTP instance '%p'\n",
 				dtls_cfg->certfile, instance);
 			BIO_free_all(certbio);
-			goto error;
+			return -1;
 		}
 
 		for (i = 0; i < size; i++) {
@@ -977,7 +983,7 @@
 		if (!SSL_CTX_set_cipher_list(rtp->ssl_ctx, dtls_cfg->cipher)) {
 			ast_log(LOG_ERROR, "Invalid cipher specified in cipher list '%s' for RTP instance '%p'\n",
 				dtls_cfg->cipher, instance);
-			goto error;
+			return -1;
 		}
 	}
 
@@ -985,65 +991,19 @@
 		if (!SSL_CTX_load_verify_locations(rtp->ssl_ctx, S_OR(dtls_cfg->cafile, NULL), S_OR(dtls_cfg->capath, NULL))) {
 			ast_log(LOG_ERROR, "Invalid certificate authority file '%s' or path '%s' specified for RTP instance '%p'\n",
 				S_OR(dtls_cfg->cafile, ""), S_OR(dtls_cfg->capath, ""), instance);
-			goto error;
+			return -1;
 		}
 	}
 
 	rtp->rekey = dtls_cfg->rekey;
-	rtp->dtls_setup = dtls_cfg->default_setup;
 	rtp->suite = dtls_cfg->suite;
 
-	if (!(rtp->ssl = SSL_new(rtp->ssl_ctx))) {
-		ast_log(LOG_ERROR, "Failed to allocate memory for SSL context on RTP instance '%p'\n",
-			instance);
-		goto error;
-	}
-
-	if (!(rtp->read_bio = BIO_new(BIO_s_mem()))) {
-		ast_log(LOG_ERROR, "Failed to allocate memory for inbound SSL traffic on RTP instance '%p'\n",
-			instance);
-		goto error;
-	}
-	BIO_set_mem_eof_return(rtp->read_bio, -1);
-
-	if (!(rtp->write_bio = BIO_new(BIO_s_mem()))) {
-		ast_log(LOG_ERROR, "Failed to allocate memory for outbound SSL traffic on RTP instance '%p'\n",
-			instance);
-		goto error;
-	}
-	BIO_set_mem_eof_return(rtp->write_bio, -1);
-
-	SSL_set_bio(rtp->ssl, rtp->read_bio, rtp->write_bio);
-
-	if (rtp->dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
-		SSL_set_accept_state(rtp->ssl);
-	} else {
-		SSL_set_connect_state(rtp->ssl);
-	}
-	rtp->connection = AST_RTP_DTLS_CONNECTION_NEW;
-
-	return 0;
-
-error:
-	if (rtp->read_bio) {
-		BIO_free(rtp->read_bio);
-		rtp->read_bio = NULL;
-	}
-
-	if (rtp->write_bio) {
-		BIO_free(rtp->write_bio);
-		rtp->write_bio = NULL;
-	}
-
-	if (rtp->ssl) {
-		SSL_free(rtp->ssl);
-		rtp->ssl = NULL;
-	}
-
-	SSL_CTX_free(rtp->ssl_ctx);
-	rtp->ssl_ctx = NULL;
-
-	return -1;
+	res = dtls_details_initialize(&rtp->dtls, rtp->ssl_ctx, dtls_cfg->default_setup);
+	if (!res) {
+		dtls_setup_rtcp(instance);
+	}
+
+	return res;
 }
 
 static int ast_rtp_dtls_active(struct ast_rtp_instance *instance)
@@ -1062,14 +1022,14 @@
 		rtp->ssl_ctx = NULL;
 	}
 
-	if (rtp->ssl) {
-		SSL_free(rtp->ssl);
-		rtp->ssl = NULL;
-	}
-
-	if (rtp->rtcp && rtp->rtcp->ssl) {
-		SSL_free(rtp->rtcp->ssl);
-		rtp->rtcp->ssl = NULL;
+	if (rtp->dtls.ssl) {
+		SSL_free(rtp->dtls.ssl);
+		rtp->dtls.ssl = NULL;
+	}
+
+	if (rtp->rtcp && rtp->rtcp->dtls.ssl) {
+		SSL_free(rtp->rtcp->dtls.ssl);
+		rtp->rtcp->dtls.ssl = NULL;
 	}
 }
 
@@ -1077,14 +1037,14 @@
 {
 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
 
-	if (SSL_is_init_finished(rtp->ssl)) {
-		SSL_shutdown(rtp->ssl);
-		rtp->connection = AST_RTP_DTLS_CONNECTION_NEW;
-	}
-
-	if (rtp->rtcp && SSL_is_init_finished(rtp->rtcp->ssl)) {
-		SSL_shutdown(rtp->rtcp->ssl);
-		rtp->rtcp->connection = AST_RTP_DTLS_CONNECTION_NEW;
+	if (SSL_is_init_finished(rtp->dtls.ssl)) {
+		SSL_shutdown(rtp->dtls.ssl);
+		rtp->dtls.connection = AST_RTP_DTLS_CONNECTION_NEW;
+	}
+
+	if (rtp->rtcp && SSL_is_init_finished(rtp->rtcp->dtls.ssl)) {
+		SSL_shutdown(rtp->rtcp->dtls.ssl);
+		rtp->rtcp->dtls.connection = AST_RTP_DTLS_CONNECTION_NEW;
 	}
 }
 
@@ -1092,14 +1052,14 @@
 {
 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
 
-	return rtp->connection;
+	return rtp->dtls.connection;
 }
 
 static enum ast_rtp_dtls_setup ast_rtp_dtls_get_setup(struct ast_rtp_instance *instance)
 {
 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
 
-	return rtp->dtls_setup;
+	return rtp->dtls.dtls_setup;
 }
 
 static void dtls_set_setup(enum ast_rtp_dtls_setup *dtls_setup, enum ast_rtp_dtls_setup setup, SSL *ssl)
@@ -1150,12 +1110,12 @@
 {
 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
 
-	if (rtp->ssl) {
-		dtls_set_setup(&rtp->dtls_setup, setup, rtp->ssl);
-	}
-
-	if (rtp->rtcp && rtp->rtcp->ssl) {
-		dtls_set_setup(&rtp->rtcp->dtls_setup, setup, rtp->rtcp->ssl);
+	if (rtp->dtls.ssl) {
+		dtls_set_setup(&rtp->dtls.dtls_setup, setup, rtp->dtls.ssl);
+	}
+
+	if (rtp->rtcp && rtp->rtcp->dtls.ssl) {
+		dtls_set_setup(&rtp->rtcp->dtls.dtls_setup, setup, rtp->rtcp->dtls.ssl);
 	}
 }
 
@@ -1244,6 +1204,29 @@
 
 static void rtp_learning_seq_init(struct rtp_learning_info *info, uint16_t seq);
 
+#ifdef HAVE_OPENSSL_SRTP
+static void dtls_perform_handshake(struct ast_rtp_instance *instance, struct dtls_details *dtls, int rtcp)
+{
+	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
+
+	if (!dtls->ssl) {
+		return;
+	}
+
+	if (SSL_is_init_finished(dtls->ssl)) {
+		SSL_clear(dtls->ssl);
+		if (dtls->dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
+			SSL_set_accept_state(dtls->ssl);
+		} else {
+			SSL_set_connect_state(dtls->ssl);
+		}
+		dtls->connection = AST_RTP_DTLS_CONNECTION_NEW;
+	}
+	SSL_do_handshake(dtls->ssl);
+	dtls_srtp_check_pending(instance, rtp, rtcp);
+}
+#endif
+
 #ifdef USE_PJPROJECT
 static void ast_rtp_on_ice_complete(pj_ice_sess *ice, pj_status_t status)
 {
@@ -1251,32 +1234,10 @@
 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
 
 #ifdef HAVE_OPENSSL_SRTP
-	if (rtp->ssl) {
-		if (SSL_is_init_finished(rtp->ssl)) {
-			SSL_clear(rtp->ssl);
-			if (rtp->dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
-				SSL_set_accept_state(rtp->ssl);
-			} else {
-				SSL_set_connect_state(rtp->ssl);
-			}
-			rtp->connection = AST_RTP_DTLS_CONNECTION_NEW;
-		}
-		SSL_do_handshake(rtp->ssl);
-		dtls_srtp_check_pending(instance, rtp, 0);
-	}
-
-	if (rtp->rtcp && rtp->rtcp->ssl) {
-		if (SSL_is_init_finished(rtp->rtcp->ssl)) {
-			SSL_clear(rtp->rtcp->ssl);
-			if (rtp->rtcp->dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
-				SSL_set_accept_state(rtp->rtcp->ssl);
-			} else {
-				SSL_set_connect_state(rtp->rtcp->ssl);
-			}
-			rtp->rtcp->connection = AST_RTP_DTLS_CONNECTION_NEW;
-		}
-		SSL_do_handshake(rtp->rtcp->ssl);
-		dtls_srtp_check_pending(instance, rtp, 1);
+	dtls_perform_handshake(instance, &rtp->dtls, 0);
+
+	if (rtp->rtcp) {
+		dtls_perform_handshake(instance, &rtp->rtcp->dtls, 1);
 	}
 #endif
 
@@ -1502,13 +1463,13 @@
 	rtp->dtlstimerid = -1;
 	ast_mutex_unlock(&rtp->dtls_timer_lock);
 
-	if (rtp->ssl && !SSL_is_init_finished(rtp->ssl)) {
-		DTLSv1_handle_timeout(rtp->ssl);
+	if (rtp->dtls.ssl && !SSL_is_init_finished(rtp->dtls.ssl)) {
+		DTLSv1_handle_timeout(rtp->dtls.ssl);
 	}
 	dtls_srtp_check_pending(instance, rtp, 0);
 
-	if (rtp->rtcp && rtp->rtcp->ssl && !SSL_is_init_finished(rtp->rtcp->ssl)) {
-		DTLSv1_handle_timeout(rtp->rtcp->ssl);
+	if (rtp->rtcp && rtp->rtcp->dtls.ssl && !SSL_is_init_finished(rtp->rtcp->dtls.ssl)) {
+		DTLSv1_handle_timeout(rtp->rtcp->dtls.ssl);
 	}
 	dtls_srtp_check_pending(instance, rtp, 1);
 
@@ -1519,16 +1480,15 @@
 
 static void dtls_srtp_check_pending(struct ast_rtp_instance *instance, struct ast_rtp *rtp, int rtcp)
 {
-	SSL *ssl = !rtcp ? rtp->ssl : rtp->rtcp->ssl;
-	BIO *write_bio = !rtcp ? rtp->write_bio : rtp->rtcp->write_bio;
+	struct dtls_details *dtls = !rtcp ? &rtp->dtls : &rtp->rtcp->dtls;
 	size_t pending;
 	struct timeval dtls_timeout; /* timeout on DTLS  */
 
-	if (!ssl || !write_bio) {
+	if (!dtls->ssl || !dtls->write_bio) {
 		return;
 	}
 
-	pending = BIO_ctrl_pending(write_bio);
+	pending = BIO_ctrl_pending(dtls->write_bio);
 
 	if (pending > 0) {
 		char outgoing[pending];
@@ -1547,7 +1507,7 @@
 			return;
 		}
 
-		out = BIO_read(write_bio, outgoing, sizeof(outgoing));
+		out = BIO_read(dtls->write_bio, outgoing, sizeof(outgoing));
 
 		/* Stop existing DTLS timer if running */
 		ast_mutex_lock(&rtp->dtls_timer_lock);
@@ -1556,7 +1516,7 @@
 			rtp->dtlstimerid = -1;
 		}
 
-		if (DTLSv1_get_timeout(ssl, &dtls_timeout)) {
+		if (DTLSv1_get_timeout(dtls->ssl, &dtls_timeout)) {
 			int timeout = dtls_timeout.tv_sec * 1000 + dtls_timeout.tv_usec / 1000;
 			ao2_ref(instance, +1);
 			if ((rtp->dtlstimerid = ast_sched_add(rtp->sched, timeout, dtls_srtp_handle_timeout, instance)) < 0) {
@@ -1575,13 +1535,13 @@
 	struct ast_rtp_instance *instance = (struct ast_rtp_instance *)data;
 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
 
-	SSL_renegotiate(rtp->ssl);
-	SSL_do_handshake(rtp->ssl);
+	SSL_renegotiate(rtp->dtls.ssl);
+	SSL_do_handshake(rtp->dtls.ssl);
 	dtls_srtp_check_pending(instance, rtp, 0);
 
-	if (rtp->rtcp && rtp->rtcp->ssl) {
-		SSL_renegotiate(rtp->rtcp->ssl);
-		SSL_do_handshake(rtp->rtcp->ssl);
+	if (rtp->rtcp && rtp->rtcp->dtls.ssl) {
+		SSL_renegotiate(rtp->rtcp->dtls.ssl);
+		SSL_do_handshake(rtp->rtcp->dtls.ssl);
 		dtls_srtp_check_pending(instance, rtp, 1);
 	}
 
@@ -1602,7 +1562,7 @@
 	if (rtp->dtls_verify & AST_RTP_DTLS_VERIFY_FINGERPRINT) {
 		X509 *certificate;
 
-		if (!(certificate = SSL_get_peer_certificate(rtp->ssl))) {
+		if (!(certificate = SSL_get_peer_certificate(rtp->dtls.ssl))) {
 			ast_log(LOG_WARNING, "No certificate was provided by the peer on RTP instance '%p'\n", instance);
 			return -1;
 		}
@@ -1636,21 +1596,21 @@
 	}
 
 	/* Ensure that certificate verification was successful */
-	if ((rtp->dtls_verify & AST_RTP_DTLS_VERIFY_CERTIFICATE) && SSL_get_verify_result(rtp->ssl) != X509_V_OK) {
+	if ((rtp->dtls_verify & AST_RTP_DTLS_VERIFY_CERTIFICATE) && SSL_get_verify_result(rtp->dtls.ssl) != X509_V_OK) {
 		ast_log(LOG_WARNING, "Peer certificate on RTP instance '%p' failed verification test\n",
 			instance);
 		return -1;
 	}
 
 	/* Produce key information and set up SRTP */
-	if (!SSL_export_keying_material(rtp->ssl, material, SRTP_MASTER_LEN * 2, "EXTRACTOR-dtls_srtp", 19, NULL, 0, 0)) {
+	if (!SSL_export_keying_material(rtp->dtls.ssl, material, SRTP_MASTER_LEN * 2, "EXTRACTOR-dtls_srtp", 19, NULL, 0, 0)) {
 		ast_log(LOG_WARNING, "Unable to extract SRTP keying material from DTLS-SRTP negotiation on RTP instance '%p'\n",
 			instance);
 		return -1;
 	}
 
 	/* Whether we are acting as a server or client determines where the keys/salts are */
-	if (rtp->dtls_setup == AST_RTP_DTLS_SETUP_ACTIVE) {
+	if (rtp->dtls.dtls_setup == AST_RTP_DTLS_SETUP_ACTIVE) {
 		local_key = material;
 		remote_key = local_key + SRTP_MASTER_KEY_LEN;
 		local_salt = remote_key + SRTP_MASTER_KEY_LEN;
@@ -1740,30 +1700,29 @@
 
 	/* If this is an SSL packet pass it to OpenSSL for processing */
 	if ((*in >= 20) && (*in <= 64)) {
-		SSL *ssl = !rtcp ? rtp->ssl : rtp->rtcp->ssl;
-		BIO *read_bio = !rtcp ? rtp->read_bio : rtp->rtcp->read_bio;
+		struct dtls_details *dtls = !rtcp ? &rtp->dtls : &rtp->rtcp->dtls;
 		int res = 0;
 
 		/* If no SSL session actually exists terminate things */
-		if (!ssl) {
+		if (!dtls->ssl) {
 			ast_log(LOG_ERROR, "Received SSL traffic on RTP instance '%p' without an SSL session\n",
 				instance);
 			return -1;
 		}
 
 		/* If we don't yet know if we are active or passive and we receive a packet... we are obviously passive */
-		if (rtp->dtls_setup == AST_RTP_DTLS_SETUP_ACTPASS) {
-			rtp->dtls_setup = AST_RTP_DTLS_SETUP_PASSIVE;
-			SSL_set_accept_state(ssl);
+		if (dtls->dtls_setup == AST_RTP_DTLS_SETUP_ACTPASS) {
+			dtls->dtls_setup = AST_RTP_DTLS_SETUP_PASSIVE;
+			SSL_set_accept_state(dtls->ssl);
 		}
 
 		dtls_srtp_check_pending(instance, rtp, rtcp);
 
-		BIO_write(read_bio, buf, len);
-
-		len = SSL_read(ssl, buf, len);
-
-		if ((len < 0) && (SSL_get_error(ssl, len) == SSL_ERROR_SSL)) {
+		BIO_write(dtls->read_bio, buf, len);
+
+		len = SSL_read(dtls->ssl, buf, len);
+
+		if ((len < 0) && (SSL_get_error(dtls->ssl, len) == SSL_ERROR_SSL)) {
 			unsigned long error = ERR_get_error();
 			ast_log(LOG_ERROR, "DTLS failure occurred on RTP instance '%p' due to reason '%s', terminating\n",
 				instance, ERR_reason_error_string(error));
@@ -1772,14 +1731,12 @@
 
 		dtls_srtp_check_pending(instance, rtp, rtcp);
 
-		if (SSL_is_init_finished(ssl)) {
+		if (SSL_is_init_finished(dtls->ssl)) {
 			/* Any further connections will be existing since this is now established */
+			dtls->connection = AST_RTP_DTLS_CONNECTION_EXISTING;
 			if (!rtcp) {
-				rtp->connection = AST_RTP_DTLS_CONNECTION_EXISTING;
 				/* Use the keying material to set up key/salt information */
 				res = dtls_srtp_setup(rtp, srtp, instance);
-			} else {
-				rtp->rtcp->connection = AST_RTP_DTLS_CONNECTION_EXISTING;
 			}
 		}
 
@@ -2250,8 +2207,8 @@
 		 */
 		close(rtp->rtcp->s);
 #ifdef HAVE_OPENSSL_SRTP
-		if (rtp->rtcp->ssl) {
-			SSL_free(rtp->rtcp->ssl);
+		if (rtp->rtcp->dtls.ssl) {
+			SSL_free(rtp->rtcp->dtls.ssl);
 		}
 #endif
 		ast_free(rtp->rtcp);
@@ -2304,8 +2261,8 @@
 	}
 
 	/* Destroy the SSL session if present */
-	if (rtp->ssl) {
-		SSL_free(rtp->ssl);
+	if (rtp->dtls.ssl) {
+		SSL_free(rtp->dtls.ssl);
 	}
 #endif
 
@@ -4350,8 +4307,8 @@
 				}
 				close(rtp->rtcp->s);
 #ifdef HAVE_OPENSSL_SRTP
-				if (rtp->rtcp->ssl) {
-					SSL_free(rtp->rtcp->ssl);
+				if (rtp->rtcp->dtls.ssl) {
+					SSL_free(rtp->rtcp->dtls.ssl);
 				}
 #endif
 				ast_free(rtp->rtcp);
@@ -4657,27 +4614,10 @@
 	}
 #endif
 
-	if (rtp->ssl) {
-		SSL_clear(rtp->ssl);
-		if (rtp->dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
-			SSL_set_accept_state(rtp->ssl);
-		} else {
-			SSL_set_connect_state(rtp->ssl);
-		}
-		rtp->connection = AST_RTP_DTLS_CONNECTION_NEW;
-		SSL_do_handshake(rtp->ssl);
-		dtls_srtp_check_pending(instance, rtp, 0);
-	}
-	if (rtp->rtcp && rtp->rtcp->ssl) {
-		SSL_clear(rtp->rtcp->ssl);
-		if (rtp->rtcp->dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
-			SSL_set_accept_state(rtp->rtcp->ssl);
-		} else {
-			SSL_set_connect_state(rtp->rtcp->ssl);
-		}
-		rtp->rtcp->connection = AST_RTP_DTLS_CONNECTION_NEW;
-		SSL_do_handshake(rtp->rtcp->ssl);
-		dtls_srtp_check_pending(instance, rtp, 1);
+	dtls_perform_handshake(instance, &rtp->dtls, 0);
+
+	if (rtp->rtcp) {
+		dtls_perform_handshake(instance, &rtp->rtcp->dtls, 1);
 	}
 
 	return 0;




More information about the asterisk-commits mailing list