--- old/usr/src/Makefile	Mon Apr 30 13:30:19 2018
+++ new/usr/src/Makefile	Mon Apr 30 13:30:19 2018
@@ -26,6 +26,7 @@
 # Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
 # Copyright 2016 Toomas Soome <tsoome@me.com>
 # Copyright 2017 Joyent, Inc.
+# Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
 #
 
 #
@@ -288,4 +289,14 @@
 	else						\
 		$(ECHO) No Java compiler found;		\
 		exit 1;					\
+	fi
+
+openssl-version:
+	@if [ -x "$(OPENSSL)" ]; then				\
+		$(ECHO) $(OPENSSL);				\
+		$(OPENSSL) version;				\
+		$(OPENSSL) version -f |				\
+		    $(SED) -n '/_API/{s/.*_API/    API/;s/ -.*//;p;}'; \
+	else							\
+		$(ECHO) No OpenSSL utility found;		\
 	fi
--- old/usr/src/Makefile.master	Mon Apr 30 13:30:19 2018
+++ new/usr/src/Makefile.master	Mon Apr 30 13:30:19 2018
@@ -28,6 +28,7 @@
 # Copyright 2015 Igor Kozhukhov <ikozhukhov@gmail.com>
 # Copyright 2016 Toomas Soome <tsoome@me.com>
 # Copyright 2017 Joyent, Inc.
+# Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
 #
 
 #
@@ -218,6 +219,7 @@
 LCDEF=		$(ONBLD_TOOLS)/bin/$(MACH)/localedef
 TIC=		$(ONBLD_TOOLS)/bin/$(MACH)/tic
 ZIC=		$(ONBLD_TOOLS)/bin/$(MACH)/zic
+OPENSSL=	/usr/bin/openssl
 
 FILEMODE=	644
 DIRMODE=	755
--- old/usr/src/cmd/sendmail/src/tls.c	Mon Apr 30 13:30:20 2018
+++ new/usr/src/cmd/sendmail/src/tls.c	Mon Apr 30 13:30:20 2018
@@ -2,6 +2,7 @@
  * Copyright (c) 2000-2006, 2008, 2009 Sendmail, Inc. and its suppliers.
  *	All rights reserved.
  * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
+ * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  *
  * By using this file, you agree to the terms and conditions set
  * forth in the LICENSE file which can be found at the top level of
@@ -17,28 +18,18 @@
 #  include <openssl/err.h>
 #  include <openssl/bio.h>
 #  include <openssl/pem.h>
+#  include <openssl/bn.h>
 #  ifndef HASURANDOMDEV
 #   include <openssl/rand.h>
 #  endif /* ! HASURANDOMDEV */
 # if !TLS_NO_RSA
+#  include <openssl/rsa.h>
 static RSA *rsa_tmp = NULL;	/* temporary RSA key */
-static RSA *tmp_rsa_key __P((SSL *, int, int));
 # endif /* !TLS_NO_RSA */
-#  if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L
-static int	tls_verify_cb __P((X509_STORE_CTX *));
-#  else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
 static int	tls_verify_cb __P((X509_STORE_CTX *, void *));
-#  endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
-
-# if OPENSSL_VERSION_NUMBER > 0x00907000L
 static int x509_verify_cb __P((int, X509_STORE_CTX *));
-# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
 
-# if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L
-#  define CONST097
-# else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
 #  define CONST097 const
-# endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
 static void	apps_ssl_info_cb __P((CONST097 SSL *, int , int));
 static bool	tls_ok_f __P((char *, char *, int));
 static bool	tls_safe_f __P((char *, long, bool));
@@ -45,6 +36,48 @@
 static int	tls_verify_log __P((int, X509_STORE_CTX *, char *));
 
 # if !NO_DH
+#  include <openssl/dh.h>
+#  include <openssl/dsa.h>
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
+/*
+ * This compatibility function is taken from
+ * https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes
+ *     #Adding_forward-compatible_code_to_older_versions
+ */
+
+#define DH_set0_pqg __DH_set0_pqg
+int __DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+    /* If the fields p and g in d are NULL, the corresponding input
+     * parameters MUST be non-NULL.  q may remain NULL.
+     */
+    if ((dh->p == NULL && p == NULL)
+        || (dh->g == NULL && g == NULL))
+        return 0;
+
+    if (p != NULL) {
+        BN_free(dh->p);
+        dh->p = p;
+    }
+    if (q != NULL) {
+        BN_free(dh->q);
+        dh->q = q;
+    }
+    if (g != NULL) {
+        BN_free(dh->g);
+        dh->g = g;
+    }
+
+    if (q != NULL) {
+        dh->length = BN_num_bits(q);
+    }
+
+    return 1;
+}
+#endif
+
 static DH *get_dh512 __P((void));
 
 static unsigned char dh512_p[] =
@@ -65,13 +98,21 @@
 get_dh512()
 {
 	DH *dh = NULL;
+	BIGNUM *p, *g;
 
 	if ((dh = DH_new()) == NULL)
 		return NULL;
-	dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
-	dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
-	if ((dh->p == NULL) || (dh->g == NULL))
+	p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
+	g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
+	if ((p == NULL) || (g == NULL)) {
+		BN_free(p);
+		BN_free(g);
+		DH_free(dh);
 		return NULL;
+	}
+
+	DH_set0_pqg(dh, p, NULL, g);
+
 	return dh;
 }
 # endif /* !NO_DH */
@@ -278,8 +319,11 @@
 init_tls_library()
 {
 	/* basic TLS initialization, ignore result for now */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+	/* No longer available (nor necessary) in OpenSSL 1.1 */
 	SSL_library_init();
 	SSL_load_error_strings();
+#endif
 # if 0
 	/* this is currently a macro for SSL_library_init */
 	SSLeay_add_ssl_algorithms();
@@ -508,13 +552,6 @@
 
 static char server_session_id_context[] = "sendmail8";
 
-/* 0.9.8a and b have a problem with SSL_OP_TLS_BLOCK_PADDING_BUG */
-#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
-# define SM_SSL_OP_TLS_BLOCK_PADDING_BUG	1
-#else
-# define SM_SSL_OP_TLS_BLOCK_PADDING_BUG	0
-#endif
-
 bool
 inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhparam)
 	SSL_CTX **ctx;
@@ -536,15 +573,9 @@
 #  if SM_CONF_SHM
 	extern int ShmId;
 #  endif /* SM_CONF_SHM */
-# if OPENSSL_VERSION_NUMBER > 0x00907000L
 	BIO *crl_file;
 	X509_CRL *crl;
 	X509_STORE *store;
-# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
-#if SM_SSL_OP_TLS_BLOCK_PADDING_BUG
-	long rt_version;
-	STACK_OF(SSL_COMP) *comp_methods;
-#endif
 
 	status = TLS_S_NONE;
 	who = srv ? "server" : "client";
@@ -593,11 +624,8 @@
 		 TLS_S_CERTP_EX, TLS_T_OTHER);
 	TLS_OK_F(cacertfile, "CACertFile", bitset(TLS_I_CERTF_EX, req),
 		 TLS_S_CERTF_EX, TLS_T_OTHER);
-
-# if OPENSSL_VERSION_NUMBER > 0x00907000L
 	TLS_OK_F(CRLFile, "CRLFile", bitset(TLS_I_CRLF_EX, req),
 		 TLS_S_CRLF_EX, TLS_T_OTHER);
-# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
 
 # if _FFR_TLS_1
 	/*
@@ -679,11 +707,9 @@
 	TLS_SAFE_F(dhparam, sff | TLS_UNR(TLS_I_DHPAR_UNR, req),
 		   bitset(TLS_I_DHPAR_EX, req),
 		   bitset(TLS_S_DHPAR_EX, status), TLS_S_DHPAR_OK, srv);
-# if OPENSSL_VERSION_NUMBER > 0x00907000L
 	TLS_SAFE_F(CRLFile, sff | TLS_UNR(TLS_I_CRLF_UNR, req),
 		   bitset(TLS_I_CRLF_EX, req),
 		   bitset(TLS_S_CRLF_EX, status), TLS_S_CRLF_OK, srv);
-# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
 	if (!ok)
 		return ok;
 # if _FFR_TLS_1
@@ -714,12 +740,11 @@
 		return false;
 	}
 
-# if OPENSSL_VERSION_NUMBER > 0x00907000L
 	if (CRLFile != NULL)
 	{
 		/* get a pointer to the current certificate validation store */
 		store = SSL_CTX_get_cert_store(*ctx);	/* does not fail */
-		crl_file = BIO_new(BIO_s_file_internal());
+		crl_file = BIO_new(BIO_s_file());
 		if (crl_file != NULL)
 		{
 			if (BIO_read_filename(crl_file, CRLFile) >= 0)
@@ -776,7 +801,6 @@
 			X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
 	}
 #  endif /* _FFR_CRLPATH */
-# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
 
 # if TLS_NO_RSA
 	/* turn off backward compatibility, required for no-rsa */
@@ -795,23 +819,33 @@
 
 	if (bitset(TLS_I_RSA_TMP, req)
 #   if SM_CONF_SHM
-	    && ShmId != SM_SHM_NO_ID &&
-	    (rsa_tmp = RSA_generate_key(RSA_KEYLENGTH, RSA_F4, NULL,
-					NULL)) == NULL
+	    && ShmId != SM_SHM_NO_ID
 #   else /* SM_CONF_SHM */
 	    && 0	/* no shared memory: no need to generate key now */
 #   endif /* SM_CONF_SHM */
-	   )
+	    )
 	{
-		if (LogLevel > 7)
+		BIGNUM *e = BN_new();
+		BN_set_word(e, RSA_F4);
+
+		if ((rsa_tmp = RSA_new()) == NULL || RSA_generate_key_ex(
+		    rsa_tmp, RSA_KEYLENGTH, e, NULL) == 0)
 		{
-			sm_syslog(LOG_WARNING, NOQID,
-				  "STARTTLS=%s, error: RSA_generate_key failed",
-				  who);
-			if (LogLevel > 9)
-				tlslogerr(who);
+			BN_free(e);
+			if (rsa_tmp != NULL)
+				RSA_free(rsa_tmp);
+			rsa_tmp = NULL;
+			if (LogLevel > 7)
+			{
+				sm_syslog(LOG_WARNING, NOQID,
+					  "STARTTLS=%s, error: RSA_generate_key failed",
+					  who);
+				if (LogLevel > 9)
+					tlslogerr(who);
+			}
+			return false;
 		}
-		return false;
+		BN_free(e);
 	}
 # endif /* !TLS_NO_RSA */
 
@@ -919,26 +953,6 @@
 
 	/* SSL_CTX_set_quiet_shutdown(*ctx, 1); violation of standard? */
 
-#if SM_SSL_OP_TLS_BLOCK_PADDING_BUG
-
-	/*
-	**  In OpenSSL 0.9.8[ab], enabling zlib compression breaks the
-	**  padding bug work-around, leading to false positives and
-	**  failed connections. We may not interoperate with systems
-	**  with the bug, but this is better than breaking on all 0.9.8[ab]
-	**  systems that have zlib support enabled.
-	**  Note: this checks the runtime version of the library, not
-	**  just the compile time version.
-	*/
-
-	rt_version = SSLeay();
-	if (rt_version >= 0x00908000L && rt_version <= 0x0090802fL)
-	{
-		comp_methods = SSL_COMP_get_compression_methods();
-		if (comp_methods != NULL && sk_SSL_COMP_num(comp_methods) > 0)
-			options &= ~SSL_OP_TLS_BLOCK_PADDING_BUG;
-	}
-#endif
 	SSL_CTX_set_options(*ctx, options);
 
 # if !NO_DH
@@ -980,16 +994,19 @@
 		}
 		if (dh == NULL && bitset(TLS_I_DH1024, req))
 		{
-			DSA *dsa;
+			DSA *dsa = NULL;
 
 			/* this takes a while! (7-130s on a 450MHz AMD K6-2) */
-			dsa = DSA_generate_parameters(1024, NULL, 0, NULL,
-						      NULL, 0, NULL);
-			dh = DSA_dup_DH(dsa);
-			DSA_free(dsa);
+			if ((dsa = DSA_new()) == NULL ||
+			    DSA_generate_parameters_ex(dsa, 1024,
+			    NULL, 0, NULL, 0, NULL) == 0)
+				dh = NULL;
+			else
+				dh = DSA_dup_DH(dsa);
+			if (dsa != NULL)
+				DSA_free(dsa);
 		}
-		else
-		if (dh == NULL && bitset(TLS_I_DH512, req))
+		else if (dh == NULL && bitset(TLS_I_DH512, req))
 			dh = get_dh512();
 
 		if (dh == NULL)
@@ -1046,11 +1063,6 @@
 		if ((r = SSL_CTX_load_verify_locations(*ctx, cacertfile,
 						       cacertpath)) == 1)
 		{
-# if !TLS_NO_RSA
-			if (bitset(TLS_I_RSA_TMP, req))
-				SSL_CTX_set_tmp_rsa_callback(*ctx, tmp_rsa_key);
-# endif /* !TLS_NO_RSA */
-
 			/*
 			**  We have to install our own verify callback:
 			**  SSL_VERIFY_PEER requests a client cert but even
@@ -1186,7 +1198,7 @@
 	macdefine(mac, A_TEMP, macid("{cipher_bits}"), bitstr);
 	(void) sm_snprintf(bitstr, sizeof(bitstr), "%d", r);
 	macdefine(mac, A_TEMP, macid("{alg_bits}"), bitstr);
-	s = SSL_CIPHER_get_version(c);
+	s = (char *)SSL_CIPHER_get_version(c);
 	if (s == NULL)
 		s = "UNKNOWN";
 	macdefine(mac, A_TEMP, macid("{tls_version}"), s);
@@ -1380,7 +1392,6 @@
 			}
 			ret = EX_SOFTWARE;
 		}
-# if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER > 0x0090602fL
 
 		/*
 		**  Bug in OpenSSL (at least up to 0.9.6b):
@@ -1429,7 +1440,6 @@
 			}
 			ret = EX_SOFTWARE;
 		}
-# endif /* !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER > 0x0090602fL */
 		SSL_free(ssl);
 		ssl = NULL;
 	}
@@ -1436,72 +1446,7 @@
 	return ret;
 }
 
-# if !TLS_NO_RSA
 /*
-**  TMP_RSA_KEY -- return temporary RSA key
-**
-**	Parameters:
-**		s -- TLS connection structure
-**		export --
-**		keylength --
-**
-**	Returns:
-**		temporary RSA key.
-*/
-
-#   ifndef MAX_RSA_TMP_CNT
-#    define MAX_RSA_TMP_CNT	1000	/* XXX better value? */
-#   endif /* ! MAX_RSA_TMP_CNT */
-
-/* ARGUSED0 */
-static RSA *
-tmp_rsa_key(s, export, keylength)
-	SSL *s;
-	int export;
-	int keylength;
-{
-#   if SM_CONF_SHM
-	extern int ShmId;
-	extern int *PRSATmpCnt;
-
-	if (ShmId != SM_SHM_NO_ID && rsa_tmp != NULL &&
-	    ++(*PRSATmpCnt) < MAX_RSA_TMP_CNT)
-		return rsa_tmp;
-#   endif /* SM_CONF_SHM */
-
-	if (rsa_tmp != NULL)
-		RSA_free(rsa_tmp);
-	rsa_tmp = RSA_generate_key(RSA_KEYLENGTH, RSA_F4, NULL, NULL);
-	if (rsa_tmp == NULL)
-	{
-		if (LogLevel > 0)
-			sm_syslog(LOG_ERR, NOQID,
-				  "STARTTLS=server, tmp_rsa_key: RSA_generate_key failed!");
-	}
-	else
-	{
-#   if SM_CONF_SHM
-#    if 0
-		/*
-		**  XXX we can't (yet) share the new key...
-		**	The RSA structure contains pointers hence it can't be
-		**	easily kept in shared memory.  It must be transformed
-		**	into a continous memory region first, then stored,
-		**	and later read out again (each time re-transformed).
-		*/
-
-		if (ShmId != SM_SHM_NO_ID)
-			*PRSATmpCnt = 0;
-#    endif /* 0 */
-#   endif /* SM_CONF_SHM */
-		if (LogLevel > 9)
-			sm_syslog(LOG_ERR, NOQID,
-				  "STARTTLS=server, tmp_rsa_key: new temp RSA key");
-	}
-	return rsa_tmp;
-}
-# endif /* !TLS_NO_RSA */
-/*
 **  APPS_SSL_INFO_CB -- info callback for TLS connections
 **
 **	Parameters:
@@ -1629,14 +1574,9 @@
 */
 
 static int
-#  if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L
-tls_verify_cb(ctx)
-	X509_STORE_CTX *ctx;
-#  else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
 tls_verify_cb(ctx, unused)
 	X509_STORE_CTX *ctx;
 	void *unused;
-#  endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
 {
 	int ok;
 
@@ -1675,7 +1615,11 @@
 	char buf[256];
 #  define CP (const char **)
 
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+	es = 0;
+#else
 	es = CRYPTO_thread_id();
+#endif
 	while ((l = ERR_get_error_line_data(CP &file, &line, CP &data, &flags))
 		!= 0)
 	{
@@ -1687,7 +1631,6 @@
 	}
 }
 
-# if OPENSSL_VERSION_NUMBER > 0x00907000L
 /*
 **  X509_VERIFY_CB -- verify callback
 **
@@ -1708,13 +1651,13 @@
 	{
 		if (LogLevel > 13)
 			tls_verify_log(ok, ctx, "x509");
-		if (ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL)
+		if (X509_STORE_CTX_get_error(ctx)
+		    == X509_V_ERR_UNABLE_TO_GET_CRL)
 		{
-			ctx->error = 0;
+			X509_STORE_CTX_set_error(ctx, 0);
 			return 1;	/* override it */
 		}
 	}
 	return ok;
 }
-# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
 #endif /* STARTTLS */
--- old/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c	Mon Apr 30 13:30:21 2018
+++ new/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.c	Mon Apr 30 13:30:21 2018
@@ -31,6 +31,7 @@
 /*
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
+ * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  */
 
 #include <errno.h>
@@ -369,6 +370,101 @@
     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
 };
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+/*
+ * Many things have changed in OpenSSL 1.1. The code in this file has been
+ * updated to use the v1.1 APIs but some are new and require emulation
+ * for older OpenSSL versions.
+ */
+
+/* EVP_MD_CTX construct and destructor names have changed */
+
+#define EVP_MD_CTX_new EVP_MD_CTX_create
+#define EVP_MD_CTX_free EVP_MD_CTX_destroy
+
+/* ASN1_STRING_data is deprecated */
+#define ASN1_STRING_get0_data ASN1_STRING_data
+
+/* X509_STORE_CTX_trusted_stack is deprecated */
+#define X509_STORE_CTX_set0_trusted_stack X509_STORE_CTX_trusted_stack
+
+/* get_rfc2409_prime_1024() has been renamed. */
+#define BN_get_rfc2409_prime_1024 get_rfc2409_prime_1024
+
+#define OBJ_get0_data(o) ((o)->data)
+#define OBJ_length(o) ((o)->length)
+
+/* Some new DH functions that aren't in OpenSSL 1.0.x */
+#define DH_bits(dh) BN_num_bits((dh)->p);
+
+#define DH_set0_pqg(dh, p, q, g) __DH_set0_pqg(dh, p, q, g)
+static int
+__DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+    if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL))
+        return 0;
+
+    if (p != NULL) {
+        BN_free(dh->p);
+        dh->p = p;
+    }
+    if (q != NULL) {
+        BN_free(dh->q);
+        dh->q = q;
+    }
+    if (g != NULL) {
+        BN_free(dh->g);
+        dh->g = g;
+    }
+
+    if (q != NULL) {
+        dh->length = BN_num_bits(q);
+    }
+
+    return 1;
+}
+
+#define DH_get0_pqg(dh, p, q, g) __DH_get0_pqg(dh, p, q, g)
+static void
+__DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q,
+    const BIGNUM **g)
+{
+    if (p != NULL)
+        *p = dh->p;
+    if (q != NULL)
+        *q = dh->q;
+    if (g != NULL)
+        *g = dh->g;
+}
+
+#define DH_set0_key(dh, pub, priv) __DH_set0_key(dh, pub, priv)
+static int
+__DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+    if (pub_key != NULL) {
+        BN_free(dh->pub_key);
+        dh->pub_key = pub_key;
+    }
+    if (priv_key != NULL) {
+        BN_free(dh->priv_key);
+        dh->priv_key = priv_key;
+    }
+
+    return 1;
+}
+
+#define DH_get0_key(dh, pub, priv) __DH_get0_key(dh, pub, priv)
+static void
+__DH_get0_key(const DH *dh, const BIGNUM **pub, const BIGNUM **priv)
+{
+    if (pub != NULL)
+        *pub = dh->pub_key;
+    if (priv != NULL)
+        *priv = dh->priv_key;
+}
+
+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+
 /* Solaris Kerberos */
 static k5_mutex_t oids_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
 static int pkinit_oids_refs = 0;
@@ -524,7 +620,7 @@
 	    } \
 	} \
 	ctx->vn = OBJ_nid2obj(nid);
-    
+
     /* Solaris Kerberos */
     retval = k5_mutex_lock(&oids_mutex);
     if (retval != 0)
@@ -567,7 +663,7 @@
 
     /* Success */
     retval = 0;
-    
+
     pkinit_oids_refs++;
     /* Solaris Kerberos */
     k5_mutex_unlock(&oids_mutex);
@@ -656,48 +752,70 @@
     /* Only call OBJ_cleanup once! */
     /* Solaris Kerberos: locking */
     k5_mutex_lock(&oids_mutex);
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+    /*
+     * In OpenSSL versions prior to 1.1.0, OBJ_cleanup() cleaned up OpenSSL's
+     * internal object table. This function is deprecated in version 1.1.0.
+     * No explicit de-initialisation is now required.
+     */
     if (--pkinit_oids_refs == 0)
 	OBJ_cleanup();
+#else
+    pkinit_oids_refs--;
+#endif
     k5_mutex_unlock(&oids_mutex);
 }
 
+/* Construct an OpenSSL DH object for an Oakley group. */
+static DH *
+make_dhprime(uint8_t *prime, size_t len)
+{
+    DH *dh = NULL;
+    BIGNUM *p = NULL, *q = NULL, *g = NULL;
+
+    if ((p = BN_bin2bn(prime, len, NULL)) == NULL)
+	goto cleanup;
+    if ((q = BN_new()) == NULL)
+	goto cleanup;
+    if (!BN_rshift1(q, p))
+	goto cleanup;
+    if ((g = BN_new()) == NULL)
+	goto cleanup;
+    if (!BN_set_word(g, DH_GENERATOR_2))
+	goto cleanup;
+
+    dh = DH_new();
+    if (dh == NULL)
+	goto cleanup;
+    DH_set0_pqg(dh, p, q, g);
+    p = g = q = NULL;
+
+cleanup:
+    BN_free(p);
+    BN_free(q);
+    BN_free(g);
+    return dh;
+}
+
 static krb5_error_code
 pkinit_init_dh_params(pkinit_plg_crypto_context plgctx)
 {
     krb5_error_code retval = ENOMEM;
 
-    plgctx->dh_1024 = DH_new();
+    plgctx->dh_1024 = make_dhprime(pkinit_1024_dhprime,
+        sizeof(pkinit_1024_dhprime));
     if (plgctx->dh_1024 == NULL)
 	goto cleanup;
-    plgctx->dh_1024->p = BN_bin2bn(pkinit_1024_dhprime,
-	sizeof(pkinit_1024_dhprime), NULL);
-    if ((plgctx->dh_1024->g = BN_new()) == NULL ||
-	(plgctx->dh_1024->q = BN_new()) == NULL)
-	goto cleanup;
-    BN_set_word(plgctx->dh_1024->g, DH_GENERATOR_2);
-    BN_rshift1(plgctx->dh_1024->q, plgctx->dh_1024->p);
 
-    plgctx->dh_2048 = DH_new();
+    plgctx->dh_2048 = make_dhprime(pkinit_2048_dhprime,
+        sizeof(pkinit_2048_dhprime));
     if (plgctx->dh_2048 == NULL)
 	goto cleanup;
-    plgctx->dh_2048->p = BN_bin2bn(pkinit_2048_dhprime,
-	sizeof(pkinit_2048_dhprime), NULL);
-    if ((plgctx->dh_2048->g = BN_new()) == NULL ||
-	(plgctx->dh_2048->q = BN_new()) == NULL)
-	goto cleanup;
-    BN_set_word(plgctx->dh_2048->g, DH_GENERATOR_2);
-    BN_rshift1(plgctx->dh_2048->q, plgctx->dh_2048->p);
 
-    plgctx->dh_4096 = DH_new();
+    plgctx->dh_4096 = make_dhprime(pkinit_4096_dhprime,
+        sizeof(pkinit_4096_dhprime));
     if (plgctx->dh_4096 == NULL)
 	goto cleanup;
-    plgctx->dh_4096->p = BN_bin2bn(pkinit_4096_dhprime,
-	sizeof(pkinit_4096_dhprime), NULL);
-    if ((plgctx->dh_4096->g = BN_new()) == NULL ||
-	(plgctx->dh_4096->q = BN_new()) == NULL)
-	goto cleanup;
-    BN_set_word(plgctx->dh_4096->g, DH_GENERATOR_2);
-    BN_rshift1(plgctx->dh_4096->q, plgctx->dh_4096->p);
 
     retval = 0;
 
@@ -858,7 +976,7 @@
     ASN1_TYPE *pkinit_data = NULL;
     STACK_OF(X509) * cert_stack = NULL;
     ASN1_OCTET_STRING *digest_attr = NULL;
-    EVP_MD_CTX ctx, ctx2;
+    EVP_MD_CTX *ctx = NULL, *ctx2 = NULL;
     const EVP_MD *md_tmp = NULL;
     unsigned char md_data[EVP_MAX_MD_SIZE], md_data2[EVP_MAX_MD_SIZE];
     unsigned char *digestInfo_buf = NULL, *abuf = NULL;
@@ -902,7 +1020,7 @@
     } else {
 	/* create a cert chain */
 	X509_STORE *certstore = NULL;
-	X509_STORE_CTX certctx;
+	X509_STORE_CTX *certctx;
 	STACK_OF(X509) *certstack = NULL;
 	char buf[DN_BUF_LEN];
 	int i = 0, size = 0;
@@ -909,20 +1027,22 @@
 
 	if ((certstore = X509_STORE_new()) == NULL)
 	    goto cleanup;
+	if ((certctx = X509_STORE_CTX_new()) == NULL)
+	    goto cleanup;
 	pkiDebug("building certificate chain\n");
-	X509_STORE_set_verify_cb_func(certstore, openssl_callback);
-	X509_STORE_CTX_init(&certctx, certstore, cert,
+	X509_STORE_set_verify_cb(certstore, openssl_callback);
+	X509_STORE_CTX_init(certctx, certstore, cert,
 			    id_cryptoctx->intermediateCAs);
-	X509_STORE_CTX_trusted_stack(&certctx, id_cryptoctx->trustedCAs);
+	X509_STORE_CTX_set0_trusted_stack(certctx, id_cryptoctx->trustedCAs);
 	/* Solaris Kerberos */
-	if (X509_verify_cert(&certctx) <= 0) {
-	    pkiDebug("failed to create a certificate chain: %s\n", 
-	    X509_verify_cert_error_string(X509_STORE_CTX_get_error(&certctx)));
-	    if (!sk_X509_num(id_cryptoctx->trustedCAs)) 
+	if (X509_verify_cert(certctx) <= 0) {
+	    pkiDebug("failed to create a certificate chain: %s\n",
+	    X509_verify_cert_error_string(X509_STORE_CTX_get_error(certctx)));
+	    if (!sk_X509_num(id_cryptoctx->trustedCAs))
 		pkiDebug("No trusted CAs found. Check your X509_anchors\n");
 	    goto cleanup;
 	}
-	certstack = X509_STORE_CTX_get1_chain(&certctx);
+	certstack = X509_STORE_CTX_get1_chain(certctx);
 	size = sk_X509_num(certstack);
 	pkiDebug("size of certificate chain = %d\n", size);
 	for(i = 0; i < size - 1; i++) {
@@ -931,7 +1051,7 @@
 	    pkiDebug("cert #%d: %s\n", i, buf);
 	    sk_X509_push(cert_stack, X509_dup(x));
 	}
-	X509_STORE_CTX_cleanup(&certctx);
+	X509_STORE_CTX_free(certctx);
 	X509_STORE_free(certstore);
 	sk_X509_pop_free(certstack, X509_free);
     }
@@ -947,9 +1067,9 @@
 	goto cleanup;
     /* because ASN1_INTEGER_set is used to set a 'long' we will do
      * things the ugly way. */
-    M_ASN1_INTEGER_free(p7si->issuer_and_serial->serial);
+    ASN1_INTEGER_free(p7si->issuer_and_serial->serial);
     if (!(p7si->issuer_and_serial->serial =
-	  M_ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
+	  ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
 	goto cleanup;
 
     /* will not fill-out EVP_PKEY because it's on the smartcard */
@@ -983,11 +1103,16 @@
     } else {
 	/* add signed attributes */
 	/* compute sha1 digest over the EncapsulatedContentInfo */
-	EVP_MD_CTX_init(&ctx);
-	EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL);
-	EVP_DigestUpdate(&ctx, data, data_len);
-	md_tmp = EVP_MD_CTX_md(&ctx);
-	EVP_DigestFinal_ex(&ctx, md_data, &md_len);
+	ctx = EVP_MD_CTX_new();
+	if (ctx == NULL)
+	    goto cleanup2;
+	EVP_MD_CTX_init(ctx);
+	EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
+	EVP_DigestUpdate(ctx, data, data_len);
+	md_tmp = EVP_MD_CTX_md(ctx);
+	EVP_DigestFinal_ex(ctx, md_data, &md_len);
+	EVP_MD_CTX_free(ctx);
+	ctx = NULL;
 
 	/* create a message digest attr */
 	digest_attr = ASN1_OCTET_STRING_new();
@@ -996,7 +1121,7 @@
 				   V_ASN1_OCTET_STRING, (char *) digest_attr);
 
 	/* create a content-type attr */
-	PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType, 
+	PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,
 				   V_ASN1_OBJECT, oid);
 
 	/* create the signature over signed attributes. get DER encoded value */
@@ -1016,17 +1141,22 @@
      *	digestAlgorithm  AlgorithmIdentifier,
      *	digest OCTET STRING }
      */
-    if (id_cryptoctx->pkcs11_method == 1 && 
+    if (id_cryptoctx->pkcs11_method == 1 &&
 	    id_cryptoctx->mech == CKM_RSA_PKCS) {
 	pkiDebug("mech = CKM_RSA_PKCS\n");
-	EVP_MD_CTX_init(&ctx2);
+	ctx2 = EVP_MD_CTX_new();
+	if (ctx2 == NULL)
+	    goto cleanup2;
+	EVP_MD_CTX_init(ctx2);
 	/* if this is not draft9 request, include digest signed attribute */
-	if (cms_msg_type != CMS_SIGN_DRAFT9) 
-	    EVP_DigestInit_ex(&ctx2, md_tmp, NULL);
+	if (cms_msg_type != CMS_SIGN_DRAFT9)
+	    EVP_DigestInit_ex(ctx2, md_tmp, NULL);
 	else
-	    EVP_DigestInit_ex(&ctx2, EVP_sha1(), NULL);
-	EVP_DigestUpdate(&ctx2, abuf, alen);
-	EVP_DigestFinal_ex(&ctx2, md_data2, &md_len2);
+	    EVP_DigestInit_ex(ctx2, EVP_sha1(), NULL);
+	EVP_DigestUpdate(ctx2, abuf, alen);
+	EVP_DigestFinal_ex(ctx2, md_data2, &md_len2);
+	EVP_MD_CTX_free(ctx2);
+	ctx2 = NULL;
 
 	alg = X509_ALGOR_new();
 	if (alg == NULL)
@@ -1074,7 +1204,7 @@
 #ifdef DEBUG_SIG
     print_buffer(sig, sig_len);
 #endif
-    if (cms_msg_type != CMS_SIGN_DRAFT9) 
+    if (cms_msg_type != CMS_SIGN_DRAFT9)
 	free(abuf);
     if (retval)
 	goto cleanup2;
@@ -1159,12 +1289,14 @@
 #endif
 
   cleanup2:
-    if (cms_msg_type != CMS_SIGN_DRAFT9) 
-	EVP_MD_CTX_cleanup(&ctx);
+    if (cms_msg_type != CMS_SIGN_DRAFT9)
+	if (ctx != NULL)
+		EVP_MD_CTX_free(ctx);
 #ifndef WITHOUT_PKCS11
-    if (id_cryptoctx->pkcs11_method == 1 && 
+    if (id_cryptoctx->pkcs11_method == 1 &&
 	    id_cryptoctx->mech == CKM_RSA_PKCS) {
-	EVP_MD_CTX_cleanup(&ctx2);
+	if (ctx2 != NULL)
+		EVP_MD_CTX_free(ctx2);
 	if (digest_buf != NULL)
 	    free(digest_buf);
 	if (digestInfo_buf != NULL)
@@ -1178,7 +1310,7 @@
     if (alg != NULL)
 	X509_ALGOR_free(alg);
   cleanup:
-    if (p7 != NULL) 
+    if (p7 != NULL)
 	PKCS7_free(p7);
     if (sig != NULL)
 	free(sig);
@@ -1210,7 +1342,7 @@
     PKCS7_SIGNER_INFO *si = NULL;
     X509 *x = NULL;
     X509_STORE *store = NULL;
-    X509_STORE_CTX cert_ctx;
+    X509_STORE_CTX *cert_ctx;
     STACK_OF(X509) *intermediateCAs = NULL;
     STACK_OF(X509_CRL) *revoked = NULL;
     STACK_OF(X509) *verified_chain = NULL;
@@ -1254,9 +1386,9 @@
     /* check if we are inforcing CRL checking */
     vflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
     if (require_crl_checking)
-	X509_STORE_set_verify_cb_func(store, openssl_callback);
+	X509_STORE_set_verify_cb(store, openssl_callback);
     else
-	X509_STORE_set_verify_cb_func(store, openssl_callback_ignore_crls);
+	X509_STORE_set_verify_cb(store, openssl_callback_ignore_crls);
     X509_STORE_set_flags(store, vflags);
 
     /* get the signer's information from the PKCS7 message */
@@ -1307,14 +1439,16 @@
     /* initialize x509 context with the received certificate and
      * trusted and intermediate CA chains and CRLs
      */
-    if (!X509_STORE_CTX_init(&cert_ctx, store, x, intermediateCAs))
+    if ((cert_ctx = X509_STORE_CTX_new()) == NULL)
 	goto cleanup;
+    if (!X509_STORE_CTX_init(cert_ctx, store, x, intermediateCAs))
+	goto cleanup;
 
-    X509_STORE_CTX_set0_crls(&cert_ctx, revoked);
+    X509_STORE_CTX_set0_crls(cert_ctx, revoked);
 
     /* add trusted CAs certificates for cert verification */
     if (idctx->trustedCAs != NULL)
-	X509_STORE_CTX_trusted_stack(&cert_ctx, idctx->trustedCAs);
+	X509_STORE_CTX_set0_trusted_stack(cert_ctx, idctx->trustedCAs);
     else {
 	pkiDebug("unable to find any trusted CAs\n");
 	goto cleanup;
@@ -1349,11 +1483,12 @@
     }
 #endif
 
-    i = X509_verify_cert(&cert_ctx);
+    i = X509_verify_cert(cert_ctx);
     if (i <= 0) {
-	int j = X509_STORE_CTX_get_error(&cert_ctx);
+	int j = X509_STORE_CTX_get_error(cert_ctx);
 
-	reqctx->received_cert = X509_dup(cert_ctx.current_cert);
+	reqctx->received_cert = X509_dup(
+	    X509_STORE_CTX_get_current_cert(cert_ctx));
 	switch(j) {
 	    case X509_V_ERR_CERT_REVOKED:
 		retval = KRB5KDC_ERR_REVOKED_CERTIFICATE;
@@ -1385,10 +1520,10 @@
 #endif
     } else {
 	/* retrieve verified certificate chain */
-	if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9) 
-	    verified_chain = X509_STORE_CTX_get1_chain(&cert_ctx);
+	if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9)
+	    verified_chain = X509_STORE_CTX_get1_chain(cert_ctx);
     }
-    X509_STORE_CTX_cleanup(&cert_ctx);
+    X509_STORE_CTX_free(cert_ctx);
     if (i <= 0)
 	goto cleanup;
 
@@ -1398,7 +1533,7 @@
     if (PKCS7_verify(p7, NULL, store, NULL, out, flags)) {
 	int valid_oid = 0;
 
-	if (!OBJ_cmp(p7->d.sign->contents->type, oid)) 
+	if (!OBJ_cmp(p7->d.sign->contents->type, oid))
 	    valid_oid = 1;
 	else if (cms_msg_type == CMS_SIGN_DRAFT9) {
 	    /*
@@ -1416,12 +1551,13 @@
 		valid_oid = 1;
 	}
 
-	if (valid_oid) 
+	if (valid_oid)
 	    pkiDebug("PKCS7 Verification successful\n");
 	else {
+	    const ASN1_OBJECT *etype = p7->d.sign->contents->type;
 	    pkiDebug("wrong oid in eContentType\n");
-	    print_buffer((unsigned char *)p7->d.sign->contents->type->data, 
-		(unsigned int)p7->d.sign->contents->type->length);
+	    print_buffer((unsigned char *)OBJ_get0_data(etype),
+		OBJ_length(etype));
 	    retval = KRB5KDC_ERR_PREAUTH_FAILED;
 	    krb5_set_error_message(context, retval, "wrong oid\n");
 	    goto cleanup;
@@ -1460,11 +1596,11 @@
     /* generate authorization data */
     if (cms_msg_type == CMS_SIGN_CLIENT || cms_msg_type == CMS_SIGN_DRAFT9) {
 
-	if (authz_data == NULL || authz_data_len == NULL) 
+	if (authz_data == NULL || authz_data_len == NULL)
 	    goto out;
 
 	*authz_data = NULL;
-	retval = create_identifiers_from_stack(verified_chain, 
+	retval = create_identifiers_from_stack(verified_chain,
 					       &krb5_verified_chain);
 	if (retval) {
 	    pkiDebug("create_identifiers_from_stack failed\n");
@@ -1602,15 +1738,15 @@
     }
     switch (pa_type) {
 	case KRB5_PADATA_PK_AS_REQ:
-	    p7->d.enveloped->enc_data->content_type = 
+	    p7->d.enveloped->enc_data->content_type =
 		OBJ_nid2obj(NID_pkcs7_signed);
 	    break;
 	case KRB5_PADATA_PK_AS_REP_OLD:
 	case KRB5_PADATA_PK_AS_REQ_OLD:
-	    p7->d.enveloped->enc_data->content_type = 
+	    p7->d.enveloped->enc_data->content_type =
 		OBJ_nid2obj(NID_pkcs7_data);
 	    break;
-    } 
+    }
 
     *out_len = i2d_PKCS7(p7, NULL);
     if (!*out_len || (p = *out = (unsigned char *)malloc(*out_len)) == NULL) {
@@ -1924,7 +2060,7 @@
 		    pkiDebug("%s: found dns name = %s\n",
 			     __FUNCTION__, gen->d.dNSName->data);
 		    dnss[d] = (unsigned char *)
-				    strdup((char *)gen->d.dNSName->data); 
+				    strdup((char *)gen->d.dNSName->data);
 		    if (dnss[d] == NULL) {
 			pkiDebug("%s: failed to duplicate dns name\n",
 				 __FUNCTION__);
@@ -2163,39 +2299,40 @@
     krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
     unsigned char *buf = NULL;
     int dh_err = 0;
-    ASN1_INTEGER *pub_key = NULL;
+    ASN1_INTEGER *asn_pub_key = NULL;
+    BIGNUM *p, *g, *q;
+    const BIGNUM *pub_key;
 
     if (cryptoctx->dh == NULL) {
 	if ((cryptoctx->dh = DH_new()) == NULL)
 	    goto cleanup;
-	if ((cryptoctx->dh->g = BN_new()) == NULL ||
-	    (cryptoctx->dh->q = BN_new()) == NULL)
+	if ((g = BN_new()) == NULL || (q = BN_new()) == NULL)
 	    goto cleanup;
 
 	switch(dh_size) {
 	    case 1024:
 		pkiDebug("client uses 1024 DH keys\n");
-		cryptoctx->dh->p = get_rfc2409_prime_1024(NULL);
+		cryptoctx->dh = make_dhprime(pkinit_1024_dhprime,
+		    sizeof(pkinit_1024_dhprime));
 		break;
 	    case 2048:
 		pkiDebug("client uses 2048 DH keys\n");
-		cryptoctx->dh->p = BN_bin2bn(pkinit_2048_dhprime,
-		    sizeof(pkinit_2048_dhprime), NULL);
+		cryptoctx->dh = make_dhprime(pkinit_2048_dhprime,
+		    sizeof(pkinit_2048_dhprime));
 		break;
 	    case 4096:
 		pkiDebug("client uses 4096 DH keys\n");
-		cryptoctx->dh->p = BN_bin2bn(pkinit_4096_dhprime,
-		    sizeof(pkinit_4096_dhprime), NULL);
+		cryptoctx->dh = make_dhprime(pkinit_4096_dhprime,
+		    sizeof(pkinit_4096_dhprime));
 		break;
-	    default:
-		goto cleanup;
 	}
-
-	BN_set_word((cryptoctx->dh->g), DH_GENERATOR_2);
-	BN_rshift1(cryptoctx->dh->q, cryptoctx->dh->p);
+	if (cryptoctx->dh == NULL)
+		goto cleanup;
     }
 
     DH_generate_key(cryptoctx->dh);
+    DH_get0_key(cryptoctx->dh, &pub_key, NULL);
+
 /* Solaris Kerberos */
 #ifdef DEBUG
     DH_check(cryptoctx->dh, &dh_err);
@@ -2213,10 +2350,10 @@
 #endif
 #ifdef DEBUG_DH
     print_dh(cryptoctx->dh, "client's DH params\n");
-    print_pubkey(cryptoctx->dh->pub_key, "client's pub_key=");
+    print_pubkey(pub_key, "client's pub_key=");
 #endif
 
-    DH_check_pub_key(cryptoctx->dh, cryptoctx->dh->pub_key, &dh_err);
+    DH_check_pub_key(cryptoctx->dh, pub_key, &dh_err);
     if (dh_err != 0) {
 	pkiDebug("dh_check_pub_key failed with %d\n", dh_err);
 	goto cleanup;
@@ -2226,8 +2363,9 @@
     /* aglo: usually we could just call i2d_DHparams to encode DH params
      * however, PKINIT requires RFC3279 encoding and openssl does pkcs#3.
      */
-    retval = pkinit_encode_dh_params(cryptoctx->dh->p, cryptoctx->dh->g,
-	cryptoctx->dh->q, dh_params, dh_params_len);
+    DH_get0_pqg(cryptoctx->dh, (const BIGNUM **)&p, (const BIGNUM **)&q,
+	(const BIGNUM **)&g);
+    retval = pkinit_encode_dh_params(p, g, q, dh_params, dh_params_len);
     if (retval)
 	goto cleanup;
 
@@ -2237,18 +2375,18 @@
      * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
      * data element
      */
-    if ((pub_key = BN_to_ASN1_INTEGER(cryptoctx->dh->pub_key, NULL)) == NULL)
+    if ((asn_pub_key = BN_to_ASN1_INTEGER(pub_key, NULL)) == NULL)
 	goto cleanup;
-    *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL);
+    *dh_pubkey_len = i2d_ASN1_INTEGER(asn_pub_key, NULL);
     if ((buf = *dh_pubkey = (unsigned char *)
-	    malloc((size_t) *dh_pubkey_len)) == NULL) {
-	retval  = ENOMEM;
-	goto cleanup;
+        malloc((size_t) *dh_pubkey_len)) == NULL) {
+	    retval = ENOMEM;
+	    goto cleanup;
     }
-    i2d_ASN1_INTEGER(pub_key, &buf);
+    i2d_ASN1_INTEGER(asn_pub_key, &buf);
 
-    if (pub_key != NULL)
-	ASN1_INTEGER_free(pub_key);
+    if (asn_pub_key != NULL)
+	ASN1_INTEGER_free(asn_pub_key);
 
     retval = 0;
     return retval;
@@ -2263,8 +2401,8 @@
     if (*dh_pubkey != NULL)
 	free(*dh_pubkey);
     *dh_pubkey = NULL;
-    if (pub_key != NULL)
-	ASN1_INTEGER_free(pub_key);
+    if (asn_pub_key != NULL)
+	ASN1_INTEGER_free(asn_pub_key);
 
     return retval;
 }
@@ -2352,6 +2490,7 @@
     unsigned char *tmp = NULL;
     int dh_prime_bits;
     krb5_error_code retval = KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
+    const BIGNUM *p, *g, *q, *p2;
 
     tmp = dh_params->data;
     dh = DH_new();
@@ -2361,8 +2500,10 @@
 	goto cleanup;
     }
 
+    DH_get0_pqg(dh, &p, &q, &g);
+
     /* KDC SHOULD check to see if the key parameters satisfy its policy */
-    dh_prime_bits = BN_num_bits(dh->p);
+    dh_prime_bits = BN_num_bits(p);
     if (minbits && dh_prime_bits < minbits) {
 	pkiDebug("client sent dh params with %d bits, we require %d\n",
 		 dh_prime_bits, minbits);
@@ -2370,22 +2511,22 @@
     }
 
     /* check dhparams is group 2 */
-    if (pkinit_check_dh_params(cryptoctx->dh_1024->p,
-			       dh->p, dh->g, dh->q) == 0) {
+    DH_get0_pqg(cryptoctx->dh_1024, &p2, NULL, NULL);
+    if (pkinit_check_dh_params(p2, p, g, q) == 0) {
 	retval = 0;
 	goto cleanup;
     }
 
     /* check dhparams is group 14 */
-    if (pkinit_check_dh_params(cryptoctx->dh_2048->p,
-			       dh->p, dh->g, dh->q) == 0) {
+    DH_get0_pqg(cryptoctx->dh_2048, &p2, NULL, NULL);
+    if (pkinit_check_dh_params(p2, p, g, q) == 0) {
 	retval = 0;
 	goto cleanup;
     }
 
     /* check dhparams is group 16 */
-    if (pkinit_check_dh_params(cryptoctx->dh_4096->p,
-			       dh->p, dh->g, dh->q) == 0) {
+    DH_get0_pqg(cryptoctx->dh_4096, &p2, NULL, NULL);
+    if (pkinit_check_dh_params(p2, p, g, q) == 0) {
 	retval = 0;
 	goto cleanup;
     }
@@ -2416,8 +2557,10 @@
     /* Solaris Kerberos */
     krb5_error_code retval = KRB5KRB_ERR_GENERIC;
     DH *dh = NULL, *dh_server = NULL;
-    unsigned char *p = NULL;
-    ASN1_INTEGER *pub_key = NULL;
+    const BIGNUM *p, *g, *q, *s_pub_key;
+    BIGNUM *pub_key;
+    unsigned char *s = NULL;
+    ASN1_INTEGER *asn_pub_key = NULL;
 
     /* get client's received DH parameters that we saved in server_check_dh */
     dh = cryptoctx->dh;
@@ -2425,19 +2568,20 @@
     dh_server = DH_new();
     if (dh_server == NULL)
 	goto cleanup;
-    dh_server->p = BN_dup(dh->p);
-    dh_server->g = BN_dup(dh->g);
-    dh_server->q = BN_dup(dh->q);
+    DH_get0_pqg(dh, &p, &g, &q);
+    DH_set0_pqg(dh_server, BN_dup(p), BN_dup(g), BN_dup(q));
 
     /* decode client's public key */
-    p = data;
-    pub_key = d2i_ASN1_INTEGER(NULL, (const unsigned char **)&p, (int)data_len);
+    s = data;
+    asn_pub_key = d2i_ASN1_INTEGER(NULL,
+	(const unsigned char **)&s, (int)data_len);
+    if (asn_pub_key == NULL)
+	goto cleanup;
+    pub_key = ASN1_INTEGER_to_BN(asn_pub_key, NULL);
     if (pub_key == NULL)
 	goto cleanup;
-    dh->pub_key = ASN1_INTEGER_to_BN(pub_key, NULL);
-    if (dh->pub_key == NULL)
-	goto cleanup;
-    ASN1_INTEGER_free(pub_key);
+    DH_set0_key(dh, pub_key, NULL);
+    ASN1_INTEGER_free(asn_pub_key);
 
     if (!DH_generate_key(dh_server))
 	goto cleanup;
@@ -2444,14 +2588,16 @@
 
     /* generate DH session key */
     *server_key_len = DH_size(dh_server);
-    if ((*server_key = (unsigned char *) malloc((size_t)*server_key_len)) == NULL)
-	goto cleanup;
-    DH_compute_key(*server_key, dh->pub_key, dh_server);
+    if ((*server_key = (unsigned char *) malloc((size_t)*server_key_len))
+	== NULL)
+	    goto cleanup;
+    DH_compute_key(*server_key, pub_key, dh_server);
+    DH_get0_key(dh_server, &s_pub_key, NULL);
 
 #ifdef DEBUG_DH
     print_dh(dh_server, "client&server's DH params\n");
-    print_pubkey(dh->pub_key, "client's pub_key=");
-    print_pubkey(dh_server->pub_key, "server's pub_key=");
+    print_pubkey(pub_key, "client's pub_key=");
+    print_pubkey(s_pub_key, "server's pub_key=");
     pkiDebug("server secret key=");
     print_buffer(*server_key, *server_key_len);
 #endif
@@ -2463,14 +2609,15 @@
      * subjectPublicKey component (a BIT STRING) of the SubjectPublicKeyInfo
      * data element
      */
-    if ((pub_key = BN_to_ASN1_INTEGER(dh_server->pub_key, NULL)) == NULL)
+    if ((asn_pub_key = BN_to_ASN1_INTEGER(s_pub_key, NULL)) == NULL)
 	goto cleanup;
-    *dh_pubkey_len = i2d_ASN1_INTEGER(pub_key, NULL);
-    if ((p = *dh_pubkey = (unsigned char *) malloc((size_t)*dh_pubkey_len)) == NULL)
-	goto cleanup;
-    i2d_ASN1_INTEGER(pub_key, &p);
-    if (pub_key != NULL)
-	ASN1_INTEGER_free(pub_key);
+    *dh_pubkey_len = i2d_ASN1_INTEGER(asn_pub_key, NULL);
+    if ((s = *dh_pubkey = (unsigned char *) malloc((size_t)*dh_pubkey_len))
+	== NULL)
+	    goto cleanup;
+    i2d_ASN1_INTEGER(asn_pub_key, &s);
+    if (asn_pub_key != NULL)
+	ASN1_INTEGER_free(asn_pub_key);
 
     retval = 0;
 
@@ -2504,9 +2651,15 @@
     if (ret == 0) {
 	if (!did_init) {
 	    /* initialize openssl routines */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+	    /*
+	     * As of version 1.1.0, OpenSSL will automatically allocate
+	     * resources as-needed.
+	     */
 	    CRYPTO_malloc_init();
 	    ERR_load_crypto_strings();
 	    OpenSSL_add_all_algorithms();
+#endif
 	    did_init++;
 	}
 	k5_mutex_unlock(&init_mutex);
@@ -2515,7 +2668,7 @@
 }
 
 static krb5_error_code
-pkinit_encode_dh_params(BIGNUM *p, BIGNUM *g, BIGNUM *q,
+pkinit_encode_dh_params(const BIGNUM *p, const BIGNUM *g, const BIGNUM *q,
 			unsigned char **buf, unsigned int *buf_len)
 {
     krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
@@ -2560,6 +2713,8 @@
     return retval;
 }
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
 static DH *
 pkinit_decode_dh_params(DH ** a, unsigned char **pp, unsigned int len)
 {
@@ -2619,6 +2774,63 @@
 
 }
 
+#else
+
+/*
+ * This is taken from the internal dh_asn1.c file in OpenSSL 1.1, modified to
+ * make q an optional field.
+ */
+
+typedef struct {
+    ASN1_BIT_STRING *seed;
+    BIGNUM *counter;
+} int_dhvparams;
+
+typedef struct {
+    BIGNUM *p;
+    BIGNUM *q;
+    BIGNUM *g;
+    BIGNUM *j;
+    int_dhvparams *vparams;
+} int_dhx942_dh;
+
+ASN1_SEQUENCE(DHvparams) = {
+    ASN1_SIMPLE(int_dhvparams, seed, ASN1_BIT_STRING),
+    ASN1_SIMPLE(int_dhvparams, counter, BIGNUM)
+} static_ASN1_SEQUENCE_END_name(int_dhvparams, DHvparams)
+
+ASN1_SEQUENCE(DHxparams) = {
+    ASN1_SIMPLE(int_dhx942_dh, p, BIGNUM),
+    ASN1_SIMPLE(int_dhx942_dh, g, BIGNUM),
+    ASN1_OPT(int_dhx942_dh, q, BIGNUM),
+    ASN1_OPT(int_dhx942_dh, j, BIGNUM),
+    ASN1_OPT(int_dhx942_dh, vparams, DHvparams),
+} static_ASN1_SEQUENCE_END_name(int_dhx942_dh, DHxparams)
+
+static DH *
+pkinit_decode_dh_params(DH **a, unsigned char **pp, unsigned int len)
+{
+	int_dhx942_dh *params;
+	DH *dh = *a;
+
+	if (dh == NULL)
+		return NULL;
+
+	params = (int_dhx942_dh *)ASN1_item_d2i(NULL,
+	    (const unsigned char **)pp, len, ASN1_ITEM_rptr(DHxparams));
+	if (params == NULL) {
+		DH_free(dh);
+		return NULL;
+	}
+
+	DH_set0_pqg(dh, params->p, params->q, params->g);
+	params->p = params->q = params->g = NULL;
+	ASN1_item_free((ASN1_VALUE *)params, ASN1_ITEM_rptr(DHxparams));
+	return dh;
+}
+
+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+
 static krb5_error_code
 pkinit_create_sequence_of_principal_identifiers(
     krb5_context context,
@@ -2763,6 +2975,7 @@
     krb5_typed_data **typed_data = NULL;
     krb5_data *data = NULL, *encoded_algId = NULL;
     krb5_algorithm_identifier **algId = NULL;
+    const BIGNUM *p, *q, *g;
 
     /* Solaris Kerberos */
     if (opts->dh_min_bits > 4096) {
@@ -2771,22 +2984,19 @@
     }
 
     if (opts->dh_min_bits <= 1024) {
-	retval = pkinit_encode_dh_params(plg_cryptoctx->dh_1024->p,
-	    plg_cryptoctx->dh_1024->g, plg_cryptoctx->dh_1024->q,
-	    &buf1, &buf1_len);
+	DH_get0_pqg(plg_cryptoctx->dh_1024, &p, &q, &g);
+	retval = pkinit_encode_dh_params(p, g, q, &buf1, &buf1_len);
 	if (retval)
 	    goto cleanup;
     }
     if (opts->dh_min_bits <= 2048) {
-	retval = pkinit_encode_dh_params(plg_cryptoctx->dh_2048->p,
-	    plg_cryptoctx->dh_2048->g, plg_cryptoctx->dh_2048->q,
-	    &buf2, &buf2_len);
+	DH_get0_pqg(plg_cryptoctx->dh_2048, &p, &q, &g);
+	retval = pkinit_encode_dh_params(p, g, q, &buf2, &buf2_len);
 	if (retval)
 	    goto cleanup;
     }
-    retval = pkinit_encode_dh_params(plg_cryptoctx->dh_4096->p,
-	plg_cryptoctx->dh_4096->g, plg_cryptoctx->dh_4096->q,
-	&buf3, &buf3_len);
+    DH_get0_pqg(plg_cryptoctx->dh_4096, &p, &q, &g);
+    retval = pkinit_encode_dh_params(p, g, q, &buf3, &buf3_len);
     if (retval)
 	goto cleanup;
 
@@ -2980,7 +3190,8 @@
 }
 
 static int
-pkinit_check_dh_params(BIGNUM * p1, BIGNUM * p2, BIGNUM * g1, BIGNUM * q1)
+pkinit_check_dh_params(const BIGNUM *p1, const BIGNUM *p2, const BIGNUM *g1,
+    const BIGNUM *q1)
 {
     BIGNUM *g2 = NULL, *q2 = NULL;
     /* Solaris Kerberos */
@@ -3024,6 +3235,7 @@
     while (algId[i] != NULL) {
 	DH *dh = NULL;
 	unsigned char *tmp = NULL;
+	const BIGNUM *p, *g, *q, *p2;
 	int dh_prime_bits = 0;
 
 	if (algId[i]->algorithm.length != dh_oid.length ||
@@ -3033,27 +3245,28 @@
 	tmp = algId[i]->parameters.data;
 	dh = DH_new();
 	dh = pkinit_decode_dh_params(&dh, &tmp, algId[i]->parameters.length);
-	dh_prime_bits = BN_num_bits(dh->p);
+	dh_prime_bits = DH_bits(dh);
 	pkiDebug("client sent %d DH bits server prefers %d DH bits\n",
 		 *new_dh_size, dh_prime_bits);
+	DH_get0_pqg(dh, &p, &q, &g);
 	switch(dh_prime_bits) {
 	    case 1024:
-		if (pkinit_check_dh_params(cryptoctx->dh_1024->p, dh->p,
-			dh->g, dh->q) == 0) {
+		DH_get0_pqg(cryptoctx->dh_1024, &p2, NULL, NULL);
+		if (pkinit_check_dh_params(p2, p, g, q) == 0) {
 		    *new_dh_size = 1024;
 		    ok = 1;
 		}
 		break;
 	    case 2048:
-		if (pkinit_check_dh_params(cryptoctx->dh_2048->p, dh->p,
-			dh->g, dh->q) == 0) {
+		DH_get0_pqg(cryptoctx->dh_2048, &p2, NULL, NULL);
+		if (pkinit_check_dh_params(p2, p, g, q) == 0) {
 		    *new_dh_size = 2048;
 		    ok = 1;
 		}
 		break;
 	    case 4096:
-		if (pkinit_check_dh_params(cryptoctx->dh_4096->p, dh->p,
-			dh->g, dh->q) == 0) {
+		DH_get0_pqg(cryptoctx->dh_4096, &p2, NULL, NULL);
+		if (pkinit_check_dh_params(p2, p, g, q) == 0) {
 		    *new_dh_size = 4096;
 		    ok = 1;
 		}
@@ -3093,7 +3306,7 @@
     return retval;
 }
 
-/* ARGSUSED */ 
+/* ARGSUSED */
 static int
 openssl_callback(int ok, X509_STORE_CTX * ctx)
 {
@@ -3113,14 +3326,8 @@
 static int
 openssl_callback_ignore_crls(int ok, X509_STORE_CTX * ctx)
 {
-    if (!ok) {
-	switch (ctx->error) {
-	    case X509_V_ERR_UNABLE_TO_GET_CRL:
-		return 1;
-	    default:
-		return 0;
-	}
-    }
+    if (!ok)
+	return (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL);
     return ok;
 }
 
@@ -3141,7 +3348,7 @@
 	     * We need this shadow version because our code
 	     * depends on the "other" type to be unknown to the
 	     * OpenSSL code.
-	     */ 
+	     */
 	    if (cryptoctx->id_pkinit_authData9 == NULL) {
 		pkiDebug("%s: Creating shadow instance of pkcs7-data oid\n",
 			 __FUNCTION__);
@@ -3309,34 +3516,31 @@
 		 unsigned char **outdata,
 		 int *outdata_len)
 {
-    /* Solaris Kerberos */
-    ASN1_const_CTX c;
-    long length = indata_len;
-    int Ttag, Tclass;
-    long Tlen;
+    int tag, class;
+    long tlen, slen;
+    const uint8_t *p = indata, *oldp;
 
-    c.pp = (const unsigned char **)&indata;
-    c.q = *(const unsigned char **)&indata;
-    c.error = ERR_R_NESTED_ASN1_ERROR;
-    c.p= *(const unsigned char **)&indata;
-    c.max = (length == 0)?0:(c.p+length);
+    /* Top-bit set means that the conversion failed. */
+    if (ASN1_get_object(&p, &slen, &tag, &class, indata_len) & 0x80)
+        return EINVAL;
+    if (tag != V_ASN1_SEQUENCE)
+        return EINVAL;
 
-    asn1_GetSequence(&c,&length);
+    oldp = p;
+    if (ASN1_get_object(&p, &tlen, &tag, &class, slen) & 0x80)
+        return EINVAL;
+    p += tlen;
+    slen -= (p - oldp);
 
-    ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen);
-    c.p += Tlen;
-    ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen);
+    if (ASN1_get_object(&p, &tlen, &tag, &class, slen) & 0x80)
+        return EINVAL;
 
-    asn1_const_Finish(&c);
+    *outdata = malloc(tlen);
+    if (*outdata == NULL)
+        return ENOMEM;
+    memcpy(*outdata, p, tlen);
+    *outdata_len = tlen;
 
-    *outdata = (unsigned char *)malloc((size_t)Tlen);
-    /* Solaris Kerberos */
-    if (outdata == NULL)
-	return ENOMEM;
-    
-    (void) memcpy(*outdata, c.p, (size_t)Tlen);
-    *outdata_len = Tlen;
-
     return 0;
 }
 
@@ -3901,7 +4105,7 @@
 
     if (cert_id)
         free(cert_id);
-    
+
     return (r);
 }
 
@@ -3965,7 +4169,7 @@
      * If C_Initialize was already called by the process before the pkinit
      * module was loaded then record that fact.
      * "finalize_pkcs11" is used by pkinit_fini_pkcs11 to determine whether
-     * or not C_Finalize() should be called. 
+     * or not C_Finalize() should be called.
      */
      cctx->finalize_pkcs11 =
 	(r == CKR_CRYPTOKI_ALREADY_INITIALIZED ? FALSE : TRUE);
@@ -4023,7 +4227,7 @@
 	    goto out;
 	}
     }
-    
+
 tryagain:
     /* get count of slots that have tokens */
     if ((r = cctx->p11->C_GetSlotList(TRUE, NULL, &count)) != CKR_OK) {
@@ -4065,7 +4269,7 @@
 
     if (slotlist != NULL)
 	free(slotlist);
- 
+
     slotlist = malloc(count * sizeof (CK_SLOT_ID));
     if (slotlist == NULL) {
 	krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
@@ -4368,6 +4572,7 @@
     CK_ATTRIBUTE attrs[4];
     CK_ULONG count;
     CK_KEY_TYPE keytype;
+    RSA *rsa;
     unsigned int nattrs = 0;
     int r;
 #ifdef PKINIT_USE_KEY_USAGE
@@ -4428,6 +4633,7 @@
 
 	EVP_PKEY *priv;
 	X509 *cert;
+	const BIGNUM *rsan;
 	unsigned int n_len;
 	unsigned char *n_bytes;
 
@@ -4459,20 +4665,28 @@
 	attrs[nattrs].ulValueLen = sizeof keytype;
 	nattrs++;
 
-	n_len = BN_num_bytes(priv->pkey.rsa->n);
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+	rsa = priv->pkey.rsa;
+	rsan = rsa->n;
+	n_len = BN_num_bytes(rsan);
+#else
+	rsa = EVP_PKEY_get0_RSA(priv);
+	RSA_get0_key(rsa, &rsan, NULL, NULL);
+	n_len = RSA_size(rsa);
+#endif
 	n_bytes = (unsigned char *) malloc((size_t) n_len);
 	if (n_bytes == NULL) {
 		return (ENOMEM);
 	}
 
-	if (BN_bn2bin(priv->pkey.rsa->n, n_bytes) == 0) {
+	if (BN_bn2bin(rsan, n_bytes) == 0) {
 		free (n_bytes);
-    		pkiDebug("zero-byte key modulus\n");
+		pkiDebug("zero-byte key modulus\n");
 		return KRB5KDC_ERR_PREAUTH_FAILED;
 	}
 
 	attrs[nattrs].type = CKA_MODULUS;
-	attrs[nattrs].ulValueLen = n_len; 
+	attrs[nattrs].ulValueLen = n_len;
 	attrs[nattrs].pValue = n_bytes;
 
 	nattrs++;
@@ -4774,11 +4988,7 @@
     if (buf == NULL)
 	return ENOMEM;
 
-#if OPENSSL_VERSION_NUMBER < 0x10000000L
-    len = EVP_PKEY_decrypt(buf, data, (int)data_len, pkey);
-#else
     len = EVP_PKEY_decrypt_old(buf, data, (int)data_len, pkey);
-#endif
     if (len <= 0) {
 	pkiDebug("unable to decrypt received data (len=%d)\n", data_len);
 	/* Solaris Kerberos */
@@ -4796,23 +5006,26 @@
 		 unsigned char *data, unsigned int data_len, EVP_PKEY *pkey)
 {
     krb5_error_code retval = ENOMEM;
-    EVP_MD_CTX md_ctx;
+    EVP_MD_CTX *md_ctx;
 
     if (pkey == NULL)
 	/* Solaris Kerberos */
 	return EINVAL;
 
-    EVP_VerifyInit(&md_ctx, EVP_sha1());
-    EVP_SignUpdate(&md_ctx, data, data_len);
+    if ((md_ctx = EVP_MD_CTX_new()) == NULL)
+	return EINVAL;
+
+    EVP_VerifyInit(md_ctx, EVP_sha1());
+    EVP_SignUpdate(md_ctx, data, data_len);
     *sig_len = EVP_PKEY_size(pkey);
     if ((*sig = (unsigned char *) malloc((size_t) *sig_len)) == NULL)
 	goto cleanup;
-    EVP_SignFinal(&md_ctx, *sig, sig_len, pkey);
+    EVP_SignFinal(md_ctx, *sig, sig_len, pkey);
 
     retval = 0;
 
   cleanup:
-    EVP_MD_CTX_cleanup(&md_ctx);
+    EVP_MD_CTX_free(md_ctx);
 
     return retval;
 }
@@ -5153,7 +5366,7 @@
     retval = 0;
 
   cleanup:
-    if (d) 
+    if (d)
 	(void) closedir(d);
 
     return retval;
@@ -5450,7 +5663,7 @@
 
     if (id_cryptoctx->creds[id->index] == NULL)
 	return PKINIT_ITER_NO_MORE;
-    
+
     cd = calloc(1, sizeof(*cd));
     if (cd == NULL)
 	return ENOMEM;
@@ -5506,7 +5719,7 @@
 	pkiDebug("%s: EKUs not requested, not checking\n", __FUNCTION__);
 	goto check_kus;
     }
-    
+
     /* Start with Extended Key usage */
     i = X509_get_ext_by_NID(x, NID_ext_key_usage, -1);
     if (i >= 0) {
@@ -5727,8 +5940,8 @@
     cd = (struct _pkinit_cert_data *)md->ch;
     if (cd == NULL || cd->magic != CERT_MAGIC)
 	return EINVAL;
-    
-    /* copy the selected cert into our id_cryptoctx */ 
+
+    /* copy the selected cert into our id_cryptoctx */
     if (cd->idctx->my_certs != NULL) {
 	sk_X509_pop_free(cd->idctx->my_certs, X509_free);
     }
@@ -5740,7 +5953,7 @@
     if (cd->idctx->pkcs11_method != 1) {
 	cd->idctx->my_key = cd->cred->key;
 	cd->idctx->creds[cd->index]->key = NULL;    /* Don't free it twice */
-    } 
+    }
 #ifndef WITHOUT_PKCS11
     else {
 	cd->idctx->cert_id = cd->cred->cert_id;
@@ -5782,7 +5995,7 @@
 		 __FUNCTION__, cert_count);
 	goto errout;
     }
-    /* copy the selected cert into our id_cryptoctx */ 
+    /* copy the selected cert into our id_cryptoctx */
     if (id_cryptoctx->my_certs != NULL) {
 	sk_X509_pop_free(id_cryptoctx->my_certs, X509_free);
     }
@@ -5794,7 +6007,7 @@
     if (id_cryptoctx->pkcs11_method != 1) {
 	id_cryptoctx->my_key = id_cryptoctx->creds[0]->key;
 	id_cryptoctx->creds[0]->key = NULL;	/* Don't free it twice */
-    } 
+    }
 #ifndef WITHOUT_PKCS11
     else {
 	id_cryptoctx->cert_id = id_cryptoctx->creds[0]->cert_id;
@@ -5878,7 +6091,7 @@
      */
     for (i = 0; i < sk_X509_INFO_num(sk); i++) {
 	X509_INFO *xi = sk_X509_INFO_value(sk, i);
-	if (xi != NULL && xi->x509 != NULL && catype != CATYPE_CRLS) { 
+	if (xi != NULL && xi->x509 != NULL && catype != CATYPE_CRLS) {
 	    int j = 0, size = sk_X509_num(ca_certs), flag = 0;
 
 	    if (!size) {
@@ -5891,7 +6104,7 @@
 		flag = X509_cmp(x, xi->x509);
 		if (flag == 0)
 		    break;
-		else 
+		else
 		    continue;
 	    }
 	    if (flag != 0) {
@@ -5925,7 +6138,7 @@
     case CATYPE_ANCHORS:
 	if (sk_X509_num(ca_certs) == 0) {
 	    pkiDebug("no anchors in file, %s\n", filename);
-	    if (id_cryptoctx->trustedCAs == NULL) 
+	    if (id_cryptoctx->trustedCAs == NULL)
 		sk_X509_free(ca_certs);
 	} else {
 	    if (id_cryptoctx->trustedCAs == NULL)
@@ -5935,7 +6148,7 @@
     case CATYPE_INTERMEDIATES:
 	if (sk_X509_num(ca_certs) == 0) {
 	    pkiDebug("no intermediates in file, %s\n", filename);
-	    if (id_cryptoctx->intermediateCAs == NULL) 
+	    if (id_cryptoctx->intermediateCAs == NULL)
 		sk_X509_free(ca_certs);
 	} else {
 	    if (id_cryptoctx->intermediateCAs == NULL)
@@ -5976,7 +6189,7 @@
 		      pkinit_req_crypto_context req_cryptoctx,
 		      pkinit_identity_crypto_context id_cryptoctx,
 		      int catype,
-		      char *dirname) 
+		      char *dirname)
 {
     krb5_error_code retval = EINVAL;
     DIR *d = NULL;
@@ -5987,7 +6200,7 @@
 	return EINVAL;
 
     d = opendir(dirname);
-    if (d == NULL) 
+    if (d == NULL)
 	return ENOENT;
 
     while ((dentry = readdir(d))) {
@@ -6014,7 +6227,7 @@
     retval = 0;
 
   cleanup:
-    if (d != NULL) 
+    if (d != NULL)
 	(void) closedir(d);
 
     return retval;
@@ -6029,7 +6242,7 @@
 			 pkinit_identity_crypto_context id_cryptoctx,
 			 int idtype,
 			 int catype,
-			 char *id) 
+			 char *id)
 {
     pkiDebug("%s: called with idtype %s and catype %s\n",
 	     __FUNCTION__, idtype2string(idtype), catype2string(catype));
@@ -6098,8 +6311,8 @@
 #endif
 	is = PKCS7_ISSUER_AND_SERIAL_new();
 	X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
-	M_ASN1_INTEGER_free(is->serial);
-	is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x));
+	ASN1_INTEGER_free(is->serial);
+	is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(x));
 	len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
 	if ((p = krb5_cas[i]->issuerAndSerialNumber.data =
 	     (unsigned char *)malloc((size_t) len)) == NULL)
@@ -6173,7 +6386,7 @@
 	return KRB5KDC_ERR_PREAUTH_FAILED;
 
     sk = sk_X509_new_null();
-    if (sk == NULL) 
+    if (sk == NULL)
 	goto cleanup;
     sk_X509_push(sk, req_cryptoctx->received_cert);
 
@@ -6241,7 +6454,7 @@
 	return KRB5KDC_ERR_PREAUTH_FAILED;
 
     return create_identifiers_from_stack(sk, ids);
-    
+
 }
 
 /* ARGSUSED */
@@ -6303,8 +6516,8 @@
 		krb5_cas[i]->u.issuerAndSerial.length = 0;
 		is = PKCS7_ISSUER_AND_SERIAL_new();
 		X509_NAME_set(&is->issuer, X509_get_issuer_name(x));
-		M_ASN1_INTEGER_free(is->serial);
-		is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(x));
+		ASN1_INTEGER_free(is->serial);
+		is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(x));
 		len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
 		if ((p = krb5_cas[i]->u.issuerAndSerial.data =
 		    (unsigned char *)malloc((size_t) len)) == NULL)
@@ -6353,8 +6566,8 @@
 
     is = PKCS7_ISSUER_AND_SERIAL_new();
     X509_NAME_set(&is->issuer, X509_get_issuer_name(cert));
-    M_ASN1_INTEGER_free(is->serial);
-    is->serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
+    ASN1_INTEGER_free(is->serial);
+    is->serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert));
     len = i2d_PKCS7_ISSUER_AND_SERIAL(is, NULL);
     if ((p = *out = (unsigned char *)malloc((size_t) len)) == NULL)
 	goto cleanup;
@@ -6404,7 +6617,7 @@
     }
 #pragma error_messages (default, E_END_OF_LOOP_CODE_NOT_REACHED)
 
-    return 0; 
+    return 0;
 }
 
 krb5_error_code
@@ -6539,9 +6752,9 @@
 	    int tmp_ret = 0;
 	    ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
 	    tmp_ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
-				    cert->cert_info->issuer);
+		X509_get_issuer_name(cert));
 	    if (!tmp_ret) {
-		tmp_ret = M_ASN1_INTEGER_cmp(cert->cert_info->serialNumber,
+		tmp_ret = ASN1_INTEGER_cmp(X509_get_serialNumber(cert),
 					     ri->issuer_and_serial->serial);
 		if (!tmp_ret)
 		    break;
@@ -6562,8 +6775,8 @@
 	for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) {
 	    ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
 	    jj = pkinit_decode_data(context, id_cryptoctx,
-		M_ASN1_STRING_data(ri->enc_key),
-		(unsigned int) M_ASN1_STRING_length(ri->enc_key),
+		(unsigned char *)ASN1_STRING_get0_data(ri->enc_key),
+		ASN1_STRING_length(ri->enc_key),
 		&tmp, &tmp_len);
 	    if (jj) {
 		PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB);
@@ -6580,14 +6793,14 @@
 	}
 
 	if (ri == NULL) {
-	    PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_KEY);
+	    PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
 	    goto cleanup;
 	}
     }
     else {
 	jj = pkinit_decode_data(context, id_cryptoctx,
-	    M_ASN1_STRING_data(ri->enc_key),
-	    (unsigned int) M_ASN1_STRING_length(ri->enc_key),
+	    (unsigned char *)ASN1_STRING_get0_data(ri->enc_key),
+	    ASN1_STRING_length(ri->enc_key),
 	    &tmp, &tmp_len);
 	/* Solaris Kerberos: tmp_len is unsigned. Cannot be < 0 */
 	if (jj || tmp_len == 0) {
@@ -6611,7 +6824,7 @@
 	 */
 	if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, (int)jj)) {
 	    PKCS7err(PKCS7_F_PKCS7_DATADECODE,
-		     PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
+		     PKCS7_R_DECRYPT_ERROR);
 	    goto cleanup;
 	}
     }
--- old/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h	Mon Apr 30 13:30:22 2018
+++ new/usr/src/lib/krb5/plugins/preauth/pkinit/pkinit_crypto_openssl.h	Mon Apr 30 13:30:22 2018
@@ -30,6 +30,7 @@
 
 /*
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  */
 
 #ifndef _PKINIT_CRYPTO_OPENSSL_H
@@ -44,11 +45,17 @@
 #include <openssl/x509v3.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
-#include <openssl/asn1_mac.h>
 #include <openssl/sha.h>
 #include <openssl/asn1.h>
 #include <openssl/pem.h>
+#include <openssl/rsa.h>
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#include <openssl/asn1_mac.h>
+#else
+#include <openssl/asn1t.h>
+#endif
+
 #include "pkinit.h"
 
 #define DN_BUF_LEN  256
@@ -162,11 +169,13 @@
 static void pkinit_fini_pkcs11(pkinit_identity_crypto_context ctx);
 
 static krb5_error_code pkinit_encode_dh_params
-	(BIGNUM *, BIGNUM *, BIGNUM *, unsigned char **, unsigned int *);
+	(const BIGNUM *, const BIGNUM *, const BIGNUM *,
+		unsigned char **, unsigned int *);
 static DH *pkinit_decode_dh_params
 	(DH **, unsigned char **, unsigned int );
 static int pkinit_check_dh_params
-	(BIGNUM * p1, BIGNUM * p2, BIGNUM * g1, BIGNUM * q1);
+	(const BIGNUM *p1, const BIGNUM *p2, const BIGNUM *g1,
+		const BIGNUM *q1);
 
 static krb5_error_code pkinit_sign_data
 	(krb5_context context, pkinit_identity_crypto_context cryptoctx,
@@ -275,8 +284,15 @@
 #endif
 
 /* This handy macro borrowed from crypto/x509v3/v3_purp.c */
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 #define ku_reject(x, usage) \
 	(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
+#else
+#define ku_reject(x, usage) \
+	((X509_get_extension_flags(x) & EXFLAG_KUSAGE) && \
+	!(X509_get_key_usage(x) & (usage)))
+#endif
 
 static char *
 pkinit_pkcs11_code_to_text(int err);
--- old/usr/src/lib/libkmf/plugins/kmf_openssl/Makefile.com	Mon Apr 30 13:30:23 2018
+++ new/usr/src/lib/libkmf/plugins/kmf_openssl/Makefile.com	Mon Apr 30 13:30:23 2018
@@ -27,7 +27,7 @@
 LIBRARY=	kmf_openssl.a
 VERS=		.1
 
-OBJECTS=	openssl_spi.o
+OBJECTS=	openssl_spi.o compat.o
 
 include	$(SRC)/lib/Makefile.lib
 
--- old/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c	Mon Apr 30 13:30:23 2018
+++ new/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c	Mon Apr 30 13:30:23 2018
@@ -5,6 +5,7 @@
  */
 /*
  * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
+ * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  */
 /*
  * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
@@ -80,7 +81,6 @@
 #include <openssl/bn.h>
 #include <openssl/asn1.h>
 #include <openssl/err.h>
-#include <openssl/bn.h>
 #include <openssl/x509.h>
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
@@ -91,6 +91,7 @@
 #include <openssl/ocsp.h>
 #include <openssl/des.h>
 #include <openssl/rand.h>
+#include "compat.h"
 
 #define	PRINT_ANY_EXTENSION (\
 	KMF_X509_EXT_KEY_USAGE |\
@@ -137,6 +138,7 @@
 /*
  * Declare some new macros for managing stacks of EVP_PKEYS.
  */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 DECLARE_STACK_OF(EVP_PKEY)
 
 #define	sk_EVP_PKEY_new_null() SKM_sk_new_null(EVP_PKEY)
@@ -147,6 +149,11 @@
 #define	sk_EVP_PKEY_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY, (st), \
 	(free_func))
 
+#else
+/* LINTED E_STATIC_UNUSED */
+DEFINE_STACK_OF(EVP_PKEY)
+#endif
+
 mutex_t init_lock = DEFAULTMUTEX;
 static int ssl_initialized = 0;
 static BIO *bio_err = NULL;
@@ -293,6 +300,7 @@
 	NULL	/* Finalize */
 };
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 static mutex_t *lock_cs;
 static long *lock_count;
 
@@ -313,11 +321,14 @@
 {
 	return ((unsigned long)thr_self());
 }
+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
 
 KMF_PLUGIN_FUNCLIST *
 KMF_Plugin_Initialize()
 {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 	int i;
+#endif
 
 	(void) mutex_lock(&init_lock);
 	if (!ssl_initialized) {
@@ -335,8 +346,11 @@
 		    "X509v3 Freshest CRL");
 		(void) OBJ_create("2.5.29.54", "inhibitAnyPolicy",
 		    "X509v3 Inhibit Any-Policy");
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 		/*
 		 * Set up for thread-safe operation.
+		 * This is not required for OpenSSL 1.1
 		 */
 		lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t));
 		if (lock_cs == NULL) {
@@ -360,10 +374,11 @@
 		if (CRYPTO_get_locking_callback() == NULL)
 			CRYPTO_set_locking_callback((void (*)())locking_cb);
 
-		OpenSSL_add_all_algorithms();
+		(void) OpenSSL_add_all_algorithms();
 
 		/* Enable error strings for reporting */
-		ERR_load_crypto_strings();
+		(void) ERR_load_crypto_strings();
+#endif
 
 		ssl_initialized = 1;
 	}
@@ -371,6 +386,7 @@
 
 	return (&openssl_plugin_table);
 }
+
 /*
  * Convert an SSL DN to a KMF DN.
  */
@@ -485,7 +501,7 @@
 		if (rv != KMF_OK)
 			return (KMF_ERR_BAD_PARAMETER);
 
-		rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN);
+		rv = get_x509_dn(X509_get_issuer_name(xcert), &certIssuerDN);
 		if (rv != KMF_OK) {
 			kmf_free_dn(&issuerDN);
 			return (KMF_ERR_BAD_PARAMETER);
@@ -500,7 +516,7 @@
 			goto cleanup;
 		}
 
-		rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN);
+		rv = get_x509_dn(X509_get_subject_name(xcert), &certSubjectDN);
 		if (rv != KMF_OK) {
 			rv = KMF_ERR_BAD_PARAMETER;
 			goto cleanup;
@@ -514,7 +530,7 @@
 		BIGNUM *bn;
 
 		/* Comparing BIGNUMs is a pain! */
-		bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL);
+		bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(xcert), NULL);
 		if (bn != NULL) {
 			int bnlen = BN_num_bytes(bn);
 
@@ -1420,17 +1436,13 @@
 		case KMF_FORMAT_RAWKEY:
 			/* same as ASN.1 */
 		case KMF_FORMAT_ASN1:
-			if (pkey->type == EVP_PKEY_RSA) {
-				rsa = EVP_PKEY_get1_RSA(pkey);
+			if ((rsa = EVP_PKEY_get0_RSA(pkey)) != NULL) {
 				if (private)
 					rv = i2d_RSAPrivateKey_bio(out, rsa);
 				else
 					rv = i2d_RSAPublicKey_bio(out, rsa);
-				RSA_free(rsa);
-			} else if (pkey->type == EVP_PKEY_DSA) {
-				dsa = EVP_PKEY_get1_DSA(pkey);
+			} else if ((dsa = EVP_PKEY_get0_DSA(pkey)) != NULL) {
 				rv = i2d_DSAPrivateKey_bio(out, dsa);
-				DSA_free(dsa);
 			}
 			if (rv == 1) {
 				rv = KMF_OK;
@@ -1439,8 +1451,7 @@
 			}
 			break;
 		case KMF_FORMAT_PEM:
-			if (pkey->type == EVP_PKEY_RSA) {
-				rsa = EVP_PKEY_get1_RSA(pkey);
+			if ((rsa = EVP_PKEY_get0_RSA(pkey)) != NULL) {
 				if (private)
 					rv = PEM_write_bio_RSAPrivateKey(out,
 					    rsa, NULL, NULL, 0, NULL,
@@ -1448,13 +1459,10 @@
 				else
 					rv = PEM_write_bio_RSAPublicKey(out,
 					    rsa);
-				RSA_free(rsa);
-			} else if (pkey->type == EVP_PKEY_DSA) {
-				dsa = EVP_PKEY_get1_DSA(pkey);
+			} else if ((dsa = EVP_PKEY_get0_DSA(pkey)) != NULL) {
 				rv = PEM_write_bio_DSAPrivateKey(out,
 				    dsa, NULL, NULL, 0, NULL,
 				    (cred != NULL ? cred->cred : NULL));
-				DSA_free(dsa);
 			}
 
 			if (rv == 1) {
@@ -1477,7 +1485,8 @@
 {
 	KMF_RETURN rv = KMF_OK;
 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
-	uint32_t eValue = 0x010001;
+	uint32_t eValue = RSA_F4;
+	BIGNUM *eValue_bn = NULL;
 	RSA *sslPrivKey = NULL;
 	DSA *sslDSAKey = NULL;
 	EVP_PKEY *eprikey = NULL;
@@ -1489,6 +1498,14 @@
 	boolean_t storekey = TRUE;
 	KMF_KEY_ALG keytype = KMF_RSA;
 
+	eValue_bn = BN_new();
+	if (eValue_bn == NULL)
+		return (KMF_ERR_MEMORY);
+	if (BN_set_word(eValue_bn, eValue) == 0) {
+		rv = KMF_ERR_KEYGEN_FAILED;
+		goto cleanup;
+	}
+
 	rv = kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr,
 	    &storekey, NULL);
 	if (rv != KMF_OK) {
@@ -1503,12 +1520,16 @@
 		rv = KMF_OK;
 
 	pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
-	if (pubkey == NULL)
-		return (KMF_ERR_BAD_PARAMETER);
+	if (pubkey == NULL) {
+		rv = KMF_ERR_BAD_PARAMETER;
+		goto cleanup;
+	}
 
 	privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
-	if (privkey == NULL)
-		return (KMF_ERR_BAD_PARAMETER);
+	if (privkey == NULL) {
+		rv = KMF_ERR_BAD_PARAMETER;
+		goto cleanup;
+	}
 
 	(void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
 	(void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
@@ -1535,6 +1556,10 @@
 			    rsaexp->val != NULL) {
 				/* LINTED E_BAD_PTR_CAST_ALIGN */
 				eValue = *(uint32_t *)rsaexp->val;
+				if (BN_set_word(eValue_bn, eValue) == 0) {
+					rv = KMF_ERR_BAD_PARAMETER;
+					goto cleanup;
+				}
 			} else {
 				rv = KMF_ERR_BAD_PARAMETER;
 				goto cleanup;
@@ -1554,8 +1579,10 @@
 			goto cleanup;
 		}
 
-		sslPrivKey = RSA_generate_key(keylen, eValue, NULL, NULL);
-		if (sslPrivKey == NULL) {
+		sslPrivKey = RSA_new();
+		if (sslPrivKey == NULL ||
+		    RSA_generate_key_ex(sslPrivKey, keylen, eValue_bn, NULL)
+		    == 0) {
 			SET_ERROR(kmfh, ERR_get_error());
 			rv = KMF_ERR_KEYGEN_FAILED;
 		} else {
@@ -1575,7 +1602,8 @@
 			pubkey->keyp = (void *)epubkey;
 		}
 	} else if (keytype == KMF_DSA) {
-		DSA *dp;
+		BIGNUM *p, *q, *g;
+
 		sslDSAKey = DSA_new();
 		if (sslDSAKey == NULL) {
 			SET_ERROR(kmfh, ERR_get_error());
@@ -1582,24 +1610,23 @@
 			return (KMF_ERR_MEMORY);
 		}
 
-		if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) ==
-		    NULL) {
+		p = BN_bin2bn(P, sizeof (P), NULL);
+		q = BN_bin2bn(Q, sizeof (Q), NULL);
+		g = BN_bin2bn(G, sizeof (G), NULL);
+		if (p == NULL || q == NULL || g == NULL) {
+			BN_free(p);
+			BN_free(q);
+			BN_free(g);
 			SET_ERROR(kmfh, ERR_get_error());
 			rv = KMF_ERR_KEYGEN_FAILED;
 			goto cleanup;
 		}
-		if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) ==
-		    NULL) {
+
+		if (DSA_set0_pqg(sslDSAKey, p, q, g) == 0) {
 			SET_ERROR(kmfh, ERR_get_error());
 			rv = KMF_ERR_KEYGEN_FAILED;
 			goto cleanup;
 		}
-		if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) ==
-		    NULL) {
-			SET_ERROR(kmfh, ERR_get_error());
-			rv = KMF_ERR_KEYGEN_FAILED;
-			goto cleanup;
-		}
 
 		if (!DSA_generate_key(sslDSAKey)) {
 			SET_ERROR(kmfh, ERR_get_error());
@@ -1618,56 +1645,18 @@
 			rv = KMF_ERR_KEYGEN_FAILED;
 			goto cleanup;
 		}
-		dp = DSA_new();
-		/* Make a copy for the public key */
-		if (dp != NULL) {
-			if ((dp->p = BN_new()) == NULL) {
-				SET_ERROR(kmfh, ERR_get_error());
-				rv = KMF_ERR_MEMORY;
-				DSA_free(dp);
-				goto cleanup;
-			}
-			if ((dp->q = BN_new()) == NULL) {
-				SET_ERROR(kmfh, ERR_get_error());
-				rv = KMF_ERR_MEMORY;
-				BN_free(dp->p);
-				DSA_free(dp);
-				goto cleanup;
-			}
-			if ((dp->g = BN_new()) == NULL) {
-				SET_ERROR(kmfh, ERR_get_error());
-				rv = KMF_ERR_MEMORY;
-				BN_free(dp->q);
-				BN_free(dp->p);
-				DSA_free(dp);
-				goto cleanup;
-			}
-			if ((dp->pub_key = BN_new()) == NULL) {
-				SET_ERROR(kmfh, ERR_get_error());
-				rv = KMF_ERR_MEMORY;
-				BN_free(dp->q);
-				BN_free(dp->p);
-				BN_free(dp->g);
-				DSA_free(dp);
-				goto cleanup;
-			}
-			(void) BN_copy(dp->p, sslDSAKey->p);
-			(void) BN_copy(dp->q, sslDSAKey->q);
-			(void) BN_copy(dp->g, sslDSAKey->g);
-			(void) BN_copy(dp->pub_key, sslDSAKey->pub_key);
 
-			pubkey->kstype = KMF_KEYSTORE_OPENSSL;
-			pubkey->keyalg = KMF_DSA;
-			pubkey->keyclass = KMF_ASYM_PUB;
-			pubkey->israw = FALSE;
+		pubkey->kstype = KMF_KEYSTORE_OPENSSL;
+		pubkey->keyalg = KMF_DSA;
+		pubkey->keyclass = KMF_ASYM_PUB;
+		pubkey->israw = FALSE;
 
-			if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) {
-				pubkey->keyp = (void *)epubkey;
-			} else {
-				SET_ERROR(kmfh, ERR_get_error());
-				rv = KMF_ERR_KEYGEN_FAILED;
-				goto cleanup;
-			}
+		if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) {
+			pubkey->keyp = (void *)epubkey;
+		} else {
+			SET_ERROR(kmfh, ERR_get_error());
+			rv = KMF_ERR_KEYGEN_FAILED;
+			goto cleanup;
 		}
 	}
 
@@ -1719,6 +1708,9 @@
 	}
 
 cleanup:
+	if (eValue_bn != NULL)
+		BN_free(eValue_bn);
+
 	if (rv != KMF_OK) {
 		if (eprikey != NULL)
 			EVP_PKEY_free(eprikey);
@@ -1759,7 +1751,7 @@
  * all of the bits.
  */
 static int
-fixbnlen(BIGNUM *bn, unsigned char *buf, int len) {
+fixbnlen(const BIGNUM *bn, unsigned char *buf, int len) {
 	int bytes = len - BN_num_bytes(bn);
 
 	/* prepend with leading 0x00 if necessary */
@@ -1781,7 +1773,7 @@
 	KMF_RETURN ret = KMF_OK;
 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
 	KMF_ALGORITHM_INDEX		AlgId;
-	EVP_MD_CTX ctx;
+	EVP_MD_CTX *ctx;
 	const EVP_MD *md;
 
 	if (key == NULL || AlgOID == NULL ||
@@ -1826,19 +1818,20 @@
 			}
 			output->Length = len;
 		} else {
-			(void) EVP_MD_CTX_init(&ctx);
-			(void) EVP_SignInit_ex(&ctx, md, NULL);
-			(void) EVP_SignUpdate(&ctx, tobesigned->Data,
+			if ((ctx = EVP_MD_CTX_new()) == NULL)
+				return (KMF_ERR_MEMORY);
+			(void) EVP_SignInit_ex(ctx, md, NULL);
+			(void) EVP_SignUpdate(ctx, tobesigned->Data,
 			    (uint32_t)tobesigned->Length);
 			len = (uint32_t)output->Length;
 			p = output->Data;
-			if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) {
+			if (!EVP_SignFinal(ctx, p, (uint32_t *)&len, pkey)) {
 				SET_ERROR(kmfh, ERR_get_error());
 				len = 0;
 				ret = KMF_ERR_INTERNAL;
 			}
 			output->Length = len;
-			(void) EVP_MD_CTX_cleanup(&ctx);
+			EVP_MD_CTX_free(ctx);
 		}
 	} else if (key->keyalg == KMF_DSA) {
 		DSA *dsa = EVP_PKEY_get1_DSA(key->keyp);
@@ -1863,11 +1856,12 @@
 		 * not all mechanisms return ASN.1 encodings (PKCS#11
 		 * and NSS return raw signature data).
 		 */
-		EVP_MD_CTX_init(&ctx);
-		(void) EVP_DigestInit_ex(&ctx, md, NULL);
-		(void) EVP_DigestUpdate(&ctx, tobesigned->Data,
+		if ((ctx = EVP_MD_CTX_new()) == NULL)
+			return (KMF_ERR_MEMORY);
+		(void) EVP_DigestInit_ex(ctx, md, NULL);
+		(void) EVP_DigestUpdate(ctx, tobesigned->Data,
 		    tobesigned->Length);
-		(void) EVP_DigestFinal_ex(&ctx, hash, &hashlen);
+		(void) EVP_DigestFinal_ex(ctx, hash, &hashlen);
 
 		/* Only sign first 20 bytes for SHA2 */
 		if (AlgId == KMF_ALGID_SHA256WithDSA)
@@ -1875,10 +1869,13 @@
 		dsasig = DSA_do_sign(hash, hashlen, dsa);
 		if (dsasig != NULL) {
 			int i;
-			output->Length = i = fixbnlen(dsasig->r, output->Data,
+			const BIGNUM *r, *s;
+
+			DSA_SIG_get0(dsasig, &r, &s);
+			output->Length = i = fixbnlen(r, output->Data,
 			    hashlen);
 
-			output->Length += fixbnlen(dsasig->s, &output->Data[i],
+			output->Length += fixbnlen(s, &output->Data[i],
 			    hashlen);
 
 			DSA_SIG_free(dsasig);
@@ -1885,7 +1882,7 @@
 		} else {
 			SET_ERROR(kmfh, ERR_get_error());
 		}
-		(void) EVP_MD_CTX_cleanup(&ctx);
+		EVP_MD_CTX_free(ctx);
 	} else {
 		return (KMF_ERR_BAD_PARAMETER);
 	}
@@ -2023,17 +2020,11 @@
 	X509 *xcert = NULL;
 	unsigned char *outbuf = NULL;
 	unsigned char *outbuf_p;
-	char *tmpstr = NULL;
 	int j;
 	int ext_index, nid, len;
 	BIO *mem = NULL;
-#if OPENSSL_VERSION_NUMBER < 0x10000000L
-	STACK *emlst = NULL;
-#else
 	STACK_OF(OPENSSL_STRING) *emlst = NULL;
-#endif
 	X509_EXTENSION *ex;
-	X509_CINF *ci;
 
 	if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) {
 		return (KMF_ERR_BAD_PARAMETER);
@@ -2075,9 +2066,8 @@
 		break;
 
 	case KMF_CERT_VERSION:
-		tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version);
-		(void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN);
-		OPENSSL_free(tmpstr);
+		(void) snprintf(resultStr, KMF_CERT_PRINTABLE_LEN,
+		    "%ld", X509_get_version(xcert));
 		len = strlen(resultStr);
 		break;
 
@@ -2090,17 +2080,20 @@
 		break;
 
 	case KMF_CERT_NOTBEFORE:
-		(void) ASN1_TIME_print(mem, X509_get_notBefore(xcert));
+		(void) ASN1_TIME_print(mem, X509_getm_notBefore(xcert));
 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
 		break;
 
 	case KMF_CERT_NOTAFTER:
-		(void) ASN1_TIME_print(mem, X509_get_notAfter(xcert));
+		(void) ASN1_TIME_print(mem, X509_getm_notAfter(xcert));
 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
 		break;
 
 	case KMF_CERT_PUBKEY_DATA:
 		{
+			RSA *rsa;
+			DSA *dsa;
+
 			EVP_PKEY *pkey = X509_get_pubkey(xcert);
 			if (pkey == NULL) {
 				SET_ERROR(kmfh, ERR_get_error());
@@ -2108,15 +2101,16 @@
 				goto out;
 			}
 
-			if (pkey->type == EVP_PKEY_RSA) {
+			if ((rsa = EVP_PKEY_get0_RSA(pkey)) != NULL) {
 				(void) BIO_printf(mem,
 				    "RSA Public Key: (%d bit)\n",
-				    BN_num_bits(pkey->pkey.rsa->n));
-				(void) RSA_print(mem, pkey->pkey.rsa, 0);
-			} else if (pkey->type == EVP_PKEY_DSA) {
+				    RSA_bits(rsa));
+				(void) RSA_print(mem, rsa, 0);
+
+			} else if ((dsa = EVP_PKEY_get0_DSA(pkey)) != NULL) {
 				(void) BIO_printf(mem,
 				    "%12sDSA Public Key:\n", "");
-				(void) DSA_print(mem, pkey->pkey.dsa, 0);
+				(void) DSA_print(mem, dsa, 0);
 			} else {
 				(void) BIO_printf(mem,
 				    "%12sUnknown Public Key:\n", "");
@@ -2128,30 +2122,50 @@
 		break;
 	case KMF_CERT_SIGNATURE_ALG:
 	case KMF_CERT_PUBKEY_ALG:
-		if (flag == KMF_CERT_SIGNATURE_ALG) {
-			len = i2a_ASN1_OBJECT(mem,
-			    xcert->sig_alg->algorithm);
-		} else {
-			len = i2a_ASN1_OBJECT(mem,
-			    xcert->cert_info->key->algor->algorithm);
-		}
+		{
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+			ASN1_OBJECT *alg = NULL;
+#else
+			const ASN1_OBJECT *alg = NULL;
+#endif
 
-		if (len > 0) {
-			len = BIO_read(mem, resultStr,
-			    KMF_CERT_PRINTABLE_LEN);
+			if (flag == KMF_CERT_SIGNATURE_ALG) {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+				alg = xcert->sig_alg->algorithm;
+#else
+				const X509_ALGOR *sig_alg = NULL;
+
+				X509_get0_signature(NULL, &sig_alg, xcert);
+				if (sig_alg != NULL)
+					X509_ALGOR_get0(&alg, NULL, NULL,
+					    sig_alg);
+#endif
+			} else {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+				alg = xcert->cert_info->key->algor->algorithm;
+#else
+				X509_PUBKEY *key = X509_get_X509_PUBKEY(xcert);
+
+				if (key != NULL)
+					(void) X509_PUBKEY_get0_param(
+					    (ASN1_OBJECT **)&alg, NULL, 0,
+					    NULL, key);
+#endif
+			}
+
+			if (alg == NULL)
+				len = -1;
+			else if ((len = i2a_ASN1_OBJECT(mem, alg)) > 0)
+				len = BIO_read(mem, resultStr,
+				    KMF_CERT_PRINTABLE_LEN);
 		}
 		break;
 
 	case KMF_CERT_EMAIL:
 		emlst = X509_get1_email(xcert);
-#if OPENSSL_VERSION_NUMBER < 0x10000000L
-		for (j = 0; j < sk_num(emlst); j++)
-			(void) BIO_printf(mem, "%s\n", sk_value(emlst, j));
-#else
 		for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
 			(void) BIO_printf(mem, "%s\n",
 			    sk_OPENSSL_STRING_value(emlst, j));
-#endif
 
 		len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
 		X509_email_free(emlst);
@@ -2176,9 +2190,8 @@
 			ret = KMF_ERR_EXTENSION_NOT_FOUND;
 			goto out;
 		}
-		ci = xcert->cert_info;
 
-		ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1);
+		ext_index = X509_get_ext_by_NID(xcert, nid, -1);
 		if (ext_index == -1) {
 			SET_ERROR(kmfh, ERR_get_error());
 
@@ -2185,7 +2198,7 @@
 			ret = KMF_ERR_EXTENSION_NOT_FOUND;
 			goto out;
 		}
-		ex = X509v3_get_ext(ci->extensions, ext_index);
+		ex = X509_get_ext(xcert, ext_index);
 
 		(void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex));
 
@@ -2197,7 +2210,8 @@
 		}
 		if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) {
 			(void) BIO_printf(mem, "%*s", 4, "");
-			(void) M_ASN1_OCTET_STRING_print(mem, ex->value);
+			(void) ASN1_STRING_print(mem,
+			    X509_EXTENSION_get_data(ex));
 		}
 		if (BIO_write(mem, "\n", 1) <= 0) {
 			SET_ERROR(kmfh, ERR_get_error());
@@ -2478,22 +2492,36 @@
 }
 
 /* ocsp_find_signer_sk() is copied from openssl source */
-static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
+static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_BASICRESP *bs)
 {
 	int i;
 	unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
+	const ASN1_OCTET_STRING *pid;
 
-	/* Easy if lookup by name */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+	OCSP_RESPID *id = bs->tbsResponseData->responderId;
+
 	if (id->type == V_OCSP_RESPID_NAME)
 		return (X509_find_by_subject(certs, id->value.byName));
 
+	pid = id->value.byKey;
+#else
+	const X509_NAME *pname;
+
+	if (OCSP_resp_get0_id(bs, &pid, &pname) == 0)
+		return (NULL);
+
+	if (pname != NULL)
+		return (X509_find_by_subject(certs, (X509_NAME *)pname));
+#endif
+
 	/* Lookup by key hash */
 
 	/* If key hash isn't SHA1 length then forget it */
-	if (id->value.byKey->length != SHA_DIGEST_LENGTH)
+	if (pid->length != SHA_DIGEST_LENGTH)
 		return (NULL);
 
-	keyhash = id->value.byKey->data;
+	keyhash = pid->data;
 	/* Calculate hash of each key and compare */
 	for (i = 0; i < sk_X509_num(certs); i++) {
 		/* LINTED E_BAD_PTR_CAST_ALIGN */
@@ -2513,13 +2541,14 @@
     X509_STORE *st, unsigned long flags)
 {
 	X509 *signer;
-	OCSP_RESPID *rid = bs->tbsResponseData->responderId;
-	if ((signer = ocsp_find_signer_sk(certs, rid)))	{
+	if ((signer = ocsp_find_signer_sk(certs, bs)))	{
 		*psigner = signer;
 		return (2);
 	}
+
 	if (!(flags & OCSP_NOINTERN) &&
-	    (signer = ocsp_find_signer_sk(bs->certs, rid))) {
+	    (signer = ocsp_find_signer_sk(
+	    (STACK_OF(X509) *)OCSP_resp_get0_certs(bs), bs))) {
 		*psigner = signer;
 		return (1);
 	}
@@ -2542,10 +2571,13 @@
 	STACK_OF(X509) *cert_stack = NULL;
 	X509 *signer = NULL;
 	X509 *issuer = NULL;
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 	EVP_PKEY *skey = NULL;
+#else
+	STACK_OF(X509) *cert_stack2 = NULL;
+#endif
 	unsigned char *ptmp;
 
-
 	if (bs == NULL || issuer_cert == NULL)
 		return (KMF_ERR_BAD_PARAMETER);
 
@@ -2599,6 +2631,7 @@
 	}
 
 	/* Verify the signature of the response */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 	skey = X509_get_pubkey(signer);
 	if (skey == NULL) {
 		ret = KMF_ERR_OCSP_BAD_SIGNER;
@@ -2606,6 +2639,25 @@
 	}
 
 	ret = OCSP_BASICRESP_verify(bs, skey, 0);
+#else
+	/*
+	 * Technique based on
+	 * https://mta.openssl.org/pipermail/openssl-users/
+	 *	2017-October/006814.html
+	 */
+	if ((cert_stack2 = sk_X509_new_null()) == NULL) {
+		ret = KMF_ERR_INTERNAL;
+		goto end;
+	}
+
+	if (sk_X509_push(cert_stack2, signer) == NULL) {
+		ret = KMF_ERR_INTERNAL;
+		goto end;
+	}
+
+	ret = OCSP_basic_verify(bs, cert_stack2, NULL, OCSP_NOVERIFY);
+#endif
+
 	if (ret == 0) {
 		ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE;
 		goto end;
@@ -2620,9 +2672,15 @@
 		X509_free(signer);
 	}
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 	if (skey != NULL) {
 		EVP_PKEY_free(skey);
 	}
+#else
+	if (cert_stack2 != NULL) {
+		sk_X509_free(cert_stack2);
+	}
+#endif
 
 	if (cert_stack != NULL) {
 		sk_X509_free(cert_stack);
@@ -2631,8 +2689,6 @@
 	return (ret);
 }
 
-
-
 KMF_RETURN
 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle,
 	int numattr, KMF_ATTRIBUTE *attrlist)
@@ -2821,9 +2877,9 @@
 			return (KMF_ERR_KEY_NOT_FOUND);
 		}
 		if (key != NULL) {
-			if (pkey->type == EVP_PKEY_RSA)
+			if (EVP_PKEY_get0_RSA(pkey) != NULL)
 				key->keyalg = KMF_RSA;
-			else if (pkey->type == EVP_PKEY_DSA)
+			else if (EVP_PKEY_get0_DSA(pkey) != NULL)
 				key->keyalg = KMF_DSA;
 
 			key->kstype = KMF_KEYSTORE_OPENSSL;
@@ -3020,11 +3076,12 @@
 static int
 add_alias_to_bag(PKCS12_SAFEBAG *bag, X509 *xcert)
 {
-	if (xcert != NULL && xcert->aux != NULL &&
-	    xcert->aux->alias != NULL) {
+	unsigned char *alias;
+	int len;
+
+	if (xcert != NULL && (alias = X509_alias_get0(xcert, &len)) != NULL) {
 		if (PKCS12_add_friendlyname_asc(bag,
-		    (const char *)xcert->aux->alias->data,
-		    xcert->aux->alias->length) == 0)
+		    (const char *)alias, len) == 0)
 			return (0);
 	}
 	return (1);
@@ -3043,7 +3100,7 @@
 		return (NULL);
 
 	/* Convert cert from X509 struct to PKCS#12 bag */
-	bag = PKCS12_x5092certbag(sslcert);
+	bag = PKCS12_SAFEBAG_create_cert(sslcert);
 	if (bag == NULL) {
 		goto out;
 	}
@@ -3088,7 +3145,7 @@
 		return (NULL);
 	}
 	/* Put the shrouded key into a PKCS#12 bag. */
-	bag = PKCS12_MAKE_SHKEYBAG(
+	bag = PKCS12_SAFEBAG_create_pkcs8_encrypt(
 	    NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
 	    cred->cred, cred->credlen,
 	    NULL, 0, PKCS12_DEFAULT_ITER, p8);
@@ -3127,55 +3184,71 @@
 ImportRawRSAKey(KMF_RAW_RSA_KEY *key)
 {
 	RSA		*rsa = NULL;
-	EVP_PKEY 	*newkey = NULL;
+	EVP_PKEY	*newkey = NULL;
+	BIGNUM		*n = NULL, *e = NULL, *d = NULL,
+			*p = NULL, *q = NULL,
+			*dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
 
 	if ((rsa = RSA_new()) == NULL)
-		return (NULL);
+		goto cleanup;
 
-	if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL)
-		return (NULL);
+	if ((n = BN_bin2bn(key->mod.val, key->mod.len, NULL)) == NULL)
+		goto cleanup;
 
-	if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) ==
-	    NULL)
-		return (NULL);
+	if ((e = BN_bin2bn(key->pubexp.val, key->pubexp.len, NULL)) == NULL)
+		goto cleanup;
 
-	if (key->priexp.val != NULL)
-		if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len,
-		    rsa->d)) == NULL)
-			return (NULL);
+	if (key->priexp.val != NULL &&
+	    (d = BN_bin2bn(key->priexp.val, key->priexp.len, NULL)) == NULL)
+		goto cleanup;
 
-	if (key->prime1.val != NULL)
-		if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len,
-		    rsa->p)) == NULL)
-			return (NULL);
+	if (key->prime1.val != NULL &&
+	    (p = BN_bin2bn(key->prime1.val, key->prime1.len, NULL)) == NULL)
+		goto cleanup;
 
-	if (key->prime2.val != NULL)
-		if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len,
-		    rsa->q)) == NULL)
-			return (NULL);
+	if (key->prime2.val != NULL &&
+	    (q = BN_bin2bn(key->prime2.val, key->prime2.len, NULL)) == NULL)
+		goto cleanup;
 
-	if (key->exp1.val != NULL)
-		if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len,
-		    rsa->dmp1)) == NULL)
-			return (NULL);
+	if (key->exp1.val != NULL &&
+	    (dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len, NULL)) == NULL)
+		goto cleanup;
 
-	if (key->exp2.val != NULL)
-		if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len,
-		    rsa->dmq1)) == NULL)
-			return (NULL);
+	if (key->exp2.val != NULL &&
+	    (dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len, NULL)) == NULL)
+		goto cleanup;
 
-	if (key->coef.val != NULL)
-		if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len,
-		    rsa->iqmp)) == NULL)
-			return (NULL);
+	if (key->coef.val != NULL &&
+	    (iqmp = BN_bin2bn(key->coef.val, key->coef.len, NULL)) == NULL)
+		goto cleanup;
 
+	if (RSA_set0_key(rsa, n, e, d) == 0)
+		goto cleanup;
+	n = e = d = NULL;
+	if (RSA_set0_factors(rsa, p, q) == 0)
+		goto cleanup;
+	p = q = NULL;
+	if (RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) == 0)
+		goto cleanup;
+	dmp1 = dmq1 = iqmp = NULL;
+
 	if ((newkey = EVP_PKEY_new()) == NULL)
-		return (NULL);
+		goto cleanup;
 
 	(void) EVP_PKEY_set1_RSA(newkey, rsa);
 
+cleanup:
 	/* The original key must be freed once here or it leaks memory */
-	RSA_free(rsa);
+	if (rsa)
+		RSA_free(rsa);
+	BN_free(n);
+	BN_free(e);
+	BN_free(d);
+	BN_free(p);
+	BN_free(q);
+	BN_free(dmp1);
+	BN_free(dmq1);
+	BN_free(iqmp);
 
 	return (newkey);
 }
@@ -3184,40 +3257,52 @@
 ImportRawDSAKey(KMF_RAW_DSA_KEY *key)
 {
 	DSA		*dsa = NULL;
-	EVP_PKEY 	*newkey = NULL;
+	EVP_PKEY	*newkey = NULL;
+	BIGNUM		*p = NULL, *q = NULL, *g = NULL,
+			*priv_key = NULL, *pub_key = NULL;
 
 	if ((dsa = DSA_new()) == NULL)
-		return (NULL);
+		goto cleanup;
 
-	if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len,
-	    dsa->p)) == NULL)
-		return (NULL);
+	if ((p = BN_bin2bn(key->prime.val, key->prime.len, NULL)) == NULL)
+		goto cleanup;
 
-	if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len,
-	    dsa->q)) == NULL)
-		return (NULL);
+	if ((q = BN_bin2bn(key->subprime.val, key->subprime.len, NULL)) == NULL)
+		goto cleanup;
 
-	if ((dsa->g = BN_bin2bn(key->base.val, key->base.len,
-	    dsa->g)) == NULL)
-		return (NULL);
+	if ((g = BN_bin2bn(key->base.val, key->base.len, NULL)) == NULL)
+		goto cleanup;
 
-	if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len,
-	    dsa->priv_key)) == NULL)
-		return (NULL);
+	if ((priv_key = BN_bin2bn(key->value.val, key->value.len,
+	    NULL)) == NULL)
+		goto cleanup;
 
-	if (key->pubvalue.val != NULL) {
-		if ((dsa->pub_key = BN_bin2bn(key->pubvalue.val,
-		    key->pubvalue.len, dsa->pub_key)) == NULL)
-			return (NULL);
-	}
+	if (key->pubvalue.val != NULL && (pub_key =
+	    BN_bin2bn(key->pubvalue.val, key->pubvalue.len, NULL)) == NULL)
+		goto cleanup;
 
+	if (DSA_set0_pqg(dsa, p, q, g) == 0)
+		goto cleanup;
+	p = q = g = NULL;
+	if (DSA_set0_key(dsa, pub_key, priv_key) == 0)
+		goto cleanup;
+	pub_key = priv_key = 0;
+
 	if ((newkey = EVP_PKEY_new()) == NULL)
-		return (NULL);
+		goto cleanup;
 
 	(void) EVP_PKEY_set1_DSA(newkey, dsa);
 
+cleanup:
 	/* The original key must be freed once here or it leaks memory */
-	DSA_free(dsa);
+	if (dsa)
+		DSA_free(dsa);
+	BN_free(p);
+	BN_free(q);
+	BN_free(g);
+	BN_free(priv_key);
+	BN_free(pub_key);
+
 	return (newkey);
 }
 
@@ -3732,7 +3817,7 @@
 }
 
 static KMF_RETURN
-openssl_parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *pin,
+openssl_parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, char *pin,
 	STACK_OF(EVP_PKEY) *keys, STACK_OF(X509) *certs)
 {
 	KMF_RETURN ret;
@@ -3759,28 +3844,13 @@
 	if (pkey == NULL || attrib == NULL)
 		return (KMF_ERR_BAD_PARAMETER);
 
-	if (pkey->attributes == NULL) {
-		pkey->attributes = sk_X509_ATTRIBUTE_new_null();
-		if (pkey->attributes == NULL)
-			return (KMF_ERR_MEMORY);
-	}
 	attr = X509_ATTRIBUTE_create(nid, attrib->type, attrib->value.ptr);
 	if (attr != NULL) {
 		int i;
-		X509_ATTRIBUTE *a;
-		for (i = 0;
-		    i < sk_X509_ATTRIBUTE_num(pkey->attributes); i++) {
-			/* LINTED E_BAD_PTR_CASE_ALIGN */
-			a = sk_X509_ATTRIBUTE_value(pkey->attributes, i);
-			if (OBJ_obj2nid(a->object) == nid) {
-				X509_ATTRIBUTE_free(a);
-				/* LINTED E_BAD_PTR_CAST_ALIGN */
-				(void) sk_X509_ATTRIBUTE_set(pkey->attributes,
-				    i, attr);
-				return (KMF_OK);
-			}
-		}
-		if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == NULL) {
+
+		if ((i = EVP_PKEY_get_attr_by_NID(pkey, nid, -1)) != -1)
+			(void) EVP_PKEY_delete_attr(pkey, i);
+		if (EVP_PKEY_add1_attr(pkey, attr) == 0) {
 			X509_ATTRIBUTE_free(attr);
 			return (KMF_ERR_MEMORY);
 		}
@@ -3799,18 +3869,19 @@
 	PKCS8_PRIV_KEY_INFO *p8 = NULL;
 	EVP_PKEY *pkey = NULL;
 	X509 *xcert = NULL;
-	ASN1_TYPE *keyid = NULL;
-	ASN1_TYPE *fname = NULL;
+	const ASN1_TYPE *keyid = NULL;
+	const ASN1_TYPE *fname = NULL;
 	uchar_t *data = NULL;
 
-	keyid = PKCS12_get_attr(bag, NID_localKeyID);
-	fname = PKCS12_get_attr(bag, NID_friendlyName);
+	keyid = PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID);
+	fname = PKCS12_SAFEBAG_get0_attr(bag, NID_friendlyName);
 
-	switch (M_PKCS12_bag_type(bag)) {
+	switch (PKCS12_SAFEBAG_get_nid(bag)) {
 		case NID_keyBag:
 			if (keylist == NULL)
 				goto end;
-			pkey = EVP_PKCS82PKEY(bag->value.keybag);
+			pkey = EVP_PKCS82PKEY(
+			    PKCS12_SAFEBAG_get0_p8inf(bag));
 			if (pkey == NULL)
 				ret = KMF_ERR_PKCS12_FORMAT;
 
@@ -3818,7 +3889,7 @@
 		case NID_pkcs8ShroudedKeyBag:
 			if (keylist == NULL)
 				goto end;
-			p8 = M_PKCS12_decrypt_skey(bag, pass, passlen);
+			p8 = PKCS12_decrypt_skey(bag, pass, passlen);
 			if (p8 == NULL)
 				return (KMF_ERR_AUTH_FAILED);
 			pkey = EVP_PKCS82PKEY(p8);
@@ -3829,9 +3900,10 @@
 		case NID_certBag:
 			if (certlist == NULL)
 				goto end;
-			if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
+			if (PKCS12_SAFEBAG_get_bag_nid(bag) !=
+			    NID_x509Certificate)
 				return (KMF_ERR_PKCS12_FORMAT);
-			xcert = M_PKCS12_certbag2x509(bag);
+			xcert = PKCS12_SAFEBAG_get1_cert(bag);
 			if (xcert == NULL) {
 				ret = KMF_ERR_PKCS12_FORMAT;
 				goto end;
@@ -3865,8 +3937,9 @@
 				xcert = NULL;
 			break;
 		case NID_safeContentsBag:
-			return (openssl_parse_bags(bag->value.safes, pass,
-			    keylist, certlist));
+			return (openssl_parse_bags(
+			    PKCS12_SAFEBAG_get0_safes(bag),
+			    pass, keylist, certlist));
 		default:
 			ret = KMF_ERR_PKCS12_FORMAT;
 			break;
@@ -4076,35 +4149,41 @@
 	KMF_RETURN rv;
 	KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa;
 
+	const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmpq, *iqmp;
+
+	RSA_get0_key(rsa, &n, &e, &d);
+	RSA_get0_factors(rsa, &p, &q);
+	RSA_get0_crt_params(rsa, &dmp1, &dmpq, &iqmp);
+
 	(void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY));
-	if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK)
+	if ((rv = sslBN2KMFBN((BIGNUM *)n, &kmfkey->mod)) != KMF_OK)
 		goto cleanup;
 
-	if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK)
+	if ((rv = sslBN2KMFBN((BIGNUM *)e, &kmfkey->pubexp)) != KMF_OK)
 		goto cleanup;
 
-	if (rsa->d != NULL)
-		if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK)
+	if (d != NULL)
+		if ((rv = sslBN2KMFBN((BIGNUM *)d, &kmfkey->priexp)) != KMF_OK)
 			goto cleanup;
 
-	if (rsa->p != NULL)
-		if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK)
+	if (p != NULL)
+		if ((rv = sslBN2KMFBN((BIGNUM *)p, &kmfkey->prime1)) != KMF_OK)
 			goto cleanup;
 
-	if (rsa->q != NULL)
-		if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK)
+	if (q != NULL)
+		if ((rv = sslBN2KMFBN((BIGNUM *)q, &kmfkey->prime2)) != KMF_OK)
 			goto cleanup;
 
-	if (rsa->dmp1 != NULL)
-		if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK)
+	if (dmp1 != NULL)
+		if ((rv = sslBN2KMFBN((BIGNUM *)dmp1, &kmfkey->exp1)) != KMF_OK)
 			goto cleanup;
 
-	if (rsa->dmq1 != NULL)
-		if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK)
+	if (dmpq != NULL)
+		if ((rv = sslBN2KMFBN((BIGNUM *)dmpq, &kmfkey->exp2)) != KMF_OK)
 			goto cleanup;
 
-	if (rsa->iqmp != NULL)
-		if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK)
+	if (iqmp != NULL)
+		if ((rv = sslBN2KMFBN((BIGNUM *)iqmp, &kmfkey->coef)) != KMF_OK)
 			goto cleanup;
 cleanup:
 	if (rv != KMF_OK)
@@ -4126,18 +4205,22 @@
 {
 	KMF_RETURN rv;
 	KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa;
+	const BIGNUM *p, *q, *g, *priv_key;
 
+	DSA_get0_pqg(dsa, &p, &q, &g);
+	DSA_get0_key(dsa, NULL, &priv_key);
+
 	(void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY));
-	if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK)
+	if ((rv = sslBN2KMFBN((BIGNUM *)p, &kmfkey->prime)) != KMF_OK)
 		goto cleanup;
 
-	if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK)
+	if ((rv = sslBN2KMFBN((BIGNUM *)q, &kmfkey->subprime)) != KMF_OK)
 		goto cleanup;
 
-	if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK)
+	if ((rv = sslBN2KMFBN((BIGNUM *)g, &kmfkey->base)) != KMF_OK)
 		goto cleanup;
 
-	if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK)
+	if ((rv = sslBN2KMFBN((BIGNUM *)priv_key, &kmfkey->value)) != KMF_OK)
 		goto cleanup;
 
 cleanup:
@@ -4220,68 +4303,44 @@
 	return (KMF_OK);
 }
 
-static X509_ATTRIBUTE *
-find_attr(STACK_OF(X509_ATTRIBUTE) *attrs, int nid)
-{
-	X509_ATTRIBUTE *a;
-	int i;
-
-	if (attrs == NULL)
-		return (NULL);
-
-	for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) {
-		/* LINTED E_BAD_PTR_CAST_ALIGN */
-		a = sk_X509_ATTRIBUTE_value(attrs, i);
-		if (OBJ_obj2nid(a->object) == nid)
-			return (a);
-	}
-	return (NULL);
-}
-
 static KMF_RETURN
 convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key)
 {
 	KMF_RETURN rv = KMF_OK;
 	X509_ATTRIBUTE *attr;
+	RSA *rsa;
+	DSA *dsa;
+	int loc;
 
 	if (pkey == NULL || key == NULL)
 		return (KMF_ERR_BAD_PARAMETER);
 	/* Convert SSL key to raw key */
-	switch (pkey->type) {
-		case EVP_PKEY_RSA:
-			rv = exportRawRSAKey(EVP_PKEY_get1_RSA(pkey),
-			    key);
-			if (rv != KMF_OK)
-				return (rv);
-			break;
-		case EVP_PKEY_DSA:
-			rv = exportRawDSAKey(EVP_PKEY_get1_DSA(pkey),
-			    key);
-			if (rv != KMF_OK)
-				return (rv);
-			break;
-		default:
-			return (KMF_ERR_BAD_PARAMETER);
-	}
+	if ((rsa = EVP_PKEY_get1_RSA(pkey)) != NULL) {
+		rv = exportRawRSAKey(rsa, key);
+		if (rv != KMF_OK)
+			return (rv);
+	} else if ((dsa = EVP_PKEY_get1_DSA(pkey)) != NULL) {
+		rv = exportRawDSAKey(dsa, key);
+		if (rv != KMF_OK)
+			return (rv);
+	} else
+		return (KMF_ERR_BAD_PARAMETER);
+
 	/*
 	 * If friendlyName, add it to record.
 	 */
-	attr = find_attr(pkey->attributes, NID_friendlyName);
-	if (attr != NULL) {
+
+	if ((loc = EVP_PKEY_get_attr_by_NID(pkey,
+	    NID_friendlyName, -1)) != -1 &&
+	    (attr = EVP_PKEY_get_attr(pkey, loc))) {
 		ASN1_TYPE *ty = NULL;
-		int numattr = sk_ASN1_TYPE_num(attr->value.set);
-		if (attr->single == 0 && numattr > 0) {
-			/* LINTED E_BAD_PTR_CAST_ALIGN */
-			ty = sk_ASN1_TYPE_value(attr->value.set, 0);
+		int numattr = X509_ATTRIBUTE_count(attr);
+		if (numattr > 0) {
+			ty = X509_ATTRIBUTE_get0_type(attr, 0);
 		}
 		if (ty != NULL) {
-#if OPENSSL_VERSION_NUMBER < 0x10000000L
-			key->label = uni2asc(ty->value.bmpstring->data,
-			    ty->value.bmpstring->length);
-#else
 			key->label = OPENSSL_uni2asc(ty->value.bmpstring->data,
 			    ty->value.bmpstring->length);
-#endif
 		}
 	} else {
 		key->label = NULL;
@@ -4290,14 +4349,13 @@
 	/*
 	 * If KeyID, add it to record as a KMF_DATA object.
 	 */
-	attr = find_attr(pkey->attributes, NID_localKeyID);
-	if (attr != NULL) {
+	if ((loc = EVP_PKEY_get_attr_by_NID(pkey,
+	    NID_localKeyID, -1)) != -1 &&
+	    (attr = EVP_PKEY_get_attr(pkey, loc)) != NULL) {
 		ASN1_TYPE *ty = NULL;
-		int numattr = sk_ASN1_TYPE_num(attr->value.set);
-		if (attr->single == 0 && numattr > 0) {
-			/* LINTED E_BAD_PTR_CAST_ALIGN */
-			ty = sk_ASN1_TYPE_value(attr->value.set, 0);
-		}
+		int numattr = X509_ATTRIBUTE_count(attr);
+		if (numattr > 0)
+			ty = X509_ATTRIBUTE_get0_type(attr, 0);
 		key->id.Data = (uchar_t *)malloc(
 		    ty->value.octet_string->length);
 		if (key->id.Data == NULL)
@@ -5406,7 +5464,8 @@
 	}
 
 	/* Check if the certificate and the CRL have same issuer */
-	if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) {
+	if (X509_NAME_cmp(X509_get_issuer_name(xcert),
+	    X509_CRL_get_issuer(xcrl)) != 0) {
 		ret = KMF_ERR_ISSUER;
 		goto end;
 	}
@@ -5423,8 +5482,8 @@
 	for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) {
 		/* LINTED E_BAD_PTR_CAST_ALIGN */
 		revoke = sk_X509_REVOKED_value(revoke_stack, i);
-		if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber,
-		    revoke->serialNumber) == 0) {
+		if (ASN1_INTEGER_cmp(X509_get_serialNumber(xcert),
+		    X509_REVOKED_get0_serialNumber(revoke)) == 0) {
 			break;
 		}
 	}
@@ -5567,13 +5626,13 @@
 		ret = KMF_ERR_BAD_CRLFILE;
 		goto cleanup;
 	}
-	i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL);
+	i = X509_cmp_time(X509_CRL_get0_lastUpdate(xcrl), NULL);
 	if (i >= 0) {
 		ret = KMF_ERR_VALIDITY_PERIOD;
 		goto cleanup;
 	}
-	if (X509_CRL_get_nextUpdate(xcrl)) {
-		i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL);
+	if (X509_CRL_get0_nextUpdate(xcrl)) {
+		i = X509_cmp_time(X509_CRL_get0_nextUpdate(xcrl), NULL);
 
 		if (i <= 0) {
 			ret = KMF_ERR_VALIDITY_PERIOD;
--- old/usr/src/tools/scripts/nightly.sh	Mon Apr 30 13:30:24 2018
+++ new/usr/src/tools/scripts/nightly.sh	Mon Apr 30 13:30:24 2018
@@ -28,6 +28,7 @@
 # Copyright 2018 (c) Joyent, Inc.  All rights reserved.
 # Copyright (c) 2017 by Delphix. All rights reserved.
 # Copyright 2018 Joyent, Inc.
+# Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
 #
 # Based on the nightly script from the integration folks,
 # Mostly modified and owned by mike_s.
@@ -1663,7 +1664,7 @@
 fi
 
 ( cd $SRC
-  for target in cc-version cc64-version java-version; do
+  for target in cc-version cc64-version java-version openssl-version; do
 	echo
 	#
 	# Put statefile somewhere we know we can write to rather than trip
