[pkg-opensc-commit] [pkcs11-helper] 230/253: openssl: add ecdsa support

Eric Dorland eric at moszumanska.debian.org
Fri Jan 6 23:39:23 UTC 2017


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

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

commit 084da7012e3cef8f8cad22216e72f301854e3307
Author: Alon Bar-Lev <alon.barlev at gmail.com>
Date:   Sun Sep 15 00:28:55 2013 +0300

    openssl: add ecdsa support
    
    Tested-By: Sanaullah <sanaullah82 at gmail.com>
    Signed-off-by: Alon Bar-Lev <alon.barlev at gmail.com>
---
 ChangeLog             |   1 +
 configure.ac          |  52 +++++++++++++
 lib/pkcs11h-openssl.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 260 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 8e1da42..325ce14 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,7 @@ $Id$
 
  * openssl: support generic pkey.
  * openssl: add dsa support.
+ * openssl: add ecdsa support, thanks for Sanaullah for testing.
 
 2012-02-29 - Version 1.10
 
diff --git a/configure.ac b/configure.ac
index ba7be15..2ea1030 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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/lib/pkcs11h-openssl.c b/lib/pkcs11h-openssl.c
index 4f4978f..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
@@ -89,6 +96,10 @@ static struct {
 	DSA_METHOD dsa;
 	int dsa_index;
 #endif
+#ifdef __ENABLE_EC
+	ECDSA_METHOD *ecdsa;
+	int ecdsa_index;
+#endif
 } __openssl_methods;
 
 static
@@ -585,6 +596,174 @@ cleanup:
 
 #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 (
@@ -617,6 +796,21 @@ _pkcs11h_openssl_initialize (void) {
 		__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"
@@ -630,6 +824,12 @@ _pkcs11h_openssl_terminate (void) {
 		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;
 }
 
@@ -946,6 +1146,13 @@ pkcs11h_openssl_session_getEVP (
 		}
 	}
 #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;

-- 
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