mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
1024: Use RFC 3546 server_name TLS extension
For both GnuTLS and OpenSSL. Not tested with nss-compat-openssl.
This commit is contained in:
parent
5d0e4e2452
commit
6c84978cf5
@ -181,12 +181,28 @@ int
|
||||
ssl_connect(struct socket *socket)
|
||||
{
|
||||
int ret;
|
||||
unsigned char *server_name;
|
||||
struct connection *conn = socket->conn;
|
||||
|
||||
if (init_ssl_connection(socket) == S_SSL_ERROR) {
|
||||
/* TODO: Recode server_name to UTF-8. */
|
||||
server_name = get_uri_string(conn->proxied_uri, URI_HOST);
|
||||
if (!server_name) {
|
||||
socket->ops->done(socket, connection_state(S_OUT_OF_MEM));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* RFC 3546 says literal IPv4 and IPv6 addresses are not allowed. */
|
||||
if (is_ip_address(server_name, strlen(server_name)))
|
||||
mem_free_set(&server_name, NULL);
|
||||
|
||||
if (init_ssl_connection(socket, server_name) == S_SSL_ERROR) {
|
||||
mem_free_if(server_name);
|
||||
socket->ops->done(socket, connection_state(S_SSL_ERROR));
|
||||
return -1;
|
||||
}
|
||||
|
||||
mem_free_if(server_name);
|
||||
|
||||
if (socket->no_tls)
|
||||
ssl_set_no_tls(socket);
|
||||
|
||||
|
@ -249,13 +249,26 @@ struct module ssl_module = struct_module(
|
||||
);
|
||||
|
||||
int
|
||||
init_ssl_connection(struct socket *socket)
|
||||
init_ssl_connection(struct socket *socket,
|
||||
const unsigned char *server_name)
|
||||
{
|
||||
#ifdef USE_OPENSSL
|
||||
socket->ssl = SSL_new(context);
|
||||
if (!socket->ssl) return S_SSL_ERROR;
|
||||
|
||||
/* If the server name is known, pass it to OpenSSL.
|
||||
*
|
||||
* The return value of SSL_set_tlsext_host_name is not
|
||||
* documented. The source shows that it returns 1 if
|
||||
* successful; on error, it calls SSLerr and returns 0. */
|
||||
if (server_name
|
||||
&& !SSL_set_tlsext_host_name(socket->ssl, server_name)) {
|
||||
SSL_free(socket->ssl);
|
||||
socket->ssl = NULL;
|
||||
return S_SSL_ERROR;
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_GNUTLS)
|
||||
/* const unsigned char server_name[] = "localhost"; */
|
||||
ssl_t *state = mem_alloc(sizeof(ssl_t));
|
||||
|
||||
if (!state) return S_SSL_ERROR;
|
||||
@ -294,11 +307,17 @@ init_ssl_connection(struct socket *socket)
|
||||
/* gnutls_handshake_set_private_extensions(*state, 1); */
|
||||
gnutls_cipher_set_priority(*state, cipher_priority);
|
||||
gnutls_kx_set_priority(*state, kx_priority);
|
||||
/* gnutls_certificate_type_set_priority(*state, cert_type_priority);
|
||||
gnutls_server_name_set(*state, GNUTLS_NAME_DNS, server_name,
|
||||
sizeof(server_name) - 1); */
|
||||
/* gnutls_certificate_type_set_priority(*state, cert_type_priority); */
|
||||
#endif
|
||||
|
||||
if (server_name
|
||||
&& gnutls_server_name_set(*state, GNUTLS_NAME_DNS, server_name,
|
||||
strlen(server_name))) {
|
||||
gnutls_deinit(*state);
|
||||
mem_free(state);
|
||||
return S_SSL_ERROR;
|
||||
}
|
||||
|
||||
socket->ssl = state;
|
||||
#endif
|
||||
|
||||
|
@ -11,8 +11,18 @@ struct socket;
|
||||
extern struct module ssl_module;
|
||||
|
||||
/* Initializes the SSL connection data. Returns S_OK on success and S_SSL_ERROR
|
||||
* on failure. */
|
||||
int init_ssl_connection(struct socket *socket);
|
||||
* on failure.
|
||||
*
|
||||
* server_name is the DNS name of the server (in UTF-8), or NULL if
|
||||
* ELinks knows only the IP address. ELinks reports that name to the
|
||||
* server so that the server can choose the correct certificate if it
|
||||
* has multiple virtual hosts on the same IP address. See RFC 3546
|
||||
* section 3.1.
|
||||
*
|
||||
* server_name does not affect how ELinks verifies the certificate
|
||||
* after the server has returned it. */
|
||||
int init_ssl_connection(struct socket *socket,
|
||||
const unsigned char *server_name);
|
||||
|
||||
/* Releases the SSL connection data */
|
||||
void done_ssl_connection(struct socket *socket);
|
||||
|
Loading…
Reference in New Issue
Block a user