diff --git a/SOURCES/neon-0.30.0-pkcs11.patch b/SOURCES/neon-0.30.0-pkcs11.patch
new file mode 100644
index 0000000..a8d7910
--- /dev/null
+++ b/SOURCES/neon-0.30.0-pkcs11.patch
@@ -0,0 +1,300 @@
+--- neon-0.30.0/macros/neon.m4.pkcs11
++++ neon-0.30.0/macros/neon.m4
+@@ -982,10 +982,11 @@
+ 
+    # Check for functions in later releases
+    NE_CHECK_FUNCS([gnutls_session_get_data2 gnutls_x509_dn_get_rdn_ava \
+-                  gnutls_sign_callback_set \
+                   gnutls_certificate_get_issuer \
+                   gnutls_certificate_get_x509_cas \
+-                  gnutls_x509_crt_sign2])
++                  gnutls_x509_crt_sign2 \
++                  gnutls_certificate_set_retrieve_function2 \
++                  gnutls_privkey_import_ext])
+ 
+    # fail if gnutls_x509_crt_sign2 is not found (it was introduced in 1.2.0, which is required)
+    if test x${ac_cv_func_gnutls_x509_crt_sign2} != xyes; then
+@@ -1039,7 +1040,7 @@
+   ;;
+ esac
+ 
+-case ${with_pakchois}X${ac_cv_func_gnutls_sign_callback_set}Y${ne_cv_lib_ssl097} in
++case ${with_pakchois}X${ac_cv_func_gnutls_privkey_import_ext}Y${ne_cv_lib_ssl097} in
+ noX*Y*) ;;
+ *X*Yyes|*XyesY*)
+     # PKCS#11... ho!
+--- neon-0.30.0/src/ne_gnutls.c.pkcs11
++++ neon-0.30.0/src/ne_gnutls.c
+@@ -89,6 +89,13 @@
+     ne_ssl_certificate cert;
+     gnutls_x509_privkey_t pkey;
+     char *friendly_name;
++#ifdef HAVE_GNUTLS_PRIVKEY_IMPORT_EXT
++    /* Signing callback & userdata provided by ne_pkcs11.c.  It would
++     * be better to rewrite the whole module to use gnutls_privkey_t
++     * directly, but it seems impossible to dup such an object. */
++    gnutls_privkey_sign_func sign_func;
++    void *sign_ud;
++#endif
+ };
+ 
+ /* Returns the highest used index in subject (or issuer) DN of
+@@ -189,7 +196,7 @@
+ char *ne_ssl_readable_dname(const ne_ssl_dname *name)
+ {
+     gnutls_x509_dn_t dn;
+-    int ret, rdn = 0, flag = 0;
++    int ret, rdn = 0;
+     ne_buffer *buf;
+     gnutls_x509_ava_st val;
+ 
+@@ -227,7 +234,6 @@
+                 && ((!CMPOID(&val, OID_emailAddress)
+                      && !CMPOID(&val, OID_commonName))
+                     || (buf->used == 1 && rdn == 0))) {
+-                flag = 1;
+                 if (buf->used > 1) ne_buffer_append(buf, ", ", 2);
+ 
+                 append_dirstring(buf, &val.value, val.value_tag);
+@@ -526,6 +532,10 @@
+     
+     if (cc->keyless) {
+         newcc->keyless = 1;
++#ifdef HAVE_GNUTLS_PRIVKEY_IMPORT_EXT
++        newcc->sign_func = cc->sign_func;
++        newcc->sign_ud = cc->sign_ud;
++#endif
+     }
+     else {
+         ret = gnutls_x509_privkey_init(&newcc->pkey);
+@@ -554,7 +564,15 @@
+ static int provide_client_cert(gnutls_session_t session,
+                                const gnutls_datum_t *req_ca_rdn, int nreqs,
+                                const gnutls_pk_algorithm_t *sign_algos,
+-                               int sign_algos_length, gnutls_retr_st *st)
++                               int sign_algos_length, 
++#ifdef HAVE_GNUTLS_CERTIFICATE_SET_RETRIEVE_FUNCTION2
++                               gnutls_pcert_st **pcert, 
++                               unsigned int *pcert_length, 
++                               gnutls_privkey_t *pkey
++#else
++                               gnutls_retr2_st *st
++#endif
++    )
+ {
+     ne_session *sess = gnutls_session_get_ptr(session);
+     
+@@ -612,27 +630,58 @@
+     if (sess->client_cert) {
+         gnutls_certificate_type_t type = gnutls_certificate_type_get(session);
+         if (type == GNUTLS_CRT_X509
+-#if LIBGNUTLS_VERSION_NUMBER > 0x030000
+-            /* Ugly hack; prevent segfaults w/GnuTLS 3.0. */
+-            && sess->client_cert->pkey != NULL
++            && (sess->client_cert->pkey || sess->client_cert->keyless)) {
++            int ret;
++
++#ifdef HAVE_GNUTLS_CERTIFICATE_SET_RETRIEVE_FUNCTION2
++            gnutls_privkey_init(pkey);
++
++#ifdef HAVE_GNUTLS_PRIVKEY_IMPORT_EXT
++            if (sess->client_cert->sign_func) {
++                int algo = gnutls_x509_crt_get_pk_algorithm(sess->client_cert->cert.subject, NULL);
++                NE_DEBUG(NE_DBG_SSL, "ssl: Signing for %s.\n", gnutls_pk_algorithm_get_name(algo));
++                         
++                ret = gnutls_privkey_import_ext(*pkey, algo, sess->client_cert->sign_ud,
++                                                sess->client_cert->sign_func, NULL, 0);
++            }
++            else
+ #endif
+-            ) {
+-            NE_DEBUG(NE_DBG_SSL, "Supplying client certificate.\n");
++            if (sess->client_cert->keyless) {
++                ret = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
++            }
++            else {
++                ret = gnutls_privkey_import_x509(*pkey, sess->client_cert->pkey, 0);
++            }
+ 
+-            st->type = type;
++            if (ret) {
++                NE_DEBUG(NE_DBG_SSL, "ssl: Failed to import private key: %s.\n", gnutls_strerror(ret));
++                ne_set_error(sess, _("Failed to import private key: %s"), gnutls_strerror(ret));
++                return ret;
++            }
++            
++            *pcert = gnutls_calloc(1, sizeof **pcert);
++            gnutls_pcert_import_x509(*pcert, sess->client_cert->cert.subject, 0);
++            *pcert_length = 1;
++#else /* !HAVE_GNUTLS_CERTIFICATE_SET_RETRIEVE_FUNCTION2 */
++            st->cert_type = type;
+             st->ncerts = 1;
+             st->cert.x509 = &sess->client_cert->cert.subject;
+             st->key.x509 = sess->client_cert->pkey;
+             
+             /* tell GNU TLS not to deallocate the certs. */
+             st->deinit_all = 0;
++#endif
+         } else {
+             return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
+         }
+     } 
+     else {
+-        NE_DEBUG(NE_DBG_SSL, "No client certificate supplied.\n");
++        NE_DEBUG(NE_DBG_SSL, "ssl: No client certificate supplied.\n");
++#ifdef HAVE_GNUTLS_CERTIFICATE_SET_RETRIEVE_FUNCTION2
++        *pcert_length = 0;
++#else        
+         st->ncerts = 0;
++#endif
+         sess->ssl_cc_requested = 1;
+         return 0;
+     }
+@@ -650,8 +699,12 @@
+     ne_ssl_context *ctx = ne_calloc(sizeof *ctx);
+     gnutls_certificate_allocate_credentials(&ctx->cred);
+     if (flags == NE_SSL_CTX_CLIENT) {
++#ifdef HAVE_GNUTLS_CERTIFICATE_SET_RETRIEVE_FUNCTION2
++        gnutls_certificate_set_retrieve_function2(ctx->cred, provide_client_cert);
++#else
+         gnutls_certificate_client_set_retrieve_function(ctx->cred,
+                                                         provide_client_cert);
++#endif
+     }
+     gnutls_certificate_set_verify_flags(ctx->cred, 
+                                         GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
+@@ -694,7 +747,11 @@
+ {
+     gnutls_certificate_free_credentials(ctx->cred);
+     if (ctx->cache.client.data) {
++#if defined(HAVE_GNUTLS_SESSION_GET_DATA2)
++        gnutls_free(ctx->cache.client.data);
++#else
+         ne_free(ctx->cache.client.data);
++#endif
+     } else if (ctx->cache.server.key.data) {
+         gnutls_free(ctx->cache.server.key.data);
+         gnutls_free(ctx->cache.server.data.data);
+@@ -1164,7 +1221,9 @@
+     gnutls_x509_crt_t cert = NULL;
+     gnutls_x509_privkey_t pkey = NULL;
+ 
+-    data.data = buffer;
++    /* The datum structure is not modified by gnutls_pkcs12_import,
++     * cast safely: */
++    data.data = (unsigned char *)buffer;
+     data.size = buflen;
+ 
+     if (gnutls_pkcs12_init(&p12) != 0) {
+@@ -1201,8 +1260,10 @@
+     }
+ }
+ 
+-ne_ssl_client_cert *ne__ssl_clicert_exkey_import(const unsigned char *der,
+-                                                 size_t der_len)
++#ifdef HAVE_GNUTLS_PRIVKEY_IMPORT_EXT
++ne_ssl_client_cert *ne__ssl_clicert_exkey_import(const unsigned char *der, size_t der_len,
++                                                 gnutls_privkey_sign_func sign_func,
++                                                 void *userdata)
+ {
+     ne_ssl_client_cert *cc;
+     gnutls_x509_crt_t x5;
+@@ -1221,9 +1282,12 @@
+     cc->keyless = 1;
+     cc->decrypted = 1;
+     populate_cert(&cc->cert, x5);
++    cc->sign_func = sign_func;
++    cc->sign_ud = userdata;
+ 
+-    return cc;    
++    return cc;
+ }
++#endif
+ 
+ int ne_ssl_clicert_encrypted(const ne_ssl_client_cert *cc)
+ {
+--- neon-0.30.0/src/ne_pkcs11.c.pkcs11
++++ neon-0.30.0/src/ne_pkcs11.c
+@@ -160,6 +160,13 @@
+ }
+ #endif
+ 
++#ifdef HAVE_GNUTLS
++static int pk11_sign_callback(gnutls_privkey_t pkey,
++                              void *userdata,
++                              const gnutls_datum_t *raw_data,
++                              gnutls_datum_t *signature);
++#endif
++
+ static int pk11_find_x509(ne_ssl_pkcs11_provider *prov,
+                           pakchois_session_t *pks, 
+                           unsigned char *certid, unsigned long *cid_len)
+@@ -207,9 +214,9 @@
+             ne_ssl_client_cert *cc;
+             
+ #ifdef HAVE_GNUTLS
+-            cc = ne__ssl_clicert_exkey_import(value, a[0].value_len);
++            cc = ne__ssl_clicert_exkey_import(value, a[0].value_len, pk11_sign_callback, prov);
+ #else
+-            cc = ne__ssl_clicert_exkey_import(value, a[0].value_len, pk11_rsa_method(prov));
++            cc = ne__ssl_clicert_exkey_import(value, a[0].value_len, prov->method);
+ #endif
+             if (cc) {
+                 NE_DEBUG(NE_DBG_SSL, "pk11: Imported X.509 cert.\n");
+@@ -302,10 +309,8 @@
+ #ifdef HAVE_GNUTLS
+ /* Callback invoked by GnuTLS to provide the signature.  The signature
+  * operation is handled here by the PKCS#11 provider.  */
+-static int pk11_sign_callback(gnutls_session_t session,
++static int pk11_sign_callback(gnutls_privkey_t pkey,
+                               void *userdata,
+-                              gnutls_certificate_type_t cert_type,
+-                              const gnutls_datum_t *cert,
+                               const gnutls_datum_t *hash,
+                               gnutls_datum_t *signature)
+ {
+@@ -575,11 +580,6 @@
+ void ne_ssl_set_pkcs11_provider(ne_session *sess, 
+                                 ne_ssl_pkcs11_provider *provider)
+ {
+-#ifdef HAVE_GNUTLS
+-    sess->ssl_context->sign_func = pk11_sign_callback;
+-    sess->ssl_context->sign_data = provider;
+-#endif
+-
+     ne_ssl_provide_clicert(sess, pk11_provide, provider);
+ }
+ 
+--- neon-0.30.0/src/ne_privssl.h.pkcs11
++++ neon-0.30.0/src/ne_privssl.h
+@@ -58,6 +58,10 @@
+ 
+ #include <gnutls/gnutls.h>
+ 
++#ifdef HAVE_GNUTLS_PRIVKEY_IMPORT_EXT
++#include <gnutls/abstract.h>
++#endif
++
+ struct ne_ssl_context_s {
+     gnutls_certificate_credentials_t cred;
+     int verify; /* non-zero if client cert verification required */
+@@ -78,17 +82,13 @@
+         } client;
+ #endif
+     } cache;
+-
+-#ifdef HAVE_GNUTLS_SIGN_CALLBACK_SET
+-    gnutls_sign_func sign_func;
+-    void *sign_data;
+-#endif
+ };
+ 
+ typedef gnutls_session_t ne_ssl_socket;
+ 
+ NE_PRIVATE ne_ssl_client_cert *
+-ne__ssl_clicert_exkey_import(const unsigned char *der, size_t der_len);
++ne__ssl_clicert_exkey_import(const unsigned char *der, size_t der_len,
++                             gnutls_privkey_sign_func sign_func, void *userdata);
+ 
+ #endif /* HAVE_GNUTLS */
+ 
diff --git a/SPECS/neon.spec b/SPECS/neon.spec
index 598a609..d8e0956 100644
--- a/SPECS/neon.spec
+++ b/SPECS/neon.spec
@@ -1,15 +1,16 @@
 Summary: An HTTP and WebDAV client library
 Name: neon
 Version: 0.30.0
-Release: 3%{?dist}
+Release: 4%{?dist}
 License: LGPLv2+
 Group: System Environment/Libraries
 URL: http://www.webdav.org/neon/
 Source0: http://www.webdav.org/neon/neon-%{version}.tar.gz
 Patch0: neon-0.27.0-multilib.patch
+Patch1: neon-0.30.0-pkcs11.patch
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: expat-devel, gnutls-devel, zlib-devel, krb5-devel, libproxy-devel
-BuildRequires: pkgconfig, pakchois-devel
+BuildRequires: pkgconfig, pakchois-devel, autoconf, automake, libtool
 Requires: ca-certificates
 
 %description
@@ -33,8 +34,10 @@ The development library for the C language HTTP and WebDAV client library.
 %prep
 %setup -q
 %patch0 -p1 -b .multilib
+%patch1 -p1 -b .pkcs11
 
 %build
+./autogen.sh
 export CC="%{__cc} -pthread"
 # Use standard system CA bundle:
 %define cabundle %{_sysconfdir}/pki/tls/certs/ca-bundle.crt
@@ -76,6 +79,9 @@ rm -rf $RPM_BUILD_ROOT
 %{_libdir}/*.so
 
 %changelog
+* Fri Mar 22 2019 Joe Orton <jorton@redhat.com> - 0.30.0-4
+- fix PKCS#11 support (#1482769)
+
 * Fri Jan 24 2014 Daniel Mach <dmach@redhat.com> - 0.30.0-3
 - Mass rebuild 2014-01-24