diff -ruNp elinks-0.12pre2.orig/configure.in elinks-0.12pre2/configure.in --- elinks-0.12pre2.orig/configure.in 2008-10-01 10:38:34.000000000 +0200 +++ elinks-0.12pre2/configure.in 2008-10-01 10:39:43.000000000 +0200 @@ -949,6 +949,7 @@ gnutls_withval="$withval" if test "$enable_gnutls" = yes; then disable_openssl=yes; + with_nss_compat_ossl=no; fi AC_ARG_WITH(openssl, [ --without-openssl disable OpenSSL support], @@ -956,6 +957,37 @@ AC_ARG_WITH(openssl, [ --without-openss AC_ARG_WITH(openssl, [ --with-openssl[=DIR] enable OpenSSL support (default)]) openssl_withval="$withval" +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]) @@ -1078,10 +1110,11 @@ AC_MSG_RESULT($cf_result) # 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 -ruNp elinks-0.12pre2.orig/src/network/ssl/socket.c elinks-0.12pre2/src/network/ssl/socket.c --- elinks-0.12pre2.orig/src/network/ssl/socket.c 2008-09-21 10:45:22.000000000 +0200 +++ elinks-0.12pre2/src/network/ssl/socket.c 2008-10-01 10:41:01.000000000 +0200 @@ -6,6 +6,10 @@ #ifdef CONFIG_OPENSSL #include +#define USE_OPENSSL +#elif defined(CONFIG_NSS_COMPAT_OSSL) +#include +#define USE_OPENSSL #elif defined(CONFIG_GNUTLS) #include #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, unsigne 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 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 -ruNp elinks-0.12pre2.orig/src/network/ssl/ssl.c elinks-0.12pre2/src/network/ssl/ssl.c --- elinks-0.12pre2.orig/src/network/ssl/ssl.c 2008-10-01 10:38:34.000000000 +0200 +++ elinks-0.12pre2/src/network/ssl/ssl.c 2008-10-01 10:39:43.000000000 +0200 @@ -7,6 +7,10 @@ #ifdef CONFIG_OPENSSL #include #include +#define USE_OPENSSL +#elif defined(CONFIG_NSS_COMPAT_OSSL) +#include +#define USE_OPENSSL #elif defined(CONFIG_GNUTLS) #include #include @@ -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,26 @@ static struct option_info openssl_option N_("Enable or not the sending of X509 client certificates\n" "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\n" + "database. If this value is unset, the nickname from\n" + "the X509_CLIENT_CERT variable is used instead. If you\n" + "have a PKCS#12 file containing client certificate, you\n" + "can import it into your NSS database with:\n" + "$ pk12util -i mycert.p12 -d /path/to/database\n\n" + "The NSS database location can be changed by SSL_DIR\n" + "environment variable. The database can be also shared\n" + "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\n" "and unencrypted private key in PEM format. If unset, the\n" "file pointed to by the X509_CLIENT_CERT variable is used\n" "instead.")), +#endif NULL_OPTION_INFO, }; @@ -181,7 +199,7 @@ static struct module gnutls_module = str /* done: */ done_gnutls ); -#endif /* CONFIG_OPENSSL or CONFIG_GNUTLS */ +#endif /* USE_OPENSSL or CONFIG_GNUTLS */ static struct option_info ssl_options[] = { INIT_OPT_TREE("connection", N_("SSL"), @@ -192,7 +210,7 @@ static struct option_info ssl_options[] }; static struct module *ssl_modules[] = { -#ifdef CONFIG_OPENSSL +#ifdef USE_OPENSSL &openssl_module, #elif defined(CONFIG_GNUTLS) &gnutls_module, @@ -213,7 +231,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) @@ -262,7 +280,7 @@ done_ssl_connection(struct socket *socke ssl_t *ssl = socket->ssl; if (!ssl) return; -#ifdef CONFIG_OPENSSL +#ifdef USE_OPENSSL SSL_free(ssl); #elif defined(CONFIG_GNUTLS) gnutls_deinit(*ssl); @@ -279,7 +297,7 @@ get_ssl_connection_cipher(struct 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 -ruNp elinks-0.12pre2.orig/src/network/ssl/ssl.h elinks-0.12pre2/src/network/ssl/ssl.h --- elinks-0.12pre2.orig/src/network/ssl/ssl.h 2008-09-21 10:45:22.000000000 +0200 +++ elinks-0.12pre2/src/network/ssl/ssl.h 2008-10-01 10:39:43.000000000 +0200 @@ -22,7 +22,7 @@ unsigned char *get_ssl_connection_cipher /* 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