kdudka pushed to elinks (master). "use OpenSSL instead of nss_compat_ossl (..more)"

notifications at fedoraproject.org notifications at fedoraproject.org
Mon Mar 30 14:46:19 UTC 2015


>From 6e8e7242dd82677d60945515bab59cfda63cf7db Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka at redhat.com>
Date: Mon, 30 Mar 2015 16:32:24 +0200
Subject: use OpenSSL instead of nss_compat_ossl

... which is no longer maintained

diff --git a/elinks-0.12pre6-ssl-hostname.patch b/elinks-0.12pre6-ssl-hostname.patch
index 5a3820f..a51c6b8 100644
--- a/elinks-0.12pre6-ssl-hostname.patch
+++ b/elinks-0.12pre6-ssl-hostname.patch
@@ -1,70 +1,847 @@
-From cc428d37023b3f73458cf2054f19395035307045 Mon Sep 17 00:00:00 2001
-From: Kamil Dudka <kdudka at redhat.com>
-Date: Wed, 18 Sep 2013 13:42:40 +0200
-Subject: [PATCH] verify server certificate hostname with nss_compat_ossl
+From 30d96f81dbefffd3f1523256cc5a5328ea1c7ecb Mon Sep 17 00:00:00 2001
+From: Kalle Olavi Niemitalo <kon at iki.fi>
+Date: Mon, 2 May 2011 14:41:40 +0300
+Subject: [PATCH 1/3] 1024: Use RFC 3546 server_name TLS extension
 
-Bug: https://bugzilla.redhat.com/881411
+For both GnuTLS and OpenSSL.  Not tested with nss-compat-openssl.
+
+Signed-off-by: Kamil Dudka <kdudka at redhat.com>
 ---
- src/network/ssl/socket.c |   32 ++++++++++++++++++++++++++++++++
- 1 files changed, 32 insertions(+), 0 deletions(-)
+ src/network/ssl/socket.c | 19 ++++++++++++++++++-
+ src/network/ssl/ssl.c    | 29 ++++++++++++++++++++++++-----
+ src/network/ssl/ssl.h    | 14 ++++++++++++--
+ 3 files changed, 54 insertions(+), 8 deletions(-)
 
 diff --git a/src/network/ssl/socket.c b/src/network/ssl/socket.c
-index 3265107..0aeb037 100644
+index 45b4b4a..dc682d0 100644
 --- a/src/network/ssl/socket.c
 +++ b/src/network/ssl/socket.c
-@@ -9,6 +9,9 @@
- #define USE_OPENSSL
- #elif defined(CONFIG_NSS_COMPAT_OSSL)
- #include <nss_compat_ossl/nss_compat_ossl.h>
-+#include <nspr.h>		/* for PR_GetError()    */
-+#include <ssl.h>		/* for SSL_SetURL()     */
-+#include "protocol/uri.h"	/* for get_uri_string() */
- #define USE_OPENSSL
+@@ -22,6 +22,7 @@
+ #include "network/socket.h"
+ #include "network/ssl/socket.h"
+ #include "network/ssl/ssl.h"
++#include "protocol/uri.h"
+ #include "util/memory.h"
+ 
+ 
+@@ -117,12 +118,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);
+ 
+diff --git a/src/network/ssl/ssl.c b/src/network/ssl/ssl.c
+index 685c31e..7767a71 100644
+--- a/src/network/ssl/ssl.c
++++ b/src/network/ssl/ssl.c
+@@ -212,13 +212,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 CONFIG_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;
+@@ -255,9 +268,15 @@ 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); */
++
++	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
+diff --git a/src/network/ssl/ssl.h b/src/network/ssl/ssl.h
+index 7c54a7a..bfd94e1 100644
+--- a/src/network/ssl/ssl.h
++++ b/src/network/ssl/ssl.h
+@@ -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);
+-- 
+2.1.0
+
+
+From e7484a980572b665747c28aa1376e29a12fb4b19 Mon Sep 17 00:00:00 2001
+From: Kalle Olavi Niemitalo <kon at iki.fi>
+Date: Tue, 3 May 2011 03:52:21 +0300
+Subject: [PATCH 2/3] 1024: Verify server certificate hostname with OpenSSL
+
+Not tested with nss-compat-ossl.
+
+Signed-off-by: Kamil Dudka <kdudka at redhat.com>
+---
+ src/network/ssl/Makefile                   |   7 +-
+ src/network/ssl/match-hostname.c           | 125 +++++++++++++++++
+ src/network/ssl/match-hostname.h           |  10 ++
+ src/network/ssl/socket.c                   | 211 ++++++++++++++++++++++++++++-
+ src/network/ssl/ssl.c                      |  41 +++++-
+ src/network/ssl/ssl.h                      |   3 +
+ src/network/ssl/test/Makefile              |   9 ++
+ src/network/ssl/test/match-hostname-test.c | 123 +++++++++++++++++
+ src/network/ssl/test/test-match-hostname   |   3 +
+ 9 files changed, 529 insertions(+), 3 deletions(-)
+ create mode 100644 src/network/ssl/match-hostname.c
+ create mode 100644 src/network/ssl/match-hostname.h
+ create mode 100644 src/network/ssl/test/Makefile
+ create mode 100644 src/network/ssl/test/match-hostname-test.c
+ create mode 100755 src/network/ssl/test/test-match-hostname
+
+diff --git a/src/network/ssl/Makefile b/src/network/ssl/Makefile
+index 26f02c2..6f265da 100644
+--- a/src/network/ssl/Makefile
++++ b/src/network/ssl/Makefile
+@@ -3,6 +3,11 @@ include $(top_builddir)/Makefile.config
+ 
+ INCLUDES += $(GNUTLS_CFLAGS) $(OPENSSL_CFLAGS)
+ 
+-OBJS = ssl.o socket.o
++SUBDIRS = test
++
++# ELinks uses match-hostname.o only if CONFIG_OPENSSL.
++# However, match-hostname.o has test cases that always need it.
++# The test framework doesn't seem to support conditional tests.
++OBJS = match-hostname.o ssl.o socket.o
+ 
+ include $(top_srcdir)/Makefile.lib
+diff --git a/src/network/ssl/match-hostname.c b/src/network/ssl/match-hostname.c
+new file mode 100644
+index 0000000..9a64bb4
+--- /dev/null
++++ b/src/network/ssl/match-hostname.c
+@@ -0,0 +1,125 @@
++/* Matching a host name to wildcards in SSL certificates */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include "elinks.h"
++
++#include "intl/charsets.h"
++#include "network/ssl/match-hostname.h"
++#include "util/conv.h"
++#include "util/error.h"
++#include "util/string.h"
++
++/** Checks whether a host name matches a pattern that may contain
++ * wildcards.
++ *
++ * @param[in] hostname
++ *   The host name to which the user wanted to connect.
++ *   Should be in UTF-8 and need not be null-terminated.
++ * @param[in] hostname_length
++ *   The length of @a hostname, in bytes.
++ * @param[in] pattern
++ *   A pattern that the host name might match.
++ *   Should be in UTF-8 and need not be null-terminated.
++ *   The pattern may contain wildcards, as specified in
++ *   RFC 2818 section 3.1.
++ * @param[in] pattern_length
++ *   The length of @a pattern, in bytes.
++ *
++ * @return
++ *   Nonzero if the host name matches.  Zero if it doesn't.
++ *
++ * According to RFC 2818 section 3.1, '*' matches any number of
++ * characters except '.'.  For example, "*r*.example.org" matches
++ * "random.example.org" or "history.example.org" but not
++ * "frozen.fruit.example.org".
++ *
++ * This function does not allocate memory, and consumes at most
++ * O(@a hostname_length * @a pattern_length) time.  */
++int
++match_hostname_pattern(const unsigned char *hostname,
++		       size_t hostname_length,
++		       const unsigned char *pattern,
++		       size_t pattern_length)
++{
++	const unsigned char *const hostname_end = hostname + hostname_length;
++	const unsigned char *const pattern_end = pattern + pattern_length;
++
++	assert(hostname <= hostname_end);
++	assert(pattern <= pattern_end);
++	if_assert_failed return 0;
++
++	while (pattern < pattern_end) {
++		if (*pattern == '*') {
++			const unsigned char *next_wildcard;
++			size_t literal_length;
++
++			++pattern;
++			next_wildcard = memchr(pattern, '*',
++					       pattern_end - pattern);
++			if (next_wildcard == NULL)
++				literal_length = pattern_end - pattern;
++			else
++				literal_length = next_wildcard - pattern;
++
++			for (;;) {
++				size_t hostname_left = hostname_end - hostname;
++				unicode_val_T uni;
++
++				if (hostname_left < literal_length)
++					return 0;
++
++				/* If next_wildcard == NULL, then the
++				 * literal string is at the end of the
++				 * pattern, so anchor the match to the
++				 * end of the hostname.  The end of
++				 * this function can then easily
++				 * verify that the whole hostname was
++				 * matched.
++				 *
++				 * But do not jump directly there;
++				 * first verify that there are no '.'
++				 * characters in between.  */
++				if ((next_wildcard != NULL
++				     || hostname_left == literal_length)
++				    && !c_strlcasecmp(pattern, literal_length,
++						      hostname, literal_length))
++					break;
++
++				/* The literal string doesn't match here.
++				 * Skip one character of the hostname and
++				 * retry.  If the skipped character is '.'
++				 * or one of the equivalent characters
++				 * listed in RFC 3490 section 3.1
++				 * requirement 1, then return 0, because
++				 * '*' must not match such characters.
++				 * Do the same if invalid UTF-8 is found.
++				 * Cast away const.  */
++				uni = utf8_to_unicode((unsigned char **) hostname,
++						      hostname_end);
++				if (uni == 0x002E
++				    || uni == 0x3002
++				    || uni == 0xFF0E
++				    || uni == 0xFF61
++				    || uni == UCS_NO_CHAR)
++					return 0;
++			}
++
++			pattern += literal_length;
++			hostname += literal_length;
++		} else {
++			if (hostname == hostname_end)
++				return 0;
++
++			if (c_toupper(*pattern) != c_toupper(*hostname))
++				return 0;
++
++			++pattern;
++			++hostname;
++		}
++	}
++
++	return hostname == hostname_end;
++}
+diff --git a/src/network/ssl/match-hostname.h b/src/network/ssl/match-hostname.h
+new file mode 100644
+index 0000000..60d32b2
+--- /dev/null
++++ b/src/network/ssl/match-hostname.h
+@@ -0,0 +1,10 @@
++
++#ifndef EL__NETWORK_SSL_MATCH_HOSTNAME_H
++#define EL__NETWORK_SSL_MATCH_HOSTNAME_H
++
++int match_hostname_pattern(const unsigned char *hostname,
++			   size_t hostname_length,
++			   const unsigned char *pattern,
++			   size_t pattern_length);
++
++#endif
+diff --git a/src/network/ssl/socket.c b/src/network/ssl/socket.c
+index dc682d0..a67bbde 100644
+--- a/src/network/ssl/socket.c
++++ b/src/network/ssl/socket.c
+@@ -6,13 +6,24 @@
+ 
+ #ifdef CONFIG_OPENSSL
+ #include <openssl/ssl.h>
++#include <openssl/x509v3.h>
++#define USE_OPENSSL
++#elif defined(CONFIG_NSS_COMPAT_OSSL)
++#include <nss_compat_ossl/nss_compat_ossl.h>
++#define USE_OPENSSL
  #elif defined(CONFIG_GNUTLS)
  #include <gnutls/gnutls.h>
-@@ -116,6 +119,19 @@ ssl_want_read(struct socket *socket)
- 	}
+ #else
+ #error "Huh?! You have SSL enabled, but not OPENSSL nor GNUTLS!! And then you want exactly *what* from me?"
+ #endif
+ 
++#ifdef HAVE_ARPA_INET_H
++#include <arpa/inet.h>
++#endif
+ #include <errno.h>
++#ifdef HAVE_NETINET_IN_H
++#include <netinet/in.h>
++#endif
+ 
+ #include "elinks.h"
+ 
+@@ -20,6 +31,7 @@
+ #include "main/select.h"
+ #include "network/connection.h"
+ #include "network/socket.h"
++#include "network/ssl/match-hostname.h"
+ #include "network/ssl/socket.h"
+ #include "network/ssl/ssl.h"
+ #include "protocol/uri.h"
+@@ -83,6 +95,203 @@ ssl_set_no_tls(struct socket *socket)
+ #endif
  }
  
-+#ifdef CONFIG_NSS_COMPAT_OSSL
-+/* wrap nss_compat_ossl to honour SSL_ERROR_BAD_CERT_DOMAIN */
-+SECStatus BadCertHandler(void *arg, PRFileDesc *ssl);
-+static SECStatus nss_bad_cert_hook(void *arg, PRFileDesc *ssl)
++#ifdef USE_OPENSSL
++
++/** Checks whether the host component of a URI matches a host name in
++ * the server certificate.
++ *
++ * @param[in] uri_host
++ *   The host name (or IP address) to which the user wanted to connect.
++ *   Should be in UTF-8.
++ * @param[in] cert_host_asn1
++ *   A host name found in the server certificate: either as commonName
++ *   in the subject field, or as a dNSName in the subjectAltName
++ *   extension.  This may contain wildcards, as specified in RFC 2818
++ *   section 3.1.
++ *
++ * @return
++ *   Nonzero if the host matches.  Zero if it doesn't, or on error.
++ *
++ * If @a uri_host is an IP address literal rather than a host name,
++ * then this function returns 0, meaning that the host name does not match.
++ * According to RFC 2818, if the certificate is intended to match an
++ * IP address, then it must have that IP address as an iPAddress
++ * SubjectAltName, rather than in commonName.  For comparing those,
++ * match_uri_host_ip() must be used instead of this function.  */
++static int
++match_uri_host_name(const unsigned char *uri_host,
++		    ASN1_STRING *cert_host_asn1)
 +{
-+	if (SSL_ERROR_BAD_CERT_DOMAIN == PR_GetError())
-+		return SECFailure;
++	const size_t uri_host_len = strlen(uri_host);
++	unsigned char *cert_host = NULL;
++	int cert_host_len;
++	int matched = 0;
++
++	if (is_ip_address(uri_host, uri_host_len))
++		goto mismatch;
++
++	/* This function is used for both dNSName and commonName.
++	 * Although dNSName is always an IA5 string, commonName allows
++	 * many other encodings too.  Normalize all to UTF-8.  */
++	cert_host_len = ASN1_STRING_to_UTF8(&cert_host,
++					    cert_host_asn1);
++	if (cert_host_len < 0)
++		goto mismatch;
++
++	matched = match_hostname_pattern(uri_host, uri_host_len,
++					 cert_host, cert_host_len);
 +
-+	/* fallback to the default hook of nss_compat_ossl */
-+	return BadCertHandler(arg, ssl);
++mismatch:
++	if (cert_host)
++		OPENSSL_free(cert_host);
++	return matched;
 +}
++
++/** Checks whether the host component of a URI matches an IP address
++ * in the server certificate.
++ *
++ * @param[in] uri_host
++ *   The IP address (or host name) to which the user wanted to connect.
++ *   Should be in UTF-8.
++ * @param[in] cert_host_asn1
++ *   An IP address found as iPAddress in the subjectAltName extension
++ *   of the server certificate.  According to RFC 5280 section 4.2.1.6,
++ *   that is an octet string in network byte order.  According to
++ *   RFC 2818 section 3.1, wildcards are not allowed.
++ *
++ * @return
++ *   Nonzero if the host matches.  Zero if it doesn't, or on error.
++ *
++ * If @a uri_host is a host name rather than an IP address literal,
++ * then this function returns 0, meaning that the address does not match.
++ * This function does not try to resolve the host name to an IP address
++ * and compare that to @a cert_host_asn1, because such an approach would
++ * be vulnerable to DNS spoofing.
++ *
++ * This function does not support the address-and-netmask format used
++ * in the name constraints extension of a CA certificate (RFC 5280
++ * section 4.2.1.10).  */
++static int
++match_uri_host_ip(const unsigned char *uri_host,
++		  ASN1_OCTET_STRING *cert_host_asn1)
++{
++	const unsigned char *cert_host_addr = ASN1_STRING_data(cert_host_asn1);
++	struct in_addr uri_host_in;
++#ifdef CONFIG_IPV6
++	struct in6_addr uri_host_in6;
 +#endif
 +
- /* Return -1 on error, 0 or success. */
- int
- ssl_connect(struct socket *socket)
-@@ -127,6 +143,22 @@ ssl_connect(struct socket *socket)
- 		return -1;
- 	}
- 
-+#ifdef CONFIG_NSS_COMPAT_OSSL
-+	/* fix for https://bugzilla.redhat.com/881411 */
-+	{
-+		struct connection *conn = socket->conn;
-+		unsigned char *host = get_uri_string(conn->uri, URI_HOST);
-+		if (!host
-+				|| SECSuccess != SSL_SetURL(socket->ssl, host)
-+				|| SECSuccess != SSL_BadCertHook(socket->ssl,
-+					nss_bad_cert_hook, /* XXX */ NULL))
-+		{
-+			socket->ops->done(socket, connection_state(S_SSL_ERROR));
-+			return -1;
++	/* RFC 5280 defines the iPAddress alternative of GeneralName
++	 * as an OCTET STRING.  Verify that the type is indeed that.
++	 * This is an assertion because, if someone puts the wrong
++	 * type of data there, then it will not even be recognized as
++	 * an iPAddress, and this function will not be called.
++	 *
++	 * (Because GeneralName is defined in an implicitly tagged
++	 * ASN.1 module, the OCTET STRING tag is not part of the DER
++	 * encoding.  BER also allows a constructed encoding where
++	 * each substring begins with the OCTET STRING tag; but ITU-T
++	 * Rec. X.690 (07/2002) subclause 8.21 says those would be
++	 * OCTET STRING even if the outer string were of some other
++	 * type.  "A Layman's Guide to a Subset of ASN.1, BER, and
++	 * DER" (Kaliski, 1993) claims otherwise, though.)  */
++	assert(ASN1_STRING_type(cert_host_asn1) == V_ASN1_OCTET_STRING);
++	if_assert_failed return 0;
++
++	/* cert_host_addr, url_host_in, and url_host_in6 are all in
++	 * network byte order.  */
++	switch (ASN1_STRING_length(cert_host_asn1)) {
++	case 4:
++		return inet_aton(uri_host, &uri_host_in) != 0
++		    && memcmp(cert_host_addr, &uri_host_in.s_addr, 4) == 0;
++
++#ifdef CONFIG_IPV6
++	case 16:
++		return inet_pton(AF_INET6, uri_host, &uri_host_in6) == 1
++		    && memcmp(cert_host_addr, &uri_host_in6.s6_addr, 16) == 0;
++#endif
++
++	default:
++		return 0;
++	}
++}
++
++/** Verify one certificate in the server certificate chain.
++ * This callback is documented in SSL_set_verify(3).  */
++static int
++verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
++{
++	X509 *cert;
++	SSL *ssl;
++	struct socket *socket;
++	struct connection *conn;
++	unsigned char *host_in_uri;
++	GENERAL_NAMES *alts;
++	int saw_dns_name = 0;
++	int matched = 0;
++
++	/* If OpenSSL already found a problem, keep that.  */
++	if (!preverify_ok)
++		return 0;
++
++	/* Examine only the server certificate, not CA certificates.  */
++	if (X509_STORE_CTX_get_error_depth(ctx) != 0)
++		return preverify_ok;
++
++	cert = X509_STORE_CTX_get_current_cert(ctx);
++	ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
++	socket = SSL_get_ex_data(ssl, socket_SSL_ex_data_idx);
++	conn = socket->conn;
++	host_in_uri = get_uri_string(conn->uri, URI_HOST | URI_IDN);
++	if (!host_in_uri)
++		return 0;
++
++	/* RFC 5280 section 4.2.1.6 describes the subjectAltName extension.
++	 * RFC 2818 section 3.1 says Common Name must not be used
++	 * if dNSName is present.  */
++	alts = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
++	if (alts != NULL) {
++		int alt_count;
++		int alt_pos;
++		GENERAL_NAME *alt;
++
++		alt_count = sk_GENERAL_NAME_num(alts);
++		for (alt_pos = 0; !matched && alt_pos < alt_count; ++alt_pos) {
++			alt = sk_GENERAL_NAME_value(alts, alt_pos);
++			if (alt->type == GEN_DNS) {
++				saw_dns_name = 1;
++				matched = match_uri_host_name(host_in_uri,
++							      alt->d.dNSName);
++			} else if (alt->type == GEN_IPADD) {
++				matched = match_uri_host_ip(host_in_uri,
++							    alt->d.iPAddress);
++			}
 +		}
++
++		/* Free the GENERAL_NAMES list and each element.  */
++		sk_GENERAL_NAME_pop_free(alts, GENERAL_NAME_free);
 +	}
-+#endif
 +
- 	if (socket->no_tls)
- 		ssl_set_no_tls(socket);
++	if (!matched && !saw_dns_name) {
++		X509_NAME *name;
++		int cn_index;
++		X509_NAME_ENTRY *entry = NULL;
++
++		name = X509_get_subject_name(cert);
++		cn_index = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
++		if (cn_index >= 0)
++			entry = X509_NAME_get_entry(name, cn_index);
++		if (entry != NULL)
++			matched = match_uri_host_name(host_in_uri,
++						      X509_NAME_ENTRY_get_data(entry));
++	}
++
++	mem_free(host_in_uri);
++	return matched;
++}
++
++#endif	/* USE_OPENSSL */
++
+ static void
+ ssl_want_read(struct socket *socket)
+ {
+@@ -149,7 +358,7 @@ ssl_connect(struct socket *socket)
+ 	if (get_opt_bool("connection.ssl.cert_verify"))
+ 		SSL_set_verify(socket->ssl, SSL_VERIFY_PEER
+ 					  | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+-				NULL);
++			       verify_callback);
+ 
+ 	if (get_opt_bool("connection.ssl.client_cert.enable")) {
+ 		unsigned char *client_cert;
+diff --git a/src/network/ssl/ssl.c b/src/network/ssl/ssl.c
+index 7767a71..d1881c8 100644
+--- a/src/network/ssl/ssl.c
++++ b/src/network/ssl/ssl.c
+@@ -39,7 +39,35 @@
+ #define	PATH_MAX	256 /* according to my /usr/include/bits/posix1_lim.h */
+ #endif
+ 
+-SSL_CTX *context = NULL;
++static SSL_CTX *context = NULL;
++int socket_SSL_ex_data_idx = -1;
++
++/** Prevent SSL_dup() if the SSL is associated with struct socket.
++ * We cannot copy struct socket and it doesn't have a reference count
++ * either.  */
++static int
++socket_SSL_ex_data_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from,
++		       void *from_d, int idx, long argl, void *argp)
++{
++	/* The documentation of from_d in RSA_get_ex_new_index(3)
++	 * is a bit unclear.  The caller does something like:
++	 *
++	 * void *data = CRYPTO_get_ex_data(from, idx);
++	 * socket_SSL_dup(to, from, &data, idx, argl, argp);
++	 * CRYPTO_set_ex_data(to, idx, data);
++	 *
++	 * i.e., from_d always points to a pointer, even though
++	 * it is just a void * in the prototype.  */
++	struct socket *socket = *(void **) from_d;
++
++	assert(idx == socket_SSL_ex_data_idx);
++	if_assert_failed return 0;
++
++	if (socket)
++		return 0;	/* prevent SSL_dup() */
++	else
++		return 1;	/* allow SSL_dup() */
++}
+ 
+ static void
+ init_openssl(struct module *module)
+@@ -48,12 +76,17 @@ init_openssl(struct module *module)
+ 	context = SSL_CTX_new(SSLv23_client_method());
+ 	SSL_CTX_set_options(context, SSL_OP_ALL);
+ 	SSL_CTX_set_default_verify_paths(context);
++	socket_SSL_ex_data_idx = SSL_get_ex_new_index(0, NULL,
++						      NULL,
++						      socket_SSL_ex_data_dup,
++						      NULL);
+ }
+ 
+ static void
+ done_openssl(struct module *module)
+ {
+ 	if (context) SSL_CTX_free(context);
++	/* There is no function that undoes SSL_get_ex_new_index.  */
+ }
+ 
+ static union option_info openssl_options[] = {
+@@ -219,6 +252,12 @@ init_ssl_connection(struct socket *socket,
+ 	socket->ssl = SSL_new(context);
+ 	if (!socket->ssl) return S_SSL_ERROR;
+ 
++	if (!SSL_set_ex_data(socket->ssl, socket_SSL_ex_data_idx, socket)) {
++		SSL_free(socket->ssl);
++		socket->ssl = NULL;
++		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
+diff --git a/src/network/ssl/ssl.h b/src/network/ssl/ssl.h
+index bfd94e1..480b4db 100644
+--- a/src/network/ssl/ssl.h
++++ b/src/network/ssl/ssl.h
+@@ -29,6 +29,9 @@ void done_ssl_connection(struct socket *socket);
  
+ unsigned char *get_ssl_connection_cipher(struct socket *socket);
+ 
++#if defined(CONFIG_OPENSSL) || defined(CONFIG_NSS_COMPAT_OSSL)
++extern int socket_SSL_ex_data_idx;
++#endif
+ 
+ /* Internal type used in ssl module. */
+ 
+diff --git a/src/network/ssl/test/Makefile b/src/network/ssl/test/Makefile
+new file mode 100644
+index 0000000..f2196eb
+--- /dev/null
++++ b/src/network/ssl/test/Makefile
+@@ -0,0 +1,9 @@
++top_builddir=../../../..
++include $(top_builddir)/Makefile.config
++
++SUBDIRS = 
++TEST_PROGS = match-hostname-test
++TESTDEPS += \
++ $(top_builddir)/src/network/ssl/match-hostname.o
++
++include $(top_srcdir)/Makefile.lib
+diff --git a/src/network/ssl/test/match-hostname-test.c b/src/network/ssl/test/match-hostname-test.c
+new file mode 100644
+index 0000000..fbdf6fa
+--- /dev/null
++++ b/src/network/ssl/test/match-hostname-test.c
+@@ -0,0 +1,123 @@
++/* Test match_hostname_pattern() */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include <stdio.h>
++#include <stdlib.h>
++
++#include "elinks.h"
++
++#include "network/ssl/match-hostname.h"
++#include "util/string.h"
++
++struct match_hostname_pattern_test_case
++{
++	const unsigned char *pattern;
++	const unsigned char *hostname;
++	int match;
++};
++
++static const struct match_hostname_pattern_test_case match_hostname_pattern_test_cases[] = {
++	{ "*r*.example.org", "random.example.org", 1 },
++	{ "*r*.example.org", "history.example.org", 1 },
++	{ "*r*.example.org", "frozen.fruit.example.org", 0 },
++	{ "*r*.example.org", "steamed.fruit.example.org", 0 },
++
++	{ "ABC.def.Ghi", "abc.DEF.gHI", 1 },
++
++	{ "*", "localhost", 1 },
++	{ "*", "example.org", 0 },
++	{ "*.*", "example.org", 1 },
++	{ "*.*.*", "www.example.org", 1 },
++	{ "*.*.*", "example.org", 0 },
++
++	{ "assign", "assignee", 0 },
++	{ "*peg", "arpeggiator", 0 },
++	{ "*peg*", "arpeggiator", 1 },
++	{ "*r*gi*", "arpeggiator", 1 },
++	{ "*r*git*", "arpeggiator", 0 },
++
++	{ NULL, NULL, 0 }
++};
++
++int
++main(void)
++{
++	const struct match_hostname_pattern_test_case *test;
++	int count_ok = 0;
++	int count_fail = 0;
++	struct string hostname_str = NULL_STRING;
++	struct string pattern_str = NULL_STRING;
++
++	if (!init_string(&hostname_str) || !init_string(&pattern_str)) {
++		fputs("Out of memory.\n", stderr);
++		done_string(&hostname_str);
++		done_string(&pattern_str);
++		return EXIT_FAILURE;
++	}
++
++	for (test = match_hostname_pattern_test_cases; test->pattern; test++) {
++		int match;
++
++		match = match_hostname_pattern(
++			test->hostname,
++			strlen(test->hostname),
++			test->pattern,
++			strlen(test->pattern));
++		if (!match == !test->match) {
++			/* Test OK */
++			count_ok++;
++		} else {
++			fprintf(stderr, "match_hostname_pattern() test failed\n"
++				"\tHostname: %s\n"
++				"\tPattern: %s\n"
++				"\tActual result: %d\n"
++				"\tCorrect result: %d\n",
++				test->hostname,
++				test->pattern,
++				match,
++				test->match);
++			count_fail++;
++		}
++
++		/* Try with strings that are not null-terminated.  */
++		hostname_str.length = 0;
++		add_to_string(&hostname_str, test->hostname);
++		add_to_string(&hostname_str, "ZZZ");
++		pattern_str.length = 0;
++		add_to_string(&pattern_str, test->pattern);
++		add_to_string(&hostname_str, "______");
++
++		match = match_hostname_pattern(
++			hostname_str.source,
++			strlen(test->hostname),
++			pattern_str.source,
++			strlen(test->pattern));
++		if (!match == !test->match) {
++			/* Test OK */
++			count_ok++;
++		} else {
++			fprintf(stderr, "match_hostname_pattern() test failed\n"
++				"\tVariant: Strings were not null-terminated.\n"
++				"\tHostname: %s\n"
++				"\tPattern: %s\n"
++				"\tActual result: %d\n"
++				"\tCorrect result: %d\n",
++				test->hostname,
++				test->pattern,
++				match,
++				test->match);
++			count_fail++;
++		}
++	}
++
++	printf("Summary of match_hostname_pattern() tests: %d OK, %d failed.\n",
++	       count_ok, count_fail);
++
++	done_string(&hostname_str);
++	done_string(&pattern_str);
++	return count_fail ? EXIT_FAILURE : EXIT_SUCCESS;
++	
++}
+diff --git a/src/network/ssl/test/test-match-hostname b/src/network/ssl/test/test-match-hostname
+new file mode 100755
+index 0000000..01d7173
+--- /dev/null
++++ b/src/network/ssl/test/test-match-hostname
+@@ -0,0 +1,3 @@
++#! /bin/sh -e
++
++./match-hostname-test
+-- 
+2.1.0
+
+
+From 0cb6967bb9ccabc583bbdc6ee76baf4fdf0f90cc Mon Sep 17 00:00:00 2001
+From: mancha <mancha at mac.hush.com>
+Date: Sun, 15 Jul 2012 23:27:53 +0200
+Subject: [PATCH 3/3] Fix hostname verification code.
+
+[ From bug 1123 attachment 569.  --KON ]
+
+Signed-off-by: Kamil Dudka <kdudka at redhat.com>
+---
+ src/network/ssl/match-hostname.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/network/ssl/match-hostname.c b/src/network/ssl/match-hostname.c
+index 9a64bb4..80d93b0 100644
+--- a/src/network/ssl/match-hostname.c
++++ b/src/network/ssl/match-hostname.c
+@@ -97,7 +97,7 @@ match_hostname_pattern(const unsigned char *hostname,
+ 				 * '*' must not match such characters.
+ 				 * Do the same if invalid UTF-8 is found.
+ 				 * Cast away const.  */
+-				uni = utf8_to_unicode((unsigned char **) hostname,
++				uni = utf8_to_unicode((unsigned char **) &hostname,
+ 						      hostname_end);
+ 				if (uni == 0x002E
+ 				    || uni == 0x3002
 -- 
-1.7.1
+2.1.0
 
diff --git a/elinks-nss-inc.patch b/elinks-nss-inc.patch
deleted file mode 100644
index 666fc6b..0000000
--- a/elinks-nss-inc.patch
+++ /dev/null
@@ -1,69 +0,0 @@
- src/network/ssl/ssl.c |   33 ++++++++++++++++++++++++++++++++-
- 1 files changed, 32 insertions(+), 1 deletions(-)
-
-diff --git a/src/network/ssl/ssl.c b/src/network/ssl/ssl.c
-index 73446b5..eadff7f 100644
---- a/src/network/ssl/ssl.c
-+++ b/src/network/ssl/ssl.c
-@@ -48,10 +48,20 @@ SSL_CTX *context = NULL;
- static void
- init_openssl(struct module *module)
- {
-+	unsigned char *ca_file;
- 	SSLeay_add_ssl_algorithms();
- 	context = SSL_CTX_new(SSLv23_client_method());
- 	SSL_CTX_set_options(context, SSL_OP_ALL);
-+#ifdef CONFIG_NSS_COMPAT_OSSL
-+	ca_file = get_opt_str("connection.ssl.trusted_ca_file");
-+	if (*ca_file)
-+		SSL_CTX_load_verify_locations(context, ca_file, NULL);
-+	else
-+		SSL_CTX_set_default_verify_paths(context);
-+#else
-+	(void) ca_file;
- 	SSL_CTX_set_default_verify_paths(context);
-+#endif
- }
- 
- static void
-@@ -61,10 +71,30 @@ done_openssl(struct module *module)
- }
- 
- static union option_info openssl_options[] = {
-+#ifdef CONFIG_NSS_COMPAT_OSSL
-+	INIT_OPT_BOOL("connection.ssl", N_("Verify certificates"),
-+		"cert_verify", 0, 0,
-+		N_("Verify the peer's SSL certificate.")),
-+
-+	INIT_OPT_STRING("connection.ssl", N_("Trusted CA file"),
-+		"trusted_ca_file", 0, "/etc/pki/tls/certs/ca-bundle.crt",
-+		N_("The location of a file containing certificates of "
-+		"trusted certification authorities in PEM format. "
-+		"ELinks then trusts certificates issued by these CAs.\n"
-+		"\n"
-+		"If you set this option to an empty string, default NSS root"
-+		"certificates are loaded.\n"
-+		"\n"
-+		"If you change this option or the file, you must "
-+		"restart ELinks for the changes to take effect. "
-+		"This option affects GnuTLS and nss_compat_ossl but not "
-+		"OpenSSL.")),
-+#else
- 	INIT_OPT_BOOL("connection.ssl", N_("Verify certificates"),
- 		"cert_verify", 0, 0,
- 		N_("Verify the peer's SSL certificate. Note that this "
- 		"needs extensive configuration of OpenSSL by the user.")),
-+#endif
- 
- 	INIT_OPT_TREE("connection.ssl", N_("Client Certificates"),
-         	"client_cert", OPT_SORT,
-@@ -187,7 +217,8 @@ static union option_info gnutls_options[] = {
- 		"\n"
- 		"If you change this option or the file, you must "
- 		"restart ELinks for the changes to take effect. "
--		"This option affects GnuTLS but not OpenSSL.")),
-+		"This option affects GnuTLS and nss_compat_ossl but not "
-+		"OpenSSL.")),
- 
- 	NULL_OPTION_INFO,
- };
diff --git a/elinks-nss.patch b/elinks-nss.patch
deleted file mode 100644
index 893505c..0000000
--- a/elinks-nss.patch
+++ /dev/null
@@ -1,265 +0,0 @@
- configure.in             |   34 +++++++++++++++++++++++++++++++++-
- src/network/ssl/socket.c |   28 ++++++++++++++++++++++------
- src/network/ssl/ssl.c    |   32 ++++++++++++++++++++++++++------
- src/network/ssl/ssl.h    |    2 +-
- 4 files changed, 82 insertions(+), 14 deletions(-)
-
-diff --git a/configure.in b/configure.in
-index 0e534db..972a305 100644
---- a/configure.in
-+++ b/configure.in
-@@ -970,6 +970,37 @@ AC_ARG_WITH(openssl, [[  --with-openssl[=DIR]    enable OpenSSL support (default
- 		*)	chosen_ssl_library="OpenSSL" ;;
- 	     esac])
- 
-+AC_ARG_WITH(nss_compat_ossl, [[  --with-nss_compat_ossl[=DIR]
-+                          NSS compatibility SSL libraries/include files]])
-+
-+# nss_compat_ossl
-+if test -n "$with_nss_compat_ossl" && test "$with_nss_compat_ossl" != "no"; then
-+	EL_SAVE_FLAGS
-+	if test "$with_nss_compat_ossl" = yes; then
-+		if pkg-config nss; then
-+			CFLAGS="$CFLAGS_X `pkg-config --cflags nss`"
-+			LIBS="$LIBS_X `pkg-config --libs nss`"
-+		else
-+			with_nss_compat_ossl=no
-+		fi
-+	else
-+		# Without pkg-config, we'll kludge in some defaults
-+		CFLAGS="$CFLAGS_X -I$with_nss_compat_ossl/include -I/usr/include/nss3 -I/usr/include/nspr4"
-+		LIBS="$LIBS_X -L$with_nss_compat_ossl/lib -lssl3 -lsmime3 -lnss3 -lplds4 -lplc4 -lnspr4 -lpthread -ldl"
-+	fi
-+	AC_CHECK_HEADERS(nss_compat_ossl/nss_compat_ossl.h,, [with_nss_compat_ossl=no], [#define NSS_COMPAT_OSSL_H])
-+	AC_CHECK_LIB(nss_compat_ossl, X509_free,, [with_nss_compat_ossl=no])
-+
-+	if test "$with_nss_compat_ossl" = "no"; then
-+		EL_RESTORE_FLAGS
-+	else
-+		LIBS="$LIBS -lnss_compat_ossl"
-+		EL_CONFIG(CONFIG_NSS_COMPAT_OSSL, [nss_compat_ossl])
-+		disable_openssl="yes"
-+		disable_gnutls="yes"
-+	fi
-+fi
-+
- # ---- OpenSSL
- 
- AC_MSG_CHECKING([for OpenSSL])
-@@ -1092,10 +1123,11 @@ fi
- 
- # Final SSL setup
- 
--EL_CONFIG_DEPENDS(CONFIG_SSL, [CONFIG_OPENSSL CONFIG_GNUTLS], [SSL])
-+EL_CONFIG_DEPENDS(CONFIG_SSL, [CONFIG_OPENSSL CONFIG_GNUTLS CONFIG_NSS_COMPAT_OSSL], [SSL])
- AC_SUBST(CONFIG_GNUTLS_OPENSSL_COMPAT)
- AC_SUBST(CONFIG_OPENSSL)
- AC_SUBST(CONFIG_GNUTLS)
-+AC_SUBST(CONFIG_NSS_COMPAT_OSSL)
- 
- #endif
- 
-diff --git a/src/network/ssl/socket.c b/src/network/ssl/socket.c
-index 45b4b4a..3265107 100644
---- a/src/network/ssl/socket.c
-+++ b/src/network/ssl/socket.c
-@@ -6,6 +6,10 @@
- 
- #ifdef CONFIG_OPENSSL
- #include <openssl/ssl.h>
-+#define USE_OPENSSL
-+#elif defined(CONFIG_NSS_COMPAT_OSSL)
-+#include <nss_compat_ossl/nss_compat_ossl.h>
-+#define USE_OPENSSL
- #elif defined(CONFIG_GNUTLS)
- #include <gnutls/gnutls.h>
- #else
-@@ -26,7 +30,7 @@
- 
- 
- /* SSL errors */
--#ifdef CONFIG_OPENSSL
-+#ifdef USE_OPENSSL
- #define	SSL_ERROR_WANT_READ2	9999 /* XXX */
- #define	SSL_ERROR_WANT_WRITE2	SSL_ERROR_WANT_WRITE
- #define	SSL_ERROR_SYSCALL2	SSL_ERROR_SYSCALL
-@@ -40,7 +44,7 @@
- #define	SSL_ERROR_SYSCALL2	GNUTLS_E_PULL_ERROR
- #endif
- 
--#ifdef CONFIG_OPENSSL
-+#ifdef USE_OPENSSL
- 
- #define ssl_do_connect(socket)		SSL_get_error(socket->ssl, SSL_connect(socket->ssl))
- #define ssl_do_write(socket, data, len)	SSL_write(socket->ssl, data, len)
-@@ -126,7 +130,7 @@ ssl_connect(struct socket *socket)
- 	if (socket->no_tls)
- 		ssl_set_no_tls(socket);
- 
--#ifdef CONFIG_OPENSSL
-+#ifdef USE_OPENSSL
- 	SSL_set_fd(socket->ssl, socket->fd);
- 
- 	if (get_opt_bool("connection.ssl.cert_verify"))
-@@ -137,7 +141,13 @@ ssl_connect(struct socket *socket)
- 	if (get_opt_bool("connection.ssl.client_cert.enable")) {
- 		unsigned char *client_cert;
- 
--		client_cert = get_opt_str("connection.ssl.client_cert.file");
-+#ifdef CONFIG_NSS_COMPAT_OSSL
-+		client_cert = get_opt_str(
-+				"connection.ssl.client_cert.nickname");
-+#else
-+		client_cert = get_opt_str(
-+				"connection.ssl.client_cert.file");
-+#endif
- 		if (!*client_cert) {
- 			client_cert = getenv("X509_CLIENT_CERT");
- 			if (client_cert && !*client_cert)
-@@ -145,11 +155,17 @@ ssl_connect(struct socket *socket)
- 		}
- 
- 		if (client_cert) {
-+#ifdef CONFIG_NSS_COMPAT_OSSL
-+			SSL_CTX_use_certificate_chain_file(
-+					(SSL *) socket->ssl,
-+					client_cert);
-+#else
- 			SSL_CTX *ctx = ((SSL *) socket->ssl)->ctx;
- 
- 			SSL_CTX_use_certificate_chain_file(ctx, client_cert);
- 			SSL_CTX_use_PrivateKey_file(ctx, client_cert,
- 						    SSL_FILETYPE_PEM);
-+#endif
- 		}
- 	}
- 
-@@ -206,7 +222,7 @@ ssl_write(struct socket *socket, unsigned char *data, int len)
- 	ssize_t wr = ssl_do_write(socket, data, len);
- 
- 	if (wr <= 0) {
--#ifdef CONFIG_OPENSSL
-+#ifdef USE_OPENSSL
- 		int err = SSL_get_error(socket->ssl, wr);
- #elif defined(CONFIG_GNUTLS)
- 		int err = wr;
-@@ -235,7 +251,7 @@ ssl_read(struct socket *socket, unsigned char *data, int len)
- 	ssize_t rd = ssl_do_read(socket, data, len);
- 
- 	if (rd <= 0) {
--#ifdef CONFIG_OPENSSL
-+#ifdef USE_OPENSSL
- 		int err = SSL_get_error(socket->ssl, rd);
- #elif defined(CONFIG_GNUTLS)
- 		int err = rd;
-diff --git a/src/network/ssl/ssl.c b/src/network/ssl/ssl.c
-index 685c31e..73446b5 100644
---- a/src/network/ssl/ssl.c
-+++ b/src/network/ssl/ssl.c
-@@ -7,6 +7,10 @@
- #ifdef CONFIG_OPENSSL
- #include <openssl/ssl.h>
- #include <openssl/rand.h>
-+#define USE_OPENSSL
-+#elif defined(CONFIG_NSS_COMPAT_OSSL)
-+#include <nss_compat_ossl/nss_compat_ossl.h>
-+#define USE_OPENSSL
- #elif defined(CONFIG_GNUTLS)
- #include <gnutls/gnutls.h>
- #include <gnutls/x509.h>
-@@ -33,7 +37,7 @@
- /* FIXME: As you can see, SSL is currently implemented in very, erm,
-  * decentralized manner. */
- 
--#ifdef CONFIG_OPENSSL
-+#ifdef USE_OPENSSL
- 
- #ifndef PATH_MAX
- #define	PATH_MAX	256 /* according to my /usr/include/bits/posix1_lim.h */
-@@ -71,12 +75,28 @@ static union option_info openssl_options[] = {
- 		N_("Enable or not the sending of X509 client certificates "
- 		"to servers which request them.")),
- 
-+#ifdef CONFIG_NSS_COMPAT_OSSL
-+	INIT_OPT_STRING("connection.ssl.client_cert", N_("Certificate nickname"),
-+		"nickname", 0, "",
-+		N_("The nickname of the client certificate stored in NSS "
-+		"database. If this value is unset, the nickname from "
-+		"the X509_CLIENT_CERT variable is used instead. If you "
-+		"have a PKCS#12 file containing client certificate, you "
-+		"can import it into your NSS database with:\n"
-+		"\n"
-+		"$ pk12util -i mycert.p12 -d /path/to/database\n"
-+		"\n"
-+		"The NSS database location can be changed by SSL_DIR "
-+		"environment variable. The database can be also shared "
-+		"with Mozilla browsers.")),
-+#else
- 	INIT_OPT_STRING("connection.ssl.client_cert", N_("Certificate File"),
- 		"file", 0, "",
- 		N_("The location of a file containing the client certificate "
- 		"and unencrypted private key in PEM format. If unset, the "
- 		"file pointed to by the X509_CLIENT_CERT variable is used "
- 		"instead.")),
-+#endif
- 
- 	NULL_OPTION_INFO,
- };
-@@ -182,7 +202,7 @@ static struct module gnutls_module = struct_module(
- 	/* done: */		done_gnutls
- );
- 
--#endif /* CONFIG_OPENSSL or CONFIG_GNUTLS */
-+#endif /* USE_OPENSSL or CONFIG_GNUTLS */
- 
- static union option_info ssl_options[] = {
- 	INIT_OPT_TREE("connection", N_("SSL"),
-@@ -193,7 +213,7 @@ static union option_info ssl_options[] = {
- };
- 
- static struct module *ssl_modules[] = {
--#ifdef CONFIG_OPENSSL
-+#ifdef USE_OPENSSL
- 	&openssl_module,
- #elif defined(CONFIG_GNUTLS)
- 	&gnutls_module,
-@@ -214,7 +234,7 @@ struct module ssl_module = struct_module(
- int
- init_ssl_connection(struct socket *socket)
- {
--#ifdef CONFIG_OPENSSL
-+#ifdef USE_OPENSSL
- 	socket->ssl = SSL_new(context);
- 	if (!socket->ssl) return S_SSL_ERROR;
- #elif defined(CONFIG_GNUTLS)
-@@ -271,7 +291,7 @@ done_ssl_connection(struct socket *socket)
- 	ssl_t *ssl = socket->ssl;
- 
- 	if (!ssl) return;
--#ifdef CONFIG_OPENSSL
-+#ifdef USE_OPENSSL
- 	SSL_free(ssl);
- #elif defined(CONFIG_GNUTLS)
- 	gnutls_deinit(*ssl);
-@@ -288,7 +308,7 @@ get_ssl_connection_cipher(struct socket *socket)
- 
- 	if (!init_string(&str)) return NULL;
- 
--#ifdef CONFIG_OPENSSL
-+#ifdef USE_OPENSSL
- 	add_format_to_string(&str, "%ld-bit %s %s",
- 		SSL_get_cipher_bits(ssl, NULL),
- 		SSL_get_cipher_version(ssl),
-diff --git a/src/network/ssl/ssl.h b/src/network/ssl/ssl.h
-index 7c54a7a..21ca142 100644
---- a/src/network/ssl/ssl.h
-+++ b/src/network/ssl/ssl.h
-@@ -22,7 +22,7 @@ unsigned char *get_ssl_connection_cipher(struct socket *socket);
- 
- /* Internal type used in ssl module. */
- 
--#ifdef CONFIG_OPENSSL
-+#if defined(CONFIG_OPENSSL) || defined(CONFIG_NSS_COMPAT_OSSL)
- #define	ssl_t	SSL
- #elif defined(CONFIG_GNUTLS)
- #define	ssl_t	gnutls_session_t
diff --git a/elinks.spec b/elinks.spec
index a55fe6d..650ef0c 100644
--- a/elinks.spec
+++ b/elinks.spec
@@ -3,7 +3,7 @@
 Name:      elinks
 Summary:   A text-mode Web browser
 Version:   0.12
-Release:   0.43.%{prerel}%{?dist}
+Release:   0.44.%{prerel}%{?dist}
 License:   GPLv2
 URL:       http://elinks.or.cz
 Group:     Applications/Internet
@@ -18,7 +18,7 @@ BuildRequires: js-devel
 BuildRequires: krb5-devel
 BuildRequires: libidn2-devel
 BuildRequires: lua-devel
-BuildRequires: nss_compat_ossl-devel
+BuildRequires: openssl-devel
 BuildRequires: pkgconfig
 BuildRequires: zlib-devel
 Requires(preun): %{_sbindir}/alternatives
@@ -37,8 +37,6 @@ Patch4: elinks-0.11.0-sysname.patch
 Patch5: elinks-0.10.1-xterm.patch
 Patch7: elinks-0.11.3-macropen.patch
 Patch8: elinks-scroll.patch
-Patch9: elinks-nss.patch
-Patch10: elinks-nss-inc.patch
 Patch11: elinks-0.12pre5-js185.patch
 Patch12: elinks-0.12pre5-ddg-search.patch
 Patch13: elinks-0.12pre6-autoconf.patch
@@ -77,12 +75,6 @@ quickly and swiftly displays Web pages.
 #upstream fix for out of screen dialogs
 %patch8 -p1
 
-# Port elinks to use NSS library for cryptography (#346861) - accepted upstream
-%patch9 -p1
-
-# Port elinks to use NSS library for cryptography (#346861) - incremental patch
-%patch10 -p1
-
 # backported upstream commits f31cf6f, 2844f8b, 218a225, and 12803e4
 %patch11 -p1
 
@@ -92,7 +84,7 @@ quickly and swiftly displays Web pages.
 # add missing AC_LANG_PROGRAM around the first argument of AC_COMPILE_IFELSE
 %patch13 -p1
 
-# verify server certificate hostname with nss_compat_ossl (#881411)
+# verify server certificate hostname with OpenSSL (#881411)
 %patch14 -p1
 
 # let list_is_singleton() return false for an empty list (#1075415)
@@ -114,9 +106,14 @@ autoheader
 
 %build
 export CFLAGS="$RPM_OPT_FLAGS $(getconf LFS_CFLAGS) -D_GNU_SOURCE"
-%configure %{?rescue:--without-gpm} --without-x --with-gssapi \
-  --enable-bittorrent --with-nss_compat_ossl --enable-256-colors \
-  --without-openssl --without-gnutls --with-lua
+%configure %{?rescue:--without-gpm} \
+    --enable-256-colors             \
+    --enable-bittorrent             \
+    --with-gssapi                   \
+    --with-lua                      \
+    --with-openssl                  \
+    --without-gnutls                \
+    --without-x
 
 # uncomment to turn off optimizations
 #sed -i 's/-O2/-O0/' Makefile.config
@@ -172,6 +169,9 @@ exit 0
 %{_mandir}/man5/*
 
 %changelog
+* Mon Mar 30 2015 Kamil Dudka <kdudka at redhat.com> - 0.12-0.44.pre6
+- use OpenSSL instead of nss_compat_ossl, which is no longer maintained
+
 * Fri Jan 16 2015 Tom Callaway <spot at fedoraproject.org> - 0.12-0.43.pre6
 - rebuild for lua 5.3
 
-- 
cgit v0.10.2


	http://pkgs.fedoraproject.org/cgit/elinks.git/commit/?h=master&id=6e8e7242dd82677d60945515bab59cfda63cf7db


More information about the scm-commits mailing list