[pkg-opensc-commit] [opensc] 96/295: Use OpenSSL versions OpenSSL-0.9.7 to 1.1.0a for OpenSC

Eric Dorland eric at moszumanska.debian.org
Sat Jun 24 21:11:20 UTC 2017


This is an automated email from the git hooks/post-receive script.

eric pushed a commit to branch master
in repository opensc.

commit 5fb4db63739915399ed9f0d4499b79a1cc9e0139
Author: Doug Engert <deengert at gmail.com>
Date:   Wed Jan 6 08:40:59 2016 -0600

    Use OpenSSL versions OpenSSL-0.9.7 to 1.1.0a for OpenSC
    
    OpenSSL-1.1.0 was released 8/25/2016
    OpenSSL-1.1.0a was released 9/22/2016
    
      https://www.openssl.org/news/openssl-1.1.0-notes.html
    
    Changes to allow the OpenSC code base to work with OpenSSL versions from
    0.9.7 to 1.1.0 with few changes.
    
    This is an update and rebased version of my prep-openssl-1.1.0-pre6 branch.
    
    No attempt was made to back port any OpenSSL features. These changes
    just allow an updated OpenSC code base to use what is in the various OpenSSL
    releases.
    
    A new header libopensc/sc-ossl-compat.h contains extra defines
    to reduce the need for so many #if OPENSSL_VERSION_NUMBER statements
    in the source code.
    
    The OpenSC source can now use the OpenSSL 1.1 API. The libopensc/sc-ossl-compat.h
    has defines for the new API for use with older versions of OpenSSL.
    
    sc-ossl-compat.h is included by libopensc/internal.h so all OpenSC
    library routines can take advantage of it. For the tools, which do not use
    libopensc/internal.h, libopensc/sc-ossl-compat.h is included by the tools.
    
    The OpenSC source has been modified to use OpenSSL functions to access
    hidden structures, such X509, BIGNUM, EVP_CIPHER_CTX, and use XXX_new
    functions to allocate structures which must use pointer such as
    BIGNUM and EVP_CIPHER_CTX.
    
    For backward compatability sc-ossl-compat.h now defines inline routines
    to emulate the RSA and DSA  access routines in OpenSSL-1.1.0. Thus
    the same OpenSC source code can be used with openSSL versions from
    0.9.7 to 1.1.0.
    
    Inline routines were chosen, because using macros does not work on all platforms.
    Having OpenSC versions of these routines in libopensc would be a posibility,
    but they are only used for older version of OpenSSL, and could be removed in
    the future.
     Changes to be committed:
    	modified:   src/libopensc/card-entersafe.c
    	modified:   src/libopensc/card-epass2003.c
    	modified:   src/libopensc/card-gids.c
    	modified:   src/libopensc/card-gpk.c
    	modified:   src/libopensc/card-oberthur.c
    	modified:   src/libopensc/card-piv.c
    	modified:   src/libopensc/card-westcos.c
    	modified:   src/libopensc/cwa-dnie.c
    	modified:   src/libopensc/cwa14890.c
    	modified:   src/libopensc/internal.h
    	modified:   src/libopensc/p15card-helper.c
    	modified:   src/libopensc/pkcs15-itacns.c
    	modified:   src/libopensc/pkcs15-prkey.c
    	modified:   src/libopensc/pkcs15-pubkey.c
    	new file:   src/libopensc/sc-ossl-compat.h
    	modified:   src/pkcs11/openssl.c
    	modified:   src/pkcs15init/pkcs15-lib.c
    	modified:   src/pkcs15init/pkcs15-oberthur-awp.c
    	modified:   src/pkcs15init/pkcs15-oberthur.c
    	modified:   src/pkcs15init/pkcs15-oberthur.h
    	modified:   src/pkcs15init/pkcs15-westcos.c
    	modified:   src/tools/cryptoflex-tool.c
    	modified:   src/tools/gids-tool.c
    	modified:   src/tools/netkey-tool.c
    	modified:   src/tools/piv-tool.c
    	modified:   src/tools/pkcs11-tool.c
    	modified:   src/tools/pkcs15-init.c
    	modified:   src/tools/sc-hsm-tool.c
    	modified:   src/tools/westcos-tool.c
---
 src/libopensc/card-entersafe.c       |  46 +++----
 src/libopensc/card-epass2003.c       |  68 ++++++----
 src/libopensc/card-gids.c            |  27 ++--
 src/libopensc/card-gpk.c             |  67 ++++++----
 src/libopensc/card-oberthur.c        |  16 ++-
 src/libopensc/card-piv.c             |  50 +++++---
 src/libopensc/card-westcos.c         |   3 +-
 src/libopensc/cwa-dnie.c             |  44 +++++--
 src/libopensc/cwa14890.c             |  18 ++-
 src/libopensc/internal.h             |   4 +
 src/libopensc/p15card-helper.c       |   8 +-
 src/libopensc/pkcs15-itacns.c        |  21 ++-
 src/libopensc/pkcs15-prkey.c         |  58 ++++++---
 src/libopensc/pkcs15-pubkey.c        |  31 +++--
 src/libopensc/sc-ossl-compat.h       | 240 +++++++++++++++++++++++++++++++++++
 src/pkcs11/openssl.c                 |  12 +-
 src/pkcs15init/pkcs15-lib.c          |  52 ++++----
 src/pkcs15init/pkcs15-oberthur-awp.c |  28 +++-
 src/pkcs15init/pkcs15-oberthur.c     |   7 +-
 src/pkcs15init/pkcs15-oberthur.h     |   5 +
 src/pkcs15init/pkcs15-westcos.c      |   4 +-
 src/tools/cryptoflex-tool.c          |  61 ++++++---
 src/tools/gids-tool.c                |   5 +-
 src/tools/netkey-tool.c              |   4 +-
 src/tools/piv-tool.c                 |  16 ++-
 src/tools/pkcs11-tool.c              | 186 +++++++++++++++++++--------
 src/tools/pkcs15-init.c              |  60 ++++++---
 src/tools/sc-hsm-tool.c              | 194 ++++++++++++++--------------
 src/tools/westcos-tool.c             |  18 ++-
 29 files changed, 953 insertions(+), 400 deletions(-)

diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c
index 7311e5d..a8cdf6b 100644
--- a/src/libopensc/card-entersafe.c
+++ b/src/libopensc/card-entersafe.c
@@ -194,7 +194,7 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu,
 								 u8 *key, size_t keylen,
 								 u8 *buff, size_t buffsize)
 {
-	 EVP_CIPHER_CTX ctx;
+	 EVP_CIPHER_CTX * ctx = NULL;
 	 u8 iv[8]={0};
 	 int len;
 
@@ -211,27 +211,26 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu,
 	 memcpy(buff+1,apdu->data,apdu->lc);
 	 buff[apdu->lc+1]=0x80;
 
-	 EVP_CIPHER_CTX_init(&ctx);
-	 EVP_CIPHER_CTX_set_padding(&ctx,0);
+	 ctx = EVP_CIPHER_CTX_new();
+	 if (ctx == NULL)
+		 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
+	 EVP_CIPHER_CTX_set_padding(ctx,0);
 
 	 if(keylen == 8)
-		  EVP_EncryptInit_ex(&ctx, EVP_des_ecb(), NULL, key, iv);
+		  EVP_EncryptInit_ex(ctx, EVP_des_ecb(), NULL, key, iv);
 	 else if (keylen == 16) 
-		  EVP_EncryptInit_ex(&ctx, EVP_des_ede(), NULL, key, iv);
+		  EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, key, iv);
 	 else
 		  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
 	 
 	 len = apdu->lc;
-	 if(!EVP_EncryptUpdate(&ctx, buff, &len, buff, buffsize)){
+	 if(!EVP_EncryptUpdate(ctx, buff, &len, buff, buffsize)){
 		  sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "entersafe encryption error.");
 		  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
 	 }
 	 apdu->lc = len;
 
-	 if (!EVP_CIPHER_CTX_cleanup(&ctx)){
-		  sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "entersafe encryption error.");
-		  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
-	 }
+	 EVP_CIPHER_CTX_free(ctx);
 
 	 if(apdu->lc!=buffsize)
 	 {
@@ -254,7 +253,7 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu,
 	 u8 *tmp=0,*tmp_rounded=NULL;
 	 size_t tmpsize=0,tmpsize_rounded=0;
 	 int outl=0;
-	 EVP_CIPHER_CTX ctx;
+	 EVP_CIPHER_CTX * ctx = NULL;
 
 	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
 
@@ -292,12 +291,16 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu,
 	 tmp_rounded[tmpsize]=0x80;
 
 	 /* block_size-1 blocks*/
-	 EVP_CIPHER_CTX_init(&ctx);
-	 EVP_CIPHER_CTX_set_padding(&ctx,0);
-	 EVP_EncryptInit_ex(&ctx, EVP_des_cbc(), NULL, key, iv);
+	 ctx = EVP_CIPHER_CTX_new();
+	 if (ctx == NULL) {
+		r =  SC_ERROR_OUT_OF_MEMORY;
+		goto out;
+	 }
+	 EVP_CIPHER_CTX_set_padding(ctx,0);
+	 EVP_EncryptInit_ex(ctx, EVP_des_cbc(), NULL, key, iv);
 
 	 if(tmpsize_rounded>8){
-		  if(!EVP_EncryptUpdate(&ctx,tmp_rounded,&outl,tmp_rounded,tmpsize_rounded-8)){
+		  if(!EVP_EncryptUpdate(ctx,tmp_rounded,&outl,tmp_rounded,tmpsize_rounded-8)){
 			   r = SC_ERROR_INTERNAL;
 			   goto out;			   
 		  }
@@ -305,25 +308,20 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu,
 	 /* last block */
 	 if(keylen==8)
 	 {
-		  if(!EVP_EncryptUpdate(&ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){
+		  if(!EVP_EncryptUpdate(ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){
 			   r = SC_ERROR_INTERNAL;
 			   goto out;			   
 		  }
 	 }
 	 else
 	 {
-		  EVP_EncryptInit_ex(&ctx, EVP_des_ede_cbc(), NULL, key,tmp_rounded+outl-8);
-		  if(!EVP_EncryptUpdate(&ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){
+		  EVP_EncryptInit_ex(ctx, EVP_des_ede_cbc(), NULL, key,tmp_rounded+outl-8);
+		  if(!EVP_EncryptUpdate(ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){
 			   r = SC_ERROR_INTERNAL;
 			   goto out;			   
 		  }
 	 }
 
-	 if (!EVP_CIPHER_CTX_cleanup(&ctx)){
-		  r = SC_ERROR_INTERNAL;
-		  goto out;			   
-	 }
-
 	 memcpy(buff,apdu->data,apdu->lc);
 	 /* use first 4 bytes of last block as mac value*/
 	 memcpy(buff+apdu->lc,tmp_rounded+tmpsize_rounded-8,4);
@@ -336,6 +334,8 @@ out:
 		  free(tmp);
 	 if(tmp_rounded)
 		  free(tmp_rounded);
+	 if  (ctx)
+		EVP_CIPHER_CTX_free(ctx);
 
 	 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
 }
diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c
index 1727f25..c7bca94 100644
--- a/src/libopensc/card-epass2003.c
+++ b/src/libopensc/card-epass2003.c
@@ -127,27 +127,28 @@ openssl_enc(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned
 		const unsigned char *input, size_t length, unsigned char *output)
 {
 	int r = SC_ERROR_INTERNAL;
-	EVP_CIPHER_CTX ctx;
+	EVP_CIPHER_CTX * ctx = NULL;
 	int outl = 0;
 	int outl_tmp = 0;
 	unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = { 0 };
 
 	memcpy(iv_tmp, iv, EVP_MAX_IV_LENGTH);
-	EVP_CIPHER_CTX_init(&ctx);
-	EVP_EncryptInit_ex(&ctx, cipher, NULL, key, iv_tmp);
-	EVP_CIPHER_CTX_set_padding(&ctx, 0);
-
-	if (!EVP_EncryptUpdate(&ctx, output, &outl, input, length))
+	ctx = EVP_CIPHER_CTX_new();
+	if (ctx == NULL)
 		goto out;
+	EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv_tmp);
+	EVP_CIPHER_CTX_set_padding(ctx, 0);
 
-	if (!EVP_EncryptFinal_ex(&ctx, output + outl, &outl_tmp))
+	if (!EVP_EncryptUpdate(ctx, output, &outl, input, length))
 		goto out;
 
-	if (!EVP_CIPHER_CTX_cleanup(&ctx))
+	if (!EVP_EncryptFinal_ex(ctx, output + outl, &outl_tmp))
 		goto out;
 
 	r = SC_SUCCESS;
 out:
+	if (ctx)
+	    EVP_CIPHER_CTX_free(ctx);
 	return r;
 }
 
@@ -156,27 +157,28 @@ openssl_dec(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned
 		const unsigned char *input, size_t length, unsigned char *output)
 {
 	int r = SC_ERROR_INTERNAL;
-	EVP_CIPHER_CTX ctx;
+	EVP_CIPHER_CTX * ctx = NULL;
 	int outl = 0;
 	int outl_tmp = 0;
 	unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = { 0 };
 
 	memcpy(iv_tmp, iv, EVP_MAX_IV_LENGTH);
-	EVP_CIPHER_CTX_init(&ctx);
-	EVP_DecryptInit_ex(&ctx, cipher, NULL, key, iv_tmp);
-	EVP_CIPHER_CTX_set_padding(&ctx, 0);
-
-	if (!EVP_DecryptUpdate(&ctx, output, &outl, input, length))
+	ctx = EVP_CIPHER_CTX_new();
+	if (ctx == NULL)
 		goto out;
+	EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv_tmp);
+	EVP_CIPHER_CTX_set_padding(ctx, 0);
 
-	if (!EVP_DecryptFinal_ex(&ctx, output + outl, &outl_tmp))
+	if (!EVP_DecryptUpdate(ctx, output, &outl, input, length))
 		goto out;
 
-	if (!EVP_CIPHER_CTX_cleanup(&ctx))
+	if (!EVP_DecryptFinal_ex(ctx, output + outl, &outl_tmp))
 		goto out;
 
 	r = SC_SUCCESS;
 out:
+	if (ctx)
+		EVP_CIPHER_CTX_free(ctx);
 	return r;
 }
 
@@ -280,21 +282,33 @@ static int
 openssl_dig(const EVP_MD * digest, const unsigned char *input, size_t length,
 		unsigned char *output)
 {
-	EVP_MD_CTX ctx;
+	int r = 0;
+	EVP_MD_CTX *ctx = NULL;
 	unsigned outl = 0;
 
-	EVP_MD_CTX_init(&ctx);
-	EVP_DigestInit_ex(&ctx, digest, NULL);
-	if (!EVP_DigestUpdate(&ctx, input, length))
-		return SC_ERROR_INTERNAL;
-
-	if (!EVP_DigestFinal_ex(&ctx, output, &outl))
-		return SC_ERROR_INTERNAL;
+	ctx = EVP_MD_CTX_create();
+	if (ctx == NULL) {
+	    r = SC_ERROR_OUT_OF_MEMORY;
+	    goto err;
+	}
+	    
+	EVP_MD_CTX_init(ctx);
+	EVP_DigestInit_ex(ctx, digest, NULL);
+	if (!EVP_DigestUpdate(ctx, input, length)) {
+		r = SC_ERROR_INTERNAL;
+		goto err;
+	}
 
-	if (!EVP_MD_CTX_cleanup(&ctx))
-		return SC_ERROR_INTERNAL;
+	if (!EVP_DigestFinal_ex(ctx, output, &outl)) {
+		r = SC_ERROR_INTERNAL;
+		goto err;
+	}
+	r = SC_SUCCESS;
+err:
+	if (ctx)
+		EVP_MD_CTX_destroy(ctx);
 
-	return SC_SUCCESS;
+	return r;
 }
 
 
diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c
index d7e8569..51db9af 100644
--- a/src/libopensc/card-gids.c
+++ b/src/libopensc/card-gids.c
@@ -1860,7 +1860,7 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) {
 #ifndef ENABLE_OPENSSL
 	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED);
 #else
-	EVP_CIPHER_CTX ctx;
+	EVP_CIPHER_CTX *ctx = NULL;
 	int r;
 	u8 apduSetRandom[20] = {0x7C,0x12,0x81,0x10,0};
 	u8* randomR1 = apduSetRandom + 4;
@@ -1878,8 +1878,6 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) {
 	const EVP_CIPHER *cipher;
 
 	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
-	// init crypto
-	EVP_CIPHER_CTX_init(&ctx);
 	// this is CBC instead of ECB
 	cipher = EVP_des_ede3_cbc();
 	if (!cipher) {
@@ -1920,21 +1918,28 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) {
 	memcpy(buffer, randomR2, 16);
 	memcpy(buffer+16, randomR1, 16);
 	memcpy(buffer+32, z1, sizeof(z1));
-	if (!EVP_EncryptInit(&ctx, cipher, key, NULL)) {
-		EVP_CIPHER_CTX_cleanup(&ctx);
+	// init crypto
+	ctx = EVP_CIPHER_CTX_new();
+	if (ctx == NULL) {
+	    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
+	}
+
+	if (!EVP_EncryptInit(ctx, cipher, key, NULL)) {
+		EVP_CIPHER_CTX_free(ctx);
 		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
 	}
-	EVP_CIPHER_CTX_set_padding(&ctx,0);
-	if (!EVP_EncryptUpdate(&ctx, buffer2, &buffer2size, buffer, sizeof(buffer))) {
-		EVP_CIPHER_CTX_cleanup(&ctx);
+	EVP_CIPHER_CTX_set_padding(ctx,0);
+	if (!EVP_EncryptUpdate(ctx, buffer2, &buffer2size, buffer, sizeof(buffer))) {
+		EVP_CIPHER_CTX_free(ctx);
 		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
 	}
 
-	if(!EVP_EncryptFinal(&ctx, buffer2+buffer2size, &buffer2size)) {
-		EVP_CIPHER_CTX_cleanup(&ctx);
+	if(!EVP_EncryptFinal(ctx, buffer2+buffer2size, &buffer2size)) {
+		EVP_CIPHER_CTX_free(ctx);
 		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
 	}
-	EVP_CIPHER_CTX_cleanup(&ctx);
+	EVP_CIPHER_CTX_free(ctx);
+	ctx = NULL;
 	// send it to the card
 	sc_format_apdu(card, &apdu, SC_APDU_CASE_4, INS_GENERAL_AUTHENTICATE, 0x00, 0x00);
 	apdu.lc = sizeof(apduSendReponse);
diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c
index 3480f02..1e6dcea 100644
--- a/src/libopensc/card-gpk.c
+++ b/src/libopensc/card-gpk.c
@@ -731,7 +731,12 @@ gpk_compute_crycks(sc_card_t *card, sc_apdu_t *apdu,
 	u8		in[8], out[8], block[64];
 	unsigned int	len = 0, i;
 	int             r = SC_SUCCESS, outl;
-	EVP_CIPHER_CTX  ctx;
+	EVP_CIPHER_CTX  *ctx = NULL;
+
+	ctx = EVP_CIPHER_CTX_new();
+	if (ctx == NULL)
+		return SC_ERROR_INTERNAL;
+
 
 	/* Fill block with 0x00 and then with the data. */
 	memset(block, 0x00, sizeof(block));
@@ -748,16 +753,14 @@ gpk_compute_crycks(sc_card_t *card, sc_apdu_t *apdu,
 	/* Set IV */
 	memset(in, 0x00, 8);
 
-	EVP_CIPHER_CTX_init(&ctx);
-	EVP_EncryptInit_ex(&ctx, EVP_des_ede_cbc(), NULL, priv->key, in);
+	EVP_EncryptInit_ex(ctx, EVP_des_ede_cbc(), NULL, priv->key, in);
 	for (i = 0; i < len; i += 8) {
-		if (!EVP_EncryptUpdate(&ctx, out, &outl, &block[i], 8)) {
+		if (!EVP_EncryptUpdate(ctx, out, &outl, &block[i], 8)) {
 			r = SC_ERROR_INTERNAL;
 			break;
 		}
 	}
-	if (!EVP_CIPHER_CTX_cleanup(&ctx))
-		r = SC_ERROR_INTERNAL;
+	EVP_CIPHER_CTX_free(ctx);
 
 	memcpy((u8 *) (apdu->data + apdu->datalen), out + 5, 3);
 	apdu->datalen += 3;
@@ -883,25 +886,29 @@ gpk_set_filekey(const u8 *key, const u8 *challenge,
 		const u8 *r_rn, u8 *kats)
 {
 	int			r = SC_SUCCESS, outl;
-	EVP_CIPHER_CTX		ctx;
+	EVP_CIPHER_CTX		* ctx = NULL;
 	u8                      out[16];
 
 	memcpy(out, key+8, 8);
 	memcpy(out+8, key, 8);
 
-	EVP_CIPHER_CTX_init(&ctx);
-	EVP_EncryptInit_ex(&ctx, EVP_des_ede(), NULL, key, NULL);
-	if (!EVP_EncryptUpdate(&ctx, kats, &outl, r_rn+4, 8))
+	ctx = EVP_CIPHER_CTX_new();
+	if (ctx == NULL)
+		return SC_ERROR_INTERNAL;
+
+	EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, key, NULL);
+	if (!EVP_EncryptUpdate(ctx, kats, &outl, r_rn+4, 8))
 		r = SC_ERROR_INTERNAL;
-	if (!EVP_CIPHER_CTX_cleanup(&ctx))
+
+	if (!EVP_CIPHER_CTX_cleanup(ctx))
 		r = SC_ERROR_INTERNAL;
 	if (r == SC_SUCCESS) {
-		EVP_CIPHER_CTX_init(&ctx);
-		EVP_EncryptInit_ex(&ctx, EVP_des_ede(), NULL, out, NULL);
-		if (!EVP_EncryptUpdate(&ctx, kats+8, &outl, r_rn+4, 8))
-			r = SC_ERROR_INTERNAL;
-		if (!EVP_CIPHER_CTX_cleanup(&ctx))
+		EVP_CIPHER_CTX_init(ctx);
+		EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, out, NULL);
+		if (!EVP_EncryptUpdate(ctx, kats+8, &outl, r_rn+4, 8))
 			r = SC_ERROR_INTERNAL;
+	if (!EVP_CIPHER_CTX_cleanup(ctx))
+		r = SC_ERROR_INTERNAL;
 	}
 	memset(out, 0, sizeof(out));
 
@@ -910,16 +917,17 @@ gpk_set_filekey(const u8 *key, const u8 *challenge,
 	 * here? INVALID_ARGS doesn't seem quite right
 	 */
 	if (r == SC_SUCCESS) {
-		EVP_CIPHER_CTX_init(&ctx);
-		EVP_EncryptInit_ex(&ctx, EVP_des_ede(), NULL, kats, NULL);
-		if (!EVP_EncryptUpdate(&ctx, out, &outl, challenge, 8))
-			r = SC_ERROR_INTERNAL;
-		if (!EVP_CIPHER_CTX_cleanup(&ctx))
+		EVP_CIPHER_CTX_init(ctx);
+		EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, kats, NULL);
+		if (!EVP_EncryptUpdate(ctx, out, &outl, challenge, 8))
 			r = SC_ERROR_INTERNAL;
 		if (memcmp(r_rn, out+4, 4) != 0)
 			r = SC_ERROR_INVALID_ARGUMENTS;
 	}
 
+	if (ctx)
+	    EVP_CIPHER_CTX_free(ctx);
+
 	sc_mem_clear(out, sizeof(out));
 	return r;
 }
@@ -941,7 +949,7 @@ gpk_select_key(sc_card_t *card, int key_sfi, const u8 *buf, size_t buflen)
 		return SC_ERROR_INVALID_ARGUMENTS;
 
 	/* now do the SelFk */
-	RAND_pseudo_bytes(rnd, sizeof(rnd));
+	RAND_bytes(rnd, sizeof(rnd));
 	memset(&apdu, 0, sizeof(apdu));
 	apdu.cla = 0x80;
 	apdu.cse = SC_APDU_CASE_4_SHORT;
@@ -1509,11 +1517,15 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args)
 	unsigned int	n;
 	u8		temp[256];
 	int		r = SC_SUCCESS, outl;
-	EVP_CIPHER_CTX  ctx;
+	EVP_CIPHER_CTX  * ctx;
 
 	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "gpk_pkfile_load(fid=%04x, len=%d, datalen=%d)\n",
 			args->file->id, args->len, args->datalen);
 
+	ctx = EVP_CIPHER_CTX_new();
+	if (ctx == NULL)
+		return SC_ERROR_INTERNAL;
+
 	if (0) {
 		char buf[2048];
 
@@ -1539,15 +1551,16 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args)
 		return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
 	}
 
-	EVP_CIPHER_CTX_init(&ctx);
-	EVP_EncryptInit_ex(&ctx, EVP_des_ede(), NULL, priv->key, NULL);
+	EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, priv->key, NULL);
 	for (n = 0; n < args->datalen; n += 8) {
-		if (!EVP_EncryptUpdate(&ctx, temp+n, &outl, args->data + n, 8)) {
+		if (!EVP_EncryptUpdate(ctx, temp+n, &outl, args->data + n, 8)) {
 			r = SC_ERROR_INTERNAL;
 			break;
 		}
 	}
-	if (!EVP_CIPHER_CTX_cleanup(&ctx) || r != SC_SUCCESS)
+	if (ctx)
+		EVP_CIPHER_CTX_free(ctx);
+	if (r != SC_SUCCESS)
 		return SC_ERROR_INTERNAL;
 
 	apdu.data = temp;
diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c
index 52dfb4b..fa6c968 100644
--- a/src/libopensc/card-oberthur.c
+++ b/src/libopensc/card-oberthur.c
@@ -1340,19 +1340,23 @@ auth_update_component(struct sc_card *card, struct auth_update_component_info *a
 		int outl;
 		const unsigned char in[8] = {0,0,0,0,0,0,0,0};
 		unsigned char out[8];
-		EVP_CIPHER_CTX ctx;
+		EVP_CIPHER_CTX  * ctx = NULL;
 
 		if (args->len!=8 && args->len!=24)
 			LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
 
+		ctx = EVP_CIPHER_CTX_new();
+		if (ctx == NULL) 
+		    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL,SC_ERROR_OUT_OF_MEMORY);
+
 		p2 = 0;
-		EVP_CIPHER_CTX_init(&ctx);
 		if (args->len == 24)
-			EVP_EncryptInit_ex(&ctx, EVP_des_ede(), NULL, args->data, NULL);
+			EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, args->data, NULL);
 		else
-			EVP_EncryptInit_ex(&ctx, EVP_des_ecb(), NULL, args->data, NULL);
-		rv = EVP_EncryptUpdate(&ctx, out, &outl, in, 8);
-		if (!EVP_CIPHER_CTX_cleanup(&ctx) || rv == 0) {
+			EVP_EncryptInit_ex(ctx, EVP_des_ecb(), NULL, args->data, NULL);
+		rv = EVP_EncryptUpdate(ctx, out, &outl, in, 8);
+		EVP_CIPHER_CTX_free(ctx);
+		if (rv == 0) {
 			sc_log(card->ctx, "OpenSSL encryption error.");
 			LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
 		}
diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c
index e3ad4da..e883c74 100644
--- a/src/libopensc/card-piv.c
+++ b/src/libopensc/card-piv.c
@@ -1582,14 +1582,19 @@ static int piv_general_mutual_authenticate(sc_card_t *card,
 	size_t challenge_response_len;
 	u8 *decrypted_reponse = NULL;
 	size_t decrypted_reponse_len;
-	EVP_CIPHER_CTX ctx;
+	EVP_CIPHER_CTX * ctx = NULL;
 
 	u8 sbuf[255];
 	const EVP_CIPHER *cipher;
 
 	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
 
-	EVP_CIPHER_CTX_init(&ctx);
+	ctx = EVP_CIPHER_CTX_new();
+	if (ctx == NULL) {
+		r = SC_ERROR_OUT_OF_MEMORY;
+		goto err;
+	}
+
 	cipher = get_cipher_for_algo(alg_id);
 	if(!cipher) {
 		sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid cipher selector, none found for:  %02x\n", alg_id);
@@ -1648,22 +1653,22 @@ static int piv_general_mutual_authenticate(sc_card_t *card,
 	}
 
 	/* decrypt the data from the card */
-	if (!EVP_DecryptInit(&ctx, cipher, key, NULL)) {
+	if (!EVP_DecryptInit(ctx, cipher, key, NULL)) {
 		/* may fail if des parity of key is wrong. depends on OpenSSL options */
 		r = SC_ERROR_INTERNAL;
 		goto err;
 	}
-	EVP_CIPHER_CTX_set_padding(&ctx,0);
+	EVP_CIPHER_CTX_set_padding(ctx,0);
 
 	p = plain_text;
-	if (!EVP_DecryptUpdate(&ctx, p, &N, witness_data, witness_len)) {
+	if (!EVP_DecryptUpdate(ctx, p, &N, witness_data, witness_len)) {
 		r = SC_ERROR_INTERNAL;
 		goto err;
 	}
 	plain_text_len = tmplen = N;
 	p += tmplen;
 
-	if(!EVP_DecryptFinal(&ctx, p, &N)) {
+	if(!EVP_DecryptFinal(ctx, p, &N)) {
 		r = SC_ERROR_INTERNAL;
 		goto err;
 	}
@@ -1772,24 +1777,23 @@ static int piv_general_mutual_authenticate(sc_card_t *card,
 		goto err;
 	}
 
-	EVP_CIPHER_CTX_cleanup(&ctx);
-	EVP_CIPHER_CTX_init(&ctx);
+	EVP_CIPHER_CTX_cleanup(ctx);
 
-	if (!EVP_DecryptInit(&ctx, cipher, key, NULL)) {
+	if (!EVP_DecryptInit(ctx, cipher, key, NULL)) {
 		r = SC_ERROR_INTERNAL;
 		goto err;
 	}
-	EVP_CIPHER_CTX_set_padding(&ctx,0);
+	EVP_CIPHER_CTX_set_padding(ctx,0);
 
 	tmp = decrypted_reponse;
-	if (!EVP_DecryptUpdate(&ctx, tmp, &N, challenge_response, challenge_response_len)) {
+	if (!EVP_DecryptUpdate(ctx, tmp, &N, challenge_response, challenge_response_len)) {
 		r = SC_ERROR_INTERNAL;
 		goto err;
 	}
 	decrypted_reponse_len = tmplen = N;
 	tmp += tmplen;
 
-	if(!EVP_DecryptFinal(&ctx, tmp, &N)) {
+	if(!EVP_DecryptFinal(ctx, tmp, &N)) {
 		r = SC_ERROR_INTERNAL;
 		goto err;
 	}
@@ -1805,7 +1809,8 @@ static int piv_general_mutual_authenticate(sc_card_t *card,
 	r = SC_SUCCESS;
 
 err:
-	EVP_CIPHER_CTX_cleanup(&ctx);
+	if (ctx)
+		EVP_CIPHER_CTX_free(ctx);
 	if (locked)
 		sc_unlock(card);
 	if (rbuf)
@@ -1853,12 +1858,16 @@ static int piv_general_external_authenticate(sc_card_t *card,
 	size_t keylen = 0;
 	size_t cypher_text_len = 0;
 	u8 sbuf[255];
-	EVP_CIPHER_CTX ctx;
+	EVP_CIPHER_CTX * ctx = NULL;
 	const EVP_CIPHER *cipher;
 
 	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
 
-	EVP_CIPHER_CTX_init(&ctx);
+	ctx = EVP_CIPHER_CTX_new();
+	if (ctx == NULL) {
+	    r = SC_ERROR_OUT_OF_MEMORY;
+	    goto err;
+	}
 
 	sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Selected cipher for algorithm id: %02x\n", alg_id);
 
@@ -1924,7 +1933,7 @@ static int piv_general_external_authenticate(sc_card_t *card,
 	tmplen = challenge_len;
 
 	/* Encrypt the challenge with the secret */
-	if (!EVP_EncryptInit(&ctx, cipher, key, NULL)) {
+	if (!EVP_EncryptInit(ctx, cipher, key, NULL)) {
 		sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Encrypt fail\n");
 		r = SC_ERROR_INTERNAL;
 		goto err;
@@ -1937,15 +1946,15 @@ static int piv_general_external_authenticate(sc_card_t *card,
 		goto err;
 	}
 
-	EVP_CIPHER_CTX_set_padding(&ctx,0);
-	if (!EVP_EncryptUpdate(&ctx, cypher_text, &outlen, challenge_data, challenge_len)) {
+	EVP_CIPHER_CTX_set_padding(ctx,0);
+	if (!EVP_EncryptUpdate(ctx, cypher_text, &outlen, challenge_data, challenge_len)) {
 		sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Encrypt update fail\n");
 		r = SC_ERROR_INTERNAL;
 		goto err;
 	}
 	cypher_text_len += outlen;
 
-	if (!EVP_EncryptFinal(&ctx, cypher_text + cypher_text_len, &outlen)) {
+	if (!EVP_EncryptFinal(ctx, cypher_text + cypher_text_len, &outlen)) {
 		sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Final fail\n");
 		r = SC_ERROR_INTERNAL;
 		goto err;
@@ -2005,7 +2014,8 @@ static int piv_general_external_authenticate(sc_card_t *card,
 	sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Got response  challenge\n");
 
 err:
-	EVP_CIPHER_CTX_cleanup(&ctx);
+	if (ctx)
+		EVP_CIPHER_CTX_free(ctx);
 
 	if (locked)
 		sc_unlock(card);
diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c
index 5c2e2cf..9062faf 100644
--- a/src/libopensc/card-westcos.c
+++ b/src/libopensc/card-westcos.c
@@ -1182,7 +1182,8 @@ static int westcos_sign_decipher(int mode, sc_card_t *card,
 	}
 
 	/* pkcs11 reset openssl functions */
-	rsa->meth = RSA_PKCS1_SSLeay();
+	RSA_set_method(rsa, RSA_PKCS1_OpenSSL());
+
 	if ((size_t)RSA_size(rsa) > outlen) {
 		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Buffer too small\n");
 		r = SC_ERROR_OUT_OF_MEMORY;
diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c
index 311d499..6023fe1 100644
--- a/src/libopensc/cwa-dnie.c
+++ b/src/libopensc/cwa-dnie.c
@@ -39,8 +39,11 @@
 
 #include "cwa-dnie.h"
 
+#include <openssl/ossl_typ.h>
+#include <openssl/bn.h>
 #include <openssl/x509.h>
 #include <openssl/evp.h>
+#include <openssl/rsa.h>
 
 #define MAX_RESP_BUFFER_SIZE 2048
 
@@ -344,6 +347,7 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key)
 {
 	int res=SC_SUCCESS;
 	RSA *root_ca_rsa=NULL;
+	BIGNUM *root_ca_rsa_n, *root_ca_rsa_e;
 	LOG_FUNC_CALLED(card->ctx);
 
 	/* compose root_ca_public key with data provided by Dnie Manual */
@@ -353,11 +357,20 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key)
 		sc_log(card->ctx, "Cannot create data for root CA public key");
 		return SC_ERROR_OUT_OF_MEMORY;
 	}
-	root_ca_rsa->n = BN_bin2bn(icc_root_ca_modulus,
-				   sizeof(icc_root_ca_modulus), root_ca_rsa->n);
-	root_ca_rsa->e = BN_bin2bn(icc_root_ca_public_exponent,
-				   sizeof(icc_root_ca_public_exponent),
-				   root_ca_rsa->e);
+
+	root_ca_rsa_n = BN_bin2bn(icc_root_ca_modulus, sizeof(icc_root_ca_modulus), NULL);
+	root_ca_rsa_e = BN_bin2bn(icc_root_ca_public_exponent, sizeof(icc_root_ca_public_exponent), NULL);
+	if (RSA_set0_key(root_ca_rsa, root_ca_rsa_n, root_ca_rsa_e, NULL) != 1) {
+		BN_free(root_ca_rsa_n);
+		BN_free(root_ca_rsa_e);
+		if (*root_ca_key)
+			EVP_PKEY_free(*root_ca_key);
+		if (root_ca_rsa)
+			RSA_free(root_ca_rsa);
+		sc_log(card->ctx, "Cannot set RSA valuses for CA public key");
+		return SC_ERROR_INTERNAL;
+	}
+
 	res = EVP_PKEY_assign_RSA(*root_ca_key, root_ca_rsa);
 	if (!res) {
 		if (*root_ca_key)
@@ -428,6 +441,7 @@ static int dnie_get_cvc_ifd_cert(sc_card_t * card, u8 ** cert, size_t * length)
 static int dnie_get_ifd_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey)
 {
 	RSA *ifd_rsa=NULL;
+	BIGNUM *ifd_rsa_n, *ifd_rsa_e, *ifd_rsa_d = NULL;
 	int res=SC_SUCCESS;
 
 	LOG_FUNC_CALLED(card->ctx);
@@ -439,13 +453,19 @@ static int dnie_get_ifd_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey)
 		sc_log(card->ctx, "Cannot create data for IFD private key");
 		return SC_ERROR_OUT_OF_MEMORY;
 	}
-	ifd_rsa->n = BN_bin2bn(ifd_modulus, sizeof(ifd_modulus), ifd_rsa->n);
-	ifd_rsa->e =
-	    BN_bin2bn(ifd_public_exponent, sizeof(ifd_public_exponent),
-		      ifd_rsa->e);
-	ifd_rsa->d =
-	    BN_bin2bn(ifd_private_exponent, sizeof(ifd_private_exponent),
-		      ifd_rsa->d);
+	ifd_rsa_n = BN_bin2bn(ifd_modulus, sizeof(ifd_modulus), NULL);
+	ifd_rsa_e = BN_bin2bn(ifd_public_exponent, sizeof(ifd_public_exponent), NULL);
+	ifd_rsa_d = BN_bin2bn(ifd_private_exponent, sizeof(ifd_private_exponent), NULL);
+	if (RSA_set0_key(ifd_rsa, ifd_rsa_n, ifd_rsa_e, ifd_rsa_d) != 1) {
+		BN_free(ifd_rsa_n);
+		BN_free(ifd_rsa_e);
+		BN_free(ifd_rsa_d);
+		RSA_free(ifd_rsa);
+		EVP_PKEY_free(*ifd_privkey);
+		sc_log(card->ctx, "Cannot set RSA values for IFD private key");
+		return SC_ERROR_INTERNAL;
+	}
+
 	res = EVP_PKEY_assign_RSA(*ifd_privkey, ifd_rsa);
 	if (!res) {
 		if (*ifd_privkey)
diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c
index 46594dd..62a847c 100644
--- a/src/libopensc/cwa14890.c
+++ b/src/libopensc/cwa14890.c
@@ -36,6 +36,8 @@
 #include "opensc.h"
 #include "cardctl.h"
 #include "internal.h"
+#include <openssl/rsa.h>
+#include <openssl/bn.h>
 #include <openssl/x509.h>
 #include <openssl/des.h>
 #include <openssl/rand.h>
@@ -588,6 +590,7 @@ static int cwa_prepare_external_auth(sc_card_t * card,
 	BIGNUM *bnsub = NULL;
 	BIGNUM *bnres = NULL;
 	sc_context_t *ctx = NULL;
+	const BIGNUM *ifd_privkey_n, *ifd_privkey_e, *ifd_privkey_d;
 
 	/* safety check */
 	if (!card || !card->ctx)
@@ -641,7 +644,8 @@ static int cwa_prepare_external_auth(sc_card_t * card,
 		res = SC_ERROR_INTERNAL;
 		goto prepare_external_auth_end;
 	}
-	res = BN_sub(bnsub, ifd_privkey->n, bn);	/* eval N.IFD-SIG */
+	RSA_get0_key(ifd_privkey, &ifd_privkey_n, &ifd_privkey_e, &ifd_privkey_d);
+	res = BN_sub(bnsub, ifd_privkey_n, bn);	/* eval N.IFD-SIG */
 	if (res == 0) {		/* 1:success 0 fail */
 		msg = "Prepare external auth: BN sigmin evaluation failed";
 		res = SC_ERROR_INTERNAL;
@@ -889,6 +893,7 @@ static int cwa_verify_internal_auth(sc_card_t * card,
 	BIGNUM *bn = NULL;
 	BIGNUM *sigbn = NULL;
 	sc_context_t *ctx = NULL;
+	const BIGNUM *icc_pubkey_n, *icc_pubkey_e, *icc_pubkey_d;
 
 	if (!card || !card->ctx)
 		return SC_ERROR_INVALID_ARGUMENTS;
@@ -959,7 +964,8 @@ static int cwa_verify_internal_auth(sc_card_t * card,
 		res = SC_ERROR_OUT_OF_MEMORY;
 		goto verify_internal_done;
 	}
-	res = BN_sub(sigbn, icc_pubkey->n, bn);	/* eval N.ICC-SIG */
+	RSA_get0_key(icc_pubkey, &icc_pubkey_n, &icc_pubkey_e, &icc_pubkey_d);
+	res = BN_sub(sigbn, icc_pubkey_n, bn);	/* eval N.ICC-SIG */
 	if (!res) {
 		msg = "Verify Signature: evaluation of N.ICC-SIG failed";
 		res = SC_ERROR_INTERNAL;
@@ -1319,8 +1325,8 @@ int cwa_create_secure_channel(sc_card_t * card,
 
 	/* verify received signature */
 	sc_log(ctx, "Verify Internal Auth command response");
-	res = cwa_verify_internal_auth(card, icc_pubkey->pkey.rsa,	/* evaluated icc public key */
-				       ifd_privkey->pkey.rsa,	/* evaluated from DGP's Manual Annex 3 Data */
+	res = cwa_verify_internal_auth(card, EVP_PKEY_get0_RSA(icc_pubkey),	/* evaluated icc public key */
+				       EVP_PKEY_get0_RSA(ifd_privkey),	/* evaluated from DGP's Manual Annex 3 Data */
 				       rndbuf,	/* RND.IFD || SN.IFD */
 				       16,	/* rndbuf length; should be 16 */
 				       sm	/* sm data */
@@ -1340,8 +1346,8 @@ int cwa_create_secure_channel(sc_card_t * card,
 
 	/* compose signature data for external auth */
 	res = cwa_prepare_external_auth(card,
-					icc_pubkey->pkey.rsa,
-					ifd_privkey->pkey.rsa, sn_icc, sm);
+					EVP_PKEY_get0_RSA(icc_pubkey),
+					EVP_PKEY_get0_RSA(ifd_privkey), sn_icc, sm);
 	if (res != SC_SUCCESS) {
 		msg = "Prepare external auth failed";
 		goto csc_end;
diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h
index 0ccc13a..98a4237 100644
--- a/src/libopensc/internal.h
+++ b/src/libopensc/internal.h
@@ -40,6 +40,10 @@ extern "C" {
 #include "libopensc/log.h"
 #include "libopensc/cards.h"
 
+#ifdef ENABLE_OPENSSL
+#include "libopensc/sc-ossl-compat.h"
+#endif
+
 #define SC_FILE_MAGIC			0x14426950
 
 #ifndef _WIN32
diff --git a/src/libopensc/p15card-helper.c b/src/libopensc/p15card-helper.c
index 1a16da7..94f9fe2 100644
--- a/src/libopensc/p15card-helper.c
+++ b/src/libopensc/p15card-helper.c
@@ -25,6 +25,7 @@
 #ifdef ENABLE_OPENSSL	/* empty file without openssl */
 #include <string.h>
 #include <stdlib.h>
+#include <openssl/bn.h>
 #include <openssl/bio.h>
 #include <openssl/rsa.h>
 #include <openssl/x509.h>
@@ -142,6 +143,7 @@ CERT_HANDLE_FUNCTION(default_cert_handle) {
 	int r;
 	X509 *cert_data = NULL;
 	EVP_PKEY *pkey = NULL;
+	RSA * rsa = NULL;
 	int certtype = 0;
 	int modulus_len = 0;
 	const prdata* key = get_prkey_by_cert(items, cert);
@@ -169,13 +171,15 @@ CERT_HANDLE_FUNCTION(default_cert_handle) {
 		r = SC_ERROR_INTERNAL;
 		goto err;
 	}
-	if(pkey->pkey.rsa->n == NULL) {
+	rsa = EVP_PKEY_get0_RSA(pkey);
+	if( rsa == NULL) {
 		sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Error: no modulus associated with the certificate");
 		r = SC_ERROR_INTERNAL;
 		goto err;
 	}
 	
-	modulus_len = 8 * BN_num_bytes(pkey->pkey.rsa->n); /* converting to bits */
+	modulus_len =  RSA_bits(rsa);
+
 	/* printf("Key Size: %d bits\n\n", modulus_len); */
 	/* cached_cert->modulusLength = modulus_len; */
 	
diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c
index 50b9217..53aa2b0 100644
--- a/src/libopensc/pkcs15-itacns.c
+++ b/src/libopensc/pkcs15-itacns.c
@@ -30,17 +30,25 @@
 #include <config.h>
 #endif
 
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifdef ENABLE_OPENSSL
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#endif
+
+#include "internal.h"
 #include "pkcs15.h"
 #include "log.h"
 #include "cards.h"
 #include "itacns.h"
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
 #include "common/compat_strlcpy.h"
 #include "common/compat_strlcat.h"
 
 #ifdef ENABLE_OPENSSL
+#include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #endif
 
@@ -241,10 +249,11 @@ static int itacns_add_cert(sc_pkcs15_card_t *p15card,
 	sc_pkcs15_free_certificate(cert);
 	if (!x509) return SC_SUCCESS;
 	X509_check_purpose(x509, -1, 0);
-	if(x509->ex_flags & EXFLAG_KUSAGE) {
+
+	if(X509_get_extension_flags(x509) & EXFLAG_KUSAGE) {
 		*ext_info_ok = 1;
-		*key_usage = x509->ex_kusage;
-		*x_key_usage = x509->ex_xkusage;
+		*key_usage = X509_get_key_usage(x509);
+		*x_key_usage = X509_get_extended_key_usage(x509);
 	}
 	OPENSSL_free(x509);
 
diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c
index f199aea..f557bc1 100644
--- a/src/libopensc/pkcs15-prkey.c
+++ b/src/libopensc/pkcs15-prkey.c
@@ -27,16 +27,15 @@
 #include <stdio.h>
 #include <assert.h>
 
-#include "internal.h"
-#include "asn1.h"
-#include "pkcs15.h"
-#include "common/compat_strlcpy.h"
-#include "aux-data.h"
-
 #ifdef ENABLE_OPENSSL
+#include <openssl/opensslv.h>
+#include <openssl/bn.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
 	#ifndef OPENSSL_NO_EC
 	#include <openssl/ec.h>
@@ -44,6 +43,12 @@
 #endif
 #endif
 
+#include "internal.h"
+#include "asn1.h"
+#include "pkcs15.h"
+#include "common/compat_strlcpy.h"
+#include "aux-data.h"
+
 /*
  * in src/libopensc/types.h SC_MAX_SUPPORTED_ALGORITHMS  defined as 8
  */
@@ -625,23 +630,30 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key)
 {
 #ifdef ENABLE_OPENSSL
 	EVP_PKEY *pk = (EVP_PKEY *)evp_key;
+	int pk_type;
+	 pk_type = EVP_PKEY_base_id(pk);
 
-	switch (pk->type) {
+	switch (pk_type) {
 	case EVP_PKEY_RSA: {
 		struct sc_pkcs15_prkey_rsa *dst = &pkcs15_key->u.rsa;
 		RSA *src = EVP_PKEY_get1_RSA(pk);
+		const BIGNUM *src_n, *src_e, *src_d, *src_p, *src_q, *src_iqmp, *src_dmp1, *src_dmq1;
+
+		RSA_get0_key(src, &src_n, &src_e, &src_d);
+		RSA_get0_factors(src, &src_p, &src_q);
+		RSA_get0_crt_params(src, &src_dmp1, &src_dmq1, &src_iqmp);
 
 		pkcs15_key->algorithm = SC_ALGORITHM_RSA;
-		if (!sc_pkcs15_convert_bignum(&dst->modulus, src->n)
-		 || !sc_pkcs15_convert_bignum(&dst->exponent, src->e)
-		 || !sc_pkcs15_convert_bignum(&dst->d, src->d)
-		 || !sc_pkcs15_convert_bignum(&dst->p, src->p)
-		 || !sc_pkcs15_convert_bignum(&dst->q, src->q))
+		if (!sc_pkcs15_convert_bignum(&dst->modulus, src_n)
+		 || !sc_pkcs15_convert_bignum(&dst->exponent, src_e)
+		 || !sc_pkcs15_convert_bignum(&dst->d, src_d)
+		 || !sc_pkcs15_convert_bignum(&dst->p, src_p)
+		 || !sc_pkcs15_convert_bignum(&dst->q, src_q))
 			return SC_ERROR_NOT_SUPPORTED;
-		if (src->iqmp && src->dmp1 && src->dmq1) {
-			sc_pkcs15_convert_bignum(&dst->iqmp, src->iqmp);
-			sc_pkcs15_convert_bignum(&dst->dmp1, src->dmp1);
-			sc_pkcs15_convert_bignum(&dst->dmq1, src->dmq1);
+		if (src_iqmp && src_dmp1 && src_dmq1) {
+			sc_pkcs15_convert_bignum(&dst->iqmp, src_iqmp);
+			sc_pkcs15_convert_bignum(&dst->dmp1, src_dmp1);
+			sc_pkcs15_convert_bignum(&dst->dmq1, src_dmq1);
 		}
 		RSA_free(src);
 		break;
@@ -649,13 +661,17 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key)
 	case EVP_PKEY_DSA: {
 		struct sc_pkcs15_prkey_dsa *dst = &pkcs15_key->u.dsa;
 		DSA *src = EVP_PKEY_get1_DSA(pk);
+		const BIGNUM *src_pub_key, *src_p, *src_q, *src_g, *src_priv_key;
+
+		DSA_get0_key(src, &src_pub_key, &src_priv_key);
+		DSA_get0_pqg(src, &src_p, &src_q, &src_g);
 
 		pkcs15_key->algorithm = SC_ALGORITHM_DSA;
-		sc_pkcs15_convert_bignum(&dst->pub, src->pub_key);
-		sc_pkcs15_convert_bignum(&dst->p, src->p);
-		sc_pkcs15_convert_bignum(&dst->q, src->q);
-		sc_pkcs15_convert_bignum(&dst->g, src->g);
-		sc_pkcs15_convert_bignum(&dst->priv, src->priv_key);
+		sc_pkcs15_convert_bignum(&dst->pub, src_pub_key);
+		sc_pkcs15_convert_bignum(&dst->p, src_p);
+		sc_pkcs15_convert_bignum(&dst->q, src_q);
+		sc_pkcs15_convert_bignum(&dst->g, src_g);
+		sc_pkcs15_convert_bignum(&dst->priv, src_priv_key);
 		DSA_free(src);
 		break;
 		}
diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c
index 92cc762..d121776 100644
--- a/src/libopensc/pkcs15-pubkey.c
+++ b/src/libopensc/pkcs15-pubkey.c
@@ -34,11 +34,8 @@
 #include <unistd.h>
 #endif
 
-#include "internal.h"
-#include "asn1.h"
-#include "pkcs15.h"
-
 #ifdef ENABLE_OPENSSL
+#include <openssl/bn.h>
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
 #include <openssl/evp.h>
@@ -50,6 +47,11 @@
 #endif
 #endif
 
+#include "internal.h"
+#include "asn1.h"
+#include "pkcs15.h"
+
+
 #define C_ASN1_PKINFO_ATTR_SIZE 3
 static const struct sc_asn1_entry c_asn1_pkinfo[C_ASN1_PKINFO_ATTR_SIZE] = {
 		{ "algorithm", SC_ASN1_ALGORITHM_ID,  SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
@@ -1544,14 +1546,19 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key)
 {
 #ifdef ENABLE_OPENSSL
 	EVP_PKEY *pk = (EVP_PKEY *)evp_key;
+	int pk_type;
+	pk_type = EVP_PKEY_base_id(pk);
 
-	switch (pk->type) {
+	switch (pk_type) {
 	case EVP_PKEY_RSA: {
 		struct sc_pkcs15_pubkey_rsa *dst = &pkcs15_key->u.rsa;
 		RSA *src = EVP_PKEY_get1_RSA(pk);
+		const BIGNUM *src_n, *src_e;
+
+		RSA_get0_key(src, &src_n, &src_e, NULL);
 
 		pkcs15_key->algorithm = SC_ALGORITHM_RSA;
-		if (!sc_pkcs15_convert_bignum(&dst->modulus, src->n) || !sc_pkcs15_convert_bignum(&dst->exponent, src->e))
+		if (!sc_pkcs15_convert_bignum(&dst->modulus, src_n) || !sc_pkcs15_convert_bignum(&dst->exponent, src_e))
 			return SC_ERROR_INVALID_DATA;
 		RSA_free(src);
 		break;
@@ -1559,12 +1566,16 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key)
 	case EVP_PKEY_DSA: {
 		struct sc_pkcs15_pubkey_dsa *dst = &pkcs15_key->u.dsa;
 		DSA *src = EVP_PKEY_get1_DSA(pk);
+		const BIGNUM *src_pub_key, *src_priv_key, *src_p, *src_q, *src_g;
+
+		DSA_get0_key(src, &src_pub_key, &src_priv_key);
+		DSA_get0_pqg(src, &src_p, &src_q, &src_g);
 
 		pkcs15_key->algorithm = SC_ALGORITHM_DSA;
-		sc_pkcs15_convert_bignum(&dst->pub, src->pub_key);
-		sc_pkcs15_convert_bignum(&dst->p, src->p);
-		sc_pkcs15_convert_bignum(&dst->q, src->q);
-		sc_pkcs15_convert_bignum(&dst->g, src->g);
+		sc_pkcs15_convert_bignum(&dst->pub, src_pub_key);
+		sc_pkcs15_convert_bignum(&dst->p, src_p);
+		sc_pkcs15_convert_bignum(&dst->q, src_q);
+		sc_pkcs15_convert_bignum(&dst->g, src_g);
 		DSA_free(src);
 		break;
 	}
diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h
new file mode 100644
index 0000000..42f0ca6
--- /dev/null
+++ b/src/libopensc/sc-ossl-compat.h
@@ -0,0 +1,240 @@
+/*
+ * sc-ossl-compat.h: OpenSC ecompatability for older OpenSSL versions
+ *
+ * Copyright (C) 2016	Douglas E. Engert <deengert at gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _SC_OSSL_COMPAT_H
+#define _SC_OSSL_COMPAT_H
+
+#ifdef ENABLE_OPENSSL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <openssl/opensslv.h>
+#include <openssl/opensslconf.h>
+/*
+ * Provide backward compatability to older versions of OpenSSL
+ * while using most of OpenSSL 1.1  API
+ */
+
+/*
+ * EVP_CIPHER_CTX functions:
+ * EVP_CIPHER_CTX_new	    not in 0.9.7
+ * EVP_CIPHER_CTX_free	    not in 0.9.7
+ * EVP_CIPHER_CTX_init	    in 0.9.7 to 1.0.2. defined in 1.1 as EVP_CIPHER_CTX_reset
+ * EVP_CIPHER_CTX_cleanup   in 0.9.7 to 1.0.2, defined in 1.1 as EVP_CIPHER_CTX_reset
+ * EVP_CIPHER_CTX_reset	    only in 1.1
+ *
+ * EVP_CIPHER_CTX_new	    does a EVP_CIPHER_CTX_init
+ * EVP_CIPHER_CTX_free	    does a EVP_CIPHER_CTX_cleanup
+ * EVP_CIPHER_CTX_cleanup   does equivelent of a EVP_CIPHER_CTX_init
+ * Use EVP_CIPHER_CTX_new, EVP_CIPHER_CTX_free, and  EVP_CIPHER_CTX_cleanup between operations
+ */
+
+#if OPENSSL_VERSION_NUMBER  <= 0x009070dfL
+
+/* in 0.9.7  EVP_CIPHER_CTX was always allocated inline or in other structures */
+
+#define EVP_CIPHER_CTX_new() ({ \
+	EVP_CIPHER_CTX * tmp = NULL; \
+	tmp = OPENSSL_malloc(sizeof(struct evp_cipher_ctx_st)); \
+	if (tmp) { \
+	EVP_CIPHER_CTX_init(tmp); \
+	} \
+	tmp; \
+	})
+
+#define EVP_CIPHER_CTX_free(x) ({ \
+	if (x) { \
+		EVP_CIPHER_CTX_cleanup(x); \
+		OPENSSL_free(x); \
+	} \
+	})
+#endif /* OPENSSL_VERSION_NUMBER =< 0x00907000L */
+
+/*
+ * 1.1 renames RSA_PKCS1_SSLeay to RSA_PKCS1_OpenSSL
+ * use RSA_PKCS1_OpenSSL
+ * Previous versions are missing a number of functions to access
+ * some hidden structures. Define them here:
+ */
+
+/*  EVP_PKEY_base_id introduced in 1.0.1 */
+#if OPENSSL_VERSION_NUMBER < 0x10001000L
+#define EVP_PKEY_base_id(x)		(x->type)
+#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define RSA_PKCS1_OpenSSL		RSA_PKCS1_SSLeay
+#define OPENSSL_malloc_init		CRYPTO_malloc_init
+
+#define EVP_PKEY_get0_RSA(x)		(x->pkey.rsa)
+#define EVP_PKEY_get0_DSA(x)		(x->pkey.dsa)
+#define X509_get_extension_flags(x)	(x->ex_flags)
+#define X509_get_key_usage(x)		(x->ex_kusage)
+#define X509_get_extended_key_usage(x)	(x->ex_xkusage)
+#define EVP_PKEY_up_ref(user_key)	CRYPTO_add(&user_key->references, 1, CRYPTO_LOCK_EVP_PKEY)
+#define X509_up_ref(cert)		CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509)
+#endif
+
+/*
+ * OpenSSL-1.1.0-pre5 has hidden the RSA and DSA structures
+ * One can no longer use statements like rsa->n = ...
+ * Macros and defines don't work on all systems, so use inline versions
+ * If that is not good enough, versions could be added to libopensc
+ */
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+/* based on OpenSSL-1.1.0 e_os2.h */
+/* sc_ossl_inline: portable inline definition usable in public headers */
+# if !defined(inline) && !defined(__cplusplus)
+#  if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
+   /* just use inline */
+#   define sc_ossl_inline inline
+#  elif defined(__GNUC__) && __GNUC__>=2
+#   define sc_ossl_inline __inline__
+#  elif defined(_MSC_VER)
+#   define sc_ossl_inline __inline
+#  else
+#   define sc_ossl_inline
+#  endif
+# else
+#  define sc_ossl_inline inline
+# endif
+#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
+#define RSA_bits(R) (BN_num_bits(R->n))
+
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+
+#ifndef OPENSSL_NO_RSA
+static sc_ossl_inline int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
+{
+    /* d is the private component and may be NULL */
+    if (n == NULL || e == NULL)
+        return 0;
+
+    BN_free(r->n);
+    BN_free(r->e);
+    BN_free(r->d);
+    r->n = n;
+    r->e = e;
+    r->d = d;
+
+    return 1;
+}
+
+static sc_ossl_inline int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
+{
+    if (p == NULL || q == NULL)
+        return 0;
+
+    BN_free(r->p);
+    BN_free(r->q);
+    r->p = p;
+    r->q = q;
+
+    return 1;
+}
+
+static sc_ossl_inline int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
+{
+    if (dmp1 == NULL || dmq1 == NULL || iqmp == NULL)
+        return 0;
+
+    BN_free(r->dmp1);
+    BN_free(r->dmq1);
+    BN_free(r->iqmp);
+    r->dmp1 = dmp1;
+    r->dmq1 = dmq1;
+    r->iqmp = iqmp;
+
+    return 1;
+}
+
+static sc_ossl_inline void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
+{
+    if (n != NULL)
+        *n = r->n;
+    if (e != NULL)
+        *e = r->e;
+    if (d != NULL)
+        *d = r->d;
+}
+
+static sc_ossl_inline void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
+{
+    if (p != NULL)
+        *p = r->p;
+    if (q != NULL)
+        *q = r->q;
+}
+
+static sc_ossl_inline void RSA_get0_crt_params(const RSA *r,
+                         const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp)
+{
+    if (dmp1 != NULL)
+        *dmp1 = r->dmp1;
+    if (dmq1 != NULL)
+        *dmq1 = r->dmq1;
+    if (iqmp != NULL)
+        *iqmp = r->iqmp;
+}
+
+#endif /* OPENSSL_NO_RSA */
+
+#ifndef OPENSSL_NO_DSA
+static sc_ossl_inline void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+    if (p != NULL)
+        *p = d->p;
+    if (q != NULL)
+        *q = d->q;
+    if (g != NULL)
+        *g = d->g;
+}
+
+static sc_ossl_inline void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key)
+{
+    if (pub_key != NULL)
+        *pub_key = d->pub_key;
+    if (priv_key != NULL)
+        *priv_key = d->priv_key;
+}
+
+/* NOTE: DSA_set0_*  functions not defined because they are not currently used in OpenSC */
+#endif /* OPENSSL_NO_DSA */
+
+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* ENABLE_OPENSSL */
+#endif /* _SC_OSSL_COMPAT_H */
diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c
index 4431e69..a625432 100644
--- a/src/pkcs11/openssl.c
+++ b/src/pkcs11/openssl.c
@@ -9,6 +9,7 @@
 
 #ifdef ENABLE_OPENSSL		/* empty file without openssl */
 #include <string.h>
+#include <openssl/bn.h>
 #include <openssl/evp.h>
 #include <openssl/rand.h>
 #include <openssl/rsa.h>
@@ -170,18 +171,25 @@ void
 sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card)
 {
 #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_ENGINE)
-	void (*locking_cb)(int, int, const char *, int);
 	ENGINE *e;
+/* crypto locking removed in 1.1 */
+#if OPENSSL_VERSION_NUMBER  < 0x10100000L
+	void (*locking_cb)(int, int, const char *, int);
 
 	locking_cb = CRYPTO_get_locking_callback();
 	if (locking_cb)
 		CRYPTO_set_locking_callback(NULL);
+#endif
 
 	e = ENGINE_by_id("gost");
 	if (!e)
 	{
 #if !defined(OPENSSL_NO_STATIC_ENGINE) && !defined(OPENSSL_NO_GOST) && !defined(LIBRESSL_VERSION_NUMBER)
+
+/* ENGINE_load_gost removed in 1.1 */
+#if OPENSSL_VERSION_NUMBER  < 0x10100000L
 		ENGINE_load_gost();
+#endif
 		e = ENGINE_by_id("gost");
 #else
 		/* try to load dynamic gost engine */
@@ -202,8 +210,10 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card)
 		ENGINE_free(e);
 	}
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 	if (locking_cb)
 		CRYPTO_set_locking_callback(locking_cb);
+#endif
 #endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_ENGINE) */
 
 	openssl_sha1_mech.mech_data = EVP_sha1();
diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c
index 942f9bf..72a4b4a 100644
--- a/src/pkcs15init/pkcs15-lib.c
+++ b/src/pkcs15init/pkcs15-lib.c
@@ -2175,44 +2175,52 @@ prkey_fixup_rsa(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey_rsa *key)
 	 * The cryptoflex does not seem to be able to do any sort
 	 * of RSA without the full set of CRT coefficients either
 	 */
+	 /* We don't really need an RSA structure, only the BIGNUMs */
+
 	if (!key->dmp1.len || !key->dmq1.len || !key->iqmp.len) {
 		static u8 dmp1[256], dmq1[256], iqmp[256];
-		RSA    *rsa;
 		BIGNUM *aux;
 		BN_CTX *bn_ctx;
+		BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_p, *rsa_q, *rsa_dmp1, *rsa_dmq1, *rsa_iqmp;
 
-		rsa = RSA_new();
-		rsa->n = BN_bin2bn(key->modulus.data, key->modulus.len, NULL);
-		rsa->e = BN_bin2bn(key->exponent.data, key->exponent.len, NULL);
-		rsa->d = BN_bin2bn(key->d.data, key->d.len, NULL);
-		rsa->p = BN_bin2bn(key->p.data, key->p.len, NULL);
-		rsa->q = BN_bin2bn(key->q.data, key->q.len, NULL);
-		if (!rsa->dmp1)
-			rsa->dmp1 = BN_new();
-		if (!rsa->dmq1)
-			rsa->dmq1 = BN_new();
-		if (!rsa->iqmp)
-			rsa->iqmp = BN_new();
+		rsa_n = BN_bin2bn(key->modulus.data, key->modulus.len, NULL);
+		rsa_e = BN_bin2bn(key->exponent.data, key->exponent.len, NULL);
+		rsa_d = BN_bin2bn(key->d.data, key->d.len, NULL);
+		rsa_p = BN_bin2bn(key->p.data, key->p.len, NULL);
+		rsa_q = BN_bin2bn(key->q.data, key->q.len, NULL);
+		rsa_dmp1 = BN_new();
+		rsa_dmq1 = BN_new();
+		rsa_iqmp = BN_new();
 
 		aux = BN_new();
 		bn_ctx = BN_CTX_new();
 
-		BN_sub(aux, rsa->q, BN_value_one());
-		BN_mod(rsa->dmq1, rsa->d, aux, bn_ctx);
+		BN_sub(aux, rsa_q, BN_value_one());
+		BN_mod(rsa_dmq1, rsa_d, aux, bn_ctx);
 
-		BN_sub(aux, rsa->p, BN_value_one());
-		BN_mod(rsa->dmp1, rsa->d, aux, bn_ctx);
+		BN_sub(aux, rsa_p, BN_value_one());
+		BN_mod(rsa_dmp1, rsa_d, aux, bn_ctx);
 
-		BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, bn_ctx);
+		BN_mod_inverse(rsa_iqmp, rsa_q, rsa_p, bn_ctx);
 
 		BN_clear_free(aux);
 		BN_CTX_free(bn_ctx);
 
 		/* Not thread safe, but much better than a memory leak */
-		GETBN(key->dmp1, rsa->dmp1, dmp1);
-		GETBN(key->dmq1, rsa->dmq1, dmq1);
-		GETBN(key->iqmp, rsa->iqmp, iqmp);
-		RSA_free(rsa);
+		/* TODO put on stack, or allocate and clear and then free */
+		GETBN(key->dmp1, rsa_dmp1, dmp1);
+		GETBN(key->dmq1, rsa_dmq1, dmq1);
+		GETBN(key->iqmp, rsa_iqmp, iqmp);
+
+		BN_clear_free(rsa_n);
+		BN_clear_free(rsa_e);
+		BN_clear_free(rsa_d);
+		BN_clear_free(rsa_p);
+		BN_clear_free(rsa_q);
+		BN_clear_free(rsa_dmp1);
+		BN_clear_free(rsa_dmq1);
+		BN_clear_free(rsa_iqmp);
+
 	}
 #undef GETBN
 #endif
diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c
index cda907a..48797e4 100644
--- a/src/pkcs15init/pkcs15-oberthur-awp.c
+++ b/src/pkcs15init/pkcs15-oberthur-awp.c
@@ -27,12 +27,13 @@
 #include <sys/types.h>
 
 #include "config.h"
+#include "pkcs15-oberthur.h"
+
 #include "libopensc/opensc.h"
 #include "libopensc/cardctl.h"
 #include "libopensc/log.h"
 #include "profile.h"
 #include "pkcs15-init.h"
-#include "pkcs15-oberthur.h"
 #include "libopensc/asn1.h"
 
 #ifdef ENABLE_OPENSSL
@@ -996,6 +997,30 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob
 	/*
 	 * serial number
 	 */
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+	
+	/* TODO the der encoding of a ANS1_INTEGER is a TLV, the original code only as using the 
+	 * i2c_ASN1_INTEGER which is not in OpenSSL 1.1  
+	 * It was adding the tag V_ASN1_INTEGER and the one byte length back in in effect creating
+	 * a DER encoded ASN1_INTEGER
+	 * So we can simplifty the code and make compatable with OpenSSL 1.1. This needs to be tested
+	 */
+	ci->serial.len = 0;
+	ci->serial.value = NULL;
+	/* get length */
+	ci->serial.len = i2d_ASN1_INTEGER(X509_get_serialNumber(x), NULL);
+	if (ci->serial.len > 0) {
+		if (!(ci->serial.value = malloc(ci->serial.len)))   {
+			ci->serial.len = 0;
+			r = SC_ERROR_OUT_OF_MEMORY;
+			goto done;
+		}
+		ci->serial.len = i2d_ASN1_INTEGER(X509_get_serialNumber(x), &ci->serial.value);
+	}
+	/* if len == 0, and value == NULL, then the cert did not have a serial number.*/
+	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "cert. serial encoded length %i", ci->serial.len);
+
+#else
 	do   {
 		int encoded_len;
 		unsigned char encoded[0x40], *encoded_ptr;
@@ -1015,6 +1040,7 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob
 
 		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "cert. serial encoded length %i", encoded_len);
 	} while (0);
+#endif
 
 	ci->x509 = X509_dup(x);
 done:
diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c
index 200f110..8ecc9c6 100644
--- a/src/pkcs15init/pkcs15-oberthur.c
+++ b/src/pkcs15init/pkcs15-oberthur.c
@@ -20,20 +20,15 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include "pkcs15-oberthur.h"
 #include <sys/types.h>
 #include <ctype.h>
 
-#include "config.h"
 #include "libopensc/opensc.h"
 #include "libopensc/cardctl.h"
 #include "libopensc/log.h"
 #include "profile.h"
 #include "pkcs15-init.h"
-#include "pkcs15-oberthur.h"
 
 #define COSM_TITLE "OberthurAWP"
 
diff --git a/src/pkcs15init/pkcs15-oberthur.h b/src/pkcs15init/pkcs15-oberthur.h
index 0b0b775..6528e59 100644
--- a/src/pkcs15init/pkcs15-oberthur.h
+++ b/src/pkcs15init/pkcs15-oberthur.h
@@ -9,6 +9,7 @@
 #include "config.h"
 
 #ifdef ENABLE_OPENSSL
+#include <openssl/opensslv.h>
 #include <openssl/bn.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
@@ -18,6 +19,10 @@
 #include <openssl/pkcs12.h>
 #include <openssl/x509v3.h>
 
+#include "profile.h"
+#include "libopensc/opensc.h"
+
+
 #define COSM_TLV_TAG		0x00
 
 #define TLV_TYPE_V	0
diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c
index 023ede6..f666c71 100644
--- a/src/pkcs15init/pkcs15-westcos.c
+++ b/src/pkcs15init/pkcs15-westcos.c
@@ -26,6 +26,7 @@
 
 #ifdef ENABLE_OPENSSL
 #include <openssl/opensslv.h>
+#include <openssl/bn.h>
 #include <openssl/rsa.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
@@ -33,6 +34,7 @@
 #include <openssl/bio.h>
 #endif
 
+#include "libopensc/sc-ossl-compat.h"
 #include "libopensc/opensc.h"
 #include "libopensc/cardctl.h"
 #include "pkcs15-init.h"
@@ -255,7 +257,7 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile,
 		goto out;
 	}
 
-	rsa->meth = RSA_PKCS1_SSLeay();
+	RSA_set_method(rsa, RSA_PKCS1_OpenSSL());
 
 	if(pubkey != NULL)
 	{
diff --git a/src/tools/cryptoflex-tool.c b/src/tools/cryptoflex-tool.c
index 109aa35..d9e8674 100644
--- a/src/tools/cryptoflex-tool.c
+++ b/src/tools/cryptoflex-tool.c
@@ -217,8 +217,8 @@ static int parse_public_key(const u8 *key, size_t keysize, RSA *rsa)
 	if (e == NULL)
 		return -1;
 	cf2bn(p, 4, e);
-	rsa->n = n;
-	rsa->e = e;
+	if (RSA_set0_key(rsa, n, e, NULL) != 1)
+	    return -1;
 	return 0;
 }
 
@@ -226,6 +226,8 @@ static int gen_d(RSA *rsa)
 {
 	BN_CTX *bnctx;
 	BIGNUM *r0, *r1, *r2;
+	const BIGNUM *rsa_p, *rsa_q, *rsa_n, *rsa_e, *rsa_d;
+	BIGNUM *rsa_n_new, *rsa_e_new, *rsa_d_new;
 
 	bnctx = BN_CTX_new();
 	if (bnctx == NULL)
@@ -234,13 +236,25 @@ static int gen_d(RSA *rsa)
 	r0 = BN_CTX_get(bnctx);
 	r1 = BN_CTX_get(bnctx);
 	r2 = BN_CTX_get(bnctx);
-	BN_sub(r1, rsa->p, BN_value_one());
-	BN_sub(r2, rsa->q, BN_value_one());
+	RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
+	RSA_get0_factors(rsa, &rsa_p, &rsa_q);
+
+	BN_sub(r1, rsa_p, BN_value_one());
+	BN_sub(r2, rsa_q, BN_value_one());
 	BN_mul(r0, r1, r2, bnctx);
-	if ((rsa->d = BN_mod_inverse(NULL, rsa->e, r0, bnctx)) == NULL) {
+	if ((rsa_d_new = BN_mod_inverse(NULL, rsa_e, r0, bnctx)) == NULL) {
 		fprintf(stderr, "BN_mod_inverse() failed.\n");
 		return -1;
 	}
+
+	/* RSA_set0_key will free previous value, and replace with new value
+	 * Thus the need to copy the contents of rsa_n and rsa_e
+	 */
+	rsa_n_new = BN_dup(rsa_n);
+	rsa_e_new = BN_dup(rsa_e);
+	if (RSA_set0_key(rsa, rsa_n_new, rsa_e_new, rsa_d_new) != 1)
+		return -1;
+
 	BN_CTX_end(bnctx);
 	BN_CTX_free(bnctx);
 	return 0;
@@ -288,11 +302,11 @@ static int parse_private_key(const u8 *key, size_t keysize, RSA *rsa)
 	cf2bn(p, base, dmq1);
 	p += base;
 
-	rsa->p = bn_p;
-	rsa->q = q;
-	rsa->dmp1 = dmp1;
-	rsa->dmq1 = dmq1;
-	rsa->iqmp = iqmp;
+	
+	if (RSA_set0_factors(rsa, bn_p, q) != 1)
+		return -1;
+	if (RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) != 1)
+		return -1;
 	if (gen_d(rsa))
 		return -1;
 
@@ -648,8 +662,9 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize)
 	u8 bnbuf[256];
 	int base = 0;
 	int r;
+	const BIGNUM *rsa_p, *rsa_q, *rsa_dmp1, *rsa_dmq1, *rsa_iqmp;
 
-	switch (BN_num_bits(rsa->n)) {
+	switch (RSA_bits(rsa)) {
 	case 512:
 		base = 32;
 		break;
@@ -670,7 +685,10 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize)
 	*p++ = (5 * base + 3) >> 8;
 	*p++ = (5 * base + 3) & 0xFF;
 	*p++ = opt_key_num;
-	r = bn2cf(rsa->p, bnbuf);
+
+	RSA_get0_factors(rsa, &rsa_p, &rsa_q);
+
+	r = bn2cf(rsa_p, bnbuf);
 	if (r != base) {
 		fprintf(stderr, "Invalid private key.\n");
 		return 2;
@@ -678,7 +696,7 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize)
 	memcpy(p, bnbuf, base);
 	p += base;
 
-	r = bn2cf(rsa->q, bnbuf);
+	r = bn2cf(rsa_q, bnbuf);
 	if (r != base) {
 		fprintf(stderr, "Invalid private key.\n");
 		return 2;
@@ -686,7 +704,9 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize)
 	memcpy(p, bnbuf, base);
 	p += base;
 
-	r = bn2cf(rsa->iqmp, bnbuf);
+	RSA_get0_crt_params(rsa, &rsa_dmp1, &rsa_dmq1, &rsa_iqmp);
+
+	r = bn2cf(rsa_iqmp, bnbuf);
 	if (r != base) {
 		fprintf(stderr, "Invalid private key.\n");
 		return 2;
@@ -694,7 +714,7 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize)
 	memcpy(p, bnbuf, base);
 	p += base;
 
-	r = bn2cf(rsa->dmp1, bnbuf);
+	r = bn2cf(rsa_dmp1, bnbuf);
 	if (r != base) {
 		fprintf(stderr, "Invalid private key.\n");
 		return 2;
@@ -702,7 +722,7 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize)
 	memcpy(p, bnbuf, base);
 	p += base;
 
-	r = bn2cf(rsa->dmq1, bnbuf);
+	r = bn2cf(rsa_dmq1, bnbuf);
 	if (r != base) {
 		fprintf(stderr, "Invalid private key.\n");
 		return 2;
@@ -722,8 +742,9 @@ static int encode_public_key(RSA *rsa, u8 *key, size_t *keysize)
 	u8 bnbuf[256];
 	int base = 0;
 	int r;
+	const BIGNUM *rsa_n, *rsa_e;
 
-	switch (BN_num_bits(rsa->n)) {
+	switch (RSA_bits(rsa)) {
 	case 512:
 		base = 32;
 		break;
@@ -744,7 +765,9 @@ static int encode_public_key(RSA *rsa, u8 *key, size_t *keysize)
 	*p++ = (5 * base + 7) >> 8;
 	*p++ = (5 * base + 7) & 0xFF;
 	*p++ = opt_key_num;
-	r = bn2cf(rsa->n, bnbuf);
+
+	RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL);
+	r = bn2cf(rsa_n, bnbuf);
 	if (r != 2*base) {
 		fprintf(stderr, "Invalid public key.\n");
 		return 2;
@@ -758,7 +781,7 @@ static int encode_public_key(RSA *rsa, u8 *key, size_t *keysize)
 	memset(bnbuf, 0, 2*base);
 	memcpy(p, bnbuf, 2*base);
 	p += 2*base;
-	r = bn2cf(rsa->e, bnbuf);
+	r = bn2cf(rsa_e, bnbuf);
 	memcpy(p, bnbuf, 4);
 	p += 4;
 
diff --git a/src/tools/gids-tool.c b/src/tools/gids-tool.c
index f3febe6..029c53f 100644
--- a/src/tools/gids-tool.c
+++ b/src/tools/gids-tool.c
@@ -36,6 +36,7 @@
 #include <openssl/evp.h>
 #include <openssl/err.h>
 
+#include "libopensc/sc-ossl-compat.h"
 #include "libopensc/opensc.h"
 #include "libopensc/cardctl.h"
 #include "libopensc/card-gids.h"
@@ -521,7 +522,9 @@ int main(int argc, char * const argv[])
 		}
 	}
 
-	CRYPTO_malloc_init();
+	/* OpenSSL magic */
+	OPENSSL_malloc_init();
+
 	ERR_load_crypto_strings();
 	OpenSSL_add_all_algorithms();
 
diff --git a/src/tools/netkey-tool.c b/src/tools/netkey-tool.c
index 6aef644..2c52d67 100644
--- a/src/tools/netkey-tool.c
+++ b/src/tools/netkey-tool.c
@@ -144,9 +144,9 @@ static void show_certs(sc_card_t *card)
 			printf(", Len=%d\n", (q[2]<<8)|q[3]);
 			if((c=d2i_X509(NULL,&q,f->size))){
 				char buf2[2000];
-				X509_NAME_get_text_by_NID(c->cert_info->subject, NID_commonName, buf2,sizeof(buf2));
+				X509_NAME_get_text_by_NID(X509_get_subject_name(c), NID_commonName, buf2,sizeof(buf2));
 				printf("  Subject-CN: %s\n", buf2);
-				X509_NAME_get_text_by_NID(c->cert_info->issuer, NID_commonName, buf2,sizeof(buf2));
+				X509_NAME_get_text_by_NID(X509_get_issuer_name(c), NID_commonName, buf2,sizeof(buf2));
 				printf("  Issuer-CN:  %s\n", buf2);
 				X509_free(c);
 			} else printf("  Invalid Certificate-Data\n");
diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c
index 647a432..422004c 100644
--- a/src/tools/piv-tool.c
+++ b/src/tools/piv-tool.c
@@ -45,6 +45,7 @@
 #include <openssl/err.h>
 #include <openssl/obj_mac.h>
 
+#include "libopensc/sc-ossl-compat.h"
 #include "libopensc/opensc.h"
 #include "libopensc/cardctl.h"
 #include "libopensc/asn1.h"
@@ -329,19 +330,25 @@ static int gen_key(const char * key_info)
 
 	if (keydata.key_bits > 0) { /* RSA key */
 		RSA * newkey = NULL;
+		BIGNUM *newkey_n, *newkey_e;
 
 		newkey = RSA_new();
 		if (newkey == NULL) {
 			fprintf(stderr, "gen_key RSA_new failed %d\n",r);
 			return -1;
 		}
-		newkey->n = BN_bin2bn(keydata.pubkey, keydata.pubkey_len, newkey->n);
+		newkey_n = BN_bin2bn(keydata.pubkey, keydata.pubkey_len, NULL);
 		expl = keydata.exponent;
 		expc[3] = (u8) expl & 0xff;
 		expc[2] = (u8) (expl >>8) & 0xff;
 		expc[1] = (u8) (expl >>16) & 0xff;
 		expc[0] = (u8) (expl >>24) & 0xff;
-		newkey->e =  BN_bin2bn(expc, 4,  newkey->e);
+		newkey_e =  BN_bin2bn(expc, 4, NULL);
+
+		if (RSA_set0_key(newkey, newkey_n, newkey_e, NULL) != 1) {
+			fprintf(stderr, "gen_key unable to set RSA values");
+			return -1;
+		}
 
 		if (verbose)
 			RSA_print_fp(stdout, newkey,0);
@@ -534,14 +541,15 @@ int main(int argc, char * const argv[])
 	if (action_count == 0)
 		util_print_usage_and_die(app_name, options, option_help, NULL);
 
-	CRYPTO_malloc_init();
+	OPENSSL_malloc_init();
 	ERR_load_crypto_strings();
 	OpenSSL_add_all_algorithms();
 
 
 	if (out_file) {
 		bp = BIO_new(BIO_s_file());
-		BIO_write_filename(bp, (char *)out_file);
+		if (!BIO_write_filename(bp, (char *)out_file))
+		    goto end;
 	} else {
 		bp = BIO_new(BIO_s_file());
 		BIO_set_fp(bp,stdout,BIO_NOCLOSE);
diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c
index 0587db1..2d9b610 100644
--- a/src/tools/pkcs11-tool.c
+++ b/src/tools/pkcs11-tool.c
@@ -37,12 +37,15 @@
 #include <openssl/opensslv.h>
 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
 #include <openssl/opensslconf.h>
+#include <openssl/crypto.h>
 #endif
 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
 #include <openssl/conf.h>
 #endif
 #include <openssl/evp.h>
 #include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/asn1t.h>
 #include <openssl/rsa.h>
 #include <openssl/pem.h>
 #if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA)
@@ -53,6 +56,7 @@
 #include <openssl/err.h>
 #endif
 
+#include "libopensc/sc-ossl-compat.h"
 #include "pkcs11/pkcs11.h"
 #include "pkcs11/pkcs11-opensc.h"
 #include "libopensc/asn1.h"
@@ -456,12 +460,20 @@ int main(int argc, char * argv[])
 #endif
 
 #ifdef ENABLE_OPENSSL
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L && OPENSSL_VERSION_NUMBER < 0x10100000L
 	OPENSSL_config(NULL);
 #endif
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+	OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS
+		| OPENSSL_INIT_ADD_ALL_CIPHERS
+		| OPENSSL_INIT_ADD_ALL_DIGESTS
+		| OPENSSL_INIT_LOAD_CONFIG,
+		NULL);
+#else
 	/* OpenSSL magic */
-	SSLeay_add_all_algorithms();
-	CRYPTO_malloc_init();
+	OpenSSL_add_all_algorithms();
+	OPENSSL_malloc_init();
+#endif
 #endif
 	while (1) {
 		c = getopt_long(argc, argv, "ILMOTa:bd:e:hi:klm:o:p:scvf:ty:w:z:r",
@@ -1960,36 +1972,37 @@ static void	parse_certificate(struct x509cert_info *cert,
 		util_fatal("OpenSSL error during X509 certificate parsing");
 	}
 	/* check length first */
-	n = i2d_X509_NAME(x->cert_info->subject, NULL);
+	n = i2d_X509_NAME(X509_get_subject_name(x), NULL);
 	if (n < 0)
 		util_fatal("OpenSSL error while encoding subject name");
 	if (n > (int)sizeof (cert->subject))
 		util_fatal("subject name too long");
 	/* green light, actually do it */
 	p = cert->subject;
-	n = i2d_X509_NAME(x->cert_info->subject, &p);
+	n = i2d_X509_NAME(X509_get_subject_name(x), &p);
 	cert->subject_len = n;
 
 	/* check length first */
-	n = i2d_X509_NAME(x->cert_info->issuer, NULL);
+	n = i2d_X509_NAME(X509_get_issuer_name(x), NULL);
 	if (n < 0)
 		util_fatal("OpenSSL error while encoding issuer name");
 	if (n > (int)sizeof (cert->issuer))
 		util_fatal("issuer name too long");
 	/* green light, actually do it */
 	p = cert->issuer;
-	n = i2d_X509_NAME(x->cert_info->issuer, &p);
+	n =i2d_X509_NAME(X509_get_issuer_name(x), &p);
 	cert->issuer_len = n;
 
 	/* check length first */
-	n = i2d_ASN1_INTEGER(x->cert_info->serialNumber, NULL);
+	n = 0;
+	n = i2d_ASN1_INTEGER(X509_get_serialNumber(x), NULL);
 	if (n < 0)
 		util_fatal("OpenSSL error while encoding serial number");
 	if (n > (int)sizeof (cert->serialnum))
 		util_fatal("serial number too long");
 	/* green light, actually do it */
 	p = cert->serialnum;
-	n = i2d_ASN1_INTEGER(x->cert_info->serialNumber, &p);
+	n = i2d_ASN1_INTEGER(X509_get_serialNumber(x), &p);
 	cert->serialnum_len = n;
 }
 
@@ -2023,16 +2036,24 @@ do_read_key(unsigned char *data, size_t data_len, int private, EVP_PKEY **key)
 
 #define RSA_GET_BN(RSA, LOCALNAME, BNVALUE) \
 	do { \
-		RSA->LOCALNAME = malloc(BN_num_bytes(BNVALUE)); \
-		if (!RSA->LOCALNAME) \
-			util_fatal("malloc() failure"); \
-		RSA->LOCALNAME##_len = BN_bn2bin(BNVALUE, RSA->LOCALNAME); \
+		if (BNVALUE) { \
+			RSA->LOCALNAME = malloc(BN_num_bytes(BNVALUE)); \
+			if (!RSA->LOCALNAME) \
+				util_fatal("malloc() failure\n"); \
+			RSA->LOCALNAME##_len = BN_bn2bin(BNVALUE, RSA->LOCALNAME); \
+		} else { \
+			RSA->LOCALNAME##_len = 0; \
+			RSA->LOCALNAME = NULL; \
+		} \
 	} while (0)
 
 static int
 parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa)
 {
 	RSA *r;
+	const BIGNUM *r_n, *r_e, *r_d;
+	const BIGNUM *r_p, *r_q;
+	const BIGNUM *r_dmp1, *r_dmq1, *r_iqmp;
 
 	r = EVP_PKEY_get1_RSA(pkey);
 	if (!r) {
@@ -2042,15 +2063,22 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa)
 			util_fatal("OpenSSL error during RSA public key parsing");
 	}
 
-	RSA_GET_BN(rsa, modulus, r->n);
-	RSA_GET_BN(rsa, public_exponent, r->e);
+	RSA_get0_key(r, &r_n, &r_e, NULL);
+	RSA_GET_BN(rsa, modulus, r_n);
+	RSA_GET_BN(rsa, public_exponent, r_e);
+
 	if (private) {
-		RSA_GET_BN(rsa, private_exponent, r->d);
-		RSA_GET_BN(rsa, prime_1, r->p);
-		RSA_GET_BN(rsa, prime_2, r->q);
-		RSA_GET_BN(rsa, exponent_1, r->dmp1);
-		RSA_GET_BN(rsa, exponent_2, r->dmq1);
-		RSA_GET_BN(rsa, coefficient, r->iqmp);
+		RSA_get0_key(r, NULL, NULL, &r_d);
+		RSA_GET_BN(rsa, private_exponent, r_d);
+
+		RSA_get0_factors(r, &r_p, &r_q);
+		RSA_GET_BN(rsa, prime_1, r_p);
+		RSA_GET_BN(rsa, prime_2, r_q);
+
+		RSA_get0_crt_params(r, &r_dmp1, &r_dmq1, &r_iqmp);
+		RSA_GET_BN(rsa, exponent_1, r_dmp1);
+		RSA_GET_BN(rsa, exponent_2, r_dmq1);
+		RSA_GET_BN(rsa, coefficient, r_iqmp);
 	}
 
 	RSA_free(r);
@@ -2200,6 +2228,7 @@ static int write_object(CK_SESSION_HANDLE session)
 	struct rsakey_info rsa;
 	struct gostkey_info gost;
 	EVP_PKEY *evp_key = NULL;
+	int pk_type;
 
 	memset(&cert, 0, sizeof(cert));
 	memset(&rsa,  0, sizeof(rsa));
@@ -2253,20 +2282,22 @@ static int write_object(CK_SESSION_HANDLE session)
 				util_fatal("Cannot read public key");
 		}
 
-		if (evp_key->type == EVP_PKEY_RSA) {
+		pk_type = EVP_PKEY_base_id(evp_key);
+
+		if (pk_type == EVP_PKEY_RSA)   {
 			rv = parse_rsa_pkey(evp_key, is_private, &rsa);
 		}
 #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC)
-		else if (evp_key->type == NID_id_GostR3410_2001) {
+		else if (pk_type == NID_id_GostR3410_2001)   {
 			rv = parse_gost_pkey(evp_key, is_private, &gost);
 			type = CKK_GOSTR3410;
-		} else if (evp_key->type == EVP_PKEY_EC) {
+		} else if (pk_type == EVP_PKEY_EC) {
 			rv = parse_ec_pkey(evp_key, is_private, &gost);
 			type = CKK_EC;
 		}
 #endif
 		else
-			util_fatal("Unsupported key type: 0x%X", evp_key->type);
+			util_fatal("Unsupported key type: 0x%X", pk_type);
 
 		if (rv)
 			util_fatal("Cannot parse key");
@@ -2344,9 +2375,12 @@ static int write_object(CK_SESSION_HANDLE session)
 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_SUBJECT, cert.subject, cert.subject_len);
 			n_privkey_attr++;
 		}
-		FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type));
-		n_privkey_attr++;
-		if (evp_key->type == EVP_PKEY_RSA)   {
+		pk_type = EVP_PKEY_base_id(evp_key);
+
+		if (pk_type == EVP_PKEY_RSA)   {
+			type = CKK_RSA;
+			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type));
+			n_privkey_attr++;
 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_MODULUS, rsa.modulus, rsa.modulus_len);
 			n_privkey_attr++;
 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_PUBLIC_EXPONENT, rsa.public_exponent, rsa.public_exponent_len);
@@ -2365,13 +2399,21 @@ static int write_object(CK_SESSION_HANDLE session)
 			n_privkey_attr++;
 		}
 #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC)
-		else if (evp_key->type == EVP_PKEY_EC)   {
+		else if (pk_type == EVP_PKEY_EC)   {
+			type = CKK_EC;
+
+			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type));
+			n_privkey_attr++;
 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_EC_PARAMS, gost.param_oid.value, gost.param_oid.len);
 			n_privkey_attr++;
 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, gost.private.value, gost.private.len);
 			n_privkey_attr++;
 		}
-		else if (evp_key->type == NID_id_GostR3410_2001)   {
+		else if (pk_type == NID_id_GostR3410_2001)   {
+			type = CKK_GOSTR3410;
+
+			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type));
+			n_privkey_attr++;
 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_GOSTR3410_PARAMS, gost.param_oid.value, gost.param_oid.len);
 			n_privkey_attr++;
 			FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, gost.private.value, gost.private.len);
@@ -2389,16 +2431,17 @@ static int write_object(CK_SESSION_HANDLE session)
 	if (opt_object_class == CKO_PUBLIC_KEY) {
 		clazz = CKO_PUBLIC_KEY;
 #ifdef ENABLE_OPENSSL
-		if (evp_key->type == EVP_PKEY_RSA)
+		pk_type = EVP_PKEY_base_id(evp_key);
+		if (pk_type == EVP_PKEY_RSA)
 			type = CKK_RSA;
 #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC)
-		else if (evp_key->type == EVP_PKEY_EC)
+		else if (pk_type == EVP_PKEY_EC)
 			type = CKK_EC;
-		else if (evp_key->type == NID_id_GostR3410_2001)
+		else if (pk_type == NID_id_GostR3410_2001)
 			type = CKK_GOSTR3410;
 #endif
 		else
-			util_fatal("Unsupported public key type: 0x%X", evp_key->type);
+			util_fatal("Unsupported public key type: 0x%X", pk_type);
 #endif
 
 		n_pubkey_attr = 0;
@@ -2444,22 +2487,34 @@ static int write_object(CK_SESSION_HANDLE session)
 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_SUBJECT, cert.subject, cert.subject_len);
 			n_pubkey_attr++;
 		}
-		FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type));
-		n_pubkey_attr++;
-		if (evp_key->type == EVP_PKEY_RSA) {
-			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_MODULUS, rsa.modulus, rsa.modulus_len);
+		pk_type = EVP_PKEY_base_id(evp_key);
+
+		if (pk_type == EVP_PKEY_RSA) {
+			type = CKK_RSA;
+			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type));
+			n_pubkey_attr++;
+			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_MODULUS,
+				rsa.modulus, rsa.modulus_len);
 			n_pubkey_attr++;
 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_PUBLIC_EXPONENT, rsa.public_exponent, rsa.public_exponent_len);
 			n_pubkey_attr++;
 		}
 #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC)
-		else if (evp_key->type == EVP_PKEY_EC)   {
+		else if (pk_type == EVP_PKEY_EC)   {
+			type = CKK_EC;
+
+			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type));
+			n_pubkey_attr++;
 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_EC_PARAMS, gost.param_oid.value, gost.param_oid.len);
 			n_pubkey_attr++;
 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_EC_POINT, gost.public.value, gost.public.len);
 			n_pubkey_attr++;
 		}
-		else if (evp_key->type == NID_id_GostR3410_2001) {
+		else if (pk_type == NID_id_GostR3410_2001) {
+			type = CKK_GOSTR3410;
+
+			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type));
+			n_pubkey_attr++;
 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_GOSTR3410_PARAMS, gost.param_oid.value, gost.param_oid.len);
 			n_pubkey_attr++;
 			FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_VALUE, gost.public.value, gost.public.len);
@@ -3446,25 +3501,31 @@ static int read_object(CK_SESSION_HANDLE session)
 		type = getKEY_TYPE(session, obj);
 		if (type == CKK_RSA) {
 			RSA *rsa;
+			BIGNUM *rsa_n = NULL;
+			BIGNUM *rsa_e = NULL;
+
 
 			rsa = RSA_new();
 			if (rsa == NULL)
 				util_fatal("out of memory");
 
 			if ((value = getMODULUS(session, obj, &len))) {
-				if (!(rsa->n = BN_bin2bn(value, len, rsa->n)))
+				if (!(rsa_n = BN_bin2bn(value, len, NULL)))
 					util_fatal("cannot parse MODULUS");
 				free(value);
 			} else
 				util_fatal("cannot obtain MODULUS");
 
 			if ((value = getPUBLIC_EXPONENT(session, obj, &len))) {
-				if (!(rsa->e = BN_bin2bn(value, len, rsa->e)))
+				if (!(rsa_e = BN_bin2bn(value, len, NULL)))
 					util_fatal("cannot parse PUBLIC_EXPONENT");
 				free(value);
 			} else
 				util_fatal("cannot obtain PUBLIC_EXPONENT");
 
+			if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) != 1)
+				util_fatal("cannot set RSA values");
+
 			if (!i2d_RSA_PUBKEY_bio(pout, rsa))
 				util_fatal("cannot convert RSA public key to DER");
 			RSA_free(rsa);
@@ -3802,6 +3863,7 @@ static EVP_PKEY *get_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE priv
 	CK_ULONG        pubkeyLen;
 	EVP_PKEY       *pkey;
 	RSA            *rsa;
+	BIGNUM *rsa_n, *rsa_e;
 
 	id = NULL;
 	id = getID(session, privKeyObject, &idLen);
@@ -3835,8 +3897,11 @@ static EVP_PKEY *get_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE priv
 					free(exp);
 				return NULL;
 			}
-			rsa->n = BN_bin2bn(mod, modLen, NULL);
-			rsa->e = BN_bin2bn(exp, expLen, NULL);
+			rsa_n = BN_bin2bn(mod, modLen, NULL);
+			rsa_e =	BN_bin2bn(exp, expLen, NULL);
+			if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) != 1)
+			    return NULL;
+
 			EVP_PKEY_assign_RSA(pkey, rsa);
 			free(mod);
 			free(exp);
@@ -4410,7 +4475,7 @@ static int wrap_unwrap(CK_SESSION_HANDLE session,
 	CK_OBJECT_HANDLE cipherKeyObject;
 	CK_RV           rv;
 	EVP_PKEY       *pkey;
-	EVP_CIPHER_CTX	seal_ctx;
+	EVP_CIPHER_CTX	* seal_ctx;
 	unsigned char	keybuf[512], *key = keybuf;
 	int		key_len;
 	unsigned char	iv[32], ciphered[1024], cleartext[1024];
@@ -4426,7 +4491,13 @@ static int wrap_unwrap(CK_SESSION_HANDLE session,
 
 	printf("    %s: ", OBJ_nid2sn(EVP_CIPHER_nid(algo)));
 
-	if (!EVP_SealInit(&seal_ctx, algo,
+	seal_ctx = EVP_CIPHER_CTX_new();
+	if (seal_ctx == NULL) {
+		printf("Internal error.\n");
+		return 1;
+	}
+
+	if (!EVP_SealInit(seal_ctx, algo,
 			&key, &key_len,
 			iv, &pkey, 1)) {
 		fprintf(stderr, "Internal error.\n");
@@ -4435,15 +4506,15 @@ static int wrap_unwrap(CK_SESSION_HANDLE session,
 
 	/* Encrypt something */
 	len = sizeof(ciphered);
-	if (!EVP_SealUpdate(&seal_ctx, ciphered, &len, (const unsigned char *) "hello world", 11)) {
-		fprintf(stderr, "Internal error.\n");
+	if (!EVP_SealUpdate(seal_ctx, ciphered, &len, (const unsigned char *) "hello world", 11)) {
+		printf("Internal error.\n");
 		return 1;
 	}
 	ciphered_len = len;
 
 	len = sizeof(ciphered) - ciphered_len;
-	if (!EVP_SealFinal(&seal_ctx, ciphered + ciphered_len, &len)) {
-		fprintf(stderr, "Internal error.\n");
+	if (!EVP_SealFinal(seal_ctx, ciphered + ciphered_len, &len)) {
+		printf("Internal error.\n");
 		return 1;
 	}
 	ciphered_len += len;
@@ -4479,21 +4550,21 @@ static int wrap_unwrap(CK_SESSION_HANDLE session,
 		return 1;
 	}
 
-	if (!EVP_DecryptInit(&seal_ctx, algo, key, iv)) {
-		fprintf(stderr, "Internal error.\n");
+	if (!EVP_DecryptInit(seal_ctx, algo, key, iv)) {
+		printf("Internal error.\n");
 		return 1;
 	}
 
 	len = sizeof(cleartext);
-	if (!EVP_DecryptUpdate(&seal_ctx, cleartext, &len, ciphered, ciphered_len)) {
-		fprintf(stderr, "Internal error.\n");
+	if (!EVP_DecryptUpdate(seal_ctx, cleartext, &len, ciphered, ciphered_len)) {
+		printf("Internal error.\n");
 		return 1;
 	}
 
 	cleartext_len = len;
 	len = sizeof(cleartext) - len;
-	if (!EVP_DecryptFinal(&seal_ctx, cleartext + cleartext_len, &len)) {
-		fprintf(stderr, "Internal error.\n");
+	if (!EVP_DecryptFinal(seal_ctx, cleartext + cleartext_len, &len)) {
+		printf("Internal error.\n");
 		return 1;
 	}
 	cleartext_len += len;
@@ -4504,6 +4575,9 @@ static int wrap_unwrap(CK_SESSION_HANDLE session,
 		return 1;
 	}
 
+	if (seal_ctx)
+	    EVP_CIPHER_CTX_free(seal_ctx);
+
 	printf("OK\n");
 	return 0;
 }
diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c
index 6d8487e..3652f96 100644
--- a/src/tools/pkcs15-init.c
+++ b/src/tools/pkcs15-init.c
@@ -52,6 +52,7 @@
 #include <openssl/pkcs12.h>
 #include <openssl/x509v3.h>
 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
+#include <openssl/crypto.h>
 #include <openssl/opensslconf.h> /* for OPENSSL_NO_EC */
 #ifndef OPENSSL_NO_EC
 #include <openssl/ec.h>
@@ -59,6 +60,7 @@
 #endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L */
 
 #include "common/compat_strlcpy.h"
+#include "libopensc/sc-ossl-compat.h"
 #include "libopensc/cardctl.h"
 #include "libopensc/pkcs15.h"
 #include "libopensc/log.h"
@@ -434,12 +436,22 @@ main(int argc, char **argv)
 	unsigned int		n;
 	int			r = 0;
 
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L && OPENSSL_VERSION_NUMBER < 0x10100000L
 	OPENSSL_config(NULL);
 #endif
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+	/* Openssl 1.1.0 magic */
+	OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS
+		| OPENSSL_INIT_ADD_ALL_CIPHERS
+		| OPENSSL_INIT_ADD_ALL_DIGESTS
+		| OPENSSL_INIT_LOAD_CONFIG,
+		NULL);
+#else
 	/* OpenSSL magic */
-	SSLeay_add_all_algorithms();
-	CRYPTO_malloc_init();
+	OpenSSL_add_all_algorithms();
+	OPENSSL_malloc_init();
+#endif
+
 #ifdef RANDOM_POOL
 	if (!RAND_load_file(RANDOM_POOL, 32))
 		util_fatal("Unable to seed random number pool for key generation");
@@ -909,7 +921,7 @@ do_store_private_key(struct sc_profile *profile)
 
 		printf("Importing %d certificates:\n", opt_ignore_ca_certs ? 1 : ncerts);
 		for (i = 0; i < ncerts && !(i && opt_ignore_ca_certs); i++)
-			printf("  %d: %s\n", i, X509_NAME_oneline(cert[i]->cert_info->subject,
+			printf("  %d: %s\n", i, X509_NAME_oneline(X509_get_subject_name(cert[i]),
 					namebuf, sizeof(namebuf)));
 	}
 
@@ -923,7 +935,7 @@ do_store_private_key(struct sc_profile *profile)
 
 		/* tell openssl to cache the extensions */
 		X509_check_purpose(cert[0], -1, -1);
-		usage = cert[0]->ex_kusage;
+		usage = X509_get_extended_key_usage(cert[0]);
 
 		/* No certificate usage? Assume ordinary
 		 * user cert */
@@ -973,10 +985,11 @@ do_store_private_key(struct sc_profile *profile)
 			return r;
 
 		X509_check_purpose(cert[i], -1, -1);
-		cargs.x509_usage = cert[i]->ex_kusage;
+		cargs.x509_usage = X509_get_extended_key_usage(cert[i]);
+
 		cargs.label = cert_common_name(cert[i]);
 		if (!cargs.label)
-			cargs.label = X509_NAME_oneline(cert[i]->cert_info->subject, namebuf, sizeof(namebuf));
+			cargs.label = X509_NAME_oneline(X509_get_subject_name(cert[i]), namebuf, sizeof(namebuf));
 
 		/* Just the first certificate gets the same ID
 		 * as the private key. All others get
@@ -1116,6 +1129,7 @@ do_read_check_certificate(sc_pkcs15_cert_t *sc_oldcert,
 {
 	X509 *oldcert, *newcert;
 	EVP_PKEY *oldpk, *newpk;
+	int oldpk_type, newpk_type;
 	const u8 *ptr;
 	int r;
 
@@ -1136,19 +1150,30 @@ do_read_check_certificate(sc_pkcs15_cert_t *sc_oldcert,
 	oldpk = X509_get_pubkey(oldcert);
 	newpk = X509_get_pubkey(newcert);
 
+	oldpk_type = EVP_PKEY_base_id(oldpk);
+	newpk_type = EVP_PKEY_base_id(newpk);
+
 	/* Compare the public keys, there's no high level openssl function for this(?) */
+	/* Yes there is in 1.0.2 and above EVP_PKEY_cmp */
+
+
 	r = SC_ERROR_INVALID_ARGUMENTS;
-	if (oldpk->type == newpk->type)
+	if (oldpk_type == newpk_type)
 	{
-		if ((oldpk->type == EVP_PKEY_DSA) &&
-			!BN_cmp(oldpk->pkey.dsa->p, newpk->pkey.dsa->p) &&
-			!BN_cmp(oldpk->pkey.dsa->q, newpk->pkey.dsa->q) &&
-			!BN_cmp(oldpk->pkey.dsa->g, newpk->pkey.dsa->g))
+#if  OPENSSL_VERSION_NUMBER >= 0x10002000L
+		if (EVP_PKEY_cmp(oldpk, newpk) == 1)
+			r = 0;
+#else
+		if ((oldpk_type == EVP_PKEY_DSA) &&
+			!BN_cmp(EVP_PKEY_get0_DSA(oldpk)->p, EVP_PKEY_get0_DSA(newpk)->p) &&
+			!BN_cmp(EVP_PKEY_get0_DSA(oldpk)->q, EVP_PKEY_get0_DSA(newpk)->q) &&
+			!BN_cmp(EVP_PKEY_get0_DSA(oldpk)->g, EVP_PKEY_get0_DSA(newpk)->g))
 				r = 0;
-		else if ((oldpk->type == EVP_PKEY_RSA) &&
-			!BN_cmp(oldpk->pkey.rsa->n, newpk->pkey.rsa->n) &&
-			!BN_cmp(oldpk->pkey.rsa->e, newpk->pkey.rsa->e))
+		else if ((oldpk_type == EVP_PKEY_RSA) &&
+			!BN_cmp(EVP_PKEY_get0_RSA(oldpk)->n, EVP_PKEY_get0_RSA(newpk)->n) &&
+			!BN_cmp(EVP_PKEY_get0_RSA(oldpk)->e, EVP_PKEY_get0_RSA(newpk)->e))
 				r = 0;
+#endif
 	}
 
 	EVP_PKEY_free(newpk);
@@ -2004,7 +2029,8 @@ do_read_pkcs12_private_key(const char *filename, const char *passphrase,
 		return SC_ERROR_CANNOT_LOAD_KEY;
 	}
 
-	CRYPTO_add(&user_key->references, 1, CRYPTO_LOCK_EVP_PKEY);
+	EVP_PKEY_up_ref(user_key);
+
 	if (user_cert && max_certs)
 		certs[ncerts++] = user_cert;
 
@@ -2014,7 +2040,7 @@ do_read_pkcs12_private_key(const char *filename, const char *passphrase,
 
 	/* bump reference counts for certificates */
 	for (i = 0; i < ncerts; i++) {
-		CRYPTO_add(&certs[i]->references, 1, CRYPTO_LOCK_X509);
+		X509_up_ref(certs[i]);
 	}
 
 	if (cacerts)
diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c
index a36902f..4efc1b1 100644
--- a/src/tools/sc-hsm-tool.c
+++ b/src/tools/sc-hsm-tool.c
@@ -32,6 +32,8 @@
 #include <sys/stat.h>
 
 /* Requires openssl for dkek import */
+#include <openssl/opensslv.h>
+
 #include <openssl/opensslconf.h>
 #include <openssl/bio.h>
 #include <openssl/evp.h>
@@ -39,6 +41,7 @@
 #include <openssl/rand.h>
 #include <openssl/err.h>
 
+#include "libopensc/sc-ossl-compat.h"
 #include "libopensc/opensc.h"
 #include "libopensc/cardctl.h"
 #include "libopensc/asn1.h"
@@ -123,8 +126,8 @@ static const char *option_help[] = {
 };
 
 typedef struct {
-	BIGNUM x;
-	BIGNUM y;
+	BIGNUM * x;
+	BIGNUM * y;
 } secret_share_t;
 
 static sc_context_t *ctx = NULL;
@@ -157,7 +160,11 @@ static int generatePrime(BIGNUM *prime, const BIGNUM *s, const int bits, unsigne
 
 	do {
 		// Generate random prime
+#if OPENSSL_VERSION_NUMBER  >= 0x00908000L /* last parm is BN_GENCB which is null in our case */
+		BN_generate_prime_ex(prime, bits, 1, NULL, NULL, NULL);
+#else
 		BN_generate_prime(prime, bits, 1, NULL, NULL, NULL, NULL );
+#endif
 
 	} while ((BN_ucmp(prime, s) == -1) && (max_rounds-- > 0));	// If prime < s or not reached 1000 tries
 
@@ -179,21 +186,20 @@ static int generatePrime(BIGNUM *prime, const BIGNUM *s, const int bits, unsigne
  * @param prime Prime for finite field arithmetic
  * @param y Pointer for storage of calculated y-value
  */
-static void calculatePolynomialValue(const BIGNUM x, BIGNUM **polynomial, const unsigned char t, const BIGNUM prime, BIGNUM *y)
+static void calculatePolynomialValue(const BIGNUM *x, BIGNUM **polynomial, const unsigned char t, const BIGNUM *prime, BIGNUM *y)
 {
 	BIGNUM **pp;
-	BIGNUM temp;
-	BIGNUM exponent;
+	BIGNUM *temp;
+	BIGNUM *exponent;
 
 	unsigned long exp;
 	BN_CTX *ctx;
 
 	// Create context for temporary variables of OpenSSL engine
 	ctx = BN_CTX_new();
-	BN_CTX_init(ctx);
 
-	BN_init(&temp);
-	BN_init(&exponent);
+	temp = BN_new();
+	exponent = BN_new();
 
 	// Set y to ZERO
 	BN_zero(y);
@@ -206,21 +212,21 @@ static void calculatePolynomialValue(const BIGNUM x, BIGNUM **polynomial, const
 
 	for (exp = 1; exp < t; exp++) {
 
-		BN_copy(&temp, &x);
+		BN_copy(temp, x);
 
-		BN_set_word(&exponent, exp);
+		BN_set_word(exponent, exp);
 		// temp = x^exponent mod prime
-		BN_mod_exp(&temp, &x, &exponent, &prime, ctx);
+		BN_mod_exp(temp, x, exponent, prime, ctx);
 		// exponent = temp * a = a * x^exponent mod prime
-		BN_mod_mul(&exponent, &temp, *pp, &prime, ctx);
+		BN_mod_mul(exponent, temp, *pp, prime, ctx);
 		// add the temp value from exponent to y
-		BN_copy(&temp, y);
-		BN_mod_add(y, &temp, &exponent, &prime, ctx);
+		BN_copy(temp, y);
+		BN_mod_add(y, temp, exponent, prime, ctx);
 		pp++;
 	}
 
-	BN_clear_free(&temp);
-	BN_clear_free(&exponent);
+	BN_clear_free(temp);
+	BN_clear_free(exponent);
 
 	BN_CTX_free(ctx);
 }
@@ -236,7 +242,7 @@ static void calculatePolynomialValue(const BIGNUM x, BIGNUM **polynomial, const
  * @param prime Prime for finite field arithmetic
  * @param shares Pointer for storage of calculated shares (must be big enough to hold n shares)
  */
-static int createShares(const BIGNUM *s, const unsigned char t, const unsigned char n,	const BIGNUM prime, secret_share_t *shares)
+static int createShares(const BIGNUM *s, const unsigned char t, const unsigned char n,	const BIGNUM *prime, secret_share_t *shares)
 {
 	// Array representing the polynomial a(x) = s + a_1 * x + ... + a_n-1 * x^n-1 mod p
 	BIGNUM **polynomial = malloc(n * sizeof(BIGNUM *));
@@ -247,26 +253,23 @@ static int createShares(const BIGNUM *s, const unsigned char t, const unsigned c
 	// Set the secret value as the constant part of the polynomial
 	pp = polynomial;
 	*pp = BN_new();
-	BN_init(*pp);
 	BN_copy(*pp, s);
 	pp++;
 
 	// Initialize and generate some random values for coefficients a_x in the remaining polynomial
 	for (i = 1; i < t; i++) {
 		*pp = BN_new();
-		BN_init(*pp);
-		BN_rand_range(*pp, &prime);
+		BN_rand_range(*pp, prime);
 		pp++;
 	}
 
 	sp = shares;
 	// Now calculate n secret shares
 	for (i = 1; i <= n; i++) {
-		BN_init(&(sp->x));
-		BN_init(&(sp->y));
-
-		BN_set_word(&(sp->x), i);
-		calculatePolynomialValue(sp->x, polynomial, t, prime, &(sp->y));
+		sp->x = BN_new();
+		sp->y = BN_new();
+		BN_set_word((sp->x), i);
+		calculatePolynomialValue(sp->x, polynomial, t, prime, (sp->y));
 		sp++;
 	}
 
@@ -292,7 +295,7 @@ static int createShares(const BIGNUM *s, const unsigned char t, const unsigned c
  * @param prime Prime for finite field arithmetic
  * @param s Pointer for storage of calculated secred
  */
-static int reconstructSecret(secret_share_t *shares, unsigned char t, const BIGNUM prime, BIGNUM *s)
+static int reconstructSecret(secret_share_t *shares, unsigned char t, const BIGNUM *prime, BIGNUM *s)
 {
 	unsigned char i;
 	unsigned char j;
@@ -300,9 +303,9 @@ static int reconstructSecret(secret_share_t *shares, unsigned char t, const BIGN
 	// Array representing the polynomial a(x) = s + a_1 * x + ... + a_n-1 * x^n-1 mod p
 	BIGNUM **bValue = malloc(t * sizeof(BIGNUM *));
 	BIGNUM **pbValue;
-	BIGNUM numerator;
-	BIGNUM denominator;
-	BIGNUM temp;
+	BIGNUM * numerator;
+	BIGNUM * denominator;
+	BIGNUM * temp;
 	secret_share_t *sp_i;
 	secret_share_t *sp_j;
 	BN_CTX *ctx;
@@ -311,24 +314,22 @@ static int reconstructSecret(secret_share_t *shares, unsigned char t, const BIGN
 	pbValue = bValue;
 	for (i = 0; i < t; i++) {
 		*pbValue = BN_new();
-		BN_init(*pbValue);
 		pbValue++;
 	}
 
-	BN_init(&numerator);
-	BN_init(&denominator);
-	BN_init(&temp);
+	numerator = BN_new();
+	denominator = BN_new();
+	temp = BN_new();
 
 	// Create context for temporary variables of engine
 	ctx = BN_CTX_new();
-	BN_CTX_init(ctx);
 
 	pbValue = bValue;
 	sp_i = shares;
 	for (i = 0; i < t; i++) {
 
-		BN_one(&numerator);
-		BN_one(&denominator);
+		BN_one(numerator);
+		BN_one(denominator);
 
 		sp_j = shares;
 
@@ -339,9 +340,9 @@ static int reconstructSecret(secret_share_t *shares, unsigned char t, const BIGN
 				continue;
 			}
 
-			BN_mul(&numerator, &numerator, &(sp_j->x), ctx);
-			BN_sub(&temp, &(sp_j->x), &(sp_i->x));
-			BN_mul(&denominator, &denominator, &temp, ctx);
+			BN_mul(numerator, numerator, (sp_j->x), ctx);
+			BN_sub(temp, (sp_j->x), (sp_i->x));
+			BN_mul(denominator, denominator, temp, ctx);
 
 			sp_j++;
 		}
@@ -350,12 +351,12 @@ static int reconstructSecret(secret_share_t *shares, unsigned char t, const BIGN
 		 * Use the modular inverse value of the denominator for the
 		 * multiplication
 		 */
-		if (BN_mod_inverse(&denominator, &denominator, &prime, ctx) == NULL ) {
+		if (BN_mod_inverse(denominator, denominator, prime, ctx) == NULL ) {
 			free(bValue);
 			return -1;
 		}
 
-		BN_mod_mul(*pbValue, &numerator, &denominator, &prime, ctx);
+		BN_mod_mul(*pbValue, numerator, denominator, prime, ctx);
 
 		pbValue++;
 		sp_i++;
@@ -370,19 +371,19 @@ static int reconstructSecret(secret_share_t *shares, unsigned char t, const BIGN
 	BN_zero(s);
 	for (i = 0; i < t; i++) {
 
-		BN_mul(&temp, &(sp_i->y), *pbValue, ctx);
-		BN_add(s, s, &temp);
+		BN_mul(temp, (sp_i->y), *pbValue, ctx);
+		BN_add(s, s, temp);
 		pbValue++;
 		sp_i++;
 	}
 
 	// Perform modulo operation and copy result
-	BN_nnmod(&temp, s, &prime, ctx);
-	BN_copy(s, &temp);
+	BN_nnmod(temp, s, prime, ctx);
+	BN_copy(s, temp);
 
-	BN_clear_free(&numerator);
-	BN_clear_free(&denominator);
-	BN_clear_free(&temp);
+	BN_clear_free(numerator);
+	BN_clear_free(denominator);
+	BN_clear_free(temp);
 
 	BN_CTX_free(ctx);
 
@@ -413,8 +414,8 @@ static int cleanUpShares(secret_share_t *shares, unsigned char n)
 
 	sp = shares;
 	for (i = 0; i < n; i++) {
-		BN_clear_free(&(sp->x));
-		BN_clear_free(&(sp->y));
+		BN_clear_free((sp->x));
+		BN_clear_free((sp->y));
 		sp++;
 	}
 
@@ -640,8 +641,8 @@ static int initialize(sc_card_t *card, const char *so_pin, const char *user_pin,
 static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_password_shares)
 {
 	int r, i;
-	BIGNUM prime;
-	BIGNUM secret;
+	BIGNUM *prime;
+	BIGNUM *secret;
 	BIGNUM *p;
 	char inbuf[64];
 	unsigned char bin[64];
@@ -658,8 +659,8 @@ static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_pas
 	/*
 	 * Initialize prime and secret
 	 */
-	BN_init(&prime);
-	BN_init(&secret);
+	prime = BN_new();
+	secret = BN_new();
 
 	// Allocate data buffer for the shares
 	shares = malloc(num_of_password_shares * sizeof(secret_share_t));
@@ -676,7 +677,7 @@ static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_pas
 	}
 	binlen = 64;
 	sc_hex_to_bin(inbuf, bin, &binlen);
-	BN_bin2bn(bin, binlen, &prime);
+	BN_bin2bn(bin, binlen, prime);
 
 	sp = shares;
 	for (i = 0; i < num_of_password_shares; i++) {
@@ -687,8 +688,8 @@ static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_pas
 
 		clearScreen();
 
-		BN_init(&(sp->x));
-		BN_init(&(sp->y));
+		sp->x = BN_new();
+		sp->y = BN_new();
 
 		printf("Share %i of %i\n\n", i + 1, num_of_password_shares);
 
@@ -698,7 +699,7 @@ static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_pas
 			fprintf(stderr, "Input aborted\n");
 			return -1;
 		}
-		p = &(sp->x);
+		p = (sp->x);
 		BN_hex2bn(&p, inbuf);
 
 		printf("Please enter share value: ");
@@ -709,14 +710,14 @@ static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_pas
 		}
 		binlen = 64;
 		sc_hex_to_bin(inbuf, bin, &binlen);
-		BN_bin2bn(bin, binlen, &(sp->y));
+		BN_bin2bn(bin, binlen, (sp->y));
 
 		sp++;
 	}
 
 	clearScreen();
 
-	r = reconstructSecret(shares, num_of_password_shares, prime, &secret);
+	r = reconstructSecret(shares, num_of_password_shares, prime, secret);
 
 	if (r < 0) {
 		printf("\nError during reconstruction of secret. Wrong shares?\n");
@@ -728,14 +729,14 @@ static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_pas
 	 * Encode the secret value
 	 */
 	ip = (unsigned char *) inbuf;
-	*pwdlen = BN_bn2bin(&secret, ip);
+	*pwdlen = BN_bn2bin(secret, ip);
 	*pwd = calloc(1, *pwdlen);
 	memcpy(*pwd, ip, *pwdlen);
 
 	cleanUpShares(shares, num_of_password_shares);
 
-	BN_clear_free(&prime);
-	BN_clear_free(&secret);
+	BN_clear_free(prime);
+	BN_clear_free(secret);
 
 	return 0;
 }
@@ -745,7 +746,7 @@ static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_pas
 static int import_dkek_share(sc_card_t *card, const char *inf, int iter, const char *password, int num_of_password_shares)
 {
 	sc_cardctl_sc_hsm_dkek_t dkekinfo;
-	EVP_CIPHER_CTX ctx;
+	EVP_CIPHER_CTX *ctx = NULL;
 	FILE *in = NULL;
 	u8 filebuff[64],key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH],outbuff[64];
 	char *pwd = NULL;
@@ -803,14 +804,14 @@ static int import_dkek_share(sc_card_t *card, const char *inf, int iter, const c
 		free(pwd);
 	}
 
-	EVP_CIPHER_CTX_init(&ctx);
-	EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, iv);
-	if (!EVP_DecryptUpdate(&ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16)) {
+	ctx = EVP_CIPHER_CTX_new();
+	EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
+	if (!EVP_DecryptUpdate(ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16)) {
 		fprintf(stderr, "Error decrypting DKEK share. Password correct ?\n");
 		return -1;
 	}
 
-	if (!EVP_DecryptFinal_ex(&ctx, outbuff + outlen, &r)) {
+	if (!EVP_DecryptFinal_ex(ctx, outbuff + outlen, &r)) {
 		fprintf(stderr, "Error decrypting DKEK share. Password correct ?\n");
 		return -1;
 	}
@@ -824,7 +825,7 @@ static int import_dkek_share(sc_card_t *card, const char *inf, int iter, const c
 	r = sc_card_ctl(card, SC_CARDCTL_SC_HSM_IMPORT_DKEK_SHARE, (void *)&dkekinfo);
 
 	OPENSSL_cleanse(&dkekinfo.dkek_share, sizeof(dkekinfo.dkek_share));
-	EVP_CIPHER_CTX_cleanup(&ctx);
+	EVP_CIPHER_CTX_free(ctx);
 
 	if (r == SC_ERROR_INS_NOT_SUPPORTED) {			// Not supported or not initialized for key shares
 		fprintf(stderr, "Not supported by card or card not initialized for key share usage\n");
@@ -845,7 +846,7 @@ static int print_dkek_share(sc_card_t *card, const char *inf, int iter, const ch
 	// hex output can be used in the SCSH shell with the 
 	// decrypt_keyblob.js file
 	sc_cardctl_sc_hsm_dkek_t dkekinfo;
-	EVP_CIPHER_CTX ctx;
+	EVP_CIPHER_CTX *ctx = NULL;
 	FILE *in = NULL;
 	u8 filebuff[64],key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH],outbuff[64];
 	char *pwd = NULL;
@@ -904,14 +905,14 @@ static int print_dkek_share(sc_card_t *card, const char *inf, int iter, const ch
 		free(pwd);
 	}
 
-	EVP_CIPHER_CTX_init(&ctx);
-	EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, iv);
-	if (!EVP_DecryptUpdate(&ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16)) {
+	ctx = EVP_CIPHER_CTX_new();
+	EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
+	if (!EVP_DecryptUpdate(ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16)) {
 		fprintf(stderr, "Error decrypting DKEK share. Password correct ?\n");
 		return -1;
 	}
 
-	if (!EVP_DecryptFinal_ex(&ctx, outbuff + outlen, &r)) {
+	if (!EVP_DecryptFinal_ex(ctx, outbuff + outlen, &r)) {
 		fprintf(stderr, "Error decrypting DKEK share. Password correct ?\n");
 		return -1;
 	}
@@ -931,7 +932,7 @@ static int print_dkek_share(sc_card_t *card, const char *inf, int iter, const ch
 	printf("\n\n");
 
 	OPENSSL_cleanse(&dkekinfo.dkek_share, sizeof(dkekinfo.dkek_share));
-	EVP_CIPHER_CTX_cleanup(&ctx);
+	EVP_CIPHER_CTX_free(ctx);
 
 	if (r == SC_ERROR_INS_NOT_SUPPORTED) {			// Not supported or not initialized for key shares
 		fprintf(stderr, "Not supported by card or card not initialized for key share usage\n");
@@ -987,8 +988,8 @@ static void ask_for_password(char **pwd, int *pwdlen)
 static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int password_shares_threshold, int password_shares_total)
 {
 	int r, i;
-	BIGNUM prime;
-	BIGNUM secret;
+	BIGNUM *prime;
+	BIGNUM *secret;
 	unsigned char buf[64];
 	char hex[64];
 	int l;
@@ -1044,13 +1045,13 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas
 	/*
 	 * Initialize prime and secret
 	 */
-	BN_init(&prime);
-	BN_init(&secret);
+	prime = BN_new();
+	secret = BN_new();
 
 	/*
 	 * Encode the secret value
 	 */
-	BN_bin2bn((unsigned char *)*pwd, *pwdlen, &secret);
+	BN_bin2bn((unsigned char *)*pwd, *pwdlen, secret);
 
 	/*
 	 * Generate seed and calculate a prime depending on the size of the secret
@@ -1063,7 +1064,7 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas
 		return r;
 	}
 
-	r = generatePrime(&prime, &secret, 64, rngseed, SEED_LENGTH);
+	r = generatePrime(prime, secret, 64, rngseed, SEED_LENGTH);
 	if (r < 0) {
 		printf("Error generating valid prime number. Please try again.");
 		OPENSSL_cleanse(*pwd, *pwdlen);
@@ -1074,7 +1075,7 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas
 	// Allocate data buffer for the generated shares
 	shares = malloc(password_shares_total * sizeof(secret_share_t));
 
-	createShares(&secret, password_shares_threshold, password_shares_total, prime, shares);
+	createShares(secret, password_shares_threshold, password_shares_total, prime, shares);
 
 	sp = shares;
 	for (i = 0; i < password_shares_total; i++) {
@@ -1087,12 +1088,12 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas
 
 		printf("Share %i of %i\n\n", i + 1, password_shares_total);
 
-		l = BN_bn2bin(&prime, buf);
+		l = BN_bn2bin(prime, buf);
 		sc_bin_to_hex(buf, l, hex, 64, ':');
 		printf("\nPrime       : %s\n", hex);
 
-		printf("Share ID    : %s\n", BN_bn2dec(&(sp->x)));
-		l = BN_bn2bin(&(sp->y), buf);
+		printf("Share ID    : %s\n", BN_bn2dec((sp->x)));
+		l = BN_bn2bin((sp->y), buf);
 		sc_bin_to_hex(buf, l, hex, 64, ':');
 		printf("Share value : %s\n", hex);
 
@@ -1106,8 +1107,8 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas
 
 	cleanUpShares(shares, password_shares_total);
 
-	BN_clear_free(&prime);
-	BN_clear_free(&secret);
+	BN_clear_free(prime);
+	BN_clear_free(secret);
 
 	return 0;
 }
@@ -1116,7 +1117,7 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas
 
 static int create_dkek_share(sc_card_t *card, const char *outf, int iter, const char *password, int password_shares_threshold, int password_shares_total)
 {
-	EVP_CIPHER_CTX ctx;
+	EVP_CIPHER_CTX *ctx = NULL;
 	FILE *out = NULL;
 	u8 filebuff[64], key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
 	u8 dkek_share[32];
@@ -1167,14 +1168,14 @@ static int create_dkek_share(sc_card_t *card, const char *outf, int iter, const
 		return -1;
 	}
 
-	EVP_CIPHER_CTX_init(&ctx);
-	EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, iv);
-	if (!EVP_EncryptUpdate(&ctx, filebuff + 16, &outlen, dkek_share, sizeof(dkek_share))) {
+	ctx = EVP_CIPHER_CTX_new();
+	EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
+	if (!EVP_EncryptUpdate(ctx, filebuff + 16, &outlen, dkek_share, sizeof(dkek_share))) {
 		fprintf(stderr, "Error encrypting DKEK share\n");
 		return -1;
 	}
 
-	if (!EVP_EncryptFinal_ex(&ctx, filebuff + 16 + outlen, &r)) {
+	if (!EVP_EncryptFinal_ex(ctx, filebuff + 16 + outlen, &r)) {
 		fprintf(stderr, "Error encrypting DKEK share\n");
 		return -1;
 	}
@@ -1195,7 +1196,7 @@ static int create_dkek_share(sc_card_t *card, const char *outf, int iter, const
 	fclose(out);
 
 	OPENSSL_cleanse(filebuff, sizeof(filebuff));
-	EVP_CIPHER_CTX_cleanup(&ctx);
+	EVP_CIPHER_CTX_free(ctx);
 
 	printf("DKEK share created and saved to %s\n", outf);
 	return 0;
@@ -1744,9 +1745,16 @@ int main(int argc, char * const argv[])
 		}
 	}
 
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+	OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS
+		| OPENSSL_INIT_ADD_ALL_CIPHERS
+		| OPENSSL_INIT_ADD_ALL_DIGESTS,
+		NULL);
+#else
 	CRYPTO_malloc_init();
 	ERR_load_crypto_strings();
 	OpenSSL_add_all_algorithms();
+#endif
 
 	memset(&ctx_param, 0, sizeof(sc_context_param_t));
 	ctx_param.app_name = app_name;
diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c
index 24136fb..29b75dd 100644
--- a/src/tools/westcos-tool.c
+++ b/src/tools/westcos-tool.c
@@ -33,6 +33,7 @@
 #include <openssl/x509v3.h>
 #include <openssl/bn.h>
 
+#include "libopensc/sc-ossl-compat.h"
 #include "libopensc/opensc.h"
 #include "libopensc/errors.h"
 #include "libopensc/pkcs15.h"
@@ -102,7 +103,7 @@ static int unlock = 0;
 static char *get_filename = NULL;
 static char *put_filename = NULL;
 
-static int do_convert_bignum(sc_pkcs15_bignum_t *dst, BIGNUM *src)
+static int do_convert_bignum(sc_pkcs15_bignum_t *dst, const BIGNUM *src)
 {
 	if (src == 0) return 0;
 	dst->len = BN_num_bytes(src);
@@ -617,7 +618,7 @@ int main(int argc, char *argv[])
 			goto out;
 		}
 
-		rsa->meth = RSA_PKCS1_SSLeay();
+		RSA_set_method(rsa, RSA_PKCS1_OpenSSL());
 
 		if(!i2d_RSAPrivateKey_bio(mem, rsa))
 		{
@@ -681,9 +682,16 @@ int main(int argc, char *argv[])
 		r = create_file_cert(card);
 		if(r) goto out;
 
-		if (!do_convert_bignum(&dst->modulus, rsa->n)
-		 || !do_convert_bignum(&dst->exponent, rsa->e))
-			goto out;
+		{
+			const BIGNUM *rsa_n, *rsa_e;
+
+			RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL);
+
+			if (!do_convert_bignum(&dst->modulus, rsa_n)
+			 || !do_convert_bignum(&dst->exponent, rsa_e))
+				goto out;
+
+		}
 
 		r = sc_pkcs15_encode_pubkey(ctx, &key, &pdata, &lg);
 		if(r) goto out;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-opensc/opensc.git



More information about the pkg-opensc-commit mailing list