[pkg-opensc-commit] [pkcs11-helper] 01/06: Imported Upstream version 1.11

Eric Dorland eric at moszumanska.debian.org
Tue Nov 26 03:08:27 UTC 2013


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

eric pushed a commit to branch master
in repository pkcs11-helper.

commit ab6f62a05f6ceb1b924e01e35edb43c85670fb03
Author: Eric Dorland <eric at debian.org>
Date:   Sat Nov 16 14:59:03 2013 -0500

    Imported Upstream version 1.11
---
 ChangeLog                                       |   6 +
 configure.ac                                    |  54 +-
 include/pkcs11-helper-1.0/pkcs11h-certificate.h |   4 +-
 include/pkcs11-helper-1.0/pkcs11h-core.h        |   4 +-
 include/pkcs11-helper-1.0/pkcs11h-openssl.h     |  10 +
 lib/Makefile.am                                 |   3 +-
 lib/_pkcs11h-core.h                             |   2 +-
 lib/_pkcs11h-crypto-cryptoapi.c                 |   4 +-
 lib/_pkcs11h-crypto-gnutls.c                    |   2 +-
 lib/_pkcs11h-openssl.h                          |  70 ++
 lib/openssl.exports                             |   1 +
 lib/pkcs11h-certificate.c                       |  54 +-
 lib/pkcs11h-core.c                              |  41 +-
 lib/pkcs11h-data.c                              |   8 +-
 lib/pkcs11h-openssl.c                           | 859 +++++++++++++++++++-----
 lib/pkcs11h-session.c                           |  20 +-
 lib/pkcs11h-slotevent.c                         |  18 +-
 lib/pkcs11h-threading.c                         |   8 +-
 lib/pkcs11h-token.c                             |  14 +-
 lib/pkcs11h-util.c                              |   4 +-
 lib/token.exports                               |   1 +
 tests/test-certificate/test-certificate.c       |   4 +-
 22 files changed, 931 insertions(+), 260 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f8386f0..64bb478 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,12 @@ Copyright (c) 2005-2011 Alon Bar-Lev <alon.barlev at gmail.com>
 
 $Id$
 
+2013-10-11 - Version 1.11
+
+ * openssl: support generic pkey.
+ * openssl: add dsa support.
+ * openssl: add ecdsa support, thanks for Sanaullah for testing.
+
 2012-02-29 - Version 1.10
 
  * PolarSSL crypto engine by Adriaan de Jong
diff --git a/configure.ac b/configure.ac
index ec04a8c..29eda49 100644
--- a/configure.ac
+++ b/configure.ac
@@ -52,7 +52,7 @@
 AC_PREREQ(2.60)
 
 define([PACKAGE_VERSION_MAJOR], [1])
-define([PACKAGE_VERSION_MINOR], [10])
+define([PACKAGE_VERSION_MINOR], [11])
 define([PACKAGE_VERSION_FIX], [0])
 define([PACKAGE_SUFFIX], [])
 
@@ -293,6 +293,58 @@ if test "${have_openssl}" = "no"; then
 	PKG_CHECK_MODULES([OPENSSL], [openssl >= 0.9.7], [have_openssl="yes"], [have_openssl="no"])
 fi
 
+if test "${have_openssl}" = "yes"; then
+	old_LIBS="${LIBS}"
+	LIBS="${LIBS} ${OPENSSL_LIBS}"
+	AC_CHECK_FUNC(
+		[ECDSA_METHOD_new],
+		[
+			openssl_ec="yes"
+			AC_DEFINE([ENABLE_PKCS11H_OPENSSL_EC], [1], [Enable openssl EC])
+		],
+		[
+			openssl_ec="hack"
+			old_CFLAGS="${CFLAGS}"
+			old_CPPFLAGS="${CPPFLAGS}"
+			CPPFLAGS="${CPPFLAGS} -I."
+			CFLAGS="${CFLAGS} ${OPENSSL_CFLAGS}"
+			AC_CHECK_HEADER(
+				[ecs_locl.h],
+				[
+					AC_DEFINE([ENABLE_PKCS11H_OPENSSL_EC], [1], [Enable openssl EC])
+					AC_DEFINE([ENABLE_PKCS11H_OPENSSL_EC_HACK], [1], [Enable openssl EC])
+					AC_DEFINE_UNQUOTED(
+						[ECDSA_METHOD_new(ecdsa)],
+						[(ECDSA_METHOD *)memmove(malloc(sizeof(ECDSA_METHOD)), ecdsa, sizeof(ECDSA_METHOD))],
+						[emulation],
+					)
+					AC_DEFINE_UNQUOTED(
+						[ECDSA_METHOD_free(ecdsa)],
+						[free(ecdsa)],
+						[emulation],
+					)
+					AC_DEFINE_UNQUOTED(
+						[ECDSA_METHOD_set_name(ecdsa, n)],
+						[ecdsa->name = n],
+						[emulation],
+					)
+					AC_DEFINE_UNQUOTED(
+						[ECDSA_METHOD_set_sign(ecdsa, s)],
+						[ecdsa->ecdsa_do_sign = s],
+						[emulation],
+					)
+				],
+				[openssl_ec="none"]
+			)
+			CPPFLAGS="${old_CPPFLAGS}"
+			CFLAGS="${old_CFLAGS}"
+		],
+	)
+	LIBS="${old_LIBS}"
+	AC_MSG_CHECKING([for OpenSSL ec support])
+	AC_MSG_RESULT([${openssl_ec}])
+fi
+
 PKG_CHECK_MODULES([GNUTLS], [gnutls >= 1.4], [have_gnutls="yes"], [have_gnutls="no"])
 PKG_CHECK_MODULES([NSS], [nss >= 3.11], [have_nss="yes"], [have_nss="no"])
 
diff --git a/include/pkcs11-helper-1.0/pkcs11h-certificate.h b/include/pkcs11-helper-1.0/pkcs11h-certificate.h
index 8885c77..51b162a 100644
--- a/include/pkcs11-helper-1.0/pkcs11h-certificate.h
+++ b/include/pkcs11-helper-1.0/pkcs11h-certificate.h
@@ -66,7 +66,7 @@
 
 /**
  * @example test-certificate.c
- * 
+ *
  * The following example shows some basic usage of the certificate interface.
  */
 
@@ -190,7 +190,7 @@ pkcs11h_certificate_freeCertificate (
  * @see pkcs11h_certificate_freeCertificate().
  * @remarks
  * The certificate id object may not specify the certificate blob.
- */	
+ */
 CK_RV
 pkcs11h_certificate_create (
 	IN const pkcs11h_certificate_id_t certificate_id,
diff --git a/include/pkcs11-helper-1.0/pkcs11h-core.h b/include/pkcs11-helper-1.0/pkcs11h-core.h
index 2cb445f..6e705ab 100644
--- a/include/pkcs11-helper-1.0/pkcs11h-core.h
+++ b/include/pkcs11-helper-1.0/pkcs11h-core.h
@@ -340,7 +340,7 @@ pkcs11h_getLogLevel (void);
  * @return CK_RV.
  * @attention
  * This function should be called after @ref pkcs11h_initialize()
- * @note 
+ * @note
  * This funciton is releavant if @ref PKCS11H_FEATURE_MASK_THREADING is set.
  * If safe mode is on, the child process can use the loaded PKCS#11 providers
  * but it cannot use fork(), while it is in one of the hooks functions, since
@@ -504,7 +504,7 @@ pkcs11h_forkFixup (void);
 CK_RV
 pkcs11h_plugAndPlay (void);
 
-/** 
+/**
  * @brief Logout from all sessions.
  * @return CK_RV.
  */
diff --git a/include/pkcs11-helper-1.0/pkcs11h-openssl.h b/include/pkcs11-helper-1.0/pkcs11h-openssl.h
index 91c90c9..ca1048b 100644
--- a/include/pkcs11-helper-1.0/pkcs11h-openssl.h
+++ b/include/pkcs11-helper-1.0/pkcs11h-openssl.h
@@ -154,6 +154,16 @@ pkcs11h_openssl_session_getRSA (
 );
 
 /**
+ * @brief Returns an EVP_PKEY out of the openssl_session object.
+ * @param openssl_session	OpenSSL session reference.
+ * @return EVP_PKEY.
+ */
+EVP_PKEY *
+pkcs11h_openssl_session_getEVP (
+	IN const pkcs11h_openssl_session_t openssl_session
+);
+
+/**
  * @brief Returns an X509 object out of the openssl_session object.
  * @param openssl_session	OpenSSL session reference.
  * @return X509.
diff --git a/lib/Makefile.am b/lib/Makefile.am
index d73c154..afd647a 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -90,7 +90,8 @@ libpkcs11_helper_la_SOURCES= \
 	_pkcs11h-core.h pkcs11h-core.c \
 	pkcs11h-data.c \
 	pkcs11h-serialization.c \
-	pkcs11h-openssl.c
+	_pkcs11h-openssl.h pkcs11h-openssl.c \
+	$(NULL)
 libpkcs11_helper_la_LDFLAGS= \
 	$(AM_LDFLAGS) \
 	-version-info @LIBPKCS11_HELPER_LT_CURRENT@:@LIBPKCS11_HELPER_LT_REVISION@:@LIBPKCS11_HELPER_LT_AGE@ \
diff --git a/lib/_pkcs11h-core.h b/lib/_pkcs11h-core.h
index 4223b43..4564dc1 100644
--- a/lib/_pkcs11h-core.h
+++ b/lib/_pkcs11h-core.h
@@ -112,7 +112,7 @@ struct _pkcs11h_provider_s {
 	PKCS11H_BOOL enabled;
 	char reference[1024];
 	char manufacturerID[sizeof (((CK_TOKEN_INFO *)NULL)->manufacturerID)+1];
-	
+
 #if defined(_WIN32)
 	HANDLE handle;
 #else
diff --git a/lib/_pkcs11h-crypto-cryptoapi.c b/lib/_pkcs11h-crypto-cryptoapi.c
index 2270d1a..21c1834 100644
--- a/lib/_pkcs11h-crypto-cryptoapi.c
+++ b/lib/_pkcs11h-crypto-cryptoapi.c
@@ -260,11 +260,11 @@ __pkcs11h_crypto_cryptoapi_certificate_get_dn (
 	) {
 		goto cleanup;
 	}
-	
+
 	if ((wstr = (WCHAR *)_g_pkcs11h_sys_engine.malloc (wsize * sizeof (WCHAR))) == NULL) {
 		goto cleanup;
 	}
-			
+
 	if (
 		(wsize = data->p_CertNameToStrW (
 			X509_ASN_ENCODING,
diff --git a/lib/_pkcs11h-crypto-gnutls.c b/lib/_pkcs11h-crypto-gnutls.c
index 9704bef..5548b71 100644
--- a/lib/_pkcs11h-crypto-gnutls.c
+++ b/lib/_pkcs11h-crypto-gnutls.c
@@ -112,7 +112,7 @@ __pkcs11h_crypto_gnutls_certificate_get_expiration (
 		cert = NULL;
 		goto cleanup;
 	}
-	
+
 	datum.data = (unsigned char *)blob;
 	datum.size = blob_size;
 
diff --git a/lib/_pkcs11h-openssl.h b/lib/_pkcs11h-openssl.h
new file mode 100644
index 0000000..f802f9e
--- /dev/null
+++ b/lib/_pkcs11h-openssl.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2005-2011 Alon Bar-Lev <alon.barlev at gmail.com>
+ * All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, or the BSD license.
+ *
+ * GNU General Public License (GPL) Version 2
+ * ===========================================
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING.GPL included with this
+ * distribution); if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * BSD License
+ * ============
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *     o Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ *     o Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     o Neither the name of the Alon Bar-Lev nor the names of its
+ *       contributors may be used to endorse or promote products derived from
+ *       this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ___PKCS11H_OPENSSL_H
+#define ___PKCS11H_OPENSSL_H
+
+#include "common.h"
+
+#if defined(ENABLE_PKCS11H_OPENSSL)
+
+#include <pkcs11-helper-1.0/pkcs11h-def.h>
+
+PKCS11H_BOOL
+_pkcs11h_openssl_initialize (void);
+
+PKCS11H_BOOL
+_pkcs11h_openssl_terminate (void);
+
+#endif
+
+#endif
+
diff --git a/lib/openssl.exports b/lib/openssl.exports
index 0396e44..d2be4d0 100644
--- a/lib/openssl.exports
+++ b/lib/openssl.exports
@@ -3,5 +3,6 @@ pkcs11h_openssl_freeSession
 pkcs11h_openssl_getCleanupHook
 pkcs11h_openssl_getX509
 pkcs11h_openssl_session_getRSA
+pkcs11h_openssl_session_getEVP
 pkcs11h_openssl_session_getX509
 pkcs11h_openssl_setCleanupHook
diff --git a/lib/pkcs11h-certificate.c b/lib/pkcs11h-certificate.c
index 48c3b7a..086e22d 100644
--- a/lib/pkcs11h-certificate.c
+++ b/lib/pkcs11h-certificate.c
@@ -175,7 +175,7 @@ _pkcs11h_certificate_isBetterCertificate (
 		"PKCS#11: _pkcs11h_certificate_isBetterCertificate return is_better=%d",
 		is_better ? 1 : 0
 	);
-	
+
 	return is_better;
 }
 
@@ -245,7 +245,7 @@ __pkcs11h_certificate_loadCertificate (
 
 	_PKCS11H_ASSERT (certificate!=NULL);
 	_PKCS11H_ASSERT (certificate->id!=NULL);
-	
+
 	/* Must be after assert */
 	cert_filter[1].pValue = certificate->id->attrCKA_ID;
 	cert_filter[1].ulValueLen = certificate->id->attrCKA_ID_size;
@@ -353,7 +353,7 @@ __pkcs11h_certificate_loadCertificate (
 	rv = CKR_OK;
 
 cleanup:
-	
+
 #if defined(ENABLE_PKCS11H_THREADING)
 	if (mutex_locked) {
 		_pkcs11h_threading_mutexRelease (&certificate->session->mutex);
@@ -589,7 +589,7 @@ cleanup:
 		mutex_locked = FALSE;
 	}
 #endif
-	
+
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
 		"PKCS#11: __pkcs11h_certificate_getKeyAttributes return rv=%lu-'%s'",
@@ -660,7 +660,7 @@ _pkcs11h_certificate_resetSession (
 	CK_RV rv = CKR_FUNCTION_FAILED;
 
 	_PKCS11H_ASSERT (certificate!=NULL);
-	
+
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
 		"PKCS#11: _pkcs11h_certificate_resetSession entry certificate=%p, public_only=%d, session_mutex_locked=%d",
@@ -796,7 +796,7 @@ __pkcs11h_certificate_doPrivateOperation (
 	CK_OBJECT_CLASS class = CKO_SECRET_KEY;
 	CK_KEY_TYPE keytype = CKK_GENERIC_SECRET;
 	CK_ATTRIBUTE wrap_attrs[] = {
-		{CKA_CLASS, &class, sizeof (class)}, 
+		{CKA_CLASS, &class, sizeof (class)},
 		{CKA_KEY_TYPE, &keytype, sizeof (keytype)},
 		{CKA_EXTRACTABLE, &wrap_attrs_true, sizeof (wrap_attrs_true)}
 /* OpenSC fail!	{CKA_TOKEN, &wrap_attrs_false, sizeof (wrap_attrs_false)} */
@@ -805,7 +805,7 @@ __pkcs11h_certificate_doPrivateOperation (
 		{CKA_VALUE, target, 0}
 	};
 	CK_OBJECT_HANDLE wrap_key = _PKCS11H_INVALID_OBJECT_HANDLE;
-	
+
 	CK_RV rv = CKR_FUNCTION_FAILED;
 	PKCS11H_BOOL login_retry = FALSE;
 	PKCS11H_BOOL op_succeed = FALSE;
@@ -1050,7 +1050,7 @@ cleanup:
 		pkcs11h_getMessage (rv),
 		*p_target_size
 	);
-	
+
 	return rv;
 }
 
@@ -1149,7 +1149,7 @@ cleanup:
 		pkcs11h_getMessage (rv),
 		(void *)*to
 	);
-	
+
 	return rv;
 }
 
@@ -1203,7 +1203,7 @@ cleanup:
 		rv,
 		pkcs11h_getMessage (rv)
 	);
-	
+
 	return rv;
 }
 
@@ -1355,7 +1355,7 @@ cleanup:
 		pkcs11h_getMessage (rv),
 		*p_target_size
 	);
-	
+
 	return rv;
 }
 
@@ -1612,7 +1612,7 @@ pkcs11h_certificate_signAny (
 				goto cleanup;
 		}
 	}
-	
+
 	if (
 		!acked &&
 		(certificate->mask_private_mode & PKCS11H_PRIVATEMODE_MASK_RECOVER) != 0
@@ -1648,7 +1648,7 @@ pkcs11h_certificate_signAny (
 	rv = CKR_OK;
 
 cleanup:
-	
+
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
 		"PKCS#11: pkcs11h_certificate_signAny return rv=%lu-'%s', *p_target_size="P_Z"",
@@ -1726,7 +1726,7 @@ pkcs11h_certificate_decryptAny (
 				goto cleanup;
 		}
 	}
-	
+
 	if (
 		!acked &&
 		(certificate->mask_private_mode & PKCS11H_PRIVATEMODE_MASK_UNWRAP) != 0
@@ -1762,7 +1762,7 @@ pkcs11h_certificate_decryptAny (
 	rv = CKR_OK;
 
 cleanup:
-	
+
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
 		"PKCS#11: pkcs11h_certificate_decryptAny return rv=%lu-'%s', *p_target_size="P_Z"",
@@ -1900,7 +1900,7 @@ cleanup:
 		pkcs11h_getMessage (rv),
 		(void *)*p_certificate
 	);
-	
+
 	return rv;
 }
 
@@ -1995,7 +1995,7 @@ pkcs11h_certificate_getCertificateBlob (
 #endif
 	CK_RV rv = CKR_FUNCTION_FAILED;
 	size_t certifiate_blob_size_max = 0;
-	
+
 	_PKCS11H_ASSERT (_g_pkcs11h_data!=NULL);
 	_PKCS11H_ASSERT (_g_pkcs11h_data->initialized);
 	_PKCS11H_ASSERT (certificate!=NULL);
@@ -2064,7 +2064,7 @@ pkcs11h_certificate_getCertificateBlob (
 			rv = CKR_BUFFER_TOO_SMALL;
 			goto cleanup;
 		}
-	
+
 		memmove (
 			certificate_blob,
 			certificate->id->certificate_blob,
@@ -2174,7 +2174,7 @@ pkcs11h_certificate_ensureCertificateAccess (
 		) {
 			goto cleanup;
 		}
-	
+
 		validCert = TRUE;
 	}
 
@@ -2197,7 +2197,7 @@ cleanup:
 		rv,
 		pkcs11h_getMessage (rv)
 	);
-	
+
 	return rv;
 }
 
@@ -2304,7 +2304,7 @@ cleanup:
 		rv,
 		pkcs11h_getMessage (rv)
 	);
-	
+
 	return rv;
 }
 
@@ -2332,7 +2332,7 @@ _pkcs11h_certificate_enumSessionCertificates (
 		user_data,
 		mask_prompt
 	);
-	
+
 	/* THREADS: NO NEED TO LOCK, GLOBAL CACHE IS LOCKED */
 #if defined(ENABLE_PKCS11H_THREADING)
 	if ((rv = _pkcs11h_threading_mutexLock (&session->mutex)) != CKR_OK) {
@@ -2367,11 +2367,11 @@ _pkcs11h_certificate_enumSessionCertificates (
 		) {
 			goto retry;
 		}
-			
+
 		for (i=0;i < objects_found;i++) {
 			pkcs11h_certificate_id_t certificate_id = NULL;
 			pkcs11h_certificate_id_list_t new_element = NULL;
-			
+
 			CK_ATTRIBUTE attrs[] = {
 				{CKA_ID, NULL, 0},
 				{CKA_VALUE, NULL, 0}
@@ -2451,7 +2451,7 @@ _pkcs11h_certificate_enumSessionCertificates (
 
 		op_succeed = TRUE;
 		rv = CKR_OK;
-	
+
 	retry:
 
 		if (objects != NULL) {
@@ -2794,7 +2794,7 @@ cleanup:
 		rv,
 		pkcs11h_getMessage (rv)
 	);
-	
+
 	return rv;
 }
 
@@ -3045,7 +3045,7 @@ cleanup:
 		rv,
 		pkcs11h_getMessage (rv)
 	);
-	
+
 	return rv;
 }
 
diff --git a/lib/pkcs11h-core.c b/lib/pkcs11h-core.c
index b139307..6aee495 100644
--- a/lib/pkcs11h-core.c
+++ b/lib/pkcs11h-core.c
@@ -66,6 +66,7 @@
 #include "_pkcs11h-core.h"
 #include "_pkcs11h-session.h"
 #include "_pkcs11h-slotevent.h"
+#include "_pkcs11h-openssl.h"
 
 /*======================================================================*
  * COMMON INTERNAL INTERFACE
@@ -340,6 +341,18 @@ pkcs11h_initialize (void) {
 	data->max_retries = _PKCS11H_DEFAULT_MAX_LOGIN_RETRY;
 	data->allow_protected_auth = TRUE;
 	data->pin_cache_period = _PKCS11H_DEFAULT_PIN_CACHE_PERIOD;
+
+#if defined(ENABLE_PKCS11H_OPENSSL)
+	_PKCS11H_DEBUG (
+		PKCS11H_LOG_DEBUG1,
+		"PKCS#11: Initializing openssl"
+	);
+
+	if (!_pkcs11h_openssl_initialize()) {
+		goto cleanup;
+	}
+#endif
+
 	data->initialized = TRUE;
 
 	_g_pkcs11h_data = data;
@@ -364,7 +377,7 @@ cleanup:
 			has_mutex_cache = FALSE;
 		}
 		if (has_mutex_session) {
-			_pkcs11h_threading_mutexFree (&data->mutexes.session); 
+			_pkcs11h_threading_mutexFree (&data->mutexes.session);
 			has_mutex_session = FALSE;
 		}
 #endif
@@ -393,6 +406,14 @@ pkcs11h_terminate (void) {
 	if (_g_pkcs11h_data != NULL) {
 		_pkcs11h_provider_t current_provider = NULL;
 
+#if defined(ENABLE_PKCS11H_OPENSSL)
+		_PKCS11H_DEBUG (
+			PKCS11H_LOG_DEBUG1,
+			"PKCS#11: Terminating openssl"
+		);
+		_pkcs11h_openssl_terminate();
+#endif
+
 		_PKCS11H_DEBUG (
 			PKCS11H_LOG_DEBUG1,
 			"PKCS#11: Removing providers"
@@ -464,7 +485,7 @@ pkcs11h_terminate (void) {
 			PKCS11H_LOG_DEBUG1,
 			"PKCS#11: Marking as uninitialized"
 		);
-		
+
 		_g_pkcs11h_data->initialized = FALSE;
 
 		while (_g_pkcs11h_data->providers != NULL) {
@@ -475,9 +496,9 @@ pkcs11h_terminate (void) {
 		}
 
 #if defined(ENABLE_PKCS11H_THREADING)
-		_pkcs11h_threading_mutexFree (&_g_pkcs11h_data->mutexes.global); 
+		_pkcs11h_threading_mutexFree (&_g_pkcs11h_data->mutexes.global);
 		_pkcs11h_threading_mutexFree (&_g_pkcs11h_data->mutexes.cache);
-		_pkcs11h_threading_mutexFree (&_g_pkcs11h_data->mutexes.session); 
+		_pkcs11h_threading_mutexFree (&_g_pkcs11h_data->mutexes.session);
 #endif
 
 		_g_pkcs11h_crypto_engine.uninitialize (_g_pkcs11h_crypto_engine.global_data);
@@ -710,7 +731,7 @@ pkcs11h_addProvider (
 	provider->slot_event_method = slot_event_method;
 	provider->slot_poll_interval = slot_poll_interval;
 	provider->cert_is_private = cert_is_private;
-		
+
 #if defined(_WIN32)
 	provider->handle = LoadLibraryA (provider_location);
 #else
@@ -736,7 +757,7 @@ pkcs11h_addProvider (
 		"C_GetFunctionList"
 	);
 	memmove (
-		&gfl, 
+		&gfl,
 		&p,
 		sizeof (void *)
 	);
@@ -921,7 +942,7 @@ pkcs11h_removeProvider (
 
 #if defined(ENABLE_PKCS11H_SLOTEVENT)
 	_pkcs11h_slotevent_notify ();
-	
+
 	/*
 	 * Wait until manager join this thread
 	 * this happens saldom so I can poll
@@ -947,7 +968,7 @@ pkcs11h_removeProvider (
 	rv = CKR_OK;
 
 cleanup:
-	
+
 #if defined(ENABLE_PKCS11H_THREADING)
 	for (
 		current_session = _g_pkcs11h_data->sessions;
@@ -1133,7 +1154,7 @@ _pkcs11h_log (
 	if (
 		_g_pkcs11h_data != NULL &&
 		_g_pkcs11h_data->initialized
-	) { 
+	) {
 		if (__PKCS11H_MSG_LEVEL_TEST (flags)) {
 			if (_g_pkcs11h_data->hooks.log == NULL) {
 				__pkcs11h_hooks_default_log (
@@ -1225,7 +1246,7 @@ __pkcs11h_hooks_default_pin_prompt (
 		user_data,
 		token->display
 	);
-	
+
 	return FALSE;
 }
 
diff --git a/lib/pkcs11h-data.c b/lib/pkcs11h-data.c
index 4274cc2..a817602 100644
--- a/lib/pkcs11h-data.c
+++ b/lib/pkcs11h-data.c
@@ -74,7 +74,7 @@ _pkcs11h_data_getObject (
 	CK_OBJECT_HANDLE *objects = NULL;
 	CK_ULONG objects_found = 0;
 	CK_RV rv = CKR_FUNCTION_FAILED;
-	
+
 	_PKCS11H_ASSERT (session!=NULL);
 	_PKCS11H_ASSERT (application!=NULL);
 	_PKCS11H_ASSERT (label!=NULL);
@@ -219,7 +219,7 @@ pkcs11h_data_get (
 
 		op_succeed = TRUE;
 		rv = CKR_OK;
-	
+
 	retry:
 
 		if (!op_succeed) {
@@ -372,7 +372,7 @@ pkcs11h_data_put (
 		) {
 			goto retry;
 		}
-	
+
 		op_succeed = TRUE;
 		rv = CKR_OK;
 
@@ -785,7 +785,7 @@ cleanup:
 		pkcs11h_getMessage (rv),
 		(void *)*p_data_id_list
 	);
-	
+
 	return rv;
 }
 
diff --git a/lib/pkcs11h-openssl.c b/lib/pkcs11h-openssl.c
index 6ac6525..1936705 100644
--- a/lib/pkcs11h-openssl.c
+++ b/lib/pkcs11h-openssl.c
@@ -57,6 +57,13 @@
 #include "_pkcs11h-core.h"
 #include "_pkcs11h-mem.h"
 
+#if !defined(OPENSSL_NO_EC) && defined(ENABLE_PKCS11H_OPENSSL_EC)
+#define __ENABLE_EC
+#ifdef ENABLE_PKCS11H_OPENSSL_EC_HACK
+#include <ecs_locl.h>
+#endif
+#endif
+
 #if OPENSSL_VERSION_NUMBER < 0x00907000L
 #if !defined(RSA_PKCS1_PADDING_SIZE)
 #define RSA_PKCS1_PADDING_SIZE 11
@@ -70,96 +77,109 @@ typedef const unsigned char *__pkcs11_openssl_d2i_t;
 #endif
 
 struct pkcs11h_openssl_session_s {
-	int reference_count;
+#if defined(ENABLE_PKCS11H_THREADING)
+	_pkcs11h_mutex_t reference_count_lock;
+#endif
+	volatile int reference_count;
 	PKCS11H_BOOL initialized;
 	X509 *x509;
-	RSA_METHOD smart_rsa;
-	int (*orig_finish)(RSA *rsa);
 	pkcs11h_certificate_t certificate;
 	pkcs11h_hook_openssl_cleanup_t cleanup_hook;
 };
 
-static
-int
-__pkcs11h_openssl_finish (
-	IN OUT RSA *rsa
-);
-#if OPENSSL_VERSION_NUMBER < 0x00907000L
-static
-int
-__pkcs11h_openssl_dec (
-	IN int flen,
-	IN unsigned char *from,
-	OUT unsigned char *to,
-	IN OUT RSA *rsa,
-	IN int padding
-);
-static
-int
-__pkcs11h_openssl_enc (
-	IN int flen,
-	IN unsigned char *from,
-	OUT unsigned char *to,
-	IN OUT RSA *rsa,
-	IN int padding
-);
-#else
-static
-int
-__pkcs11h_openssl_dec (
-	IN int flen,
-	IN const unsigned char *from,
-	OUT unsigned char *to,
-	IN OUT RSA *rsa,
-	IN int padding
-);
-static
-int
-__pkcs11h_openssl_enc (
-	IN int flen,
-	IN const unsigned char *from,
-	OUT unsigned char *to,
-	IN OUT RSA *rsa,
-	IN int padding
-);
+static struct {
+#ifndef OPENSSL_NO_RSA
+	RSA_METHOD rsa;
+	int rsa_index;
 #endif
-static
-pkcs11h_openssl_session_t
-__pkcs11h_openssl_get_openssl_session (
-	IN OUT const RSA *rsa
-);  
+#ifndef OPENSSL_NO_DSA
+	DSA_METHOD dsa;
+	int dsa_index;
+#endif
+#ifdef __ENABLE_EC
+	ECDSA_METHOD *ecdsa;
+	int ecdsa_index;
+#endif
+} __openssl_methods;
 
 static
-pkcs11h_certificate_t
-__pkcs11h_openssl_get_pkcs11h_certificate (
-	IN OUT const RSA *rsa
-);  
+int
+__pkcs11h_openssl_ex_data_dup (
+	CRYPTO_EX_DATA *to,
+	CRYPTO_EX_DATA *from,
+	void *from_d,
+	int idx,
+	long argl,
+	void *argp
+) {
+	pkcs11h_openssl_session_t openssl_session;
+
+	_PKCS11H_DEBUG (
+		PKCS11H_LOG_DEBUG2,
+		"PKCS#11: __pkcs11h_openssl_ex_data_dup entered - to=%p, from=%p, from_d=%p, idx=%d, argl=%ld, argp=%p",
+		(void *)to,
+		(void *)from,
+		from_d,
+		idx,
+		argl,
+		argp
+	);
+
+	_PKCS11H_ASSERT (from_d!=NULL);
+
+	if ((openssl_session = *(pkcs11h_openssl_session_t *)from_d) != NULL) {
+		_PKCS11H_DEBUG (
+			PKCS11H_LOG_DEBUG2,
+			"PKCS#11: __pkcs11h_openssl_ex_data_dup session refcount=%d",
+			openssl_session->reference_count
+		);
+		openssl_session->reference_count++;
+	}
+
+	return 1;
+}
 
 static
-pkcs11h_openssl_session_t
-__pkcs11h_openssl_get_openssl_session (
-	IN OUT const RSA *rsa
+void
+__pkcs11h_openssl_ex_data_free (
+	void *parent,
+	void *ptr,
+	CRYPTO_EX_DATA *ad,
+	int idx,
+	long argl,
+	void *argp
 ) {
-	pkcs11h_openssl_session_t session;
-		
-	_PKCS11H_ASSERT (rsa!=NULL);
-#if OPENSSL_VERSION_NUMBER < 0x00907000L
-	session = (pkcs11h_openssl_session_t)RSA_get_app_data ((RSA *)rsa);
-#else
-	session = (pkcs11h_openssl_session_t)RSA_get_app_data (rsa);
-#endif
-	_PKCS11H_ASSERT (session!=NULL);
+	pkcs11h_openssl_session_t openssl_session = (pkcs11h_openssl_session_t)ptr;
+
+	_PKCS11H_DEBUG (
+		PKCS11H_LOG_DEBUG2,
+		"PKCS#11: __pkcs11h_openssl_ex_data_free entered - parent=%p, ptr=%p, ad=%p, idx=%d, argl=%ld, argp=%p",
+		parent,
+		ptr,
+		(void *)ad,
+		idx,
+		argl,
+		argp
+	);
 
-	return session;
+	if (openssl_session != NULL) {
+		pkcs11h_openssl_freeSession (openssl_session);
+	}
 }
 
+#ifndef OPENSSL_NO_RSA
+
 static
 pkcs11h_certificate_t
-__pkcs11h_openssl_get_pkcs11h_certificate (
-	IN OUT const RSA *rsa
+__pkcs11h_openssl_rsa_get_pkcs11h_certificate (
+	IN RSA *rsa
 ) {
-	pkcs11h_openssl_session_t session = __pkcs11h_openssl_get_openssl_session (rsa);
-	
+	pkcs11h_openssl_session_t session = NULL;
+
+	_PKCS11H_ASSERT (rsa!=NULL);
+
+	session = (pkcs11h_openssl_session_t)RSA_get_ex_data (rsa, __openssl_methods.rsa_index);
+
 	_PKCS11H_ASSERT (session!=NULL);
 	_PKCS11H_ASSERT (session->certificate!=NULL);
 
@@ -169,7 +189,7 @@ __pkcs11h_openssl_get_pkcs11h_certificate (
 #if OPENSSL_VERSION_NUMBER < 0x00907000L
 static
 int
-__pkcs11h_openssl_dec (
+__pkcs11h_openssl_rsa_dec (
 	IN int flen,
 	IN unsigned char *from,
 	OUT unsigned char *to,
@@ -179,7 +199,7 @@ __pkcs11h_openssl_dec (
 #else
 static
 int
-__pkcs11h_openssl_dec (
+__pkcs11h_openssl_rsa_dec (
 	IN int flen,
 	IN const unsigned char *from,
 	OUT unsigned char *to,
@@ -187,7 +207,7 @@ __pkcs11h_openssl_dec (
 	IN int padding
 ) {
 #endif
-	pkcs11h_certificate_t certificate = __pkcs11h_openssl_get_pkcs11h_certificate (rsa);
+	pkcs11h_certificate_t certificate = __pkcs11h_openssl_rsa_get_pkcs11h_certificate (rsa);
 	PKCS11H_BOOL session_locked = FALSE;
 	CK_MECHANISM_TYPE mech = CKM_RSA_PKCS;
 	CK_RV rv = CKR_FUNCTION_FAILED;
@@ -199,7 +219,7 @@ __pkcs11h_openssl_dec (
 
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
-		"PKCS#11: __pkcs11h_openssl_dec entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d",
+		"PKCS#11: __pkcs11h_openssl_rsa_dec entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d",
 		flen,
 		from,
 		to,
@@ -259,18 +279,18 @@ cleanup:
 
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
-		"PKCS#11: __pkcs11h_openssl_dec - return rv=%lu-'%s'",
+		"PKCS#11: __pkcs11h_openssl_rsa_dec - return rv=%lu-'%s'",
 		rv,
 		pkcs11h_getMessage (rv)
 	);
 
-	return rv == CKR_OK ? (int)tlen : -1; 
+	return rv == CKR_OK ? (int)tlen : -1;
 }
 
 #if OPENSSL_VERSION_NUMBER < 0x00907000L
 static
 int
-__pkcs11h_openssl_enc (
+__pkcs11h_openssl_rsa_enc (
 	IN int flen,
 	IN unsigned char *from,
 	OUT unsigned char *to,
@@ -280,7 +300,7 @@ __pkcs11h_openssl_enc (
 #else
 static
 int
-__pkcs11h_openssl_enc (
+__pkcs11h_openssl_rsa_enc (
 	IN int flen,
 	IN const unsigned char *from,
 	OUT unsigned char *to,
@@ -288,7 +308,7 @@ __pkcs11h_openssl_enc (
 	IN int padding
 ) {
 #endif
-	pkcs11h_certificate_t certificate = __pkcs11h_openssl_get_pkcs11h_certificate (rsa);
+	pkcs11h_certificate_t certificate = __pkcs11h_openssl_rsa_get_pkcs11h_certificate (rsa);
 	PKCS11H_BOOL session_locked = FALSE;
 	CK_RV rv = CKR_FUNCTION_FAILED;
 	size_t tlen;
@@ -299,7 +319,7 @@ __pkcs11h_openssl_enc (
 
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
-		"PKCS#11: __pkcs11h_openssl_enc entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d",
+		"PKCS#11: __pkcs11h_openssl_rsa_enc entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d",
 		flen,
 		from,
 		to,
@@ -349,57 +369,468 @@ cleanup:
 
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
-		"PKCS#11: __pkcs11h_openssl_enc - return rv=%lu-'%s'",
+		"PKCS#11: __pkcs11h_openssl_rsa_enc - return rv=%lu-'%s'",
 		rv,
 		pkcs11h_getMessage (rv)
 	);
 
-	return rv == CKR_OK ? (int)tlen : -1; 
+	return rv == CKR_OK ? (int)tlen : -1;
 }
 
 static
-int
-__pkcs11h_openssl_finish (
-	IN OUT RSA *rsa
+PKCS11H_BOOL
+__pkcs11h_openssl_session_setRSA(
+	IN const pkcs11h_openssl_session_t openssl_session,
+	IN EVP_PKEY * evp
 ) {
-	pkcs11h_openssl_session_t openssl_session = __pkcs11h_openssl_get_openssl_session (rsa);
+	PKCS11H_BOOL ret = FALSE;
+	RSA *rsa = NULL;
 
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
-		"PKCS#11: __pkcs11h_openssl_finish - entered rsa=%p",
-		(void *)rsa
+		"PKCS#11: __pkcs11h_openssl_session_setRSA - entered openssl_session=%p, evp=%p",
+		(void *)openssl_session,
+		(void *)evp
 	);
 
-	RSA_set_app_data (rsa, NULL);
-	
-	if (openssl_session->orig_finish != NULL) {
-		openssl_session->orig_finish (rsa);
+	if (
+		(rsa = EVP_PKEY_get1_RSA (evp)) == NULL
+	) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get RSA key");
+		goto cleanup;
+	}
+
+	RSA_set_method (rsa, &__openssl_methods.rsa);
+	RSA_set_ex_data (rsa, __openssl_methods.rsa_index, openssl_session);
+
+	rsa->flags |= RSA_FLAG_SIGN_VER;
 
 #ifdef BROKEN_OPENSSL_ENGINE
-		{
-			/* We get called TWICE here, once for
-			 * releasing the key and also for
-			 * releasing the engine.
-			 * To prevent endless recursion, FIRST
-			 * clear rsa->engine, THEN call engine->finish
-			 */
-			ENGINE *e = rsa->engine;
-			rsa->engine = NULL;
-			if (e) {
-				ENGINE_finish(e);
-			}
-		}
+	if (!rsa->engine) {
+		rsa->engine = ENGINE_get_default_RSA ();
+	}
+
+	ENGINE_set_RSA(ENGINE_get_default_RSA (), &openssl_session->rsa);
+	_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled");
 #endif
+
+	ret = TRUE;
+
+cleanup:
+
+	if (rsa != NULL) {
+		RSA_free (rsa);
+		rsa = NULL;
+	}
+
+	_PKCS11H_DEBUG (
+		PKCS11H_LOG_DEBUG2,
+		"PKCS#11: __pkcs11h_openssl_session_setRSA - return ret=%d",
+		ret
+	);
+
+	return ret;
+}
+
+#endif
+
+#ifndef OPENSSL_NO_DSA
+
+static
+pkcs11h_certificate_t
+__pkcs11h_openssl_dsa_get_pkcs11h_certificate (
+	IN DSA *dsa
+) {
+	pkcs11h_openssl_session_t session = NULL;
+
+	_PKCS11H_ASSERT (dsa!=NULL);
+
+	session = (pkcs11h_openssl_session_t)DSA_get_ex_data (dsa, __openssl_methods.dsa_index);
+
+	_PKCS11H_ASSERT (session!=NULL);
+	_PKCS11H_ASSERT (session->certificate!=NULL);
+
+	return session->certificate;
+}
+
+static
+DSA_SIG *
+__pkcs11h_openssl_dsa_do_sign(
+	IN const unsigned char *dgst,
+	IN int dlen,
+	OUT DSA *dsa
+) {
+	pkcs11h_certificate_t certificate = __pkcs11h_openssl_dsa_get_pkcs11h_certificate (dsa);
+	unsigned char *sigbuf = NULL;
+	size_t siglen;
+	DSA_SIG *sig = NULL;
+	DSA_SIG *ret = NULL;
+	CK_RV rv = CKR_FUNCTION_FAILED;
+
+	_PKCS11H_DEBUG (
+		PKCS11H_LOG_DEBUG2,
+		"PKCS#11: __pkcs11h_openssl_dsa_do_sign - entered dgst=%p, dlen=%d, dsa=%p",
+		(void *)dgst,
+		dlen,
+		(void *)dsa
+	);
+
+	_PKCS11H_ASSERT (dgst!=NULL);
+	_PKCS11H_ASSERT (dsa!=NULL);
+	_PKCS11H_ASSERT (certificate!=NULL);
+
+	if (
+		(rv = pkcs11h_certificate_signAny (
+			certificate,
+			CKM_DSA,
+			dgst,
+			(size_t)dlen,
+			NULL,
+			&siglen
+		)) != CKR_OK
+	) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
+		goto cleanup;
+	}
+
+	if ((rv = _pkcs11h_mem_malloc ((void *)&sigbuf, siglen)) != CKR_OK) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot cannot allocate signature buffer");
+		goto cleanup;
+	}
+
+	if (
+		(rv = pkcs11h_certificate_signAny (
+			certificate,
+			CKM_DSA,
+			dgst,
+			(size_t)dlen,
+			sigbuf,
+			&siglen
+		)) != CKR_OK
+	) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
+		goto cleanup;
+	}
+
+	if ((sig = DSA_SIG_new ()) == NULL) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate DSA_SIG");
+		goto cleanup;
+	}
+
+	if (BN_bin2bn (&sigbuf[0], siglen/2, sig->r) == NULL) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot convert dsa r");
+		goto cleanup;
+	}
+
+	if (BN_bin2bn (&sigbuf[siglen/2], siglen/2, sig->s) == NULL) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot convert dsa s");
+		goto cleanup;
 	}
 
-	pkcs11h_openssl_freeSession (openssl_session);
+	ret = sig;
+	sig = NULL;
+
+cleanup:
+
+	if (sigbuf != NULL) {
+		_pkcs11h_mem_free ((void *)&sigbuf);
+	}
+
+	if (sig != NULL) {
+		DSA_SIG_free (sig);
+		sig = NULL;
+	}
 
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
-		"PKCS#11: __pkcs11h_openssl_finish - return"
+		"PKCS#11: __pkcs11h_openssl_dsa_do_sign - return sig=%p",
+		(void *)sig
 	);
-	
-	return 1;
+
+	return ret;
+}
+
+static
+PKCS11H_BOOL
+__pkcs11h_openssl_session_setDSA(
+	IN const pkcs11h_openssl_session_t openssl_session,
+	IN EVP_PKEY * evp
+) {
+	PKCS11H_BOOL ret = FALSE;
+	DSA *dsa = NULL;
+
+	_PKCS11H_DEBUG (
+		PKCS11H_LOG_DEBUG2,
+		"PKCS#11: __pkcs11h_openssl_session_setDSA - entered openssl_session=%p, evp=%p",
+		(void *)openssl_session,
+		(void *)evp
+	);
+
+	if (
+		(dsa = EVP_PKEY_get1_DSA (evp)) == NULL
+	) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get DSA key");
+		goto cleanup;
+	}
+
+	DSA_set_method (dsa, &__openssl_methods.dsa);
+	DSA_set_ex_data (dsa, __openssl_methods.dsa_index, openssl_session);
+
+	ret = TRUE;
+
+cleanup:
+
+	if (dsa != NULL) {
+		DSA_free (dsa);
+		dsa = NULL;
+	}
+
+	_PKCS11H_DEBUG (
+		PKCS11H_LOG_DEBUG2,
+		"PKCS#11: __pkcs11h_openssl_session_setDSA - return ret=%d",
+		ret
+	);
+
+	return ret;
+}
+
+#endif
+
+#ifdef __ENABLE_EC
+
+static
+pkcs11h_certificate_t
+__pkcs11h_openssl_ecdsa_get_pkcs11h_certificate (
+	IN EC_KEY *ec
+) {
+	pkcs11h_openssl_session_t session = NULL;
+
+	_PKCS11H_ASSERT (ec!=NULL);
+
+	session = (pkcs11h_openssl_session_t)ECDSA_get_ex_data (ec, __openssl_methods.ecdsa_index);
+
+	_PKCS11H_ASSERT (session!=NULL);
+	_PKCS11H_ASSERT (session->certificate!=NULL);
+
+	return session->certificate;
+}
+
+static
+ECDSA_SIG *
+__pkcs11h_openssl_ecdsa_do_sign(
+	IN const unsigned char *dgst,
+	IN int dlen,
+	IN const BIGNUM *inv,
+	IN const BIGNUM *r,
+	OUT EC_KEY *ec
+) {
+	pkcs11h_certificate_t certificate = __pkcs11h_openssl_ecdsa_get_pkcs11h_certificate (ec);
+	unsigned char *sigbuf = NULL;
+	size_t siglen;
+	ECDSA_SIG *sig = NULL;
+	ECDSA_SIG *ret = NULL;
+	CK_RV rv = CKR_FUNCTION_FAILED;
+
+	_PKCS11H_DEBUG (
+		PKCS11H_LOG_DEBUG2,
+		"PKCS#11: __pkcs11h_openssl_ecdsa_do_sign - entered dgst=%p, dlen=%d, inv=%p, r=%p, ec=%p",
+		(void *)dgst,
+		dlen,
+		(void *)inv,
+		(void *)r,
+		(void *)ec
+	);
+
+	_PKCS11H_ASSERT (dgst!=NULL);
+	_PKCS11H_ASSERT (inv==NULL);
+	_PKCS11H_ASSERT (r==NULL);
+	_PKCS11H_ASSERT (ec!=NULL);
+	_PKCS11H_ASSERT (certificate!=NULL);
+
+	if (
+		(rv = pkcs11h_certificate_signAny (
+			certificate,
+			CKM_ECDSA,
+			dgst,
+			(size_t)dlen,
+			NULL,
+			&siglen
+		)) != CKR_OK
+	) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
+		goto cleanup;
+	}
+
+	if ((rv = _pkcs11h_mem_malloc ((void *)&sigbuf, siglen)) != CKR_OK) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot cannot allocate signature buffer");
+		goto cleanup;
+	}
+
+	if (
+		(rv = pkcs11h_certificate_signAny (
+			certificate,
+			CKM_ECDSA,
+			dgst,
+			(size_t)dlen,
+			sigbuf,
+			&siglen
+		)) != CKR_OK
+	) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
+		goto cleanup;
+	}
+
+	if ((sig = ECDSA_SIG_new ()) == NULL) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate ECDSA_SIG");
+		goto cleanup;
+	}
+
+	if (BN_bin2bn (&sigbuf[0], siglen/2, sig->r) == NULL) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot convert ecdsa r");
+		goto cleanup;
+	}
+
+	if (BN_bin2bn (&sigbuf[siglen/2], siglen/2, sig->s) == NULL) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot convert ecdsa s");
+		goto cleanup;
+	}
+
+	ret = sig;
+	sig = NULL;
+
+cleanup:
+
+	if (sigbuf != NULL) {
+		_pkcs11h_mem_free ((void *)&sigbuf);
+	}
+
+	if (sig != NULL) {
+		ECDSA_SIG_free (sig);
+		sig = NULL;
+	}
+
+	_PKCS11H_DEBUG (
+		PKCS11H_LOG_DEBUG2,
+		"PKCS#11: __pkcs11h_openssl_ecdsa_do_sign - return sig=%p",
+		(void *)sig
+	);
+
+	return ret;
+}
+
+static
+PKCS11H_BOOL
+__pkcs11h_openssl_session_setECDSA(
+	IN const pkcs11h_openssl_session_t openssl_session,
+	IN EVP_PKEY * evp
+) {
+	PKCS11H_BOOL ret = FALSE;
+	EC_KEY *ec = NULL;
+
+	_PKCS11H_DEBUG (
+		PKCS11H_LOG_DEBUG2,
+		"PKCS#11: __pkcs11h_openssl_session_setECDSA - entered openssl_session=%p, evp=%p",
+		(void *)openssl_session,
+		(void *)evp
+	);
+
+	if (
+		(ec = EVP_PKEY_get1_EC_KEY (evp)) == NULL
+	) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get EC key");
+		goto cleanup;
+	}
+
+	ECDSA_set_method (ec, __openssl_methods.ecdsa);
+	ECDSA_set_ex_data (ec, __openssl_methods.ecdsa_index, openssl_session);
+
+	ret = TRUE;
+
+cleanup:
+
+	if (ec != NULL) {
+		EC_KEY_free (ec);
+		ec = NULL;
+	}
+
+	_PKCS11H_DEBUG (
+		PKCS11H_LOG_DEBUG2,
+		"PKCS#11: __pkcs11h_openssl_session_setECDSA - return ret=%d",
+		ret
+	);
+
+	return ret;
+}
+
+#endif
+
+PKCS11H_BOOL
+_pkcs11h_openssl_initialize (void) {
+	_PKCS11H_DEBUG (
+		PKCS11H_LOG_DEBUG2,
+		"PKCS#11: _pkcs11h_openssl_initialize - entered"
+	);
+#ifndef OPENSSL_NO_RSA
+	memmove (&__openssl_methods.rsa, RSA_get_default_method (), sizeof(RSA_METHOD));
+	__openssl_methods.rsa.name = "pkcs11h";
+	__openssl_methods.rsa.rsa_priv_dec = __pkcs11h_openssl_rsa_dec;
+	__openssl_methods.rsa.rsa_priv_enc = __pkcs11h_openssl_rsa_enc;
+	__openssl_methods.rsa.flags  = RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY;
+	__openssl_methods.rsa_index = RSA_get_ex_new_index (
+		0,
+		"pkcs11h",
+		NULL,
+		__pkcs11h_openssl_ex_data_dup,
+		__pkcs11h_openssl_ex_data_free
+	);
+#endif
+#ifndef OPENSSL_NO_DSA
+	memmove (&__openssl_methods.dsa, DSA_get_default_method (), sizeof(DSA_METHOD));
+	__openssl_methods.dsa.name = "pkcs11h";
+	__openssl_methods.dsa.dsa_do_sign = __pkcs11h_openssl_dsa_do_sign;
+	__openssl_methods.dsa_index = DSA_get_ex_new_index (
+		0,
+		"pkcs11h",
+		NULL,
+		__pkcs11h_openssl_ex_data_dup,
+		__pkcs11h_openssl_ex_data_free
+	);
+#endif
+#ifdef __ENABLE_EC
+	if (__openssl_methods.ecdsa != NULL) {
+		ECDSA_METHOD_free(__openssl_methods.ecdsa);
+	}
+	__openssl_methods.ecdsa = ECDSA_METHOD_new ((ECDSA_METHOD *)ECDSA_get_default_method ());
+	ECDSA_METHOD_set_name(__openssl_methods.ecdsa, "pkcs11h");
+	ECDSA_METHOD_set_sign(__openssl_methods.ecdsa, __pkcs11h_openssl_ecdsa_do_sign);
+	__openssl_methods.ecdsa_index = ECDSA_get_ex_new_index (
+		0,
+		"pkcs11h",
+		NULL,
+		__pkcs11h_openssl_ex_data_dup,
+		__pkcs11h_openssl_ex_data_free
+	);
+#endif
+	_PKCS11H_DEBUG (
+		PKCS11H_LOG_DEBUG2,
+		"PKCS#11: _pkcs11h_openssl_initialize - return"
+	);
+	return TRUE;
+}
+
+PKCS11H_BOOL
+_pkcs11h_openssl_terminate (void) {
+	_PKCS11H_DEBUG (
+		PKCS11H_LOG_DEBUG2,
+		"PKCS#11: _pkcs11h_openssl_terminate"
+	);
+#ifdef __ENABLE_EC
+	if (__openssl_methods.ecdsa != NULL) {
+		ECDSA_METHOD_free(__openssl_methods.ecdsa);
+		__openssl_methods.ecdsa = NULL;
+	}
+#endif
+	return TRUE;
 }
 
 X509 *
@@ -467,7 +898,7 @@ cleanup:
 			x509 = NULL;
 		}
 	}
-	
+
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
 		"PKCS#11: pkcs11h_openssl_getX509 - return rv=%ld-'%s', x509=%p",
@@ -483,8 +914,8 @@ pkcs11h_openssl_session_t
 pkcs11h_openssl_createSession (
 	IN const pkcs11h_certificate_t certificate
 ) {
-	const RSA_METHOD *def;
 	pkcs11h_openssl_session_t openssl_session = NULL;
+	CK_RV rv;
 	PKCS11H_BOOL ok = FALSE;
 
 	_PKCS11H_DEBUG (
@@ -500,24 +931,19 @@ pkcs11h_openssl_createSession (
 			sizeof (struct pkcs11h_openssl_session_s)) != CKR_OK
 	) {
 		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate memory");
-		ok = FALSE;
 		goto cleanup;
 	}
 
-	def = RSA_get_default_method ();
-
-	memmove (&openssl_session->smart_rsa, def, sizeof(RSA_METHOD));
-
-	openssl_session->orig_finish = def->finish;
-
-	openssl_session->smart_rsa.name = "pkcs11";
-	openssl_session->smart_rsa.rsa_priv_dec = __pkcs11h_openssl_dec;
-	openssl_session->smart_rsa.rsa_priv_enc = __pkcs11h_openssl_enc;
-	openssl_session->smart_rsa.finish = __pkcs11h_openssl_finish;
-	openssl_session->smart_rsa.flags  = RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY;
 	openssl_session->certificate = certificate;
 	openssl_session->reference_count = 1;
 
+#if defined(ENABLE_PKCS11H_THREADING)
+	if ((rv = _pkcs11h_threading_mutexInit(&openssl_session->reference_count_lock)) != CKR_OK) {
+		_PKCS11H_LOG (PKCS11H_LOG_ERROR, "PKCS#11: Cannot initialize mutex %ld:'%s'", rv, pkcs11h_getMessage (rv));
+		goto cleanup;
+	}
+#endif
+
 	ok = TRUE;
 
 cleanup:
@@ -525,7 +951,7 @@ cleanup:
 	if (!ok) {
 		_pkcs11h_mem_free ((void *)&openssl_session);
 	}
-	
+
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
 		"PKCS#11: pkcs11h_openssl_createSession - return openssl_session=%p",
@@ -558,9 +984,10 @@ void
 pkcs11h_openssl_freeSession (
 	IN const pkcs11h_openssl_session_t openssl_session
 ) {
+	CK_RV rv;
+
 	_PKCS11H_ASSERT (openssl_session!=NULL);
-	_PKCS11H_ASSERT (openssl_session->reference_count>0);
-	
+
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
 		"PKCS#11: pkcs11h_openssl_freeSession - entry openssl_session=%p, count=%d",
@@ -568,9 +995,24 @@ pkcs11h_openssl_freeSession (
 		openssl_session->reference_count
 	);
 
+#if defined(ENABLE_PKCS11H_THREADING)
+	if ((rv = _pkcs11h_threading_mutexLock(&openssl_session->reference_count_lock)) != CKR_OK) {
+		_PKCS11H_LOG (PKCS11H_LOG_ERROR, "PKCS#11: Cannot lock mutex %ld:'%s'", rv, pkcs11h_getMessage (rv));
+		goto cleanup;
+	}
+#endif
 	openssl_session->reference_count--;
-	
+#if defined(ENABLE_PKCS11H_THREADING)
+	_pkcs11h_threading_mutexRelease(&openssl_session->reference_count_lock);
+#endif
+
+	_PKCS11H_ASSERT (openssl_session->reference_count>=0);
+
 	if (openssl_session->reference_count == 0) {
+#if defined(ENABLE_PKCS11H_THREADING)
+		_pkcs11h_threading_mutexFree(&openssl_session->reference_count_lock);
+#endif
+
 		if (openssl_session->cleanup_hook != NULL) {
 			openssl_session->cleanup_hook (openssl_session->certificate);
 		}
@@ -583,10 +1025,12 @@ pkcs11h_openssl_freeSession (
 			pkcs11h_certificate_freeCertificate (openssl_session->certificate);
 			openssl_session->certificate = NULL;
 		}
-		
+
 		_pkcs11h_mem_free ((void *)&openssl_session);
 	}
 
+cleanup:
+
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
 		"PKCS#11: pkcs11h_openssl_freeSession - return"
@@ -597,10 +1041,71 @@ RSA *
 pkcs11h_openssl_session_getRSA (
 	IN const pkcs11h_openssl_session_t openssl_session
 ) {
-	X509 *x509 = NULL;
+#ifndef OPENSSL_NO_RSA
 	RSA *rsa = NULL;
-	EVP_PKEY *pubkey = NULL;
-	PKCS11H_BOOL ok = FALSE;
+	RSA *ret = NULL;
+	EVP_PKEY *evp = NULL;
+
+	_PKCS11H_DEBUG (
+		PKCS11H_LOG_DEBUG2,
+		"PKCS#11: pkcs11h_openssl_session_getRSA - entry openssl_session=%p",
+		(void *)openssl_session
+	);
+
+	if ((evp = pkcs11h_openssl_session_getEVP(openssl_session)) == NULL) {
+		goto cleanup;
+	}
+
+	if (evp->type != EVP_PKEY_RSA) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Invalid public key algorithm");
+		goto cleanup;
+	}
+
+	if (
+		(rsa = EVP_PKEY_get1_RSA (evp)) == NULL
+	) {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get RSA key");
+		goto cleanup;
+	}
+
+	ret = rsa;
+	rsa = NULL;
+
+cleanup:
+
+	/*
+	 * openssl objects have reference
+	 * count, so release them
+	 */
+	if (rsa != NULL) {
+		RSA_free (rsa);
+		rsa = NULL;
+	}
+
+	if (evp != NULL) {
+		EVP_PKEY_free (evp);
+		evp = NULL;
+	}
+
+	_PKCS11H_DEBUG (
+		PKCS11H_LOG_DEBUG2,
+		"PKCS#11: pkcs11h_openssl_session_getRSA - return ret=%p",
+		(void *)rsa
+	);
+
+	return ret;
+#else
+	return NULL;
+#endif
+}
+
+EVP_PKEY *
+pkcs11h_openssl_session_getEVP (
+	IN const pkcs11h_openssl_session_t openssl_session
+) {
+	X509 *x509 = NULL;
+	EVP_PKEY *evp = NULL;
+	EVP_PKEY *ret = NULL;
 
 	_PKCS11H_ASSERT (openssl_session!=NULL);
 	_PKCS11H_ASSERT (!openssl_session->initialized);
@@ -608,10 +1113,10 @@ pkcs11h_openssl_session_getRSA (
 
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
-		"PKCS#11: pkcs11h_openssl_session_getRSA - entry openssl_session=%p",
+		"PKCS#11: pkcs11h_openssl_session_getEVP - entry openssl_session=%p",
 		(void *)openssl_session
 	);
-	
+
 	/*
 	 * Dup x509 so RSA will not hold session x509
 	 */
@@ -620,71 +1125,75 @@ pkcs11h_openssl_session_getRSA (
 		goto cleanup;
 	}
 
-	if ((pubkey = X509_get_pubkey (x509)) == NULL) {
+	if ((evp = X509_get_pubkey (x509)) == NULL) {
 		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get public key");
 		goto cleanup;
 	}
-	
-	if (pubkey->type != EVP_PKEY_RSA) {
-		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Invalid public key algorithm");
-		goto cleanup;
-	}
 
-	if (
-		(rsa = EVP_PKEY_get1_RSA (pubkey)) == NULL
-	) {
-		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get RSA key");
+	if (0) {
+	}
+#ifndef OPENSSL_NO_RSA
+	else if (evp->type == EVP_PKEY_RSA) {
+		if (!__pkcs11h_openssl_session_setRSA(openssl_session, evp)) {
+			goto cleanup;
+		}
+	}
+#endif
+#ifndef OPENSSL_NO_RSA
+	else if (evp->type == EVP_PKEY_DSA) {
+		if (!__pkcs11h_openssl_session_setDSA(openssl_session, evp)) {
+			goto cleanup;
+		}
+	}
+#endif
+#ifdef __ENABLE_EC
+	else if (evp->type == EVP_PKEY_EC) {
+		if (!__pkcs11h_openssl_session_setECDSA(openssl_session, evp)) {
+			goto cleanup;
+		}
+	}
+#endif
+	else {
+		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Invalid public key algorithm %d", evp->type);
 		goto cleanup;
 	}
 
-	RSA_set_method (rsa, &openssl_session->smart_rsa);
-	RSA_set_app_data (rsa, openssl_session);
+#if defined(ENABLE_PKCS11H_THREADING)
+	_pkcs11h_threading_mutexLock(&openssl_session->reference_count_lock);
+#endif
 	openssl_session->reference_count++;
-	
-#ifdef BROKEN_OPENSSL_ENGINE
-	if (!rsa->engine) {
-		rsa->engine = ENGINE_get_default_RSA ();
-	}
-
-	ENGINE_set_RSA(ENGINE_get_default_RSA (), &openssl_session->smart_rsa);
-	_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled");
+#if defined(ENABLE_PKCS11H_THREADING)
+	_pkcs11h_threading_mutexRelease(&openssl_session->reference_count_lock);
 #endif
-		
-	rsa->flags |= RSA_FLAG_SIGN_VER;
+
 	openssl_session->initialized = TRUE;
 
-	ok = TRUE;
+	ret = evp;
+	evp = NULL;
 
 cleanup:
 
-	if (!ok) {
-		if (rsa != NULL) {
-			RSA_free (rsa);
-			rsa = NULL;
-		}
-	}
-
 	/*
 	 * openssl objects have reference
 	 * count, so release them
 	 */
-	if (pubkey != NULL) {
-		EVP_PKEY_free (pubkey);
-		pubkey = NULL;
+	if (evp != NULL) {
+		EVP_PKEY_free (evp);
+		evp = NULL;
 	}
 
 	if (x509 != NULL) {
 		X509_free (x509);
 		x509 = NULL;
 	}
-	
+
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
-		"PKCS#11: pkcs11h_openssl_session_getRSA - return rsa=%p",
-		(void *)rsa
+		"PKCS#11: pkcs11h_openssl_session_getEVP - return ret=%p",
+		(void *)ret
 	);
 
-	return rsa;
+	return ret;
 }
 
 X509 *
@@ -693,7 +1202,7 @@ pkcs11h_openssl_session_getX509 (
 ) {
 	X509 *x509 = NULL;
 	PKCS11H_BOOL ok = FALSE;
-	
+
 	_PKCS11H_ASSERT (openssl_session!=NULL);
 
 	_PKCS11H_DEBUG (
@@ -705,7 +1214,7 @@ pkcs11h_openssl_session_getX509 (
 	if (
 		openssl_session->x509 == NULL &&
 		(openssl_session->x509 = pkcs11h_openssl_getX509 (openssl_session->certificate)) == NULL
-	) {	
+	) {
 		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get certificate object");
 		goto cleanup;
 	}
@@ -725,7 +1234,7 @@ cleanup:
 			x509 = NULL;
 		}
 	}
-	
+
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
 		"PKCS#11: pkcs11h_openssl_session_getX509 - return x509=%p",
diff --git a/lib/pkcs11h-session.c b/lib/pkcs11h-session.c
index 050064a..81fbefd 100644
--- a/lib/pkcs11h-session.c
+++ b/lib/pkcs11h-session.c
@@ -276,7 +276,7 @@ _pkcs11h_session_findObjects (
 	_PKCS11H_ASSERT (!(filter==NULL && filter_attrs!=0) || filter!=NULL);
 	_PKCS11H_ASSERT (p_objects!=NULL);
 	_PKCS11H_ASSERT (p_objects_found!=NULL);
-	
+
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
 		"PKCS#11: _pkcs11h_session_findObjects entry session=%p, filter=%p, filter_attrs=%ld, p_objects=%p, p_objects_found=%p",
@@ -309,9 +309,9 @@ _pkcs11h_session_findObjects (
 			&objects_found
 		)) == CKR_OK &&
 		objects_found > 0
-	) { 
+	) {
 		CK_OBJECT_HANDLE *temp = NULL;
-		
+
 		/*
 		 * Begin workaround
 		 *
@@ -327,7 +327,7 @@ _pkcs11h_session_findObjects (
 		}
 		oLast = objects_buffer[0];
 		/* End workaround */
-		
+
 		if (
 			(rv = _pkcs11h_mem_malloc (
 				(void *)&temp,
@@ -366,7 +366,7 @@ _pkcs11h_session_findObjects (
 		);
 		should_FindObjectsFinal = FALSE;
 	}
-	
+
 	*p_objects = objects;
 	*p_objects_found = objects_size;
 	objects = NULL;
@@ -462,7 +462,7 @@ _pkcs11h_session_getSessionByTokenId (
 
 		session->reference_count = 1;
 		session->session_handle = _PKCS11H_INVALID_SESSION_HANDLE;
-		
+
 		session->pin_cache_period = _g_pkcs11h_data->pin_cache_period;
 
 		if (
@@ -633,7 +633,7 @@ _pkcs11h_session_reset (
 			) {
 				continue;
 			}
-		
+
 			if (
 				(rv = _pkcs11h_session_getSlotList (
 					current_provider,
@@ -739,7 +739,7 @@ _pkcs11h_session_reset (
 				"PKCS#11: Calling token_prompt hook for '%s'",
 				session->token_id->display
 			);
-	
+
 			canceled = !_g_pkcs11h_data->hooks.token_prompt (
 				_g_pkcs11h_data->hooks.token_prompt_data,
 				user_data,
@@ -794,7 +794,7 @@ _pkcs11h_session_getObjectById (
 	CK_OBJECT_HANDLE *objects = NULL;
 	CK_ULONG objects_found = 0;
 	CK_RV rv = CKR_FUNCTION_FAILED;
-	
+
 	/*_PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
 	_PKCS11H_ASSERT (id!=NULL);
 	_PKCS11H_ASSERT (p_handle!=NULL);
@@ -1000,7 +1000,7 @@ _pkcs11h_session_login (
 
 		while (
 			!login_succeeded &&
-			retry_count < _g_pkcs11h_data->max_retries 
+			retry_count < _g_pkcs11h_data->max_retries
 		) {
 			CK_UTF8CHAR_PTR utfPIN = NULL;
 			CK_ULONG lPINLength = 0;
diff --git a/lib/pkcs11h-slotevent.c b/lib/pkcs11h-slotevent.c
index e32f6e6..2e8edb3 100644
--- a/lib/pkcs11h-slotevent.c
+++ b/lib/pkcs11h-slotevent.c
@@ -130,7 +130,7 @@ __pkcs11h_slotevent_provider (
 	if (
 		provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_AUTO ||
 		provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_TRIGGER
-	) { 
+	) {
 		_PKCS11H_DEBUG (
 			PKCS11H_LOG_DEBUG1,
 			"PKCS#11: Setup slotevent provider='%s' checking trigger",
@@ -163,7 +163,7 @@ __pkcs11h_slotevent_provider (
 	if (
 		provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_AUTO ||
 		provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_POLL
-	) { 
+	) {
 		PKCS11H_BOOL had_sleep = TRUE;
 
 		_PKCS11H_DEBUG (
@@ -210,7 +210,7 @@ __pkcs11h_slotevent_provider (
 	if (
 		provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_AUTO ||
 		provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_FETCH
-	) { 
+	) {
 		unsigned long last_checksum = 0;
 		PKCS11H_BOOL is_first_time = TRUE;
 
@@ -271,7 +271,7 @@ __pkcs11h_slotevent_provider (
 					);
 				}
 			}
-			
+
 			if (is_first_time) {
 				is_first_time = FALSE;
 			}
@@ -295,7 +295,7 @@ __pkcs11h_slotevent_provider (
 			if (slots != NULL) {
 				_pkcs11h_mem_free ((void *)&slots);
 			}
-			
+
 			if (rv != CKR_OK) {
 				goto cleanup;
 			}
@@ -451,7 +451,7 @@ _pkcs11h_slotevent_init (void) {
 		if ((rv = _pkcs11h_threading_condInit (&_g_pkcs11h_data->slotevent.cond_event)) != CKR_OK) {
 			goto cleanup;
 		}
-		
+
 		if (
 			(rv = _pkcs11h_threading_threadStart (
 				&_g_pkcs11h_data->slotevent.thread,
@@ -461,7 +461,7 @@ _pkcs11h_slotevent_init (void) {
 		) {
 			goto cleanup;
 		}
-		
+
 		_g_pkcs11h_data->slotevent.initialized = TRUE;
 	}
 
@@ -481,7 +481,7 @@ cleanup:
 
 CK_RV
 _pkcs11h_slotevent_notify (void) {
-	
+
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
 		"PKCS#11: _pkcs11h_slotevent_notify entry"
@@ -512,7 +512,7 @@ _pkcs11h_slotevent_terminate_force (void) {
 
 CK_RV
 _pkcs11h_slotevent_terminate (void) {
-	
+
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
 		"PKCS#11: _pkcs11h_slotevent_terminate entry"
diff --git a/lib/pkcs11h-threading.c b/lib/pkcs11h-threading.c
index f6c0d13..4fb9495 100644
--- a/lib/pkcs11h-threading.c
+++ b/lib/pkcs11h-threading.c
@@ -120,7 +120,7 @@ cleanup:
 			goto cleanup;
 		}
 		mutex_locked = TRUE;
-		
+
 		if (
 			(rv = _pkcs11h_mem_malloc (
 				(void *)&entry,
@@ -276,7 +276,7 @@ _pkcs1h_threading_mutexLockAll (void) {
 
 	while (!all_mutexes_locked) {
 		PKCS11H_BOOL ok = TRUE;
-		
+
 		for (
 			entry = __s_pkcs11h_threading_mutex_list.head;
 			entry != NULL && ok;
@@ -438,10 +438,10 @@ _pkcs11h_threading_condWait (
 			rv = CKR_FUNCTION_FAILED;
 			goto cleanup;
 		}
-		
+
 		timeout.tv_sec = now.tv_sec + milli/1000;
 		timeout.tv_nsec = now.tv_usec*1000 + milli%1000;
-		
+
 		if (pthread_cond_timedwait (&cond->cond, &cond->mut, &timeout)) {
 			rv = CKR_FUNCTION_FAILED;
 			goto cleanup;
diff --git a/lib/pkcs11h-token.c b/lib/pkcs11h-token.c
index 070db43..350d1dd 100644
--- a/lib/pkcs11h-token.c
+++ b/lib/pkcs11h-token.c
@@ -124,7 +124,7 @@ cleanup:
 		pkcs11h_getMessage (rv),
 		(void *)*to
 	);
-	
+
 	return rv;
 }
 
@@ -151,10 +151,10 @@ _pkcs11h_token_getTokenId (
 ) {
 	pkcs11h_token_id_t token_id;
 	CK_RV rv = CKR_FUNCTION_FAILED;
-	
+
 	_PKCS11H_ASSERT (info!=NULL);
 	_PKCS11H_ASSERT (p_token_id!=NULL);
-	
+
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
 		"PKCS#11: _pkcs11h_token_getTokenId entry p_token_id=%p",
@@ -276,7 +276,7 @@ pkcs11h_token_logout (
 
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
-		"PKCS#11: pkcs11h_token_logout entry token_id=%p\n", 
+		"PKCS#11: pkcs11h_token_logout entry token_id=%p\n",
 		(void *)token_id
 	);
 
@@ -348,7 +348,7 @@ pkcs11h_token_login (
 
 	_PKCS11H_DEBUG (
 		PKCS11H_LOG_DEBUG2,
-		"PKCS#11: pkcs11h_token_login entry token_id=%p, readonly=%d\n", 
+		"PKCS#11: pkcs11h_token_login entry token_id=%p, readonly=%d\n",
 		(void *)token_id,
 		readonly ? 1 : 0
 	);
@@ -696,7 +696,7 @@ pkcs11h_token_enumTokenIds (
 					(rv = pkcs11h_token_duplicateTokenId (
 						&entry->token_id,
 						session->token_id
-					)) != CKR_OK 
+					)) != CKR_OK
 				) {
 					goto retry12;
 				}
@@ -742,7 +742,7 @@ cleanup:
 		pkcs11h_getMessage (rv),
 		(void *)p_token_id_list
 	);
-	
+
 	return rv;
 }
 
diff --git a/lib/pkcs11h-util.c b/lib/pkcs11h-util.c
index ab6fd38..0743fd1 100644
--- a/lib/pkcs11h-util.c
+++ b/lib/pkcs11h-util.c
@@ -62,7 +62,7 @@ _pkcs11h_util_fixupFixedString (
 
 	_PKCS11H_ASSERT (source!=NULL);
 	_PKCS11H_ASSERT (target!=NULL);
-	
+
 	p = target+length;
 	memmove (target, source, length);
 	*p = '\0';
@@ -163,7 +163,7 @@ _pkcs11h_util_escapeString (
 
 	while (*s != '\x0') {
 
-		if (*s == '\\' || strchr (invalid_chars, *s) || !isgraph (*s)) {
+		if (*s == '\\' || strchr (invalid_chars, (unsigned char)*s) || !isgraph (*s)) {
 			if (t != NULL) {
 				if (n+4 > *max) {
 					rv = CKR_ATTRIBUTE_VALUE_INVALID;
diff --git a/lib/token.exports b/lib/token.exports
index 9ac673b..42fa27c 100644
--- a/lib/token.exports
+++ b/lib/token.exports
@@ -5,5 +5,6 @@ pkcs11h_token_enumTokenIds
 pkcs11h_token_freeTokenId
 pkcs11h_token_freeTokenIdList
 pkcs11h_token_login
+pkcs11h_token_logout
 pkcs11h_token_sameTokenId
 pkcs11h_token_serializeTokenId
diff --git a/tests/test-certificate/test-certificate.c b/tests/test-certificate/test-certificate.c
index fbaf2d7..8cd28df 100644
--- a/tests/test-certificate/test-certificate.c
+++ b/tests/test-certificate/test-certificate.c
@@ -83,7 +83,7 @@ _pkcs11h_hooks_token_prompt (
 		}
 	}
 
-	return fRet; 
+	return fRet;
 }
 
 static
@@ -133,7 +133,7 @@ sign_test (const pkcs11h_certificate_t cert) {
 	};
 
 	CK_RV rv;
-					 
+
 	unsigned char *blob;
 	size_t blob_size;
 

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



More information about the pkg-opensc-commit mailing list