diff --git a/.gitignore b/.gitignore
index 2f0aa7d..a1fb9dd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/gnutls-3.3.24-hobbled.tar.xz
+SOURCES/gnutls-3.3.26-hobbled.tar.xz
diff --git a/.gnutls.metadata b/.gnutls.metadata
index 70743da..695a36c 100644
--- a/.gnutls.metadata
+++ b/.gnutls.metadata
@@ -1 +1 @@
-8e6860e7208db4b695e28c0389df1965161015b9 SOURCES/gnutls-3.3.24-hobbled.tar.xz
+d3ec13b080bd01c7705e81f5a5e80284e571115c SOURCES/gnutls-3.3.26-hobbled.tar.xz
diff --git a/SOURCES/gnutls-3.3.26-cve-2017-7869.patch b/SOURCES/gnutls-3.3.26-cve-2017-7869.patch
new file mode 100644
index 0000000..d2ddc38
--- /dev/null
+++ b/SOURCES/gnutls-3.3.26-cve-2017-7869.patch
@@ -0,0 +1,235 @@
+diff --git a/lib/opencdk/kbnode.c b/lib/opencdk/kbnode.c
+index c28cb34..f865b16 100644
+--- a/lib/opencdk/kbnode.c
++++ b/lib/opencdk/kbnode.c
+@@ -369,12 +369,14 @@ cdk_packet_t cdk_kbnode_get_packet(cdk_kbnode_t node)
+  * @armor: whether base64 or not
+  * @buf: the buffer which stores the key sequence
+  * @buflen: the length of the buffer
++ * @public: non-zero if reading a public key
+  *
+  * Tries to read a key node from the memory buffer @buf.
+  **/
+ cdk_error_t
+ cdk_kbnode_read_from_mem(cdk_kbnode_t * ret_node,
+-			 int armor, const byte * buf, size_t buflen)
++			 int armor, const byte * buf, size_t buflen,
++			 unsigned public)
+ {
+ 	cdk_stream_t inp;
+ 	cdk_error_t rc;
+@@ -393,7 +395,7 @@ cdk_kbnode_read_from_mem(cdk_kbnode_t * ret_node,
+ 	if (armor)
+ 		cdk_stream_set_armor_flag(inp, 0);
+ 
+-	rc = cdk_keydb_get_keyblock(inp, ret_node);
++	rc = cdk_keydb_get_keyblock(inp, ret_node, public);
+ 	if (rc)
+ 		gnutls_assert();
+ 	cdk_stream_close(inp);
+diff --git a/lib/opencdk/keydb.c b/lib/opencdk/keydb.c
+index 64eebf0..9112d9a 100644
+--- a/lib/opencdk/keydb.c
++++ b/lib/opencdk/keydb.c
+@@ -108,7 +108,7 @@ static cdk_error_t keydb_idx_build(const char *file)
+ 	while (!cdk_stream_eof(inp)) {
+ 		off_t pos = cdk_stream_tell(inp);
+ 
+-		rc = cdk_pkt_read(inp, pkt);
++		rc = cdk_pkt_read(inp, pkt, 1);
+ 		if (rc) {
+ 			_cdk_log_debug
+ 			    ("index build failed packet off=%lu\n",
+@@ -816,7 +816,7 @@ cdk_keydb_search(cdk_keydb_search_t st, cdk_keydb_hd_t hd,
+ 
+ 		pos = cdk_stream_tell(kr);
+ 
+-		rc = cdk_keydb_get_keyblock(kr, &knode);
++		rc = cdk_keydb_get_keyblock(kr, &knode, 1);
+ 
+ 		if (rc) {
+ 			if (rc == CDK_EOF)
+@@ -1679,7 +1679,7 @@ add_key_usage(cdk_kbnode_t knode, u32 keyid[2], unsigned int usage)
+ }
+ 
+ cdk_error_t
+-cdk_keydb_get_keyblock(cdk_stream_t inp, cdk_kbnode_t * r_knode)
++cdk_keydb_get_keyblock(cdk_stream_t inp, cdk_kbnode_t * r_knode, unsigned public)
+ {
+ 	cdk_packet_t pkt;
+ 	cdk_kbnode_t knode, node;
+@@ -1706,7 +1706,7 @@ cdk_keydb_get_keyblock(cdk_stream_t inp, cdk_kbnode_t * r_knode)
+ 	while (!cdk_stream_eof(inp)) {
+ 		cdk_pkt_new(&pkt);
+ 		old_off = cdk_stream_tell(inp);
+-		rc = cdk_pkt_read(inp, pkt);
++		rc = cdk_pkt_read(inp, pkt, public);
+ 		if (rc) {
+ 			cdk_pkt_release(pkt);
+ 			if (rc == CDK_EOF)
+@@ -2126,7 +2126,7 @@ cdk_error_t cdk_keydb_check_sk(cdk_keydb_hd_t hd, u32 * keyid)
+ 		return rc;
+ 	}
+ 	cdk_pkt_new(&pkt);
+-	while (!cdk_pkt_read(db, pkt)) {
++	while (!cdk_pkt_read(db, pkt, 0)) {
+ 		if (pkt->pkttype != CDK_PKT_SECRET_KEY &&
+ 		    pkt->pkttype != CDK_PKT_SECRET_SUBKEY) {
+ 			cdk_pkt_free(pkt);
+@@ -2241,14 +2241,14 @@ cdk_error_t cdk_listkey_next(cdk_listkey_t ctx, cdk_kbnode_t * ret_key)
+ 	}
+ 
+ 	if (ctx->type && ctx->u.patt[0] == '*')
+-		return cdk_keydb_get_keyblock(ctx->inp, ret_key);
++		return cdk_keydb_get_keyblock(ctx->inp, ret_key, 1);
+ 	else if (ctx->type) {
+ 		cdk_kbnode_t node;
+ 		struct cdk_keydb_search_s ks;
+ 		cdk_error_t rc;
+ 
+ 		for (;;) {
+-			rc = cdk_keydb_get_keyblock(ctx->inp, &node);
++			rc = cdk_keydb_get_keyblock(ctx->inp, &node, 1);
+ 			if (rc) {
+ 				gnutls_assert();
+ 				return rc;
+diff --git a/lib/opencdk/literal.c b/lib/opencdk/literal.c
+index 7b4baec..6996774 100644
+--- a/lib/opencdk/literal.c
++++ b/lib/opencdk/literal.c
+@@ -67,7 +67,7 @@ static cdk_error_t literal_decode(void *data, FILE * in, FILE * out)
+ 		return rc;
+ 
+ 	cdk_pkt_new(&pkt);
+-	rc = cdk_pkt_read(si, pkt);
++	rc = cdk_pkt_read(si, pkt, 1);
+ 	if (rc || pkt->pkttype != CDK_PKT_LITERAL) {
+ 		cdk_pkt_release(pkt);
+ 		cdk_stream_close(si);
+diff --git a/lib/opencdk/opencdk.h b/lib/opencdk/opencdk.h
+index c06b749..d95cc32 100644
+--- a/lib/opencdk/opencdk.h
++++ b/lib/opencdk/opencdk.h
+@@ -553,7 +553,7 @@ extern "C" {
+ 	void cdk_pkt_release(cdk_packet_t pkt);
+ 
+ /* Read or write the given output from or to the stream. */
+-	cdk_error_t cdk_pkt_read(cdk_stream_t inp, cdk_packet_t pkt);
++	cdk_error_t cdk_pkt_read(cdk_stream_t inp, cdk_packet_t pkt, unsigned public);
+ 	cdk_error_t cdk_pkt_write(cdk_stream_t out, cdk_packet_t pkt);
+ 
+ /* Sub packet routines */
+@@ -814,7 +814,8 @@ extern "C" {
+ /* Try to read the next key block from the given input stream.
+    The key will be returned in @RET_KEY on success. */
+ 	cdk_error_t cdk_keydb_get_keyblock(cdk_stream_t inp,
+-					   cdk_kbnode_t * ret_key);
++					   cdk_kbnode_t * ret_key,
++					   unsigned public);
+ 
+ /* Rebuild the key db index if possible. */
+ 	cdk_error_t cdk_keydb_idx_rebuild(cdk_keydb_hd_t db,
+@@ -848,7 +849,7 @@ extern "C" {
+ 	cdk_error_t cdk_kbnode_read_from_mem(cdk_kbnode_t * ret_node,
+ 					     int armor,
+ 					     const unsigned char *buf,
+-					     size_t buflen);
++					     size_t buflen, unsigned public);
+ 	cdk_error_t cdk_kbnode_write_to_mem(cdk_kbnode_t node,
+ 					    unsigned char *buf,
+ 					    size_t * r_nbytes);
+diff --git a/lib/opencdk/read-packet.c b/lib/opencdk/read-packet.c
+index 7a474ff..72624d0 100644
+--- a/lib/opencdk/read-packet.c
++++ b/lib/opencdk/read-packet.c
+@@ -571,6 +571,9 @@ read_user_id(cdk_stream_t inp, size_t pktlen, cdk_pkt_userid_t user_id)
+ }
+ 
+ 
++#define MAX_PACKET_LEN (1<<24)
++
++
+ static cdk_error_t
+ read_subpkt(cdk_stream_t inp, cdk_subpkt_t * r_ctx, size_t * r_nbytes)
+ {
+@@ -610,6 +613,10 @@ read_subpkt(cdk_stream_t inp, cdk_subpkt_t * r_ctx, size_t * r_nbytes)
+ 	else
+ 		return CDK_Inv_Packet;
+ 
++	if (size >= MAX_PACKET_LEN) {
++		return CDK_Inv_Packet;
++	}
++
+ 	node = cdk_subpkt_new(size);
+ 	if (!node)
+ 		return CDK_Out_Of_Core;
+@@ -958,7 +965,7 @@ static cdk_error_t skip_packet(cdk_stream_t inp, size_t pktlen)
+  *
+  * Parse the next packet on the @inp stream and return its contents in @pkt.
+  **/
+-cdk_error_t cdk_pkt_read(cdk_stream_t inp, cdk_packet_t pkt)
++cdk_error_t cdk_pkt_read(cdk_stream_t inp, cdk_packet_t pkt, unsigned public)
+ {
+ 	int ctb, is_newctb;
+ 	int pkttype;
+@@ -1058,6 +1065,10 @@ cdk_error_t cdk_pkt_read(cdk_stream_t inp, cdk_packet_t pkt)
+ 		break;
+ 
+ 	case CDK_PKT_SECRET_KEY:
++		if (public) {
++			/* read secret key when expecting public */
++			return gnutls_assert_val(CDK_Inv_Packet);
++		}
+ 		pkt->pkt.secret_key =
+ 		    cdk_calloc(1, sizeof *pkt->pkt.secret_key);
+ 		if (!pkt->pkt.secret_key)
+@@ -1073,6 +1084,10 @@ cdk_error_t cdk_pkt_read(cdk_stream_t inp, cdk_packet_t pkt)
+ 		break;
+ 
+ 	case CDK_PKT_SECRET_SUBKEY:
++		if (public) {
++			/* read secret key when expecting public */
++			return gnutls_assert_val(CDK_Inv_Packet);
++		}
+ 		pkt->pkt.secret_key =
+ 		    cdk_calloc(1, sizeof *pkt->pkt.secret_key);
+ 		if (!pkt->pkt.secret_key)
+diff --git a/lib/openpgp/gnutls_openpgp.c b/lib/openpgp/gnutls_openpgp.c
+index 7c05e1f..192737f 100644
+--- a/lib/openpgp/gnutls_openpgp.c
++++ b/lib/openpgp/gnutls_openpgp.c
+@@ -479,7 +479,7 @@ int gnutls_openpgp_count_key_names(const gnutls_datum_t * cert)
+ 		return 0;
+ 	}
+ 
+-	if (cdk_kbnode_read_from_mem(&knode, 0, cert->data, cert->size)) {
++	if (cdk_kbnode_read_from_mem(&knode, 0, cert->data, cert->size, 1)) {
+ 		gnutls_assert();
+ 		return 0;
+ 	}
+diff --git a/lib/openpgp/pgp.c b/lib/openpgp/pgp.c
+index d5ef272..77e57ab 100644
+--- a/lib/openpgp/pgp.c
++++ b/lib/openpgp/pgp.c
+@@ -99,7 +99,7 @@ gnutls_openpgp_crt_import(gnutls_openpgp_crt_t key,
+ 		armor = 1;
+ 
+ 	rc = cdk_kbnode_read_from_mem(&key->knode, armor, data->data,
+-				      data->size);
++				      data->size, 1);
+ 	if (rc) {
+ 		rc = _gnutls_map_cdk_rc(rc);
+ 		gnutls_assert();
+diff --git a/lib/openpgp/privkey.c b/lib/openpgp/privkey.c
+index 6aa6fb5..81ec3ab 100644
+--- a/lib/openpgp/privkey.c
++++ b/lib/openpgp/privkey.c
+@@ -186,7 +186,7 @@ gnutls_openpgp_privkey_import(gnutls_openpgp_privkey_t key,
+ 		armor = 1;
+ 
+ 	rc = cdk_kbnode_read_from_mem(&key->knode, armor, data->data,
+-				      data->size);
++				      data->size, 0);
+ 	if (rc != 0) {
+ 		rc = _gnutls_map_cdk_rc(rc);
+ 		gnutls_assert();
diff --git a/SOURCES/gnutls-3.3.26-dh-params-1024.patch b/SOURCES/gnutls-3.3.26-dh-params-1024.patch
new file mode 100644
index 0000000..ce91678
--- /dev/null
+++ b/SOURCES/gnutls-3.3.26-dh-params-1024.patch
@@ -0,0 +1,31 @@
+diff --git a/lib/gnutls_priority.c b/lib/gnutls_priority.c
+index c5998ab..ffefce1 100644
+--- a/lib/gnutls_priority.c
++++ b/lib/gnutls_priority.c
+@@ -684,7 +684,7 @@ int check_level(const char *level, gnutls_priority_t priority_cache,
+ 		func(&priority_cache->supported_ecc, supported_ecc_normal);
+ 
+ 		SET_PROFILE(GNUTLS_PROFILE_LOW); /* set certificate level */
+-		SET_LEVEL(GNUTLS_SEC_PARAM_WEAK); /* set DH params level */
++		SET_LEVEL(GNUTLS_SEC_PARAM_LOW); /* set DH params level */
+ 		return 1;
+ 	} else if (strcasecmp(level, LEVEL_NORMAL) == 0) {
+ 		func(&priority_cache->cipher, cipher_priority_normal);
+@@ -694,7 +694,7 @@ int check_level(const char *level, gnutls_priority_t priority_cache,
+ 		func(&priority_cache->supported_ecc, supported_ecc_normal);
+ 
+ 		SET_PROFILE(GNUTLS_PROFILE_LOW);
+-		SET_LEVEL(GNUTLS_SEC_PARAM_WEAK);
++		SET_LEVEL(GNUTLS_SEC_PARAM_LOW);
+ 		return 1;
+ 	} else if (strcasecmp(level, LEVEL_PFS) == 0) {
+ 		func(&priority_cache->cipher, cipher_priority_normal);
+@@ -704,7 +704,7 @@ int check_level(const char *level, gnutls_priority_t priority_cache,
+ 		func(&priority_cache->supported_ecc, supported_ecc_normal);
+ 
+ 		SET_PROFILE(GNUTLS_PROFILE_LOW);
+-		SET_LEVEL(GNUTLS_SEC_PARAM_WEAK);
++		SET_LEVEL(GNUTLS_SEC_PARAM_LOW);
+ 		return 1;
+ 	} else if (strcasecmp(level, LEVEL_SECURE256) == 0
+ 		   || strcasecmp(level, LEVEL_SECURE192) == 0) {
diff --git a/SOURCES/gnutls-3.3.26-fips-rsa-keygen.patch b/SOURCES/gnutls-3.3.26-fips-rsa-keygen.patch
new file mode 100644
index 0000000..4093066
--- /dev/null
+++ b/SOURCES/gnutls-3.3.26-fips-rsa-keygen.patch
@@ -0,0 +1,56 @@
+diff --git a/lib/nettle/int/rsa-keygen-fips186.c b/lib/nettle/int/rsa-keygen-fips186.c
+index 624aa36..b064b45 100644
+--- a/lib/nettle/int/rsa-keygen-fips186.c
++++ b/lib/nettle/int/rsa-keygen-fips186.c
+@@ -27,7 +27,6 @@
+ #include "config.h"
+ #endif
+ 
+-#include <assert.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+@@ -337,10 +336,16 @@ _rsa_generate_fips186_4_keypair(struct rsa_public_key *pub,
+ 
+ 	mpz_mul(pub->n, key->p, key->q);
+ 
+-	assert(mpz_sizeinbase(pub->n, 2) == n_size);
++	if (mpz_sizeinbase(pub->n, 2) != n_size) {
++		ret = 0;
++		goto cleanup;
++	}
+ 
+ 	/* c = q^{-1} (mod p) */
+-	assert(mpz_invert(key->c, key->q, key->p) != 0);
++	if (mpz_invert(key->c, key->q, key->p) == 0) {
++		ret = 0;
++		goto cleanup;
++	}
+ 
+ 	mpz_sub_ui(p1, key->p, 1);
+ 	mpz_sub_ui(q1, key->q, 1);
+@@ -352,6 +357,12 @@ _rsa_generate_fips186_4_keypair(struct rsa_public_key *pub,
+ 		goto cleanup;
+ 	}
+ 
++	/* check whether d > 2^(nlen/2) -- FIPS186-4 5.3.1 */
++	if (mpz_sizeinbase(key->d, 2) < n_size/2) {
++		ret = 0;
++		goto cleanup;
++	}
++
+ 	/* Done! Almost, we must compute the auxillary private values. */
+ 	/* a = d % (p-1) */
+ 	mpz_fdiv_r(key->a, key->d, p1);
+@@ -362,7 +373,10 @@ _rsa_generate_fips186_4_keypair(struct rsa_public_key *pub,
+ 	/* c was computed earlier */
+ 
+ 	pub->size = key->size = (n_size + 7) / 8;
+-	assert(pub->size >= RSA_MINIMUM_N_OCTETS);
++	if (pub->size < RSA_MINIMUM_N_OCTETS) {
++		ret = 0;
++		goto cleanup;
++	}
+ 
+ 	ret = 1;
+  cleanup:
diff --git a/SOURCES/gnutls-3.3.26-fix-coverity-issues.patch b/SOURCES/gnutls-3.3.26-fix-coverity-issues.patch
new file mode 100644
index 0000000..fa27c05
--- /dev/null
+++ b/SOURCES/gnutls-3.3.26-fix-coverity-issues.patch
@@ -0,0 +1,15 @@
+diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
+index 56c0163..368598b 100644
+--- a/lib/nettle/pk.c
++++ b/lib/nettle/pk.c
+@@ -2021,7 +2021,9 @@ static int wrap_nettle_hash_algorithm(gnutls_pk_algorithm_t pk,
+ 			break;
+ 		}
+ 
+-		_rsa_params_to_pubkey(issuer_params, &pub);
++		ret = _rsa_params_to_pubkey(issuer_params, &pub);
++		if (ret < 0)
++			return gnutls_assert_val(ret);
+ 
+ 		digest_size = sizeof(digest);
+ 
diff --git a/SOURCES/gnutls-3.3.26-fix-uninitialized.patch b/SOURCES/gnutls-3.3.26-fix-uninitialized.patch
new file mode 100644
index 0000000..1242a1d
--- /dev/null
+++ b/SOURCES/gnutls-3.3.26-fix-uninitialized.patch
@@ -0,0 +1,12 @@
+diff --git a/lib/pkcs11.c b/lib/pkcs11.c
+index d99dedf..f5cf99d 100644
+--- a/lib/pkcs11.c
++++ b/lib/pkcs11.c
+@@ -3019,6 +3019,7 @@ gnutls_pkcs11_obj_list_import_url2(gnutls_pkcs11_obj_t ** p_list,
+ 	if (ret < 0) {
+ 		gnutls_assert();
+ 		if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
++			*p_list = NULL;
+ 			*n_list = 0;
+ 			ret = 0;
+ 		}
diff --git a/SOURCES/gnutls-3.3.26-pin-value.patch b/SOURCES/gnutls-3.3.26-pin-value.patch
new file mode 100644
index 0000000..794ba48
--- /dev/null
+++ b/SOURCES/gnutls-3.3.26-pin-value.patch
@@ -0,0 +1,662 @@
+diff --git a/configure.ac b/configure.ac
+index 0840042..c9c9fdc 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -447,6 +447,9 @@ if test "$with_p11_kit" != "no"; then
+ 		if ! $PKG_CONFIG --atleast-version=0.22.0 p11-kit-1; then
+ 			with_buggy_p11_kit=yes
+ 		fi
++		if $PKG_CONFIG --atleast-version=0.23.1 p11-kit-1; then
++			AC_DEFINE([P11_KIT_HAS_PIN_VALUE], 1, [p11-kit supports p11_kit_uri_get_pin_value()])
++		fi
+ 	else
+ 	        with_p11_kit=no
+ 	        AC_MSG_WARN([[
+diff --git a/lib/pkcs11.c b/lib/pkcs11.c
+index f5cf99d..26d88e5 100644
+--- a/lib/pkcs11.c
++++ b/lib/pkcs11.c
+@@ -2367,6 +2367,25 @@ retrieve_pin(struct pin_info_st *pin_info, struct p11_kit_uri *info,
+ 
+ 	*pin = NULL;
+ 
++#ifdef P11_KIT_HAS_PIN_VALUE
++	/* First check for pin-value field */
++	pinfile = p11_kit_uri_get_pin_value(info);
++	if (pinfile != NULL) {
++		_gnutls_debug_log("p11: Using pin-value to retrieve PIN\n");
++		*pin = p11_kit_pin_new_for_string(pinfile);
++		if (*pin != NULL)
++			ret = 0;
++	} else { /* try pin-source */
++		/* Check if a pinfile is specified, and use that if possible */
++		pinfile = p11_kit_uri_get_pin_source(info);
++		if (pinfile != NULL) {
++			_gnutls_debug_log("p11: Using pin-source to retrieve PIN\n");
++			ret =
++			    retrieve_pin_from_source(pinfile, token_info, attempts,
++						     user_type, pin);
++		}
++	}
++#else
+ 	/* Check if a pinfile is specified, and use that if possible */
+ 	pinfile = p11_kit_uri_get_pinfile(info);
+ 	if (pinfile != NULL) {
+@@ -2375,6 +2394,7 @@ retrieve_pin(struct pin_info_st *pin_info, struct p11_kit_uri *info,
+ 		    retrieve_pin_from_source(pinfile, token_info, attempts,
+ 					     user_type, pin);
+ 	}
++#endif
+ 
+ 	/* The global gnutls pin callback */
+ 	if (ret < 0)
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index 5b60899..20ed79c 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -36,7 +36,7 @@ EXTRA_DIST = suppressions.valgrind eagain-common.h test-chains.h \
+ 	certs/cert-rsa-2432.pem certs/ecc384.pem certs/ecc.pem \
+ 	certs/ca-ecc.pem certs/cert-ecc384.pem certs/cert-ecc.pem certs/ecc256.pem \
+ 	certs/ecc521.pem certs/rsa-2432.pem x509cert-dir/ca.pem \
+-	cert-common.h pkcs11/softhsm.h
++	cert-common.h pkcs11/softhsm.h pkcs11/pkcs11-pubkey-import.c
+ 
+ AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
+ AM_CPPFLAGS = \
+@@ -113,7 +113,8 @@ pkcs11_import_url_privkey_LDADD = $(LDADD) $(LIBDL)
+ 
+ ctests += pkcs11-cert-import-url-exts pkcs11-get-exts pkcs11-get-raw-issuer-exts \
+ 	pkcs11/pkcs11-chainverify pkcs11/pkcs11-get-issuer pkcs11/pkcs11-is-known \
+-	pkcs11/pkcs11-combo pkcs11-import-url-privkey
++	pkcs11/pkcs11-combo pkcs11-import-url-privkey pkcs11/pkcs11-pubkey-import-rsa \
++	pkcs11/pkcs11-import-with-pin
+ 
+ endif
+ endif
+diff --git a/tests/pkcs11/pkcs11-import-with-pin.c b/tests/pkcs11/pkcs11-import-with-pin.c
+new file mode 100644
+index 0000000..e435919
+--- /dev/null
++++ b/tests/pkcs11/pkcs11-import-with-pin.c
+@@ -0,0 +1,198 @@
++/*
++ * Copyright (C) 2017 Red Hat, Inc.
++ *
++ * Author: Nikos Mavrogiannopoulos
++ *
++ * This file is part of GnuTLS.
++ *
++ * GnuTLS is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * GnuTLS is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with GnuTLS; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <assert.h>
++#include <unistd.h>
++
++#include <gnutls/gnutls.h>
++#include <gnutls/x509.h>
++#include <gnutls/abstract.h>
++
++#include "../utils.h"
++#include "softhsm.h"
++
++/* Tests whether a protected object is imported with PIN obtained using
++ * pin-value or pin-source. */
++
++#define CONFIG_NAME "softhsm-import-with-pin"
++#define CONFIG CONFIG_NAME".config"
++
++#include "../cert-common.h"
++
++#define PIN "1234"
++
++static const gnutls_datum_t testdata = {(void*)"test test", 9};
++
++static void tls_log_func(int level, const char *str)
++{
++	fprintf(stderr, "|<%d>| %s", level, str);
++}
++
++static
++int pin_func(void* userdata, int attempt, const char* url, const char *label,
++		unsigned flags, char *pin, size_t pin_max)
++{
++	if (attempt == 0) {
++		strcpy(pin, PIN);
++		return 0;
++	}
++	return -1;
++}
++
++static void write_pin(const char *file, const char *pin)
++{
++	FILE *fp = fopen(file, "w");
++	assert(fp != NULL);
++	fputs(pin, fp);
++	fclose(fp);
++}
++
++void doit()
++{
++	char buf[512];
++	int ret, pk;
++	const char *lib, *bin;
++	gnutls_x509_privkey_t key;
++	gnutls_datum_t tmp, sig;
++	gnutls_privkey_t pkey;
++	char file[TMPNAME_SIZE];
++
++#ifndef P11_KIT_HAS_PIN_VALUE
++	exit(77);
++#endif
++
++	bin = softhsm_bin();
++
++	lib = softhsm_lib();
++
++	ret = global_init();
++	if (ret != 0) {
++		fail("%d: %s\n", ret, gnutls_strerror(ret));
++		exit(1);
++	}
++
++	gnutls_pkcs11_set_pin_function(pin_func, NULL);
++	gnutls_global_set_log_function(tls_log_func);
++	if (debug)
++		gnutls_global_set_log_level(4711);
++
++	set_softhsm_conf(CONFIG);
++	snprintf(buf, sizeof(buf), "%s --init-token --slot 0 --label test --so-pin "PIN" --pin "PIN, bin);
++	system(buf);
++
++	ret = gnutls_pkcs11_add_provider(lib, "trusted");
++	if (ret < 0) {
++		fprintf(stderr, "add_provider: %s\n",
++			gnutls_strerror(ret));
++		exit(1);
++	}
++
++	ret = gnutls_x509_privkey_init(&key);
++	if (ret < 0) {
++		fprintf(stderr,
++			"gnutls_x509_privkey_init: %s\n",
++			gnutls_strerror(ret));
++		exit(1);
++	}
++
++	ret =
++	    gnutls_x509_privkey_import(key, &server_key,
++				   GNUTLS_X509_FMT_PEM);
++	if (ret < 0) {
++		fprintf(stderr,
++			"gnutls_x509_privkey_import: %s\n",
++			gnutls_strerror(ret));
++			exit(1);
++	}
++
++	/* initialize softhsm token */
++	ret = gnutls_pkcs11_token_init(SOFTHSM_URL, PIN, "test");
++	if (ret < 0) {
++		fail("gnutls_pkcs11_token_init: %s\n", gnutls_strerror(ret));
++		exit(1);
++	}
++
++	ret = gnutls_pkcs11_token_set_pin(SOFTHSM_URL, NULL, PIN, GNUTLS_PIN_USER);
++	if (ret < 0) {
++		fail("gnutls_pkcs11_token_set_pin: %s\n", gnutls_strerror(ret));
++		exit(1);
++	}
++
++	ret = gnutls_pkcs11_copy_x509_privkey(SOFTHSM_URL, key, "cert", GNUTLS_KEY_DIGITAL_SIGNATURE|GNUTLS_KEY_KEY_ENCIPHERMENT,
++					      GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE|GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE|GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
++	if (ret < 0) {
++		fail("gnutls_pkcs11_copy_x509_privkey: %s\n", gnutls_strerror(ret));
++		exit(1);
++	}
++
++	gnutls_x509_privkey_deinit(key);
++	gnutls_pkcs11_set_pin_function(NULL, NULL);
++
++	assert(gnutls_privkey_init(&pkey) == 0);
++
++	/* Test 1
++	 * Try importing with pin-value */
++	ret = gnutls_privkey_import_pkcs11_url(pkey, SOFTHSM_URL";object=cert;object-type=private;pin-value="PIN);
++	if (ret < 0) {
++		fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));
++		exit(1);
++	}
++
++	/* check whether privkey is operational by signing */
++	assert(gnutls_privkey_sign_data(pkey, GNUTLS_DIG_SHA256, 0, &testdata, &sig) == 0);
++	gnutls_free(sig.data);
++	gnutls_privkey_deinit(pkey);
++
++	/* Test 2
++	 * Try importing with pin-source */
++	track_temp_files();
++	get_tmpname(file);
++
++	write_pin(file, PIN);
++
++
++	assert(gnutls_privkey_init(&pkey) == 0);
++	snprintf(buf, sizeof(buf), "%s;object=cert;object-type=private;pin-source=%s", SOFTHSM_URL, file);
++	ret = gnutls_privkey_import_pkcs11_url(pkey, buf);
++	if (ret < 0) {
++		fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));
++		exit(1);
++	}
++
++	/* check whether privkey is operational by signing */
++	assert(gnutls_privkey_sign_data(pkey, GNUTLS_DIG_SHA256, 0, &testdata, &sig) == 0);
++	gnutls_free(sig.data);
++	gnutls_privkey_deinit(pkey);
++
++	gnutls_global_deinit();
++	delete_temp_files();
++
++	remove(CONFIG);
++}
++
+diff --git a/tests/pkcs11/pkcs11-pubkey-import-rsa.c b/tests/pkcs11/pkcs11-pubkey-import-rsa.c
+new file mode 100644
+index 0000000..d304c4f
+--- /dev/null
++++ b/tests/pkcs11/pkcs11-pubkey-import-rsa.c
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (C) 2015 Nikos Mavrogiannopoulos
++ *
++ * Author: Nikos Mavrogiannopoulos
++ *
++ * This file is part of GnuTLS.
++ *
++ * GnuTLS is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * GnuTLS is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with GnuTLS; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++#define CONFIG_NAME "softhsm-pubkey-import-rsa"
++#define CONFIG CONFIG_NAME".config"
++
++#include "pkcs11-pubkey-import.c"
++
++void doit(void)
++{
++	success("Testing RSA key\n");
++	try(1);
++}
+diff --git a/tests/pkcs11/pkcs11-pubkey-import.c b/tests/pkcs11/pkcs11-pubkey-import.c
+new file mode 100644
+index 0000000..7513aad
+--- /dev/null
++++ b/tests/pkcs11/pkcs11-pubkey-import.c
+@@ -0,0 +1,220 @@
++/*
++ * Copyright (C) 2015 Nikos Mavrogiannopoulos
++ *
++ * Author: Nikos Mavrogiannopoulos
++ *
++ * This file is part of GnuTLS.
++ *
++ * GnuTLS is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * GnuTLS is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with GnuTLS; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <assert.h>
++#include <unistd.h>
++
++#include <gnutls/gnutls.h>
++#include <gnutls/x509.h>
++#include <gnutls/abstract.h>
++
++#include "../utils.h"
++#include "softhsm.h"
++
++/* Tests whether gnutls_pubkey_import_privkey works well for 
++ * RSA keys under PKCS #11 */
++
++
++#include "../cert-common.h"
++
++#define PIN "1234"
++
++static const gnutls_datum_t testdata = {(void*)"test test", 9};
++
++static void tls_log_func(int level, const char *str)
++{
++	fprintf(stderr, "|<%d>| %s", level, str);
++}
++
++static
++int pin_func(void* userdata, int attempt, const char* url, const char *label,
++		unsigned flags, char *pin, size_t pin_max)
++{
++	if (attempt == 0) {
++		strcpy(pin, PIN);
++		return 0;
++	}
++	return -1;
++}
++
++static void try(int rsa)
++{
++	char buf[128];
++	int ret, pk;
++	const char *lib, *bin;
++	gnutls_x509_crt_t crt;
++	gnutls_x509_privkey_t key;
++	gnutls_datum_t tmp, sig;
++	gnutls_privkey_t pkey;
++	gnutls_pubkey_t pubkey;
++	gnutls_pubkey_t pubkey2;
++
++#ifndef P11_KIT_HAS_PIN_VALUE
++	exit(77);
++#endif
++
++	bin = softhsm_bin();
++
++	lib = softhsm_lib();
++
++	ret = global_init();
++	if (ret != 0) {
++		fail("%d: %s\n", ret, gnutls_strerror(ret));
++		exit(1);
++	}
++
++	gnutls_pkcs11_set_pin_function(pin_func, NULL);
++	gnutls_global_set_log_function(tls_log_func);
++	if (debug)
++		gnutls_global_set_log_level(4711);
++
++	set_softhsm_conf(CONFIG);
++	snprintf(buf, sizeof(buf), "%s --init-token --slot 0 --label test --so-pin "PIN" --pin "PIN, bin);
++	system(buf);
++
++	ret = gnutls_pkcs11_add_provider(lib, "trusted");
++	if (ret < 0) {
++		fprintf(stderr, "gnutls_x509_crt_init: %s\n",
++			gnutls_strerror(ret));
++		exit(1);
++	}
++
++	ret = gnutls_x509_crt_init(&crt);
++	if (ret < 0) {
++		fprintf(stderr,
++			"gnutls_x509_crt_init: %s\n",
++			gnutls_strerror(ret));
++		exit(1);
++	}
++
++	ret =
++	    gnutls_x509_crt_import(crt, rsa?&server_cert:&server_ecc_cert,
++				   GNUTLS_X509_FMT_PEM);
++	if (ret < 0) {
++		fprintf(stderr,
++			"gnutls_x509_crt_import: %s\n",
++			gnutls_strerror(ret));
++			exit(1);
++	}
++
++	if (debug) {
++		gnutls_x509_crt_print(crt,
++			      GNUTLS_CRT_PRINT_ONELINE,
++			      &tmp);
++
++		printf("\tCertificate: %.*s\n",
++		       tmp.size, tmp.data);
++		gnutls_free(tmp.data);
++	}
++
++	ret = gnutls_x509_privkey_init(&key);
++	if (ret < 0) {
++		fprintf(stderr,
++			"gnutls_x509_privkey_init: %s\n",
++			gnutls_strerror(ret));
++		exit(1);
++	}
++
++	ret =
++	    gnutls_x509_privkey_import(key, rsa?&server_key:&server_ecc_key,
++				   GNUTLS_X509_FMT_PEM);
++	if (ret < 0) {
++		fprintf(stderr,
++			"gnutls_x509_privkey_import: %s\n",
++			gnutls_strerror(ret));
++			exit(1);
++	}
++
++	/* initialize softhsm token */
++	ret = gnutls_pkcs11_token_init(SOFTHSM_URL, PIN, "test");
++	if (ret < 0) {
++		fail("gnutls_pkcs11_token_init: %s\n", gnutls_strerror(ret));
++		exit(1);
++	}
++
++	ret = gnutls_pkcs11_token_set_pin(SOFTHSM_URL, NULL, PIN, GNUTLS_PIN_USER);
++	if (ret < 0) {
++		fail("gnutls_pkcs11_token_set_pin: %s\n", gnutls_strerror(ret));
++		exit(1);
++	}
++
++	ret = gnutls_pkcs11_copy_x509_crt(SOFTHSM_URL, crt, "cert",
++					  GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE|GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
++	if (ret < 0) {
++		fail("gnutls_pkcs11_copy_x509_crt: %s\n", gnutls_strerror(ret));
++		exit(1);
++	}
++
++	ret = gnutls_pkcs11_copy_x509_privkey(SOFTHSM_URL, key, "cert", GNUTLS_KEY_DIGITAL_SIGNATURE|GNUTLS_KEY_KEY_ENCIPHERMENT,
++					      GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE|GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE|GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
++	if (ret < 0) {
++		fail("gnutls_pkcs11_copy_x509_privkey: %s\n", gnutls_strerror(ret));
++		exit(1);
++	}
++
++	gnutls_x509_crt_deinit(crt);
++	gnutls_x509_privkey_deinit(key);
++	gnutls_pkcs11_set_pin_function(NULL, NULL);
++
++	assert(gnutls_privkey_init(&pkey) == 0);
++
++	ret = gnutls_privkey_import_pkcs11_url(pkey, SOFTHSM_URL";object=cert;object-type=private;pin-value="PIN);
++	if (ret < 0) {
++		fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));
++		exit(1);
++	}
++
++	assert(gnutls_pubkey_init(&pubkey) == 0);
++	assert(gnutls_pubkey_import_privkey(pubkey, pkey, 0, 0) == 0);
++
++	pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL);
++
++	/* check whether privkey and pubkey are operational
++	 * by signing and verifying */
++	assert(gnutls_privkey_sign_data(pkey, GNUTLS_DIG_SHA256, 0, &testdata, &sig) == 0);
++
++	/* verify against the raw pubkey */
++	assert(gnutls_pubkey_init(&pubkey2) == 0);
++	assert(gnutls_pubkey_import_x509_raw(pubkey2, rsa?&server_cert:&server_ecc_cert, GNUTLS_X509_FMT_PEM, 0) == 0);
++	assert(gnutls_pubkey_verify_data2(pubkey2, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA256), 0, &testdata, &sig) >= 0);
++
++	/* verify against the pubkey in PKCS #11 */
++	assert(gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA256), 0, &testdata, &sig) >= 0);
++
++	gnutls_free(sig.data);
++
++	gnutls_pubkey_deinit(pubkey2);
++	gnutls_pubkey_deinit(pubkey);
++	gnutls_privkey_deinit(pkey);
++
++	gnutls_global_deinit();
++
++	remove(CONFIG);
++}
++
+diff --git a/tests/utils.c b/tests/utils.c
+index 65ceafd..37345a6 100644
+--- a/tests/utils.c
++++ b/tests/utils.c
+@@ -30,6 +30,7 @@
+ #include <time.h>
+ #include <unistd.h>
+ #include <errno.h>
++#include <assert.h>
+ #ifndef _WIN32
+ # include <netinet/in.h>
+ # include <sys/socket.h>
+@@ -39,6 +40,8 @@
+ # include <winbase.h>  
+ #endif
+ #endif
++#include <gnutls/gnutls.h>
++#include <gnutls/crypto.h>
+ 
+ #include "utils.h"
+ 
+@@ -183,3 +186,74 @@ int main(int argc, char *argv[])
+ 
+ 	return error_count ? 1 : 0;
+ }
++
++struct tmp_file_st {
++	char file[TMPNAME_SIZE];
++	struct tmp_file_st *next;
++};
++
++static struct tmp_file_st *temp_files = (void*)-1;
++
++static void append(const char *file)
++{
++	struct tmp_file_st *p;
++
++	if (temp_files == (void*)-1)
++		return;
++
++	p = calloc(1, sizeof(*p));
++
++	assert(p != NULL);
++	strcpy(p->file, file);
++	p->next = temp_files;
++	temp_files = p;
++}
++
++char *get_tmpname(char s[TMPNAME_SIZE])
++{
++	unsigned char rnd[6];
++	static char _s[TMPNAME_SIZE];
++	int ret;
++	char *p;
++	const char *path;
++
++	ret = gnutls_rnd(GNUTLS_RND_NONCE, rnd, sizeof(rnd));
++	if (ret < 0)
++		return NULL;
++
++	path = getenv("builddir");
++	if (path == NULL)
++		path = ".";
++
++	if (s == NULL)
++		p = _s;
++	else
++		p = s;
++
++	snprintf(p, TMPNAME_SIZE, "%s/tmpfile-%02x%02x%02x%02x%02x%02x.tmp", path, (unsigned)rnd[0], (unsigned)rnd[1],
++		(unsigned)rnd[2], (unsigned)rnd[3], (unsigned)rnd[4], (unsigned)rnd[5]);
++
++	append(p);
++
++	return p;
++}
++
++void track_temp_files(void)
++{
++	temp_files = NULL;
++}
++
++void delete_temp_files(void)
++{
++	struct tmp_file_st *p = temp_files;
++	struct tmp_file_st *next;
++
++	if (p == (void*)-1)
++		return;
++
++	while(p != NULL) {
++		next = p->next;
++		free(p);
++		p = next;
++	}
++}
+diff --git a/tests/utils.h b/tests/utils.h
+index 8f3ac3f..5c0afe7 100644
+--- a/tests/utils.h
++++ b/tests/utils.h
+@@ -61,4 +61,9 @@ extern void binprint(const void *str, size_t len);
+ extern void doit(void);
+ void sec_sleep(int sec);
+ 
++#define TMPNAME_SIZE 128
++char *get_tmpname(char s[TMPNAME_SIZE]);
++void track_temp_files(void);
++void delete_temp_files(void);
++
+ #endif				/* UTILS_H */
diff --git a/SOURCES/gnutls-3.3.26-remove-status-req-ext-parsing.patch b/SOURCES/gnutls-3.3.26-remove-status-req-ext-parsing.patch
new file mode 100644
index 0000000..8c00d63
--- /dev/null
+++ b/SOURCES/gnutls-3.3.26-remove-status-req-ext-parsing.patch
@@ -0,0 +1,110 @@
+diff --git a/lib/ext/status_request.c b/lib/ext/status_request.c
+index 8cefc61..c7c065e 100644
+--- a/lib/ext/status_request.c
++++ b/lib/ext/status_request.c
+@@ -1,5 +1,6 @@
+ /*
+- * Copyright (C) 2012 Free Software Foundation, Inc.
++ * Copyright (C) 2012-2017 Free Software Foundation, Inc.
++ * Copyright (C) 2017 Red Hat, Inc.
+  *
+  * Author: Simon Josefsson, Nikos Mavrogiannopoulos
+  *
+@@ -66,18 +67,6 @@ typedef struct {
+       opaque Extensions<0..2^16-1>;
+ */
+ 
+-static void deinit_responder_id(status_request_ext_st *priv)
+-{
+-unsigned i;
+-
+-	for (i = 0; i < priv->responder_id_size; i++)
+-		gnutls_free(priv->responder_id[i].data);
+-
+-	gnutls_free(priv->responder_id);
+-	priv->responder_id = NULL;
+-	priv->responder_id_size = 0;
+-}
+-
+ 
+ static int
+ client_send(gnutls_session_t session,
+@@ -132,8 +121,8 @@ server_recv(gnutls_session_t session,
+ 	    status_request_ext_st * priv,
+ 	    const uint8_t * data, size_t size)
+ {
+-	size_t i;
+ 	ssize_t data_size = size;
++	unsigned rid_bytes = 0;
+ 
+ 	/* minimum message is type (1) + responder_id_list (2) +
+ 	   request_extension (2) = 5 */
+@@ -152,43 +141,17 @@ server_recv(gnutls_session_t session,
+ 	DECR_LEN(data_size, 1);
+ 	data++;
+ 
+-	priv->responder_id_size = _gnutls_read_uint16(data);
++	rid_bytes = _gnutls_read_uint16(data);
+ 
+ 	DECR_LEN(data_size, 2);
+-	data += 2;
++	/*data += 2;*/
+ 
+-	if (data_size <= (ssize_t) (priv->responder_id_size * 2))
++	/* sanity check only, we don't use any of the data below */
++
++	if (data_size < (ssize_t)rid_bytes)
+ 		return
+ 		    gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
+ 
+-	if (priv->responder_id != NULL)
+-		deinit_responder_id(priv);
+-
+-	priv->responder_id = gnutls_calloc(1, priv->responder_id_size
+-					   * sizeof(*priv->responder_id));
+-	if (priv->responder_id == NULL)
+-		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+-
+-	for (i = 0; i < priv->responder_id_size; i++) {
+-		size_t l;
+-
+-		DECR_LEN(data_size, 2);
+-
+-		l = _gnutls_read_uint16(data);
+-		data += 2;
+-
+-		DECR_LEN(data_size, l);
+-
+-		priv->responder_id[i].data = gnutls_malloc(l);
+-		if (priv->responder_id[i].data == NULL)
+-			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+-
+-		memcpy(priv->responder_id[i].data, data, l);
+-		priv->responder_id[i].size = l;
+-
+-		data += l;
+-	}
+-
+ 	return 0;
+ }
+ 
+@@ -472,11 +435,18 @@ gnutls_certificate_set_ocsp_status_request_file
+ static void _gnutls_status_request_deinit_data(extension_priv_data_t epriv)
+ {
+ 	status_request_ext_st *priv = epriv.ptr;
++	unsigned i;
+ 
+ 	if (priv == NULL)
+ 		return;
+ 
+-	deinit_responder_id(priv);
++	if (priv->responder_id != NULL) {
++		for (i = 0; i < priv->responder_id_size; i++)
++			gnutls_free(priv->responder_id[i].data);
++
++		gnutls_free(priv->responder_id);
++	}
++
+ 	gnutls_free(priv->request_extensions.data);
+ 	gnutls_free(priv->response.data);
+ 	gnutls_free(priv);
diff --git a/SOURCES/gnutls-3.3.26-set-unique-id-tests.patch b/SOURCES/gnutls-3.3.26-set-unique-id-tests.patch
new file mode 100644
index 0000000..6d3d65f
--- /dev/null
+++ b/SOURCES/gnutls-3.3.26-set-unique-id-tests.patch
@@ -0,0 +1,316 @@
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index 20ed79c..0d72707 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -88,7 +88,7 @@ ctests = mini-record-2 simple gc set_pkcs12_cred certder certuniqueid	\
+ 	 long-session-id mini-x509-callbacks-intr \
+ 	 crlverify init_fds mini-rehandshake-2 sign-md5-rep global-init-override \
+ 	 version-checks mini-server-name naked-alerts multi-alerts \
+-	 pkcs8-key-decode-encrypted pkcs8-key-decode
++	 pkcs8-key-decode-encrypted pkcs8-key-decode crt_apis
+ 
+ if ENABLE_PKCS11
+ if !HAVE_BUGGY_P11_KIT
+diff --git a/tests/crt_apis.c b/tests/crt_apis.c
+new file mode 100644
+index 0000000..ad183d7
+--- /dev/null
++++ b/tests/crt_apis.c
+@@ -0,0 +1,297 @@
++/*
++ * Copyright (C) 2008-2016 Free Software Foundation, Inc.
++ * Copyright (C) 2016 Red Hat, Inc.
++ *
++ * Author: Nikos Mavrogiannopoulos
++ *
++ * This file is part of GnuTLS.
++ *
++ * GnuTLS is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * GnuTLS is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with GnuTLS; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <time.h>
++#include <string.h>
++#include <gnutls/gnutls.h>
++#include <gnutls/x509.h>
++#include <assert.h>
++
++#include "utils.h"
++
++#include "cert-common.h"
++
++static unsigned char saved_crt_pem[] =
++	"-----BEGIN CERTIFICATE-----\n"
++	"MIICMTCCAZqgAwIBAgIDChEAMA0GCSqGSIb3DQEBCwUAMCsxDjAMBgNVBAMTBW5p\n"
++	"a29zMRkwFwYDVQQKExBub25lIHRvLCBtZW50aW9uMCAXDTA4MDMzMTIyMDAwMFoY\n"
++	"Dzk5OTkxMjMxMjM1OTU5WjArMQ4wDAYDVQQDEwVuaWtvczEZMBcGA1UEChMQbm9u\n"
++	"ZSB0bywgbWVudGlvbjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAu2ZD9fLF\n"
++	"17aMzMXf9Yg7sclLag6hrSBQQAiAoU9co9D4bM/mPPfsBHYTF4tkiSJbwN1TfDvt\n"
++	"fAS7gLkovo6bxo6gpRLL9Vceoue7tzNJn+O7Sq5qTWj/yRHiMo3OPYALjXXv2ACB\n"
++	"jygEA6AijWEEB/q2N30hB0nSCWFpmJCjWKkCAwEAAYEFAAABAgOCBQAEAwIBo1Mw\n"
++	"UTAMBgNVHRMBAf8EAjAAMA8GA1UdDwEB/wQFAwMHgAAwDgYDVR0RBAcwBYIDYXBh\n"
++	"MCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsF\n"
++	"AAOBgQAFhjKULYgLWW9TmfqIdyKf+kr5zFaQnIlF0tuUcE9lq4am9NKUVuxn4yo2\n"
++	"AFePiZWksrLN8PvujOK+duJ5nljF3xXwF0Z/J83NzNa1buMafuBonTJTFQQQkoGK\n"
++	"6sN+hxb6qWBjZcyQflMeG5eMJC2b57Lao4IDLSHx+mo91fvKuw==\n"
++	"-----END CERTIFICATE-----\n";
++
++const gnutls_datum_t saved_crt = { saved_crt_pem, sizeof(saved_crt_pem)-1 };
++
++static void tls_log_func(int level, const char *str)
++{
++	fprintf(stderr, "|<%d>| %s", level, str);
++}
++
++static time_t mytime(time_t * t)
++{
++	time_t then = 1207000800;
++
++	if (t)
++		*t = then;
++
++	return then;
++}
++
++void doit(void)
++{
++	gnutls_x509_privkey_t pkey;
++	gnutls_x509_crt_t crt;
++	gnutls_x509_crt_t crt2;
++	const char *err = NULL;
++	unsigned char buf[64];
++	gnutls_datum_t out;
++	size_t s = 0;
++	int ret;
++
++	ret = global_init();
++	if (ret < 0)
++		fail("global_init\n");
++
++	gnutls_global_set_time_function(mytime);
++	gnutls_global_set_log_function(tls_log_func);
++	if (debug)
++		gnutls_global_set_log_level(4711);
++
++	ret = gnutls_x509_crt_init(&crt);
++	if (ret != 0)
++		fail("gnutls_x509_crt_init\n");
++
++	ret = gnutls_x509_crt_init(&crt2);
++	if (ret != 0)
++		fail("gnutls_x509_crt_init\n");
++
++	ret = gnutls_x509_crt_import(crt2, &server_ecc_cert, GNUTLS_X509_FMT_PEM);
++	if (ret != 0)
++		fail("gnutls_x509_crt_import\n");
++
++	ret = gnutls_x509_privkey_init(&pkey);
++	if (ret != 0)
++		fail("gnutls_x509_privkey_init\n");
++
++	ret = gnutls_x509_privkey_import(pkey, &key_dat, GNUTLS_X509_FMT_PEM);
++	if (ret != 0)
++		fail("gnutls_x509_privkey_import\n");
++
++	/* Setup CRT */
++
++	ret = gnutls_x509_crt_set_version(crt, 3);
++	if (ret != 0)
++		fail("gnutls_x509_crt_set_version\n");
++
++	ret = gnutls_x509_crt_set_serial(crt, "\x0a\x11\x00", 3);
++	if (ret != 0)
++		fail("gnutls_x509_crt_set_serial\n");
++
++	ret = gnutls_x509_crt_set_expiration_time(crt, -1);
++	if (ret != 0)
++		fail("error\n");
++
++	ret = gnutls_x509_crt_set_activation_time(crt, mytime(0));
++	if (ret != 0)
++		fail("error\n");
++
++	ret = gnutls_x509_crt_set_key(crt, pkey);
++	if (ret != 0)
++		fail("gnutls_x509_crt_set_key\n");
++
++	ret = gnutls_x509_crt_set_basic_constraints(crt, 0, -1);
++	if (ret < 0) {
++		fail("error\n");
++	}
++
++	ret = gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_DIGITAL_SIGNATURE);
++	if (ret != 0)
++		fail("gnutls_x509_crt_set_key_usage %d\n", ret);
++
++	ret = gnutls_x509_crt_set_dn(crt, "cn = nikos,o = none to\\, mention", &err);
++	if (ret < 0) {
++		fail("gnutls_x509_crt_set_dn: %s, %s\n", gnutls_strerror(ret), err);
++	}
++
++
++	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME,
++						   "foo", 3, 1);
++	if (ret != 0)
++		fail("gnutls_x509_crt_set_subject_alt_name\n");
++
++	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME,
++						   "foo@bar.org", strlen("foo@bar.org"), 1);
++	if (ret != 0)
++		fail("gnutls_x509_crt_set_subject_alt_name\n");
++
++	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_IPADDRESS,
++						   "\xc1\x5c\x96\x3", 4, 1);
++	if (ret != 0)
++		fail("gnutls_x509_crt_set_subject_alt_name\n");
++
++	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_IPADDRESS,
++						   "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 16, 1);
++	if (ret != 0)
++		fail("gnutls_x509_crt_set_subject_alt_name\n");
++
++	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME,
++						   "apa", 3, 0);
++	if (ret != 0)
++		fail("gnutls_x509_crt_set_subject_alt_name\n");
++
++	s = 0;
++	ret = gnutls_x509_crt_get_key_purpose_oid(crt, 0, NULL, &s, NULL);
++	if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
++		fail("gnutls_x509_crt_get_key_purpose_oid %d\n", ret);
++
++	s = 0;
++	ret =
++	    gnutls_x509_crt_set_key_purpose_oid(crt,
++						GNUTLS_KP_TLS_WWW_SERVER,
++						0);
++	if (ret != 0)
++		fail("gnutls_x509_crt_set_key_purpose_oid %d\n", ret);
++
++	s = 0;
++	ret = gnutls_x509_crt_get_key_purpose_oid(crt, 0, NULL, &s, NULL);
++	if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
++		fail("gnutls_x509_crt_get_key_purpose_oid %d\n", ret);
++
++	s = 0;
++	ret =
++	    gnutls_x509_crt_set_key_purpose_oid(crt,
++						GNUTLS_KP_TLS_WWW_CLIENT,
++						1);
++	if (ret != 0)
++		fail("gnutls_x509_crt_set_key_purpose_oid2 %d\n", ret);
++
++	/* in the end this will be ignored as the issuer will be set
++	 * by gnutls_x509_crt_sign2() */
++	ret = gnutls_x509_crt_set_issuer_dn(crt, "o = big\\, and one, cn = my CA", &err);
++	if (ret < 0) {
++		fail("gnutls_x509_crt_set_issuer_dn: %s, %s\n", gnutls_strerror(ret), err);
++	}
++
++#define ISSUER_UNIQUE_ID "\x00\x01\x02\x03"
++#define SUBJECT_UNIQUE_ID "\x04\x03\x02\x01"
++	ret = gnutls_x509_crt_set_issuer_unique_id(crt, ISSUER_UNIQUE_ID, sizeof(ISSUER_UNIQUE_ID)-1);
++	if (ret < 0)
++		fail("error: %s\n", gnutls_strerror(ret));
++
++	ret = gnutls_x509_crt_set_subject_unique_id(crt, SUBJECT_UNIQUE_ID, sizeof(SUBJECT_UNIQUE_ID)-1);
++	if (ret < 0)
++		fail("error: %s\n", gnutls_strerror(ret));
++
++	/* Sign and finalize the certificate */
++	ret = gnutls_x509_crt_sign2(crt, crt, pkey, GNUTLS_DIG_SHA256, 0);
++	if (ret < 0)
++		fail("gnutls_x509_crt_sign2: %s\n", gnutls_strerror(ret));
++
++
++	ret = gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_FULL, &out);
++	if (ret != 0)
++		fail("gnutls_x509_crt_print\n");
++	if (debug)
++		printf("crt: %.*s\n", out.size, out.data);
++	gnutls_free(out.data);
++
++	/* Verify whether selected input is present */
++	s = 0;
++	ret = gnutls_x509_crt_get_extension_info(crt, 0, NULL, &s, NULL);
++	if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
++		fail("gnutls_x509_crt_get_extension_info2: %s\n", strerror(ret));
++
++	s = 0;
++	ret = gnutls_x509_crt_get_extension_data(crt, 0, NULL, &s);
++	if (ret != 0)
++		fail("gnutls_x509_crt_get_extension_data: %s\n", strerror(ret));
++
++	ret = gnutls_x509_crt_get_raw_issuer_dn(crt, &out);
++	if (ret < 0 || out.size == 0)
++		fail("gnutls_x509_crt_get_raw_issuer_dn: %s\n", gnutls_strerror(ret));
++
++	if (out.size != 45 ||
++	    memcmp(out.data, "\x30\x2b\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6e\x69\x6b\x6f\x73\x31\x19\x30\x17\x06\x03\x55\x04\x0a\x13\x10\x6e\x6f\x6e\x65\x20\x74\x6f\x2c\x20\x6d\x65\x6e\x74\x69\x6f\x6e", 45) != 0) {
++		hexprint(out.data, out.size);
++		fail("issuer DN comparison failed\n");
++	}
++	gnutls_free(out.data);
++
++	s = sizeof(buf);
++	ret = gnutls_x509_crt_get_issuer_unique_id(crt, (void*)buf, &s);
++	if (ret < 0)
++		fail("error: %s\n", gnutls_strerror(ret));
++
++	if (s != sizeof(ISSUER_UNIQUE_ID)-1 ||
++		memcmp(buf, ISSUER_UNIQUE_ID, s) != 0) {
++		fail("issuer unique id comparison failed\n");
++	}
++
++	s = sizeof(buf);
++	ret = gnutls_x509_crt_get_subject_unique_id(crt, (void*)buf, &s);
++	if (ret < 0)
++		fail("error: %s\n", gnutls_strerror(ret));
++
++	if (s != sizeof(SUBJECT_UNIQUE_ID)-1 ||
++		memcmp(buf, SUBJECT_UNIQUE_ID, s) != 0) {
++		fail("subject unique id comparison failed\n");
++	}
++
++	ret = gnutls_x509_crt_get_raw_dn(crt, &out);
++	if (ret < 0 || out.size == 0)
++		fail("gnutls_x509_crt_get_raw_dn: %s\n", gnutls_strerror(ret));
++
++	if (out.size != 45 ||
++	    memcmp(out.data, "\x30\x2b\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6e\x69\x6b\x6f\x73\x31\x19\x30\x17\x06\x03\x55\x04\x0a\x13\x10\x6e\x6f\x6e\x65\x20\x74\x6f\x2c\x20\x6d\x65\x6e\x74\x69\x6f\x6e", 45) != 0) {
++		fail("DN comparison failed\n");
++	}
++	gnutls_free(out.data);
++
++	assert(gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_PEM, &out) >= 0);
++
++	if (debug)
++		fprintf(stderr, "%s\n", out.data);
++	assert(out.size == saved_crt.size);
++	assert(memcmp(out.data, saved_crt.data, out.size)==0);
++
++	gnutls_free(out.data);
++
++	gnutls_x509_crt_deinit(crt);
++	gnutls_x509_crt_deinit(crt2);
++	gnutls_x509_privkey_deinit(pkey);
++
++	gnutls_global_deinit();
++}
diff --git a/SOURCES/gnutls-3.3.8-no-libtasn1-check.patch b/SOURCES/gnutls-3.3.8-no-libtasn1-check.patch
deleted file mode 100644
index 993cfc6..0000000
--- a/SOURCES/gnutls-3.3.8-no-libtasn1-check.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff -ur gnutls-3.3.8-orig/m4/hooks.m4 gnutls-3.3.8/m4/hooks.m4
---- gnutls-3.3.8-orig/m4/hooks.m4	2014-09-18 07:54:45.000000000 +0200
-+++ gnutls-3.3.8/m4/hooks.m4	2014-09-18 19:08:19.223172863 +0200
-@@ -104,7 +104,7 @@
-       included_libtasn1=$withval,
-       included_libtasn1=no)
-   if test "$included_libtasn1" = "no"; then
--    PKG_CHECK_MODULES(LIBTASN1, [libtasn1 >= 3.9], [], [included_libtasn1=yes])
-+    PKG_CHECK_MODULES(LIBTASN1, [libtasn1 >= 3.8], [], [included_libtasn1=yes])
-     if test "$included_libtasn1" = yes; then
-       AC_MSG_WARN([[
-   *** 
-Only in gnutls-3.3.8/m4: hooks.m4~
diff --git a/SPECS/gnutls.spec b/SPECS/gnutls.spec
index 2934d88..3404620 100644
--- a/SPECS/gnutls.spec
+++ b/SPECS/gnutls.spec
@@ -2,12 +2,12 @@
 %bcond_with guile
 Summary: A TLS protocol implementation
 Name: gnutls
-Version: 3.3.24
-Release: 1%{?dist}
+Version: 3.3.26
+Release: 9%{?dist}
 # The libraries are LGPLv2.1+, utilities are GPLv3+
 License: GPLv3+ and LGPLv2+
 Group: System Environment/Libraries
-BuildRequires: p11-kit-devel >= 0.20.7, gettext
+BuildRequires: p11-kit-devel >= 0.23.1, gettext
 BuildRequires: zlib-devel, readline-devel, libtasn1-devel >= 3.8
 BuildRequires: libtool, automake, autoconf, texinfo
 BuildRequires: autogen-libopts-devel >= 5.18 autogen gettext-devel
@@ -19,8 +19,9 @@ BuildRequires: fipscheck
 BuildRequires: softhsm, net-tools
 Requires: p11-kit-trust
 # The automatic dependency on libtasn1 and p11-kit is insufficient,
-Requires: libtasn1 >= 3.8
-Requires: p11-kit >= 0.20.7
+Requires: libtasn1 >= 3.9
+Requires: p11-kit >= 0.23.1
+Requires: trousers >= 0.3.11.2
 %if %{with dane}
 BuildRequires: unbound-devel unbound-libs
 %endif
@@ -36,13 +37,21 @@ Source1: libgnutls-config
 Source2: hobble-gnutls
 Patch1: gnutls-3.2.7-rpath.patch
 Patch2: gnutls-3.1.11-nosrp.patch
-Patch3: gnutls-3.3.8-no-libtasn1-check.patch
 Patch4: gnutls-3.3.8-fips-key.patch
 Patch5: gnutls-3.3.8-padlock-disable.patch
 # In 3.3.8 we were shipping an early backport of a fix in GNUTLS_E_APPLICATION_DATA
 # behavior, which was using 3.4.0 semantics. We continue shipping to support
 # any applications depending on that.
 Patch6: gnutls-3.3.22-eapp-data.patch
+Patch7: gnutls-3.3.26-dh-params-1024.patch
+# Reported on the gnutls ML affecting Fedora 25 (potentially RHEL7 as well)
+Patch8: gnutls-3.3.26-fix-uninitialized.patch
+Patch9: gnutls-3.3.26-fix-coverity-issues.patch
+Patch10: gnutls-3.3.26-pin-value.patch
+Patch11: gnutls-3.3.26-set-unique-id-tests.patch
+Patch12: gnutls-3.3.26-fips-rsa-keygen.patch
+Patch13: gnutls-3.3.26-cve-2017-7869.patch
+Patch14: gnutls-3.3.26-remove-status-req-ext-parsing.patch
 # Wildcard bundling exception https://fedorahosted.org/fpc/ticket/174
 Provides: bundled(gnulib) = 20130424
 
@@ -144,10 +153,17 @@ This package contains Guile bindings for the library.
 
 %patch1 -p1 -b .rpath
 %patch2 -p1 -b .nosrp
-%patch3 -p1 -b .libtasn1
 %patch4 -p1 -b .fips-key
 %patch5 -p1 -b .padlock-disable
 %patch6 -p1 -b .eapp-data
+%patch7 -p1 -b .dh-1024
+%patch8 -p1 -b .fix-uninit
+%patch9 -p1 -b .fix-coverity
+%patch10 -p1 -b .pin-value
+%patch11 -p1 -b .unique-id
+%patch12 -p1 -b .rsa-keygen
+%patch13 -p1 -b .openpgp-fixes
+%patch14 -p1 -b .ocsp-ext-parse
 
 sed 's/gnutls_srp.c//g' -i lib/Makefile.in
 sed 's/gnutls_srp.lo//g' -i lib/Makefile.in
@@ -169,6 +185,7 @@ export LDFLAGS="-Wl,--no-add-needed"
            --disable-openssl-compatibility \
            --disable-srp-authentication \
 	   --disable-non-suiteb-curves \
+	   --with-trousers-lib=%{_libdir}/libtspi.so.1 \
 	   --enable-fips140-mode \
 %if %{with guile}
            --enable-guile \
@@ -296,6 +313,26 @@ fi
 %endif
 
 %changelog
+* Fri May 26 2017 Nikos Mavrogiannopoulos <nmav@redhat.com> 3.3.26-9
+- Address crash in OCSP status request extension, by eliminating the
+  unneeded parsing (CVE-2017-7507, #1455828)
+
+* Wed Apr 26 2017 Nikos Mavrogiannopoulos <nmav@redhat.com> 3.3.26-7
+- Address interoperability issue with 3.5.x (#1388932)
+- Reject CAs which are both trusted and blacklisted in trust module (#1375303)
+- Added new functions to set issuer and subject ID in certificates (#1378373)
+- Reject connections with less than 1024-bit DH parameters (#1335931)
+- Fix issue that made GnuTLS parse only the first 32 extensions (#1383748)
+- Mention limitations of certtool in manpage (#1375463)
+- Read PKCS#8 files with HMAC-SHA256 -as generated by openssl 1.1 (#1380642)
+- Do not link directly to trousers but instead use dlopen (#1379739)
+- Fix incorrect OCSP validation (#1377569)
+- Added support for pin-value in PKCS#11 URIs (#1379283)
+- Added the --id option to p11tool (#1399232)
+- Improved sanity checks in RSA key generation (#1444780)
+- Addressed CVE-2017-5334, CVE-2017-5335, CVE-2017-5336, CVE-2017-5337,
+  CVE-2017-7869
+
 * Tue Jul 12 2016 Nikos Mavrogiannopoulos <nmav@redhat.com> 3.3.24-1
 - Addressed issue with DSA public keys smaller than 2^1024 (#1238279)
 - Addressed two-byte buffer overflow in the DTLS-0.9 protocol (#1209365)