Hello elinks workers! I have been using elinks to test HTTPS with GnuTLS (I'm the GnuTLS maintainer) and I've noticed some, let's say, sub-optimal things in elinks related to the GnuTLS code, and I'd like to offer fixes for some of the problems.
I hope to find time to add support for client certificates etc too, it is mostly a matter of cut'n'paste from the example code. The patch to ssl.c below removes some hard-coding of specific algorithms, and use the gnutls_set_default_priority() which is the recommended way. It should work with GnuTLS back to 1.2.x which you already require in configure.in. The patch to socket.? removes some never needed code with GnuTLS, and removes the need for the no_tls variable and the ssl_set_no_tls() function altogether by replacing each occurrence of setting the no_tls variable, and calling the function if that variable is set, with the actions done by that function (for the OpenSSL case, no such code is needed for GnuTLS). I have not tested this with OpenSSL, so please double check it. If you apply this, and link with GnuTLS 1.7.x, you'll become (as far as I know) the first TLS 1.2 web browser in the world! :) To test whether TLS 1.2 works for you with this patch, use: ./elinks https://test.gnutls.org:5556 Thanks, Simon diff --git a/src/network/ssl/ssl.c b/src/network/ssl/ssl.c index 3c38765..241113a 100644 --- a/src/network/ssl/ssl.c +++ b/src/network/ssl/ssl.c @@ -107,9 +107,6 @@ static struct module openssl_module = struct_module( gnutls_anon_client_credentials_t anon_cred = NULL; gnutls_certificate_credentials_t xcred = NULL; -const static int protocol_priority[16] = { - GNUTLS_TLS1, GNUTLS_SSL3, 0 -}; const static int kx_priority[16] = { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, /* Do not use anonymous authentication, unless you know what that means */ @@ -119,8 +116,6 @@ const static int cipher_priority[16] = { GNUTLS_CIPHER_RIJNDAEL_128_CBC, GNUTLS_CIPHER_ARCFOUR_128, GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_AES_256_CBC, GNUTLS_CIPHER_ARCFOUR_40, 0 }; -const static int comp_priority[16] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 }; -const static int mac_priority[16] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 }; const static int cert_type_priority[16] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 }; static void @@ -232,12 +227,10 @@ init_ssl_connection(struct socket *socket) return S_SSL_ERROR; } + gnutls_set_default_priority (*state); gnutls_handshake_set_private_extensions(*state, 1); gnutls_cipher_set_priority(*state, cipher_priority); - gnutls_compression_set_priority(*state, comp_priority); gnutls_kx_set_priority(*state, kx_priority); - gnutls_protocol_set_priority(*state, protocol_priority); - gnutls_mac_set_priority(*state, mac_priority); gnutls_certificate_type_set_priority(*state, cert_type_priority); gnutls_server_name_set(*state, GNUTLS_NAME_DNS, server_name, sizeof(server_name) - 1); diff --git a/src/network/socket.h b/src/network/socket.h index d04bdb5..205d9e5 100644 --- a/src/network/socket.h +++ b/src/network/socket.h @@ -96,7 +96,6 @@ struct socket { unsigned int protocol_family:1; /* EL_PF_INET, EL_PF_INET6 */ unsigned int need_ssl:1; /* If the socket needs SSL support */ - unsigned int no_tls:1; /* Internal SSL flag. */ unsigned int duplex:1; /* Allow simultaneous reads & writes. */ }; diff --git a/src/network/ssl/socket.c b/src/network/ssl/socket.c index 96caf8b..c4f3d86 100644 --- a/src/network/ssl/socket.c +++ b/src/network/ssl/socket.c @@ -57,98 +57,9 @@ #endif - -static void -ssl_set_no_tls(struct socket *socket) -{ -#ifdef CONFIG_OPENSSL - ((ssl_t *) socket->ssl)->options |= SSL_OP_NO_TLSv1; -#elif defined(CONFIG_GNUTLS) - /* We do a little more work here, setting up all these priorities (like - * they couldn't have some reasonable defaults there).. */ - - { - int protocol_priority[3] = { - GNUTLS_TLS1, - GNUTLS_SSL3, - 0 - }; - - gnutls_protocol_set_priority(*((ssl_t *) socket->ssl), protocol_priority); - } - - /* Note that I have no clue about these; I just put all I found here - * ;-). It is all a bit confusing for me, and I just want this to work. - * Feel free to send me patch removing useless superfluous bloat, - * thanks in advance. --pasky */ - - { - int cipher_priority[5] = { - GNUTLS_CIPHER_RIJNDAEL_128_CBC, - GNUTLS_CIPHER_3DES_CBC, - GNUTLS_CIPHER_ARCFOUR, - GNUTLS_CIPHER_RIJNDAEL_256_CBC, - 0 - }; - - gnutls_cipher_set_priority(*((ssl_t *) socket->ssl), cipher_priority); - } - - { - /* Does any httpd support this..? ;) */ - int comp_priority[3] = { - GNUTLS_COMP_ZLIB, - GNUTLS_COMP_NULL, - 0 - }; - - gnutls_compression_set_priority(*((ssl_t *) socket->ssl), comp_priority); - } - - { - int kx_priority[5] = { - GNUTLS_KX_RSA, - GNUTLS_KX_DHE_DSS, - GNUTLS_KX_DHE_RSA, - /* Looks like we don't want SRP, do we? */ - GNUTLS_KX_ANON_DH, - 0 - }; - - gnutls_kx_set_priority(*((ssl_t *) socket->ssl), kx_priority); - } - - { - int mac_priority[3] = { - GNUTLS_MAC_SHA, - GNUTLS_MAC_MD5, - 0 - }; - - gnutls_mac_set_priority(*((ssl_t *) socket->ssl), mac_priority); - } - - { - int cert_type_priority[2] = { - GNUTLS_CRT_X509, - /* We don't link with -extra now; by time of writing - * this, it's unclear where OpenPGP will end up. */ - 0 - }; - - gnutls_certificate_type_set_priority(*((ssl_t *) socket->ssl), cert_type_priority); - } - - gnutls_dh_set_prime_bits(*((ssl_t *) socket->ssl), 1024); -#endif -} - static void ssl_want_read(struct socket *socket) { - if (socket->no_tls) - ssl_set_no_tls(socket); - switch (ssl_do_connect(socket)) { case SSL_ERROR_NONE: #ifdef CONFIG_GNUTLS @@ -168,7 +79,9 @@ ssl_want_read(struct socket *socket) break; default: - socket->no_tls = 1; +#ifdef CONFIG_OPENSSL + ((ssl_t *) socket->ssl)->options |= SSL_OP_NO_TLSv1; +#endif socket->ops->retry(socket, S_SSL_ERROR); } } @@ -184,9 +97,6 @@ ssl_connect(struct socket *socket) return -1; } - if (socket->no_tls) - ssl_set_no_tls(socket); - #ifdef CONFIG_OPENSSL SSL_set_fd(socket->ssl, socket->fd); @@ -243,7 +153,9 @@ ssl_connect(struct socket *socket) default: if (ret != SSL_ERROR_NONE) { /* DBG("sslerr %s", gnutls_strerror(ret)); */ - socket->no_tls = 1; +#ifdef CONFIG_OPENSSL + ((ssl_t *) socket->ssl)->options |= SSL_OP_NO_TLSv1; +#endif } connect_socket(socket, S_SSL_ERROR); _______________________________________________ elinks-dev mailing list elinks-dev@linuxfromscratch.org http://linuxfromscratch.org/mailman/listinfo/elinks-dev