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