mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	tcptls/iostream: Add support for setting SNI on client TLS connections
If the hostname field of the ast_tcptls_session_args structure is set (which it is for websocket client connections), that hostname will now automatically be used in an SNI TLS extension in the client hello. Resolves: #713 UserNote: Secure websocket client connections now send SNI in the TLS client hello.
This commit is contained in:
		
				
					committed by
					
						![asterisk-org-access-app[bot]](/avatar/58a64b62d62d5b23df7bc832f016f9db?size=40) asterisk-org-access-app[bot]
						asterisk-org-access-app[bot]
					
				
			
			
				
	
			
			
			
						parent
						
							758ed2b9fd
						
					
				
				
					commit
					8e119a72f0
				
			| @@ -106,6 +106,17 @@ void ast_iostream_set_timeout_sequence(struct ast_iostream *stream, struct timev | ||||
|  */ | ||||
| void ast_iostream_set_exclusive_input(struct ast_iostream *stream, int exclusive_input); | ||||
|  | ||||
| /*! | ||||
|  * \brief Set the iostream's SNI hostname for TLS client connections | ||||
|  * | ||||
|  * \param stream A pointer to an iostream | ||||
|  * \param sni_hostname The hostname to use for SNI when in client mode | ||||
|  * | ||||
|  * \retval 0 if the hostname was set successfully. | ||||
|  * \retval -1 if memory could not be allocated for the hostname. | ||||
|  */ | ||||
| int ast_iostream_set_sni_hostname(struct ast_iostream *stream, const char *sni_hostname); | ||||
|  | ||||
| /*! | ||||
|  * \brief Get an iostream's file descriptor. | ||||
|  * | ||||
|   | ||||
| @@ -46,6 +46,7 @@ struct ast_iostream { | ||||
| 	int rbuflen; | ||||
| 	char *rbufhead; | ||||
| 	char rbuf[2048]; | ||||
| 	char *sni_hostname; | ||||
| }; | ||||
|  | ||||
| #if defined(DO_SSL) | ||||
| @@ -152,6 +153,16 @@ void ast_iostream_set_exclusive_input(struct ast_iostream *stream, int exclusive | ||||
| 	stream->exclusive_input = exclusive_input; | ||||
| } | ||||
|  | ||||
| int ast_iostream_set_sni_hostname(struct ast_iostream *stream, const char *sni_hostname) | ||||
| { | ||||
| 	ast_assert(stream != NULL); | ||||
|  | ||||
| 	ast_free(stream->sni_hostname); | ||||
| 	stream->sni_hostname = ast_strdup(sni_hostname); | ||||
|  | ||||
| 	return stream->sni_hostname ? 0 : -1; | ||||
| } | ||||
|  | ||||
| static ssize_t iostream_read(struct ast_iostream *stream, void *buf, size_t size) | ||||
| { | ||||
| 	struct timeval start; | ||||
| @@ -591,13 +602,9 @@ int ast_iostream_close(struct ast_iostream *stream) | ||||
|  | ||||
| static void iostream_dtor(void *cookie) | ||||
| { | ||||
| #ifdef AST_DEVMODE | ||||
| 	/* Since the ast_assert below is the only one using stream, | ||||
| 	 * and ast_assert is only available with AST_DEVMODE, we | ||||
| 	 * put this in a conditional to avoid compiler warnings. */ | ||||
| 	struct ast_iostream *stream = cookie; | ||||
| #endif | ||||
|  | ||||
| 	ast_free(stream->sni_hostname); | ||||
| 	ast_assert(stream->fd == -1); | ||||
| } | ||||
|  | ||||
| @@ -639,6 +646,15 @@ int ast_iostream_start_tls(struct ast_iostream **pstream, SSL_CTX *ssl_ctx, int | ||||
| 	 */ | ||||
| 	SSL_set_fd(stream->ssl, stream->fd); | ||||
|  | ||||
| 	if (client && !ast_strlen_zero(stream->sni_hostname)) { | ||||
| 		if (!SSL_set_tlsext_host_name(stream->ssl, stream->sni_hostname)) { | ||||
| 			ast_log(LOG_ERROR, "Unable to set SNI hostname '%s'\n", | ||||
| 				stream->sni_hostname); | ||||
| 			errno = EIO; | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	res = ssl_setup(stream->ssl); | ||||
| 	if (res <= 0) { | ||||
| 		int sslerr = SSL_get_error(stream->ssl, res); | ||||
|   | ||||
| @@ -741,6 +741,13 @@ struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_s | ||||
| 	/* Set current info */ | ||||
| 	ast_sockaddr_copy(&desc->old_address, &desc->remote_address); | ||||
|  | ||||
| 	if (!ast_strlen_zero(desc->hostname)) { | ||||
| 		if (ast_iostream_set_sni_hostname(tcptls_session->stream, desc->hostname) != 0) { | ||||
| 			ast_log(LOG_WARNING, "Unable to set SNI hostname '%s' on connection '%s'\n", | ||||
| 				desc->hostname, desc->name); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return tcptls_session; | ||||
|  | ||||
| error: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user