20cebf
--- bind-9.10.4-P3/configure.in	2016-11-07 17:57:34.328237767 +0100
20cebf
+++ bind-9.10.4-P3/configure.in	2016-11-07 17:57:34.336237955 +0100
20cebf
@@ -1562,28 +1562,6 @@ Please check the argument to --with-open
20cebf
 shared library configuration (e.g., LD_LIBRARY_PATH).)],
20cebf
 		[AC_MSG_RESULT(assuming it does work on target platform)])
20cebf
 
20cebf
-		AC_MSG_CHECKING(whether linking with OpenSSL requires -ldl)
20cebf
-		AC_TRY_LINK([
20cebf
-#include <openssl/err.h>
20cebf
-#include <openssl/dso.h>
20cebf
-],
20cebf
-[ DSO_METHOD_dlfcn(); ],
20cebf
-		[AC_MSG_RESULT(no)],
20cebf
-		[LIBS="$LIBS -ldl"
20cebf
-		AC_TRY_LINK([
20cebf
-#include <openssl/err.h>
20cebf
-#include <openssl/dso.h>
20cebf
-],[ DSO_METHOD_dlfcn(); ],
20cebf
-		[AC_MSG_RESULT(yes)
20cebf
-		DST_OPENSSL_LIBS="$DST_OPENSSL_LIBS -ldl"
20cebf
-		],
20cebf
-		 [AC_MSG_RESULT(unknown)
20cebf
-		 AC_MSG_ERROR(OpenSSL has unsupported dynamic loading)],
20cebf
-		[AC_MSG_RESULT(assuming it does work on target platform)])
20cebf
-		],
20cebf
-		[AC_MSG_RESULT(assuming it does work on target platform)]
20cebf
-		)
20cebf
-		 
20cebf
 AC_ARG_ENABLE(openssl-version-check,
20cebf
 [AC_HELP_STRING([--enable-openssl-version-check],
20cebf
 	[check OpenSSL version @<:@default=yes@:>@])])
20cebf
--- bind-9.10.4-P3/lib/dns/dst_openssl.h	2016-09-14 03:23:44.000000000 +0200
20cebf
+++ bind-9.10.4-P3/lib/dns/dst_openssl.h	2016-11-07 17:57:34.336237955 +0100
20cebf
@@ -30,8 +30,10 @@ 
20cebf
 #include <openssl/conf.h>
20cebf
 #include <openssl/crypto.h>
20cebf
 #include <openssl/bn.h>
20cebf
+#include <openssl/ec.h>
20cebf
 
20cebf
-#if !defined(OPENSSL_NO_ENGINE) && defined(CRYPTO_LOCK_ENGINE) && \
20cebf
+#if !defined(OPENSSL_NO_ENGINE) && (defined(CRYPTO_LOCK_ENGINE) || \
20cebf
+    defined(CRYPTO_EX_INDEX_ENGINE)) && \
20cebf
     (OPENSSL_VERSION_NUMBER >= 0x0090707f)
20cebf
 #define USE_ENGINE 1
20cebf
 #endif
20cebf
--- bind-9.10.4-P3/lib/dns/openssldh_link.c	2016-09-14 03:23:44.000000000 +0200
20cebf
+++ bind-9.10.4-P3/lib/dns/openssldh_link.c	2016-11-07 17:57:34.336237955 +0100
20cebf
@@ -81,6 +81,7 @@ openssldh_computesecret(const dst_key_t
20cebf
 	int ret;
20cebf
 	isc_region_t r;
20cebf
 	unsigned int len;
20cebf
+	const BIGNUM *pub_key;
20cebf
 
20cebf
 	REQUIRE(pub->keydata.dh != NULL);
20cebf
 	REQUIRE(priv->keydata.dh != NULL);
20cebf
@@ -92,7 +93,12 @@ openssldh_computesecret(const dst_key_t
20cebf
 	isc_buffer_availableregion(secret, &r);
20cebf
 	if (r.length < len)
20cebf
 		return (ISC_R_NOSPACE);
20cebf
-	ret = DH_compute_key(r.base, dhpub->pub_key, dhpriv);
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	pub_key = dhpub->pub_key;
20cebf
+#else
20cebf
+	DH_get0_key(dhpub, &pub_key, NULL);
20cebf
+#endif
20cebf
+	ret = DH_compute_key(r.base, pub_key, dhpriv);
20cebf
 	if (ret <= 0)
20cebf
 		return (dst__openssl_toresult2("DH_compute_key",
20cebf
 					       DST_R_COMPUTESECRETFAILURE));
20cebf
@@ -104,6 +110,8 @@ static isc_boolean_t
20cebf
 openssldh_compare(const dst_key_t *key1, const dst_key_t *key2) {
20cebf
 	int status;
20cebf
 	DH *dh1, *dh2;
20cebf
+	const BIGNUM *p1, *g1, *pub_key1, *priv_key1;
20cebf
+	const BIGNUM *p2, *g2, *pub_key2, *priv_key2;
20cebf
 
20cebf
 	dh1 = key1->keydata.dh;
20cebf
 	dh2 = key2->keydata.dh;
20cebf
@@ -113,17 +121,33 @@ openssldh_compare(const dst_key_t *key1,
20cebf
 	else if (dh1 == NULL || dh2 == NULL)
20cebf
 		return (ISC_FALSE);
20cebf
 
20cebf
-	status = BN_cmp(dh1->p, dh2->p) ||
20cebf
-		 BN_cmp(dh1->g, dh2->g) ||
20cebf
-		 BN_cmp(dh1->pub_key, dh2->pub_key);
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	p1 = dh1->p;
20cebf
+	g1 = dh1->g;
20cebf
+	pub_key1 = dh1->pub_key;
20cebf
+	priv_key1 = dh1->priv_key;
20cebf
+	p2 = dh2->p;
20cebf
+	g2 = dh2->g;
20cebf
+	pub_key2 = dh2->pub_key;
20cebf
+	priv_key2 = dh2->priv_key;
20cebf
+#else
20cebf
+	DH_get0_pqg(dh1, &p1, NULL, &g1;;
20cebf
+	DH_get0_key(dh1, &pub_key1, &priv_key1);
20cebf
+	DH_get0_pqg(dh2, &p2, NULL, &g2;;
20cebf
+	DH_get0_key(dh2, &pub_key2, &priv_key2);
20cebf
+#endif
20cebf
+
20cebf
+	status = BN_cmp(p1, p2) ||
20cebf
+		 BN_cmp(g1, g2) ||
20cebf
+		 BN_cmp(pub_key1, pub_key2);
20cebf
 
20cebf
 	if (status != 0)
20cebf
 		return (ISC_FALSE);
20cebf
 
20cebf
-	if (dh1->priv_key != NULL || dh2->priv_key != NULL) {
20cebf
-		if (dh1->priv_key == NULL || dh2->priv_key == NULL)
20cebf
+	if (priv_key1 != NULL || priv_key2 != NULL) {
20cebf
+		if (priv_key1 == NULL || priv_key2 == NULL)
20cebf
 			return (ISC_FALSE);
20cebf
-		if (BN_cmp(dh1->priv_key, dh2->priv_key) != 0)
20cebf
+		if (BN_cmp(priv_key1, priv_key2) != 0)
20cebf
 			return (ISC_FALSE);
20cebf
 	}
20cebf
 	return (ISC_TRUE);
20cebf
@@ -133,6 +157,8 @@ static isc_boolean_t
20cebf
 openssldh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) {
20cebf
 	int status;
20cebf
 	DH *dh1, *dh2;
20cebf
+	const BIGNUM *p1, *g1;
20cebf
+	const BIGNUM *p2, *g2;
20cebf
 
20cebf
 	dh1 = key1->keydata.dh;
20cebf
 	dh2 = key2->keydata.dh;
20cebf
@@ -142,8 +168,18 @@ openssldh_paramcompare(const dst_key_t *
20cebf
 	else if (dh1 == NULL || dh2 == NULL)
20cebf
 		return (ISC_FALSE);
20cebf
 
20cebf
-	status = BN_cmp(dh1->p, dh2->p) ||
20cebf
-		 BN_cmp(dh1->g, dh2->g);
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	p1 = dh1->p;
20cebf
+	g1 = dh1->g;
20cebf
+	p2 = dh2->p;
20cebf
+	g2 = dh2->g;
20cebf
+#else
20cebf
+	DH_get0_pqg(dh1, &p1, NULL, &g1;;
20cebf
+	DH_get0_pqg(dh2, &p2, NULL, &g2;;
20cebf
+#endif
20cebf
+
20cebf
+	status = BN_cmp(p1, p2) ||
20cebf
+		 BN_cmp(g1, g2);
20cebf
 
20cebf
 	if (status != 0)
20cebf
 		return (ISC_FALSE);
20cebf
@@ -190,16 +226,29 @@ openssldh_generate(dst_key_t *key, int g
20cebf
 		    key->key_size == 1024 ||
20cebf
 		    key->key_size == 1536)
20cebf
 		{
20cebf
+			BIGNUM *p, *g;
20cebf
 			dh = DH_new();
20cebf
 			if (dh == NULL)
20cebf
 				return (dst__openssl_toresult(ISC_R_NOMEMORY));
20cebf
 			if (key->key_size == 768)
20cebf
-				dh->p = bn768;
20cebf
+				p = bn768;
20cebf
 			else if (key->key_size == 1024)
20cebf
-				dh->p = bn1024;
20cebf
+				p = bn1024;
20cebf
 			else
20cebf
-				dh->p = bn1536;
20cebf
+				p = bn1536;
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+			dh->p = p;
20cebf
 			dh->g = bn2;
20cebf
+#else
20cebf
+			p = BN_dup(p);
20cebf
+			g = BN_dup(bn2);
20cebf
+			if (p == NULL || g == NULL) {
20cebf
+				BN_free(p);
20cebf
+				BN_free(g);
20cebf
+				return (dst__openssl_toresult(ISC_R_NOMEMORY));
20cebf
+			}
20cebf
+			DH_set0_pqg(dh, p, NULL, g);
20cebf
+#endif
20cebf
 		} else
20cebf
 			generator = 2;
20cebf
 	}
20cebf
@@ -247,7 +296,11 @@ openssldh_generate(dst_key_t *key, int g
20cebf
 		return (dst__openssl_toresult2("DH_generate_key",
20cebf
 					       DST_R_OPENSSLFAILURE));
20cebf
 	}
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 	dh->flags &= ~DH_FLAG_CACHE_MONT_P;
20cebf
+#else
20cebf
+	DH_clear_flags(dh, DH_FLAG_CACHE_MONT_P);
20cebf
+#endif
20cebf
 
20cebf
 	key->keydata.dh = dh;
20cebf
 
20cebf
@@ -257,7 +310,17 @@ openssldh_generate(dst_key_t *key, int g
20cebf
 static isc_boolean_t
20cebf
 openssldh_isprivate(const dst_key_t *key) {
20cebf
 	DH *dh = key->keydata.dh;
20cebf
-	return (ISC_TF(dh != NULL && dh->priv_key != NULL));
20cebf
+	const BIGNUM *priv_key;
20cebf
+
20cebf
+	if (dh == NULL)
20cebf
+		return (ISC_TF(0));
20cebf
+
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	priv_key = dh->priv_key;
20cebf
+#else
20cebf
+	DH_get0_key(dh, NULL, &priv_key);
20cebf
+#endif
20cebf
+	return (ISC_TF(priv_key != NULL));
20cebf
 }
20cebf
 
20cebf
 static void
20cebf
@@ -267,10 +330,12 @@ openssldh_destroy(dst_key_t *key) {
20cebf
 	if (dh == NULL)
20cebf
 		return;
20cebf
 
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 	if (dh->p == bn768 || dh->p == bn1024 || dh->p == bn1536)
20cebf
 		dh->p = NULL;
20cebf
 	if (dh->g == bn2)
20cebf
 		dh->g = NULL;
20cebf
+#endif
20cebf
 	DH_free(dh);
20cebf
 	key->keydata.dh = NULL;
20cebf
 }
20cebf
@@ -299,6 +364,7 @@ uint16_fromregion(isc_region_t *region)
20cebf
 static isc_result_t
20cebf
 openssldh_todns(const dst_key_t *key, isc_buffer_t *data) {
20cebf
 	DH *dh;
20cebf
+	const BIGNUM *p, *g, *pub_key;
20cebf
 	isc_region_t r;
20cebf
 	isc_uint16_t dnslen, plen, glen, publen;
20cebf
 
20cebf
@@ -306,42 +372,51 @@ openssldh_todns(const dst_key_t *key, is
20cebf
 
20cebf
 	dh = key->keydata.dh;
20cebf
 
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	p = dh->p;
20cebf
+	g = dh->g;
20cebf
+	pub_key = dh->pub_key;
20cebf
+#else
20cebf
+	DH_get0_pqg(dh, &p, NULL, &g);
20cebf
+	DH_get0_key(dh, &pub_key, NULL);
20cebf
+#endif
20cebf
+
20cebf
 	isc_buffer_availableregion(data, &r);
20cebf
 
20cebf
-	if (dh->g == bn2 &&
20cebf
-	    (dh->p == bn768 || dh->p == bn1024 || dh->p == bn1536)) {
20cebf
+	if (BN_cmp(g, bn2) == 0 &&
20cebf
+	    (BN_cmp(p, bn768) == 0 || BN_cmp(p, bn1024) == 0 || BN_cmp(p, bn1536) == 0)) {
20cebf
 		plen = 1;
20cebf
 		glen = 0;
20cebf
 	}
20cebf
 	else {
20cebf
-		plen = BN_num_bytes(dh->p);
20cebf
-		glen = BN_num_bytes(dh->g);
20cebf
+		plen = BN_num_bytes(p);
20cebf
+		glen = BN_num_bytes(g);
20cebf
 	}
20cebf
-	publen = BN_num_bytes(dh->pub_key);
20cebf
+	publen = BN_num_bytes(pub_key);
20cebf
 	dnslen = plen + glen + publen + 6;
20cebf
 	if (r.length < (unsigned int) dnslen)
20cebf
 		return (ISC_R_NOSPACE);
20cebf
 
20cebf
 	uint16_toregion(plen, &r);
20cebf
 	if (plen == 1) {
20cebf
-		if (dh->p == bn768)
20cebf
+		if (BN_cmp(p, bn768) == 0)
20cebf
 			*r.base = 1;
20cebf
-		else if (dh->p == bn1024)
20cebf
+		else if (BN_cmp(p, bn1024) == 0)
20cebf
 			*r.base = 2;
20cebf
 		else
20cebf
 			*r.base = 3;
20cebf
 	}
20cebf
 	else
20cebf
-		BN_bn2bin(dh->p, r.base);
20cebf
+		BN_bn2bin(p, r.base);
20cebf
 	isc_region_consume(&r, plen);
20cebf
 
20cebf
 	uint16_toregion(glen, &r);
20cebf
 	if (glen > 0)
20cebf
-		BN_bn2bin(dh->g, r.base);
20cebf
+		BN_bn2bin(g, r.base);
20cebf
 	isc_region_consume(&r, glen);
20cebf
 
20cebf
 	uint16_toregion(publen, &r);
20cebf
-	BN_bn2bin(dh->pub_key, r.base);
20cebf
+	BN_bn2bin(pub_key, r.base);
20cebf
 	isc_region_consume(&r, publen);
20cebf
 
20cebf
 	isc_buffer_add(data, dnslen);
20cebf
@@ -355,6 +430,8 @@ openssldh_fromdns(dst_key_t *key, isc_bu
20cebf
 	isc_region_t r;
20cebf
 	isc_uint16_t plen, glen, publen;
20cebf
 	int special = 0;
20cebf
+	BIGNUM *p = NULL, *g = NULL, *pub_key = NULL;
20cebf
+	isc_result_t ret = ISC_R_NOMEMORY;
20cebf
 
20cebf
 	isc_buffer_remainingregion(data, &r);
20cebf
 	if (r.length == 0)
20cebf
@@ -363,24 +440,28 @@ openssldh_fromdns(dst_key_t *key, isc_bu
20cebf
 	dh = DH_new();
20cebf
 	if (dh == NULL)
20cebf
 		return (dst__openssl_toresult(ISC_R_NOMEMORY));
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 	dh->flags &= ~DH_FLAG_CACHE_MONT_P;
20cebf
+#else
20cebf
+	DH_clear_flags(dh, DH_FLAG_CACHE_MONT_P);
20cebf
+#endif
20cebf
 
20cebf
 	/*
20cebf
 	 * Read the prime length.  1 & 2 are table entries, > 16 means a
20cebf
 	 * prime follows, otherwise an error.
20cebf
 	 */
20cebf
 	if (r.length < 2) {
20cebf
-		DH_free(dh);
20cebf
-		return (DST_R_INVALIDPUBLICKEY);
20cebf
+		ret = DST_R_INVALIDPUBLICKEY;
20cebf
+		goto fail;
20cebf
 	}
20cebf
 	plen = uint16_fromregion(&r);
20cebf
 	if (plen < 16 && plen != 1 && plen != 2) {
20cebf
-		DH_free(dh);
20cebf
-		return (DST_R_INVALIDPUBLICKEY);
20cebf
+		ret = DST_R_INVALIDPUBLICKEY;
20cebf
+		goto fail;
20cebf
 	}
20cebf
 	if (r.length < plen) {
20cebf
-		DH_free(dh);
20cebf
-		return (DST_R_INVALIDPUBLICKEY);
20cebf
+		ret = DST_R_INVALIDPUBLICKEY;
20cebf
+		goto fail;
20cebf
 	}
20cebf
 	if (plen == 1 || plen == 2) {
20cebf
 		if (plen == 1) {
20cebf
@@ -391,85 +472,119 @@ openssldh_fromdns(dst_key_t *key, isc_bu
20cebf
 		}
20cebf
 		switch (special) {
20cebf
 			case 1:
20cebf
-				dh->p = bn768;
20cebf
+				p = bn768;
20cebf
 				break;
20cebf
 			case 2:
20cebf
-				dh->p = bn1024;
20cebf
+				p = bn1024;
20cebf
 				break;
20cebf
 			case 3:
20cebf
-				dh->p = bn1536;
20cebf
+				p = bn1536;
20cebf
 				break;
20cebf
 			default:
20cebf
-				DH_free(dh);
20cebf
-				return (DST_R_INVALIDPUBLICKEY);
20cebf
+				ret = DST_R_INVALIDPUBLICKEY;
20cebf
+				goto fail;
20cebf
 		}
20cebf
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
20cebf
+		p = BN_dup(p);
20cebf
+#endif
20cebf
 	} else {
20cebf
-		dh->p = BN_bin2bn(r.base, plen, NULL);
20cebf
+		p = BN_bin2bn(r.base, plen, NULL);
20cebf
 		isc_region_consume(&r, plen);
20cebf
 	}
20cebf
 
20cebf
+	if (p == NULL) {
20cebf
+		ret = dst__openssl_toresult(ISC_R_NOMEMORY);
20cebf
+		goto fail;
20cebf
+	}
20cebf
+
20cebf
 	/*
20cebf
 	 * Read the generator length.  This should be 0 if the prime was
20cebf
 	 * special, but it might not be.  If it's 0 and the prime is not
20cebf
 	 * special, we have a problem.
20cebf
 	 */
20cebf
 	if (r.length < 2) {
20cebf
-		DH_free(dh);
20cebf
-		return (DST_R_INVALIDPUBLICKEY);
20cebf
+		ret = DST_R_INVALIDPUBLICKEY;
20cebf
+		goto fail;
20cebf
 	}
20cebf
 	glen = uint16_fromregion(&r);
20cebf
 	if (r.length < glen) {
20cebf
-		DH_free(dh);
20cebf
-		return (DST_R_INVALIDPUBLICKEY);
20cebf
+		ret = DST_R_INVALIDPUBLICKEY;
20cebf
+		goto fail;
20cebf
 	}
20cebf
 	if (special != 0) {
20cebf
-		if (glen == 0)
20cebf
-			dh->g = bn2;
20cebf
-		else {
20cebf
-			dh->g = BN_bin2bn(r.base, glen, NULL);
20cebf
-			if (BN_cmp(dh->g, bn2) == 0) {
20cebf
-				BN_free(dh->g);
20cebf
-				dh->g = bn2;
20cebf
-			}
20cebf
-			else {
20cebf
-				DH_free(dh);
20cebf
-				return (DST_R_INVALIDPUBLICKEY);
20cebf
+		if (glen == 0) {
20cebf
+			g = bn2;
20cebf
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
20cebf
+			g = BN_dup(g);
20cebf
+#endif
20cebf
+		} else {
20cebf
+			g = BN_bin2bn(r.base, glen, NULL);
20cebf
+			if (BN_cmp(g, bn2) != 0) {
20cebf
+				ret = DST_R_INVALIDPUBLICKEY;
20cebf
+				goto fail;
20cebf
 			}
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+			BN_free(g);
20cebf
+			g = bn2;
20cebf
+#endif
20cebf
 		}
20cebf
 	} else {
20cebf
 		if (glen == 0) {
20cebf
-			DH_free(dh);
20cebf
-			return (DST_R_INVALIDPUBLICKEY);
20cebf
+			ret = DST_R_INVALIDPUBLICKEY;
20cebf
+			goto fail;
20cebf
 		}
20cebf
-		dh->g = BN_bin2bn(r.base, glen, NULL);
20cebf
+		g = BN_bin2bn(r.base, glen, NULL);
20cebf
 	}
20cebf
 	isc_region_consume(&r, glen);
20cebf
 
20cebf
 	if (r.length < 2) {
20cebf
-		DH_free(dh);
20cebf
-		return (DST_R_INVALIDPUBLICKEY);
20cebf
+		ret = DST_R_INVALIDPUBLICKEY;
20cebf
+		goto fail;
20cebf
 	}
20cebf
 	publen = uint16_fromregion(&r);
20cebf
 	if (r.length < publen) {
20cebf
-		DH_free(dh);
20cebf
-		return (DST_R_INVALIDPUBLICKEY);
20cebf
+		ret = DST_R_INVALIDPUBLICKEY;
20cebf
+		goto fail;
20cebf
 	}
20cebf
-	dh->pub_key = BN_bin2bn(r.base, publen, NULL);
20cebf
+	pub_key = BN_bin2bn(r.base, publen, NULL);
20cebf
 	isc_region_consume(&r, publen);
20cebf
 
20cebf
-	key->key_size = BN_num_bits(dh->p);
20cebf
+	if (p == NULL || g == NULL ||
20cebf
+		pub_key == NULL) {
20cebf
+		ret = dst__openssl_toresult(ISC_R_NOMEMORY);
20cebf
+		goto fail;
20cebf
+	}
20cebf
+
20cebf
+	key->key_size = BN_num_bits(p);
20cebf
 
20cebf
 	isc_buffer_forward(data, plen + glen + publen + 6);
20cebf
 
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	dh->p = p;
20cebf
+	dh->g = g;
20cebf
+	dh->pub_key = pub_key;
20cebf
+#else
20cebf
+	DH_set0_pqg(dh, p, NULL, g);
20cebf
+	DH_set0_key(dh, pub_key, NULL);
20cebf
+#endif
20cebf
+
20cebf
 	key->keydata.dh = dh;
20cebf
 
20cebf
 	return (ISC_R_SUCCESS);
20cebf
+fail:
20cebf
+	if (p != bn768 && p != bn1024 && p != bn1536)
20cebf
+		BN_free(p);
20cebf
+	if (g != bn2)
20cebf
+		BN_free(g);
20cebf
+	DH_free(dh);
20cebf
+	return ret;
20cebf
 }
20cebf
 
20cebf
 static isc_result_t
20cebf
 openssldh_tofile(const dst_key_t *key, const char *directory) {
20cebf
 	int i;
20cebf
 	DH *dh;
20cebf
+	const BIGNUM *p, *g, *pub_key, *priv_key;
20cebf
 	dst_private_t priv;
20cebf
 	unsigned char *bufs[4];
20cebf
 	isc_result_t result;
20cebf
@@ -482,9 +597,19 @@ openssldh_tofile(const dst_key_t *key, c
20cebf
 
20cebf
 	dh = key->keydata.dh;
20cebf
 
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	p = dh->p;
20cebf
+	g = dh->g;
20cebf
+	pub_key = dh->pub_key;
20cebf
+	priv_key = dh->priv_key;
20cebf
+#else
20cebf
+	DH_get0_pqg(dh, &p, NULL, &g);
20cebf
+	DH_get0_key(dh, &pub_key, &priv_key);
20cebf
+#endif
20cebf
+
20cebf
 	memset(bufs, 0, sizeof(bufs));
20cebf
 	for (i = 0; i < 4; i++) {
20cebf
-		bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(dh->p));
20cebf
+		bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(p));
20cebf
 		if (bufs[i] == NULL) {
20cebf
 			result = ISC_R_NOMEMORY;
20cebf
 			goto fail;
20cebf
@@ -494,26 +619,26 @@ openssldh_tofile(const dst_key_t *key, c
20cebf
 	i = 0;
20cebf
 
20cebf
 	priv.elements[i].tag = TAG_DH_PRIME;
20cebf
-	priv.elements[i].length = BN_num_bytes(dh->p);
20cebf
-	BN_bn2bin(dh->p, bufs[i]);
20cebf
+	priv.elements[i].length = BN_num_bytes(p);
20cebf
+	BN_bn2bin(p, bufs[i]);
20cebf
 	priv.elements[i].data = bufs[i];
20cebf
 	i++;
20cebf
 
20cebf
 	priv.elements[i].tag = TAG_DH_GENERATOR;
20cebf
-	priv.elements[i].length = BN_num_bytes(dh->g);
20cebf
-	BN_bn2bin(dh->g, bufs[i]);
20cebf
+	priv.elements[i].length = BN_num_bytes(g);
20cebf
+	BN_bn2bin(g, bufs[i]);
20cebf
 	priv.elements[i].data = bufs[i];
20cebf
 	i++;
20cebf
 
20cebf
 	priv.elements[i].tag = TAG_DH_PRIVATE;
20cebf
-	priv.elements[i].length = BN_num_bytes(dh->priv_key);
20cebf
-	BN_bn2bin(dh->priv_key, bufs[i]);
20cebf
+	priv.elements[i].length = BN_num_bytes(priv_key);
20cebf
+	BN_bn2bin(priv_key, bufs[i]);
20cebf
 	priv.elements[i].data = bufs[i];
20cebf
 	i++;
20cebf
 
20cebf
 	priv.elements[i].tag = TAG_DH_PUBLIC;
20cebf
-	priv.elements[i].length = BN_num_bytes(dh->pub_key);
20cebf
-	BN_bn2bin(dh->pub_key, bufs[i]);
20cebf
+	priv.elements[i].length = BN_num_bytes(pub_key);
20cebf
+	BN_bn2bin(pub_key, bufs[i]);
20cebf
 	priv.elements[i].data = bufs[i];
20cebf
 	i++;
20cebf
 
20cebf
@@ -523,7 +648,7 @@ openssldh_tofile(const dst_key_t *key, c
20cebf
 	for (i = 0; i < 4; i++) {
20cebf
 		if (bufs[i] == NULL)
20cebf
 			break;
20cebf
-		isc_mem_put(key->mctx, bufs[i], BN_num_bytes(dh->p));
20cebf
+		isc_mem_put(key->mctx, bufs[i], BN_num_bytes(p));
20cebf
 	}
20cebf
 	return (result);
20cebf
 }
20cebf
@@ -534,6 +659,7 @@ openssldh_parse(dst_key_t *key, isc_lex_
20cebf
 	isc_result_t ret;
20cebf
 	int i;
20cebf
 	DH *dh = NULL;
20cebf
+	BIGNUM *p = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL;
20cebf
 	isc_mem_t *mctx;
20cebf
 #define DST_RET(a) {ret = a; goto err;}
20cebf
 
20cebf
@@ -551,7 +677,11 @@ openssldh_parse(dst_key_t *key, isc_lex_
20cebf
 	dh = DH_new();
20cebf
 	if (dh == NULL)
20cebf
 		DST_RET(ISC_R_NOMEMORY);
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 	dh->flags &= ~DH_FLAG_CACHE_MONT_P;
20cebf
+#else
20cebf
+	DH_clear_flags(dh, DH_FLAG_CACHE_MONT_P);
20cebf
+#endif
20cebf
 	key->keydata.dh = dh;
20cebf
 
20cebf
 	for (i = 0; i < priv.nelements; i++) {
20cebf
@@ -563,51 +693,63 @@ openssldh_parse(dst_key_t *key, isc_lex_
20cebf
 
20cebf
 		switch (priv.elements[i].tag) {
20cebf
 			case TAG_DH_PRIME:
20cebf
-				dh->p = bn;
20cebf
+				p = bn;
20cebf
 				break;
20cebf
 			case TAG_DH_GENERATOR:
20cebf
-				dh->g = bn;
20cebf
+				g = bn;
20cebf
 				break;
20cebf
 			case TAG_DH_PRIVATE:
20cebf
-				dh->priv_key = bn;
20cebf
+				priv_key = bn;
20cebf
 				break;
20cebf
 			case TAG_DH_PUBLIC:
20cebf
-				dh->pub_key = bn;
20cebf
+				pub_key = bn;
20cebf
 				break;
20cebf
 		}
20cebf
 	}
20cebf
 	dst__privstruct_free(&priv, mctx);
20cebf
 
20cebf
-	key->key_size = BN_num_bits(dh->p);
20cebf
+	key->key_size = BN_num_bits(p);
20cebf
 
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 	if ((key->key_size == 768 ||
20cebf
 	     key->key_size == 1024 ||
20cebf
 	     key->key_size == 1536) &&
20cebf
-	    BN_cmp(dh->g, bn2) == 0)
20cebf
+	    BN_cmp(g, bn2) == 0)
20cebf
 	{
20cebf
-		if (key->key_size == 768 && BN_cmp(dh->p, bn768) == 0) {
20cebf
-			BN_free(dh->p);
20cebf
-			BN_free(dh->g);
20cebf
+		if (key->key_size == 768 && BN_cmp(p, bn768) == 0) {
20cebf
 			dh->p = bn768;
20cebf
 			dh->g = bn2;
20cebf
 		} else if (key->key_size == 1024 &&
20cebf
-			   BN_cmp(dh->p, bn1024) == 0) {
20cebf
-			BN_free(dh->p);
20cebf
-			BN_free(dh->g);
20cebf
+			   BN_cmp(p, bn1024) == 0) {
20cebf
 			dh->p = bn1024;
20cebf
 			dh->g = bn2;
20cebf
 		} else if (key->key_size == 1536 &&
20cebf
-			   BN_cmp(dh->p, bn1536) == 0) {
20cebf
-			BN_free(dh->p);
20cebf
-			BN_free(dh->g);
20cebf
+			   BN_cmp(p, bn1536) == 0) {
20cebf
 			dh->p = bn1536;
20cebf
 			dh->g = bn2;
20cebf
+		} else {
20cebf
+			dh->p = p;
20cebf
+			dh->g = g;
20cebf
 		}
20cebf
+	} else {
20cebf
+		dh->p = p;
20cebf
+		dh->g = g;
20cebf
 	}
20cebf
-
20cebf
+	dh->pub_key = pub_key;
20cebf
+	dh->priv_key = priv_key;
20cebf
+#else
20cebf
+	if (p == NULL || g == NULL || pub_key == NULL)
20cebf
+		DST_RET(ISC_R_NOMEMORY);
20cebf
+	DH_set0_pqg(dh, p, NULL, g);
20cebf
+	DH_set0_key(dh, pub_key, priv_key);
20cebf
+#endif
20cebf
 	return (ISC_R_SUCCESS);
20cebf
 
20cebf
  err:
20cebf
+	BN_free(p);
20cebf
+	BN_free(g);
20cebf
+	BN_free(pub_key);
20cebf
+	BN_free(priv_key);
20cebf
 	openssldh_destroy(key);
20cebf
 	dst__privstruct_free(&priv, mctx);
20cebf
 	memset(&priv, 0, sizeof(priv));
20cebf
--- bind-9.10.4-P3/lib/dns/openssldsa_link.c	2016-09-14 03:23:44.000000000 +0200
20cebf
+++ bind-9.10.4-P3/lib/dns/openssldsa_link.c	2016-11-07 17:57:34.337237978 +0100
20cebf
@@ -64,7 +64,7 @@ openssldsa_createctx(dst_key_t *key, dst
20cebf
 	if (evp_md_ctx == NULL)
20cebf
 		return (ISC_R_NOMEMORY);
20cebf
 
20cebf
-	if (!EVP_DigestInit_ex(evp_md_ctx, EVP_dss1(), NULL)) {
20cebf
+	if (!EVP_DigestInit_ex(evp_md_ctx, EVP_sha1(), NULL)) {
20cebf
 		EVP_MD_CTX_destroy(evp_md_ctx);
20cebf
 			return (ISC_R_FAILURE);
20cebf
 	}
20cebf
@@ -123,7 +123,7 @@ openssldsa_adddata(dst_context_t *dctx,
20cebf
 }
20cebf
 
20cebf
 static int
20cebf
-BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) {
20cebf
+BN_bn2bin_fixed(const BIGNUM *bn, unsigned char *buf, int size) {
20cebf
 	int bytes = size - BN_num_bytes(bn);
20cebf
 	while (bytes-- > 0)
20cebf
 		*buf++ = 0;
20cebf
@@ -137,6 +137,7 @@ openssldsa_sign(dst_context_t *dctx, isc
20cebf
 	DSA *dsa = key->keydata.dsa;
20cebf
 	isc_region_t r;
20cebf
 	DSA_SIG *dsasig;
20cebf
+	const BIGNUM *dr, *ds;
20cebf
 	unsigned int klen;
20cebf
 #if USE_EVP
20cebf
 	EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
20cebf
@@ -218,9 +219,16 @@ openssldsa_sign(dst_context_t *dctx, isc
20cebf
 	*r.base = klen;
20cebf
 	isc_region_consume(&r, 1);
20cebf
 
20cebf
-	BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH);
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	dr = dsasig->r;
20cebf
+	ds = dsasig->s;
20cebf
+#else
20cebf
+	DSA_SIG_get0(dsasig, &dr, &ds);
20cebf
+#endif
20cebf
+
20cebf
+	BN_bn2bin_fixed(dr, r.base, ISC_SHA1_DIGESTLENGTH);
20cebf
 	isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH);
20cebf
-	BN_bn2bin_fixed(dsasig->s, r.base, ISC_SHA1_DIGESTLENGTH);
20cebf
+	BN_bn2bin_fixed(ds, r.base, ISC_SHA1_DIGESTLENGTH);
20cebf
 	isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH);
20cebf
 	DSA_SIG_free(dsasig);
20cebf
 	isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1);
20cebf
@@ -235,6 +243,7 @@ openssldsa_verify(dst_context_t *dctx, c
20cebf
 	int status = 0;
20cebf
 	unsigned char *cp = sig->base;
20cebf
 	DSA_SIG *dsasig;
20cebf
+	BIGNUM *dr = NULL, *ds = NULL;
20cebf
 #if USE_EVP
20cebf
 	EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
20cebf
 #if 0
20cebf
@@ -267,9 +276,21 @@ openssldsa_verify(dst_context_t *dctx, c
20cebf
 	dsasig = DSA_SIG_new();
20cebf
 	if (dsasig == NULL)
20cebf
 		return (ISC_R_NOMEMORY);
20cebf
-	dsasig->r = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL);
20cebf
+	dr = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL);
20cebf
 	cp += ISC_SHA1_DIGESTLENGTH;
20cebf
-	dsasig->s = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL);
20cebf
+	ds = BN_bin2bn(cp, ISC_SHA1_DIGESTLENGTH, NULL);
20cebf
+	if (dr == NULL || ds == NULL) {
20cebf
+		DSA_SIG_free(dsasig);
20cebf
+		BN_free(dr);
20cebf
+		BN_free(ds);
20cebf
+		return (ISC_R_NOMEMORY);
20cebf
+	}
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	dsasig->r = dr;
20cebf
+	dsasig->s = ds;
20cebf
+#else
20cebf
+	DSA_SIG_set0(dsasig, dr, ds);
20cebf
+#endif
20cebf
 
20cebf
 #if 0
20cebf
 	pkey = EVP_PKEY_new();
20cebf
@@ -310,6 +331,8 @@ static isc_boolean_t
20cebf
 openssldsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
20cebf
 	int status;
20cebf
 	DSA *dsa1, *dsa2;
20cebf
+	const BIGNUM *p1, *q1, *g1, *pub_key1, *priv_key1;
20cebf
+	const BIGNUM *p2, *q2, *g2, *pub_key2, *priv_key2;
20cebf
 
20cebf
 	dsa1 = key1->keydata.dsa;
20cebf
 	dsa2 = key2->keydata.dsa;
20cebf
@@ -319,18 +342,36 @@ openssldsa_compare(const dst_key_t *key1
20cebf
 	else if (dsa1 == NULL || dsa2 == NULL)
20cebf
 		return (ISC_FALSE);
20cebf
 
20cebf
-	status = BN_cmp(dsa1->p, dsa2->p) ||
20cebf
-		 BN_cmp(dsa1->q, dsa2->q) ||
20cebf
-		 BN_cmp(dsa1->g, dsa2->g) ||
20cebf
-		 BN_cmp(dsa1->pub_key, dsa2->pub_key);
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	p1 = dsa1->p;
20cebf
+	q1 = dsa1->q;
20cebf
+	g1 = dsa1->g;
20cebf
+	pub_key1 = dsa1->pub_key;
20cebf
+	priv_key1 = dsa1->priv_key;
20cebf
+	p2 = dsa2->p;
20cebf
+	q2 = dsa2->q;
20cebf
+	g2 = dsa2->g;
20cebf
+	pub_key2 = dsa2->pub_key;
20cebf
+	priv_key2 = dsa2->priv_key;
20cebf
+#else
20cebf
+	DSA_get0_pqg(dsa1, &p1, &q1, &g1;;
20cebf
+	DSA_get0_key(dsa1, &pub_key1, &priv_key1);
20cebf
+	DSA_get0_pqg(dsa2, &p2, &q2, &g2;;
20cebf
+	DSA_get0_key(dsa2, &pub_key2, &priv_key2);
20cebf
+#endif
20cebf
+
20cebf
+	status = BN_cmp(p1, p2) ||
20cebf
+		 BN_cmp(q1, q2) ||
20cebf
+		 BN_cmp(g1, g2) ||
20cebf
+		 BN_cmp(pub_key1, pub_key2);
20cebf
 
20cebf
 	if (status != 0)
20cebf
 		return (ISC_FALSE);
20cebf
 
20cebf
-	if (dsa1->priv_key != NULL || dsa2->priv_key != NULL) {
20cebf
-		if (dsa1->priv_key == NULL || dsa2->priv_key == NULL)
20cebf
+	if (priv_key1 != NULL || priv_key2 != NULL) {
20cebf
+		if (priv_key1 == NULL || priv_key2 == NULL)
20cebf
 			return (ISC_FALSE);
20cebf
-		if (BN_cmp(dsa1->priv_key, dsa2->priv_key))
20cebf
+		if (BN_cmp(priv_key2, priv_key2))
20cebf
 			return (ISC_FALSE);
20cebf
 	}
20cebf
 	return (ISC_TRUE);
20cebf
@@ -422,7 +463,11 @@ openssldsa_generate(dst_key_t *key, int
20cebf
 		return (dst__openssl_toresult2("DSA_generate_key",
20cebf
 					       DST_R_OPENSSLFAILURE));
20cebf
 	}
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 	dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
20cebf
+#else
20cebf
+	DSA_clear_flags(dsa, DSA_FLAG_CACHE_MONT_P);
20cebf
+#endif
20cebf
 
20cebf
 	key->keydata.dsa = dsa;
20cebf
 
20cebf
@@ -432,7 +477,17 @@ openssldsa_generate(dst_key_t *key, int
20cebf
 static isc_boolean_t
20cebf
 openssldsa_isprivate(const dst_key_t *key) {
20cebf
 	DSA *dsa = key->keydata.dsa;
20cebf
-	return (ISC_TF(dsa != NULL && dsa->priv_key != NULL));
20cebf
+	const BIGNUM *priv_key;
20cebf
+
20cebf
+	if (dsa == NULL)
20cebf
+		return (ISC_TF(0));
20cebf
+
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	priv_key = dsa->priv_key;
20cebf
+#else
20cebf
+        DSA_get0_key(dsa, NULL, &priv_key);
20cebf
+#endif
20cebf
+	return (ISC_TF(priv_key != NULL));
20cebf
 }
20cebf
 
20cebf
 static void
20cebf
@@ -446,6 +501,7 @@ openssldsa_destroy(dst_key_t *key) {
20cebf
 static isc_result_t
20cebf
 openssldsa_todns(const dst_key_t *key, isc_buffer_t *data) {
20cebf
 	DSA *dsa;
20cebf
+	const BIGNUM *p, *q, *g, *pub_key;
20cebf
 	isc_region_t r;
20cebf
 	int dnslen;
20cebf
 	unsigned int t, p_bytes;
20cebf
@@ -456,7 +512,17 @@ openssldsa_todns(const dst_key_t *key, i
20cebf
 
20cebf
 	isc_buffer_availableregion(data, &r);
20cebf
 
20cebf
-	t = (BN_num_bytes(dsa->p) - 64) / 8;
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	p = dsa->p;
20cebf
+	q = dsa->q;
20cebf
+	g = dsa->g;
20cebf
+	pub_key = dsa->pub_key;
20cebf
+#else
20cebf
+	DSA_get0_pqg(dsa, &p, &q, &g);
20cebf
+	DSA_get0_key(dsa, &pub_key, NULL);
20cebf
+#endif
20cebf
+
20cebf
+	t = (BN_num_bytes(p) - 64) / 8;
20cebf
 	if (t > 8)
20cebf
 		return (DST_R_INVALIDPUBLICKEY);
20cebf
 	p_bytes = 64 + 8 * t;
20cebf
@@ -467,13 +533,13 @@ openssldsa_todns(const dst_key_t *key, i
20cebf
 
20cebf
 	*r.base = t;
20cebf
 	isc_region_consume(&r, 1);
20cebf
-	BN_bn2bin_fixed(dsa->q, r.base, ISC_SHA1_DIGESTLENGTH);
20cebf
+	BN_bn2bin_fixed(q, r.base, ISC_SHA1_DIGESTLENGTH);
20cebf
 	isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH);
20cebf
-	BN_bn2bin_fixed(dsa->p, r.base, key->key_size/8);
20cebf
+	BN_bn2bin_fixed(p, r.base, key->key_size/8);
20cebf
 	isc_region_consume(&r, p_bytes);
20cebf
-	BN_bn2bin_fixed(dsa->g, r.base, key->key_size/8);
20cebf
+	BN_bn2bin_fixed(g, r.base, key->key_size/8);
20cebf
 	isc_region_consume(&r, p_bytes);
20cebf
-	BN_bn2bin_fixed(dsa->pub_key, r.base, key->key_size/8);
20cebf
+	BN_bn2bin_fixed(pub_key, r.base, key->key_size/8);
20cebf
 	isc_region_consume(&r, p_bytes);
20cebf
 
20cebf
 	isc_buffer_add(data, dnslen);
20cebf
@@ -484,6 +550,7 @@ openssldsa_todns(const dst_key_t *key, i
20cebf
 static isc_result_t
20cebf
 openssldsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
20cebf
 	DSA *dsa;
20cebf
+	BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL;
20cebf
 	isc_region_t r;
20cebf
 	unsigned int t, p_bytes;
20cebf
 	isc_mem_t *mctx = key->mctx;
20cebf
@@ -497,7 +564,11 @@ openssldsa_fromdns(dst_key_t *key, isc_b
20cebf
 	dsa = DSA_new();
20cebf
 	if (dsa == NULL)
20cebf
 		return (ISC_R_NOMEMORY);
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 	dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
20cebf
+#else
20cebf
+	DSA_clear_flags(dsa, DSA_FLAG_CACHE_MONT_P);
20cebf
+#endif
20cebf
 
20cebf
 	t = (unsigned int) *r.base;
20cebf
 	isc_region_consume(&r, 1);
20cebf
@@ -512,22 +583,42 @@ openssldsa_fromdns(dst_key_t *key, isc_b
20cebf
 		return (DST_R_INVALIDPUBLICKEY);
20cebf
 	}
20cebf
 
20cebf
-	dsa->q = BN_bin2bn(r.base, ISC_SHA1_DIGESTLENGTH, NULL);
20cebf
+	q = BN_bin2bn(r.base, ISC_SHA1_DIGESTLENGTH, NULL);
20cebf
 	isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH);
20cebf
 
20cebf
-	dsa->p = BN_bin2bn(r.base, p_bytes, NULL);
20cebf
+	p = BN_bin2bn(r.base, p_bytes, NULL);
20cebf
 	isc_region_consume(&r, p_bytes);
20cebf
 
20cebf
-	dsa->g = BN_bin2bn(r.base, p_bytes, NULL);
20cebf
+	g = BN_bin2bn(r.base, p_bytes, NULL);
20cebf
 	isc_region_consume(&r, p_bytes);
20cebf
 
20cebf
-	dsa->pub_key = BN_bin2bn(r.base, p_bytes, NULL);
20cebf
+	pub_key = BN_bin2bn(r.base, p_bytes, NULL);
20cebf
 	isc_region_consume(&r, p_bytes);
20cebf
 
20cebf
 	key->key_size = p_bytes * 8;
20cebf
 
20cebf
 	isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes);
20cebf
 
20cebf
+	if (p == NULL || q == NULL || g == NULL ||
20cebf
+		pub_key == NULL) {
20cebf
+		DSA_free(dsa);
20cebf
+		BN_free(p);
20cebf
+		BN_free(q);
20cebf
+		BN_free(g);
20cebf
+		BN_free(pub_key);
20cebf
+		return dst__openssl_toresult(ISC_R_NOMEMORY);
20cebf
+	}
20cebf
+
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	dsa->p = p;
20cebf
+	dsa->q = q;
20cebf
+	dsa->g = g;
20cebf
+	dsa->pub_key = pub_key;
20cebf
+#else
20cebf
+	DSA_set0_pqg(dsa, p, q, g);
20cebf
+	DSA_set0_key(dsa, pub_key, NULL);
20cebf
+#endif
20cebf
+
20cebf
 	key->keydata.dsa = dsa;
20cebf
 
20cebf
 	return (ISC_R_SUCCESS);
20cebf
@@ -538,6 +629,7 @@ static isc_result_t
20cebf
 openssldsa_tofile(const dst_key_t *key, const char *directory) {
20cebf
 	int cnt = 0;
20cebf
 	DSA *dsa;
20cebf
+	const BIGNUM *p, *q, *g, *pub_key, *priv_key;
20cebf
 	dst_private_t priv;
20cebf
 	unsigned char bufs[5][128];
20cebf
 
20cebf
@@ -551,33 +643,44 @@ openssldsa_tofile(const dst_key_t *key,
20cebf
 
20cebf
 	dsa = key->keydata.dsa;
20cebf
 
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	p = dsa->p;
20cebf
+	q = dsa->q;
20cebf
+	g = dsa->g;
20cebf
+	pub_key = dsa->pub_key;
20cebf
+	priv_key = dsa->priv_key;
20cebf
+#else
20cebf
+	DSA_get0_pqg(dsa, &p, &q, &g);
20cebf
+	DSA_get0_key(dsa, &pub_key, &priv_key);
20cebf
+#endif
20cebf
+
20cebf
 	priv.elements[cnt].tag = TAG_DSA_PRIME;
20cebf
-	priv.elements[cnt].length = BN_num_bytes(dsa->p);
20cebf
-	BN_bn2bin(dsa->p, bufs[cnt]);
20cebf
+	priv.elements[cnt].length = BN_num_bytes(p);
20cebf
+	BN_bn2bin(p, bufs[cnt]);
20cebf
 	priv.elements[cnt].data = bufs[cnt];
20cebf
 	cnt++;
20cebf
 
20cebf
 	priv.elements[cnt].tag = TAG_DSA_SUBPRIME;
20cebf
-	priv.elements[cnt].length = BN_num_bytes(dsa->q);
20cebf
-	BN_bn2bin(dsa->q, bufs[cnt]);
20cebf
+	priv.elements[cnt].length = BN_num_bytes(q);
20cebf
+	BN_bn2bin(q, bufs[cnt]);
20cebf
 	priv.elements[cnt].data = bufs[cnt];
20cebf
 	cnt++;
20cebf
 
20cebf
 	priv.elements[cnt].tag = TAG_DSA_BASE;
20cebf
-	priv.elements[cnt].length = BN_num_bytes(dsa->g);
20cebf
-	BN_bn2bin(dsa->g, bufs[cnt]);
20cebf
+	priv.elements[cnt].length = BN_num_bytes(g);
20cebf
+	BN_bn2bin(g, bufs[cnt]);
20cebf
 	priv.elements[cnt].data = bufs[cnt];
20cebf
 	cnt++;
20cebf
 
20cebf
 	priv.elements[cnt].tag = TAG_DSA_PRIVATE;
20cebf
-	priv.elements[cnt].length = BN_num_bytes(dsa->priv_key);
20cebf
-	BN_bn2bin(dsa->priv_key, bufs[cnt]);
20cebf
+	priv.elements[cnt].length = BN_num_bytes(priv_key);
20cebf
+	BN_bn2bin(priv_key, bufs[cnt]);
20cebf
 	priv.elements[cnt].data = bufs[cnt];
20cebf
 	cnt++;
20cebf
 
20cebf
 	priv.elements[cnt].tag = TAG_DSA_PUBLIC;
20cebf
-	priv.elements[cnt].length = BN_num_bytes(dsa->pub_key);
20cebf
-	BN_bn2bin(dsa->pub_key, bufs[cnt]);
20cebf
+	priv.elements[cnt].length = BN_num_bytes(pub_key);
20cebf
+	BN_bn2bin(pub_key, bufs[cnt]);
20cebf
 	priv.elements[cnt].data = bufs[cnt];
20cebf
 	cnt++;
20cebf
 
20cebf
@@ -591,6 +694,7 @@ openssldsa_parse(dst_key_t *key, isc_lex
20cebf
 	isc_result_t ret;
20cebf
 	int i;
20cebf
 	DSA *dsa = NULL;
20cebf
+	BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL;
20cebf
 	isc_mem_t *mctx = key->mctx;
20cebf
 #define DST_RET(a) {ret = a; goto err;}
20cebf
 
20cebf
@@ -615,7 +719,11 @@ openssldsa_parse(dst_key_t *key, isc_lex
20cebf
 	dsa = DSA_new();
20cebf
 	if (dsa == NULL)
20cebf
 		DST_RET(ISC_R_NOMEMORY);
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 	dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
20cebf
+#else
20cebf
+	DSA_clear_flags(dsa, DSA_FLAG_CACHE_MONT_P);
20cebf
+#endif
20cebf
 	key->keydata.dsa = dsa;
20cebf
 
20cebf
 	for (i = 0; i < priv.nelements; i++) {
20cebf
@@ -627,28 +735,45 @@ openssldsa_parse(dst_key_t *key, isc_lex
20cebf
 
20cebf
 		switch (priv.elements[i].tag) {
20cebf
 			case TAG_DSA_PRIME:
20cebf
-				dsa->p = bn;
20cebf
+				p = bn;
20cebf
 				break;
20cebf
 			case TAG_DSA_SUBPRIME:
20cebf
-				dsa->q = bn;
20cebf
+				q = bn;
20cebf
 				break;
20cebf
 			case TAG_DSA_BASE:
20cebf
-				dsa->g = bn;
20cebf
+				g = bn;
20cebf
 				break;
20cebf
 			case TAG_DSA_PRIVATE:
20cebf
-				dsa->priv_key = bn;
20cebf
+				priv_key = bn;
20cebf
 				break;
20cebf
 			case TAG_DSA_PUBLIC:
20cebf
-				dsa->pub_key = bn;
20cebf
+				pub_key = bn;
20cebf
 				break;
20cebf
 		}
20cebf
 	}
20cebf
 	dst__privstruct_free(&priv, mctx);
20cebf
 	memset(&priv, 0, sizeof(priv));
20cebf
-	key->key_size = BN_num_bits(dsa->p);
20cebf
+	key->key_size = BN_num_bits(p);
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	dsa->p = p;
20cebf
+	dsa->q = q;
20cebf
+	dsa->g = g;
20cebf
+	dsa->pub_key = pub_key;
20cebf
+	dsa->priv_key = priv_key;
20cebf
+#else
20cebf
+	if (p == NULL || q == NULL || g == NULL || pub_key == NULL)
20cebf
+		DST_RET(ISC_R_NOMEMORY);
20cebf
+	DSA_set0_pqg(dsa, p, q, g);
20cebf
+	DSA_set0_key(dsa, pub_key, priv_key);
20cebf
+#endif
20cebf
 	return (ISC_R_SUCCESS);
20cebf
 
20cebf
  err:
20cebf
+	BN_free(p);
20cebf
+	BN_free(q);
20cebf
+	BN_free(g);
20cebf
+	BN_free(pub_key);
20cebf
+	BN_free(priv_key);
20cebf
 	openssldsa_destroy(key);
20cebf
 	dst__privstruct_free(&priv, mctx);
20cebf
 	memset(&priv, 0, sizeof(priv));
20cebf
--- bind-9.10.4-P3/lib/dns/opensslecdsa_link.c	2016-09-14 03:23:44.000000000 +0200
20cebf
+++ bind-9.10.4-P3/lib/dns/opensslecdsa_link.c	2016-11-07 17:57:34.337237978 +0100
20cebf
@@ -110,7 +110,7 @@ opensslecdsa_adddata(dst_context_t *dctx
20cebf
 }
20cebf
 
20cebf
 static int
20cebf
-BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) {
20cebf
+BN_bn2bin_fixed(const BIGNUM *bn, unsigned char *buf, int size) {
20cebf
 	int bytes = size - BN_num_bytes(bn);
20cebf
 
20cebf
 	while (bytes-- > 0)
20cebf
@@ -125,6 +125,7 @@ opensslecdsa_sign(dst_context_t *dctx, i
20cebf
 	dst_key_t *key = dctx->key;
20cebf
 	isc_region_t r;
20cebf
 	ECDSA_SIG *ecdsasig;
20cebf
+	const BIGNUM *er, *es;
20cebf
 	EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
20cebf
 	EVP_PKEY *pkey = key->keydata.pkey;
20cebf
 	EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
20cebf
@@ -156,9 +157,15 @@ opensslecdsa_sign(dst_context_t *dctx, i
20cebf
 		DST_RET(dst__openssl_toresult3(dctx->category,
20cebf
 					       "ECDSA_do_sign",
20cebf
 					       DST_R_SIGNFAILURE));
20cebf
-	BN_bn2bin_fixed(ecdsasig->r, r.base, siglen / 2);
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	er = ecdsasig->r;
20cebf
+	es = ecdsasig->s;
20cebf
+#else
20cebf
+	ECDSA_SIG_get0(ecdsasig, &er, &es);
20cebf
+#endif
20cebf
+	BN_bn2bin_fixed(er, r.base, siglen / 2);
20cebf
 	isc_region_consume(&r, siglen / 2);
20cebf
-	BN_bn2bin_fixed(ecdsasig->s, r.base, siglen / 2);
20cebf
+	BN_bn2bin_fixed(es, r.base, siglen / 2);
20cebf
 	isc_region_consume(&r, siglen / 2);
20cebf
 	ECDSA_SIG_free(ecdsasig);
20cebf
 	isc_buffer_add(sig, siglen);
20cebf
@@ -177,6 +184,7 @@ opensslecdsa_verify(dst_context_t *dctx,
20cebf
 	int status;
20cebf
 	unsigned char *cp = sig->base;
20cebf
 	ECDSA_SIG *ecdsasig = NULL;
20cebf
+	BIGNUM *er = NULL, *es = NULL;
20cebf
 	EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
20cebf
 	EVP_PKEY *pkey = key->keydata.pkey;
20cebf
 	EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
20cebf
@@ -205,14 +213,27 @@ opensslecdsa_verify(dst_context_t *dctx,
20cebf
 	ecdsasig = ECDSA_SIG_new();
20cebf
 	if (ecdsasig == NULL)
20cebf
 		DST_RET (ISC_R_NOMEMORY);
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 	if (ecdsasig->r != NULL)
20cebf
 		BN_free(ecdsasig->r);
20cebf
-	ecdsasig->r = BN_bin2bn(cp, siglen / 2, NULL);
20cebf
-	cp += siglen / 2;
20cebf
 	if (ecdsasig->s != NULL)
20cebf
 		BN_free(ecdsasig->s);
20cebf
-	ecdsasig->s = BN_bin2bn(cp, siglen / 2, NULL);
20cebf
+#endif
20cebf
+	er = BN_bin2bn(cp, siglen / 2, NULL);
20cebf
+	cp += siglen / 2;
20cebf
+	es = BN_bin2bn(cp, siglen / 2, NULL);
20cebf
 	/* cp += siglen / 2; */
20cebf
+	if (er == NULL || es == NULL) {
20cebf
+		BN_free(er);
20cebf
+		BN_free(es);
20cebf
+		DST_RET (dst__openssl_toresult(ISC_R_NOMEMORY));
20cebf
+	}
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	ecdsasig->r = er;
20cebf
+	ecdsasig->s = es;
20cebf
+#else
20cebf
+	ECDSA_SIG_set0(ecdsasig, er, es);
20cebf
+#endif
20cebf
 
20cebf
 	status = ECDSA_do_verify(digest, dgstlen, ecdsasig, eckey);
20cebf
 	switch (status) {
20cebf
--- bind-9.10.4-P3/lib/dns/openssl_link.c	2016-09-14 03:23:44.000000000 +0200
20cebf
+++ bind-9.10.4-P3/lib/dns/openssl_link.c	2016-11-07 19:04:28.830074269 +0100
20cebf
@@ -128,8 +128,15 @@ id_callback(void) {
20cebf
 }
20cebf
 #endif
20cebf
 
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 static void *
20cebf
 mem_alloc(size_t size) {
20cebf
+#else
20cebf
+static void *
20cebf
+mem_alloc(size_t size, const char *file, int line) {
20cebf
+	UNUSED(file);
20cebf
+	UNUSED(line);
20cebf
+#endif
20cebf
 #ifdef OPENSSL_LEAKS
20cebf
 	void *ptr;
20cebf
 
20cebf
@@ -142,15 +149,29 @@ mem_alloc(size_t size) {
20cebf
 #endif
20cebf
 }
20cebf
 
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 static void
20cebf
 mem_free(void *ptr) {
20cebf
+#else
20cebf
+static void
20cebf
+mem_free(void *ptr, const char *file, int line) {
20cebf
+	UNUSED(file);
20cebf
+	UNUSED(line);
20cebf
+#endif
20cebf
 	INSIST(dst__memory_pool != NULL);
20cebf
 	if (ptr != NULL)
20cebf
 		isc_mem_free(dst__memory_pool, ptr);
20cebf
 }
20cebf
 
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 static void *
20cebf
 mem_realloc(void *ptr, size_t size) {
20cebf
+#else
20cebf
+static void *
20cebf
+mem_realloc(void *ptr, size_t size, const char *file, int line) {
20cebf
+	UNUSED(file);
20cebf
+	UNUSED(line);
20cebf
+#endif
20cebf
 #ifdef OPENSSL_LEAKS
20cebf
 	void *rptr;
20cebf
 
20cebf
@@ -163,6 +184,16 @@ mem_realloc(void *ptr, size_t size) {
20cebf
 #endif
20cebf
 }
20cebf
 
20cebf
+static int
20cebf
+rndeng_destroy(ENGINE *e) {
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	mem_free(rm);
20cebf
+#else
20cebf
+	mem_free(rm, NULL, 0);
20cebf
+#endif
20cebf
+	rm = NULL;
20cebf
+}
20cebf
+
20cebf
 isc_result_t
20cebf
 dst__openssl_init(const char *engine) {
20cebf
 	isc_result_t result;
20cebf
@@ -179,6 +210,7 @@ dst__openssl_init(const char *engine) {
20cebf
 	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
20cebf
 #endif
20cebf
 	CRYPTO_set_mem_functions(mem_alloc, mem_realloc, mem_free);
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
20cebf
 	nlocks = CRYPTO_num_locks();
20cebf
 	locks = mem_alloc(sizeof(isc_mutex_t) * nlocks);
20cebf
 	if (locks == NULL)
20cebf
@@ -187,13 +219,16 @@ dst__openssl_init(const char *engine) {
20cebf
 	if (result != ISC_R_SUCCESS)
20cebf
 		goto cleanup_mutexalloc;
20cebf
 	CRYPTO_set_locking_callback(lock_callback);
20cebf
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
20cebf
 	CRYPTO_set_id_callback(id_callback);
20cebf
 #endif
20cebf
 
20cebf
 	ERR_load_crypto_strings();
20cebf
 
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 	rm = mem_alloc(sizeof(RAND_METHOD));
20cebf
+#else
20cebf
+	rm = mem_alloc(sizeof(RAND_METHOD), NULL, 0);
20cebf
+#endif
20cebf
 	if (rm == NULL) {
20cebf
 		result = ISC_R_NOMEMORY;
20cebf
 		goto cleanup_mutexinit;
20cebf
@@ -245,6 +280,7 @@ dst__openssl_init(const char *engine) {
20cebf
 			goto cleanup_rm;
20cebf
 		}
20cebf
 		ENGINE_set_RAND(re, rm);
20cebf
+		ENGINE_set_destroy_function(re, rndeng_destroy);
20cebf
 		ENGINE_set_default_RAND(re);
20cebf
 		ENGINE_free(re);
20cebf
 	} else
20cebf
@@ -259,15 +295,21 @@ dst__openssl_init(const char *engine) {
20cebf
 	if (e != NULL)
20cebf
 		ENGINE_free(e);
20cebf
 	e = NULL;
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 	mem_free(rm);
20cebf
+#else
20cebf
+	mem_free(rm, NULL, 0);
20cebf
+#endif
20cebf
 	rm = NULL;
20cebf
 #endif
20cebf
  cleanup_mutexinit:
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
20cebf
 	CRYPTO_set_locking_callback(NULL);
20cebf
 	DESTROYMUTEXBLOCK(locks, nlocks);
20cebf
  cleanup_mutexalloc:
20cebf
 	mem_free(locks);
20cebf
 	locks = NULL;
20cebf
+#endif
20cebf
 	return (result);
20cebf
 }
20cebf
 
20cebf
@@ -276,13 +318,17 @@ dst__openssl_destroy(void) {
20cebf
 	/*
20cebf
 	 * Sequence taken from apps_shutdown() in <apps/apps.h>.
20cebf
 	 */
20cebf
-	if (rm != NULL) {
20cebf
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
20cebf
+#if defined(USE_ENGINE)
20cebf
+	if (e != NULL)
20cebf
+		ENGINE_free(e);
20cebf
+	e = NULL;
20cebf
+#endif
20cebf
+	OPENSSL_cleanup();
20cebf
+#else
20cebf
 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
20cebf
-		RAND_cleanup();
20cebf
+	RAND_cleanup();
20cebf
 #endif
20cebf
-		mem_free(rm);
20cebf
-		rm = NULL;
20cebf
-	}
20cebf
 #if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
20cebf
 	CONF_modules_free();
20cebf
 #endif
20cebf
@@ -315,8 +361,13 @@ dst__openssl_destroy(void) {
20cebf
 		mem_free(locks);
20cebf
 		locks = NULL;
20cebf
 	}
20cebf
+#endif
20cebf
 }
20cebf
 
20cebf
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
20cebf
+#define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED EC_R_RANDOM_NUMBER_GENERATION_FAILED
20cebf
+#endif
20cebf
+
20cebf
 static isc_result_t
20cebf
 toresult(isc_result_t fallback) {
20cebf
 	isc_result_t result = fallback;
20cebf
--- bind-9.10.4-P3/lib/dns/opensslrsa_link.c	2016-09-14 03:23:44.000000000 +0200
20cebf
+++ bind-9.10.4-P3/lib/dns/opensslrsa_link.c	2016-11-07 17:57:34.338238002 +0100
20cebf
@@ -107,6 +107,7 @@ 
20cebf
 	(rsa)->flags &= ~RSA_FLAG_BLINDING; \
20cebf
 	} while (0)
20cebf
 #elif defined(RSA_FLAG_NO_BLINDING)
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 #define SET_FLAGS(rsa) \
20cebf
 	do { \
20cebf
 		(rsa)->flags &= ~RSA_FLAG_BLINDING; \
20cebf
@@ -115,6 +116,13 @@ 
20cebf
 #else
20cebf
 #define SET_FLAGS(rsa) \
20cebf
 	do { \
20cebf
+		RSA_clear_flags((rsa), RSA_FLAG_BLINDING); \
20cebf
+		RSA_set_flags((rsa), RSA_FLAG_NO_BLINDING); \
20cebf
+	} while (0)
20cebf
+#endif
20cebf
+#else
20cebf
+#define SET_FLAGS(rsa) \
20cebf
+	do { \
20cebf
 		(rsa)->flags &= ~RSA_FLAG_BLINDING; \
20cebf
 	} while (0)
20cebf
 #endif
20cebf
@@ -520,6 +528,7 @@ opensslrsa_verify2(dst_context_t *dctx,
20cebf
 	EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
20cebf
 	EVP_PKEY *pkey = key->keydata.pkey;
20cebf
 	RSA *rsa;
20cebf
+	const BIGNUM *e;
20cebf
 	int bits;
20cebf
 #else
20cebf
 	/* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */
20cebf
@@ -543,7 +552,12 @@ opensslrsa_verify2(dst_context_t *dctx,
20cebf
 	rsa = EVP_PKEY_get1_RSA(pkey);
20cebf
 	if (rsa == NULL)
20cebf
 		return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
20cebf
-	bits = BN_num_bits(rsa->e);
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	e = rsa->e;
20cebf
+#else
20cebf
+	RSA_get0_key(rsa, NULL, &e, NULL);
20cebf
+#endif
20cebf
+	bits = BN_num_bits(e);
20cebf
 	RSA_free(rsa);
20cebf
 	if (bits > maxbits && maxbits != 0)
20cebf
 		return (DST_R_VERIFYFAILURE);
20cebf
@@ -685,6 +699,8 @@ static isc_boolean_t
20cebf
 opensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
20cebf
 	int status;
20cebf
 	RSA *rsa1 = NULL, *rsa2 = NULL;
20cebf
+	const BIGNUM *n1, *e1, *d1, *p1, *q1;
20cebf
+	const BIGNUM *n2, *e2, *d2, *p2, *q2;
20cebf
 #if USE_EVP
20cebf
 	EVP_PKEY *pkey1, *pkey2;
20cebf
 #endif
20cebf
@@ -714,13 +730,32 @@ opensslrsa_compare(const dst_key_t *key1
20cebf
 	else if (rsa1 == NULL || rsa2 == NULL)
20cebf
 		return (ISC_FALSE);
20cebf
 
20cebf
-	status = BN_cmp(rsa1->n, rsa2->n) ||
20cebf
-		 BN_cmp(rsa1->e, rsa2->e);
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	n1 = rsa1->n;
20cebf
+	e1 = rsa1->e;
20cebf
+	d1 = rsa1->d;
20cebf
+	p1 = rsa1->p;
20cebf
+	q1 = rsa1->q;
20cebf
+	n2 = rsa2->n;
20cebf
+	e2 = rsa2->e;
20cebf
+	d2 = rsa2->d;
20cebf
+	p2 = rsa2->p;
20cebf
+	q2 = rsa2->q;
20cebf
+#else
20cebf
+	RSA_get0_key(rsa1, &n1, &e1, &d1;;
20cebf
+	RSA_get0_factors(rsa1, &p1, &q1;;
20cebf
+	RSA_get0_key(rsa2, &n2, &e2, &d2;;
20cebf
+	RSA_get0_factors(rsa2, &p2, &q2;;
20cebf
+#endif
20cebf
+
20cebf
+	status = BN_cmp(n1, n2) ||
20cebf
+		 BN_cmp(e1, e2);
20cebf
 
20cebf
 	if (status != 0)
20cebf
 		return (ISC_FALSE);
20cebf
 
20cebf
 #if USE_EVP
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 	if ((rsa1->flags & RSA_FLAG_EXT_PKEY) != 0 ||
20cebf
 	    (rsa2->flags & RSA_FLAG_EXT_PKEY) != 0) {
20cebf
 		if ((rsa1->flags & RSA_FLAG_EXT_PKEY) == 0 ||
20cebf
@@ -731,14 +766,27 @@ opensslrsa_compare(const dst_key_t *key1
20cebf
 		 */
20cebf
 		return (ISC_TRUE);
20cebf
 	}
20cebf
+#else
20cebf
+	if (RSA_test_flags(rsa1, RSA_FLAG_EXT_PKEY) != 0 ||
20cebf
+	    RSA_test_flags(rsa2, RSA_FLAG_EXT_PKEY) != 0) {
20cebf
+		if (RSA_test_flags(rsa1, RSA_FLAG_EXT_PKEY) == 0 ||
20cebf
+		    RSA_test_flags(rsa2, RSA_FLAG_EXT_PKEY) == 0)
20cebf
+			return (ISC_FALSE);
20cebf
+		/*
20cebf
+		 * Can't compare private parameters, BTW does it make sense?
20cebf
+		 */
20cebf
+		return (ISC_TRUE);
20cebf
+	}
20cebf
+
20cebf
+#endif
20cebf
 #endif
20cebf
 
20cebf
-	if (rsa1->d != NULL || rsa2->d != NULL) {
20cebf
-		if (rsa1->d == NULL || rsa2->d == NULL)
20cebf
+	if (d1 != NULL || d2 != NULL) {
20cebf
+		if (d1 == NULL || d2 == NULL)
20cebf
 			return (ISC_FALSE);
20cebf
-		status = BN_cmp(rsa1->d, rsa2->d) ||
20cebf
-			 BN_cmp(rsa1->p, rsa2->p) ||
20cebf
-			 BN_cmp(rsa1->q, rsa2->q);
20cebf
+		status = BN_cmp(d1, d2) ||
20cebf
+			 BN_cmp(p1, p2) ||
20cebf
+			 BN_cmp(q1, q2);
20cebf
 
20cebf
 		if (status != 0)
20cebf
 			return (ISC_FALSE);
20cebf
@@ -882,16 +930,31 @@ err:
20cebf
 static isc_boolean_t
20cebf
 opensslrsa_isprivate(const dst_key_t *key) {
20cebf
 #if USE_EVP
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
 	RSA *rsa = EVP_PKEY_get1_RSA(key->keydata.pkey);
20cebf
 	INSIST(rsa != NULL);
20cebf
 	RSA_free(rsa);
20cebf
 	/* key->keydata.pkey still has a reference so rsa is still valid. */
20cebf
 #else
20cebf
+	const RSA *rsa = EVP_PKEY_get0_RSA(key->keydata.pkey);
20cebf
+#endif
20cebf
+#else
20cebf
 	RSA *rsa = key->keydata.rsa;
20cebf
 #endif
20cebf
-	if (rsa != NULL && (rsa->flags & RSA_FLAG_EXT_PKEY) != 0)
20cebf
+	const BIGNUM *d;
20cebf
+
20cebf
+	if (rsa == NULL)
20cebf
+		return (ISC_FALSE);
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	if ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0)
20cebf
 		return (ISC_TRUE);
20cebf
 	return (ISC_TF(rsa != NULL && rsa->d != NULL));
20cebf
+#else
20cebf
+	if (RSA_test_flags(rsa, RSA_FLAG_EXT_PKEY) != 0)
20cebf
+		return (ISC_TRUE);
20cebf
+	RSA_get0_key(rsa, NULL, NULL, &d);
20cebf
+	return (ISC_TF(d != NULL));
20cebf
+#endif
20cebf
 }
20cebf
 
20cebf
 static void
20cebf
@@ -915,6 +978,7 @@ opensslrsa_todns(const dst_key_t *key, i
20cebf
 	unsigned int mod_bytes;
20cebf
 	isc_result_t ret;
20cebf
 	RSA *rsa;
20cebf
+	const BIGNUM *n, *e;
20cebf
 #if USE_EVP
20cebf
 	EVP_PKEY *pkey;
20cebf
 #endif
20cebf
@@ -936,8 +1000,15 @@ opensslrsa_todns(const dst_key_t *key, i
20cebf
 
20cebf
 	isc_buffer_availableregion(data, &r);
20cebf
 
20cebf
-	e_bytes = BN_num_bytes(rsa->e);
20cebf
-	mod_bytes = BN_num_bytes(rsa->n);
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	n = rsa->n;
20cebf
+	e = rsa->e;
20cebf
+#else
20cebf
+	RSA_get0_key(rsa, &n, &e, NULL);
20cebf
+#endif
20cebf
+
20cebf
+	e_bytes = BN_num_bytes(e);
20cebf
+	mod_bytes = BN_num_bytes(n);
20cebf
 
20cebf
 	if (e_bytes < 256) {	/*%< key exponent is <= 2040 bits */
20cebf
 		if (r.length < 1)
20cebf
@@ -955,9 +1026,9 @@ opensslrsa_todns(const dst_key_t *key, i
20cebf
 	if (r.length < e_bytes + mod_bytes)
20cebf
 		DST_RET(ISC_R_NOSPACE);
20cebf
 
20cebf
-	BN_bn2bin(rsa->e, r.base);
20cebf
+	BN_bn2bin(e, r.base);
20cebf
 	isc_region_consume(&r, e_bytes);
20cebf
-	BN_bn2bin(rsa->n, r.base);
20cebf
+	BN_bn2bin(n, r.base);
20cebf
 
20cebf
 	isc_buffer_add(data, e_bytes + mod_bytes);
20cebf
 
20cebf
@@ -973,6 +1044,7 @@ opensslrsa_todns(const dst_key_t *key, i
20cebf
 static isc_result_t
20cebf
 opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
20cebf
 	RSA *rsa;
20cebf
+	BIGNUM *n = NULL, *e = NULL;
20cebf
 	isc_region_t r;
20cebf
 	unsigned int e_bytes;
20cebf
 	unsigned int length;
20cebf
@@ -1012,15 +1084,29 @@ opensslrsa_fromdns(dst_key_t *key, isc_b
20cebf
 		RSA_free(rsa);
20cebf
 		return (DST_R_INVALIDPUBLICKEY);
20cebf
 	}
20cebf
-	rsa->e = BN_bin2bn(r.base, e_bytes, NULL);
20cebf
+	e = BN_bin2bn(r.base, e_bytes, NULL);
20cebf
 	isc_region_consume(&r, e_bytes);
20cebf
 
20cebf
-	rsa->n = BN_bin2bn(r.base, r.length, NULL);
20cebf
+	n = BN_bin2bn(r.base, r.length, NULL);
20cebf
 
20cebf
-	key->key_size = BN_num_bits(rsa->n);
20cebf
+	key->key_size = BN_num_bits(n);
20cebf
 
20cebf
 	isc_buffer_forward(data, length);
20cebf
 
20cebf
+	if (n == NULL || e == NULL) {
20cebf
+		RSA_free(rsa);
20cebf
+		BN_free(n);
20cebf
+		BN_free(e);
20cebf
+		return dst__openssl_toresult(ISC_R_NOMEMORY);
20cebf
+	}
20cebf
+
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	rsa->n = n;
20cebf
+	rsa->e = e;
20cebf
+#else
20cebf
+	RSA_set0_key(rsa, n, e, NULL);
20cebf
+#endif
20cebf
+
20cebf
 #if USE_EVP
20cebf
 	pkey = EVP_PKEY_new();
20cebf
 	if (pkey == NULL) {
20cebf
@@ -1045,6 +1131,7 @@ static isc_result_t
20cebf
 opensslrsa_tofile(const dst_key_t *key, const char *directory) {
20cebf
 	int i;
20cebf
 	RSA *rsa;
20cebf
+	const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
20cebf
 	dst_private_t priv;
20cebf
 	unsigned char *bufs[8];
20cebf
 	isc_result_t result;
20cebf
@@ -1068,8 +1155,23 @@ opensslrsa_tofile(const dst_key_t *key,
20cebf
 		goto fail;
20cebf
 	}
20cebf
 
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	n = rsa->n;
20cebf
+	e = rsa->e;
20cebf
+	d = rsa->d;
20cebf
+	p = rsa->p;
20cebf
+	q = rsa->q;
20cebf
+	dmp1 = rsa->dmp1;
20cebf
+	dmq1 = rsa->dmq1;
20cebf
+	iqmp = rsa->iqmp;
20cebf
+#else
20cebf
+	RSA_get0_key(rsa, &n, &e, &d);
20cebf
+	RSA_get0_factors(rsa, &p, &q);
20cebf
+	RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
20cebf
+#endif
20cebf
+
20cebf
 	for (i = 0; i < 8; i++) {
20cebf
-		bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(rsa->n));
20cebf
+		bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(n));
20cebf
 		if (bufs[i] == NULL) {
20cebf
 			result = ISC_R_NOMEMORY;
20cebf
 			goto fail;
20cebf
@@ -1079,61 +1181,61 @@ opensslrsa_tofile(const dst_key_t *key,
20cebf
 	i = 0;
20cebf
 
20cebf
 	priv.elements[i].tag = TAG_RSA_MODULUS;
20cebf
-	priv.elements[i].length = BN_num_bytes(rsa->n);
20cebf
-	BN_bn2bin(rsa->n, bufs[i]);
20cebf
+	priv.elements[i].length = BN_num_bytes(n);
20cebf
+	BN_bn2bin(n, bufs[i]);
20cebf
 	priv.elements[i].data = bufs[i];
20cebf
 	i++;
20cebf
 
20cebf
 	priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT;
20cebf
-	priv.elements[i].length = BN_num_bytes(rsa->e);
20cebf
-	BN_bn2bin(rsa->e, bufs[i]);
20cebf
+	priv.elements[i].length = BN_num_bytes(e);
20cebf
+	BN_bn2bin(e, bufs[i]);
20cebf
 	priv.elements[i].data = bufs[i];
20cebf
 	i++;
20cebf
 
20cebf
-	if (rsa->d != NULL) {
20cebf
+	if (d != NULL) {
20cebf
 		priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT;
20cebf
-		priv.elements[i].length = BN_num_bytes(rsa->d);
20cebf
-		BN_bn2bin(rsa->d, bufs[i]);
20cebf
+		priv.elements[i].length = BN_num_bytes(d);
20cebf
+		BN_bn2bin(d, bufs[i]);
20cebf
 		priv.elements[i].data = bufs[i];
20cebf
 		i++;
20cebf
 	}
20cebf
 
20cebf
-	if (rsa->p != NULL) {
20cebf
+	if (p != NULL) {
20cebf
 		priv.elements[i].tag = TAG_RSA_PRIME1;
20cebf
-		priv.elements[i].length = BN_num_bytes(rsa->p);
20cebf
-		BN_bn2bin(rsa->p, bufs[i]);
20cebf
+		priv.elements[i].length = BN_num_bytes(p);
20cebf
+		BN_bn2bin(p, bufs[i]);
20cebf
 		priv.elements[i].data = bufs[i];
20cebf
 		i++;
20cebf
 	}
20cebf
 
20cebf
-	if (rsa->q != NULL) {
20cebf
+	if (q != NULL) {
20cebf
 		priv.elements[i].tag = TAG_RSA_PRIME2;
20cebf
-		priv.elements[i].length = BN_num_bytes(rsa->q);
20cebf
-		BN_bn2bin(rsa->q, bufs[i]);
20cebf
+		priv.elements[i].length = BN_num_bytes(q);
20cebf
+		BN_bn2bin(q, bufs[i]);
20cebf
 		priv.elements[i].data = bufs[i];
20cebf
 		i++;
20cebf
 	}
20cebf
 
20cebf
-	if (rsa->dmp1 != NULL) {
20cebf
+	if (dmp1 != NULL) {
20cebf
 		priv.elements[i].tag = TAG_RSA_EXPONENT1;
20cebf
-		priv.elements[i].length = BN_num_bytes(rsa->dmp1);
20cebf
-		BN_bn2bin(rsa->dmp1, bufs[i]);
20cebf
+		priv.elements[i].length = BN_num_bytes(dmp1);
20cebf
+		BN_bn2bin(dmp1, bufs[i]);
20cebf
 		priv.elements[i].data = bufs[i];
20cebf
 		i++;
20cebf
 	}
20cebf
 
20cebf
-	if (rsa->dmq1 != NULL) {
20cebf
+	if (dmq1 != NULL) {
20cebf
 		priv.elements[i].tag = TAG_RSA_EXPONENT2;
20cebf
-		priv.elements[i].length = BN_num_bytes(rsa->dmq1);
20cebf
-		BN_bn2bin(rsa->dmq1, bufs[i]);
20cebf
+		priv.elements[i].length = BN_num_bytes(dmq1);
20cebf
+		BN_bn2bin(dmq1, bufs[i]);
20cebf
 		priv.elements[i].data = bufs[i];
20cebf
 		i++;
20cebf
 	}
20cebf
 
20cebf
-	if (rsa->iqmp != NULL) {
20cebf
+	if (iqmp != NULL) {
20cebf
 		priv.elements[i].tag = TAG_RSA_COEFFICIENT;
20cebf
-		priv.elements[i].length = BN_num_bytes(rsa->iqmp);
20cebf
-		BN_bn2bin(rsa->iqmp, bufs[i]);
20cebf
+		priv.elements[i].length = BN_num_bytes(iqmp);
20cebf
+		BN_bn2bin(iqmp, bufs[i]);
20cebf
 		priv.elements[i].data = bufs[i];
20cebf
 		i++;
20cebf
 	}
20cebf
@@ -1156,14 +1258,14 @@ opensslrsa_tofile(const dst_key_t *key,
20cebf
 	priv.nelements = i;
20cebf
 	result = dst__privstruct_writefile(key, &priv, directory);
20cebf
  fail:
20cebf
-#if USE_EVP
20cebf
-	RSA_free(rsa);
20cebf
-#endif
20cebf
 	for (i = 0; i < 8; i++) {
20cebf
 		if (bufs[i] == NULL)
20cebf
 			break;
20cebf
-		isc_mem_put(key->mctx, bufs[i], BN_num_bytes(rsa->n));
20cebf
+		isc_mem_put(key->mctx, bufs[i], BN_num_bytes(n));
20cebf
 	}
20cebf
+#if USE_EVP
20cebf
+	RSA_free(rsa);
20cebf
+#endif
20cebf
 	return (result);
20cebf
 }
20cebf
 
20cebf
@@ -1172,23 +1274,57 @@ rsa_check(RSA *rsa, RSA *pub)
20cebf
 {
20cebf
 	/* Public parameters should be the same but if they are not set
20cebf
 	 * copy them from the public key. */
20cebf
+	const BIGNUM *n, *e, *pn, *pe;
20cebf
+	int copy = 0;
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	n = rsa->n;
20cebf
+	e = rsa->e;
20cebf
+#else
20cebf
+	RSA_get0_key(rsa, &n, &e, NULL);
20cebf
+#endif
20cebf
 	if (pub != NULL) {
20cebf
-		if (rsa->n != NULL) {
20cebf
-			if (BN_cmp(rsa->n, pub->n) != 0)
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+		pn = pub->n;
20cebf
+		pe = pub->e;
20cebf
+#else
20cebf
+		RSA_get0_key(pub, &pn, &pe, NULL);
20cebf
+#endif
20cebf
+		if (n != NULL) {
20cebf
+			if (BN_cmp(n, pn) != 0)
20cebf
 				return (DST_R_INVALIDPRIVATEKEY);
20cebf
 		} else {
20cebf
-			rsa->n = pub->n;
20cebf
-			pub->n = NULL;
20cebf
+			copy = 1;
20cebf
 		}
20cebf
-		if (rsa->e != NULL) {
20cebf
-			if (BN_cmp(rsa->e, pub->e) != 0)
20cebf
+		if (e != NULL) {
20cebf
+			if (BN_cmp(e, pe) != 0)
20cebf
 				return (DST_R_INVALIDPRIVATEKEY);
20cebf
 		} else {
20cebf
-			rsa->e = pub->e;
20cebf
-			pub->e = NULL;
20cebf
+			copy = 1;
20cebf
+		}
20cebf
+
20cebf
+		if (copy) {
20cebf
+			BIGNUM *dn, *de;
20cebf
+			dn = BN_dup(pn);
20cebf
+			de = BN_dup(pe);
20cebf
+			if (dn == NULL || de == NULL) {
20cebf
+				BN_free(dn);
20cebf
+				BN_free(de);
20cebf
+				return (ISC_R_NOMEMORY);
20cebf
+			}
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+			if (rsa->n != NULL)
20cebf
+				BN_free(rsa->n);
20cebf
+			if (rsa->e != NULL)
20cebf
+				BN_free(rsa->e);
20cebf
+			rsa->n = dn;
20cebf
+			rsa->e = de;
20cebf
+#else
20cebf
+			RSA_set0_key(rsa, dn, de, NULL);
20cebf
+#endif
20cebf
+			return (ISC_R_SUCCESS);
20cebf
 		}
20cebf
 	}
20cebf
-	if (rsa->n == NULL || rsa->e == NULL)
20cebf
+	if (n == NULL || e == NULL)
20cebf
 		return (DST_R_INVALIDPRIVATEKEY);
20cebf
 	return (ISC_R_SUCCESS);
20cebf
 }
20cebf
@@ -1199,8 +1335,10 @@ opensslrsa_parse(dst_key_t *key, isc_lex
20cebf
 	isc_result_t ret;
20cebf
 	int i;
20cebf
 	RSA *rsa = NULL, *pubrsa = NULL;
20cebf
+	BIGNUM *n = NULL, *e = NULL, *d = NULL, *p = NULL, *q = NULL;
20cebf
+	BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
20cebf
 #ifdef USE_ENGINE
20cebf
-	ENGINE *e = NULL;
20cebf
+	ENGINE *eng = NULL;
20cebf
 #endif
20cebf
 	isc_mem_t *mctx = key->mctx;
20cebf
 	const char *engine = NULL, *label = NULL;
20cebf
@@ -1255,12 +1393,13 @@ opensslrsa_parse(dst_key_t *key, isc_lex
20cebf
 	 */
20cebf
 	if (label != NULL) {
20cebf
 #ifdef USE_ENGINE
20cebf
+		const BIGNUM *e;
20cebf
 		if (engine == NULL)
20cebf
 			DST_RET(DST_R_NOENGINE);
20cebf
-		e = dst__openssl_getengine(engine);
20cebf
-		if (e == NULL)
20cebf
+		eng = dst__openssl_getengine(engine);
20cebf
+		if (eng == NULL)
20cebf
 			DST_RET(DST_R_NOENGINE);
20cebf
-		pkey = ENGINE_load_private_key(e, label, NULL, NULL);
20cebf
+		pkey = ENGINE_load_private_key(eng, label, NULL, NULL);
20cebf
 		if (pkey == NULL)
20cebf
 			DST_RET(dst__openssl_toresult2(
20cebf
 					"ENGINE_load_private_key",
20cebf
@@ -1276,7 +1415,12 @@ opensslrsa_parse(dst_key_t *key, isc_lex
20cebf
 			DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
20cebf
 		if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
20cebf
 			DST_RET(DST_R_INVALIDPRIVATEKEY);
20cebf
-		if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS)
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+		e = rsa->e;
20cebf
+#else
20cebf
+		RSA_get0_key(rsa, NULL, &e, NULL);
20cebf
+#endif
20cebf
+		if (BN_num_bits(e) > RSA_MAX_PUBEXP_BITS)
20cebf
 			DST_RET(ISC_R_RANGE);
20cebf
 		if (pubrsa != NULL)
20cebf
 			RSA_free(pubrsa);
20cebf
@@ -1305,9 +1449,6 @@ opensslrsa_parse(dst_key_t *key, isc_lex
20cebf
 	pkey = EVP_PKEY_new();
20cebf
 	if (pkey == NULL)
20cebf
 		DST_RET(ISC_R_NOMEMORY);
20cebf
-	if (!EVP_PKEY_set1_RSA(pkey, rsa))
20cebf
-		DST_RET(ISC_R_FAILURE);
20cebf
-	key->keydata.pkey = pkey;
20cebf
 #else
20cebf
 	key->keydata.rsa = rsa;
20cebf
 #endif
20cebf
@@ -1328,42 +1469,86 @@ opensslrsa_parse(dst_key_t *key, isc_lex
20cebf
 
20cebf
 		switch (priv.elements[i].tag) {
20cebf
 			case TAG_RSA_MODULUS:
20cebf
-				rsa->n = bn;
20cebf
+				n = bn;
20cebf
 				break;
20cebf
 			case TAG_RSA_PUBLICEXPONENT:
20cebf
-				rsa->e = bn;
20cebf
+				e = bn;
20cebf
 				break;
20cebf
 			case TAG_RSA_PRIVATEEXPONENT:
20cebf
-				rsa->d = bn;
20cebf
+				d = bn;
20cebf
 				break;
20cebf
 			case TAG_RSA_PRIME1:
20cebf
-				rsa->p = bn;
20cebf
+				p = bn;
20cebf
 				break;
20cebf
 			case TAG_RSA_PRIME2:
20cebf
-				rsa->q = bn;
20cebf
+				q = bn;
20cebf
 				break;
20cebf
 			case TAG_RSA_EXPONENT1:
20cebf
-				rsa->dmp1 = bn;
20cebf
+				dmp1 = bn;
20cebf
 				break;
20cebf
 			case TAG_RSA_EXPONENT2:
20cebf
-				rsa->dmq1 = bn;
20cebf
+				dmq1 = bn;
20cebf
 				break;
20cebf
 			case TAG_RSA_COEFFICIENT:
20cebf
-				rsa->iqmp = bn;
20cebf
+				iqmp = bn;
20cebf
 				break;
20cebf
 		}
20cebf
 	}
20cebf
 	dst__privstruct_free(&priv, mctx);
20cebf
 	memset(&priv, 0, sizeof(priv));
20cebf
 
20cebf
-	if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	rsa->n = n;
20cebf
+	rsa->e = e;
20cebf
+	rsa->d = d;
20cebf
+	rsa->p = p;
20cebf
+	rsa->q = q;
20cebf
+	rsa->dmp1 = dmp1;
20cebf
+	rsa->dmq1 = dmq1;
20cebf
+	rsa->iqmp = iqmp;
20cebf
+	n = e = d = p = q = dmp1 = dmq1 = iqmp = NULL;
20cebf
+#else
20cebf
+	if (RSA_set0_key(rsa, n, e, d) <= 0)
20cebf
+		DST_RET(ISC_R_NOMEMORY);
20cebf
+	n = e = d = NULL;
20cebf
+	if (p != NULL && q != NULL) {
20cebf
+		RSA_set0_factors(rsa, p, q);
20cebf
+		p = q = NULL;
20cebf
+		if (dmp1 != NULL && dmq1 != NULL && iqmp != NULL) {
20cebf
+			RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp);
20cebf
+			dmp1 = dmq1 = iqmp = NULL;
20cebf
+		}
20cebf
+	}
20cebf
+	/* free any stray parameters */
20cebf
+	BN_free(p);
20cebf
+	BN_free(q);
20cebf
+	BN_free(dmp1);
20cebf
+	BN_free(dmq1);
20cebf
+	BN_free(iqmp);
20cebf
+	p = q = dmp1 = dmq1 = iqmp = NULL;
20cebf
+#endif
20cebf
+	if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) {
20cebf
 		DST_RET(DST_R_INVALIDPRIVATEKEY);
20cebf
-	if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS)
20cebf
-		DST_RET(ISC_R_RANGE);
20cebf
-	key->key_size = BN_num_bits(rsa->n);
20cebf
+	} else {
20cebf
+		const BIGNUM *n, *e;
20cebf
+
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+		e = rsa->e;
20cebf
+		n = rsa->n;
20cebf
+#else
20cebf
+		RSA_get0_key(rsa, &n, &e, NULL);
20cebf
+#endif
20cebf
+		if (BN_num_bits(e) > RSA_MAX_PUBEXP_BITS)
20cebf
+			DST_RET(ISC_R_RANGE);
20cebf
+
20cebf
+		key->key_size = BN_num_bits(n);
20cebf
+	}
20cebf
 	if (pubrsa != NULL)
20cebf
 		RSA_free(pubrsa);
20cebf
 #if USE_EVP
20cebf
+	if (!EVP_PKEY_set1_RSA(pkey, rsa))
20cebf
+		DST_RET(ISC_R_FAILURE);
20cebf
+	key->keydata.pkey = pkey;
20cebf
 	RSA_free(rsa);
20cebf
 #endif
20cebf
 
20cebf
@@ -1378,6 +1563,14 @@ opensslrsa_parse(dst_key_t *key, isc_lex
20cebf
 		RSA_free(rsa);
20cebf
 	if (pubrsa != NULL)
20cebf
 		RSA_free(pubrsa);
20cebf
+	BN_free(n);
20cebf
+	BN_free(e);
20cebf
+	BN_free(d);
20cebf
+	BN_free(p);
20cebf
+	BN_free(q);
20cebf
+	BN_free(dmp1);
20cebf
+	BN_free(dmq1);
20cebf
+	BN_free(iqmp);
20cebf
 	key->keydata.generic = NULL;
20cebf
 	dst__privstruct_free(&priv, mctx);
20cebf
 	memset(&priv, 0, sizeof(priv));
20cebf
@@ -1389,10 +1582,11 @@ opensslrsa_fromlabel(dst_key_t *key, con
20cebf
 		     const char *pin)
20cebf
 {
20cebf
 #ifdef USE_ENGINE
20cebf
-	ENGINE *e = NULL;
20cebf
+	ENGINE *eng = NULL;
20cebf
 	isc_result_t ret;
20cebf
 	EVP_PKEY *pkey = NULL;
20cebf
 	RSA *rsa = NULL, *pubrsa = NULL;
20cebf
+	const BIGNUM *e;
20cebf
 	char *colon, *tmpengine = NULL;
20cebf
 
20cebf
 	UNUSED(pin);
20cebf
@@ -1407,17 +1601,17 @@ opensslrsa_fromlabel(dst_key_t *key, con
20cebf
 		INSIST(colon != NULL);
20cebf
 		*colon = '\0';
20cebf
 	}
20cebf
-	e = dst__openssl_getengine(engine);
20cebf
-	if (e == NULL)
20cebf
+	eng = dst__openssl_getengine(engine);
20cebf
+	if (eng == NULL)
20cebf
 		DST_RET(DST_R_NOENGINE);
20cebf
-	pkey = ENGINE_load_public_key(e, label, NULL, NULL);
20cebf
+	pkey = ENGINE_load_public_key(eng, label, NULL, NULL);
20cebf
 	if (pkey != NULL) {
20cebf
 		pubrsa = EVP_PKEY_get1_RSA(pkey);
20cebf
 		EVP_PKEY_free(pkey);
20cebf
 		if (pubrsa == NULL)
20cebf
 			DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
20cebf
 	}
20cebf
-	pkey = ENGINE_load_private_key(e, label, NULL, NULL);
20cebf
+	pkey = ENGINE_load_private_key(eng, label, NULL, NULL);
20cebf
 	if (pkey == NULL)
20cebf
 		DST_RET(dst__openssl_toresult2("ENGINE_load_private_key",
20cebf
 					       ISC_R_NOTFOUND));
20cebf
@@ -1437,7 +1631,12 @@ opensslrsa_fromlabel(dst_key_t *key, con
20cebf
 		DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
20cebf
 	if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
20cebf
 		DST_RET(DST_R_INVALIDPRIVATEKEY);
20cebf
-	if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS)
20cebf
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
20cebf
+	e = rsa->e;
20cebf
+#else
20cebf
+	RSA_get0_key(rsa, NULL, &e, NULL);
20cebf
+#endif
20cebf
+	if (BN_num_bits(e) > RSA_MAX_PUBEXP_BITS)
20cebf
 		DST_RET(ISC_R_RANGE);
20cebf
 	if (pubrsa != NULL)
20cebf
 		RSA_free(pubrsa);