[pkg-opensc-commit] [libp11] 04/86: OpenSSL-1.1 initial changes for libp11
Eric Dorland
eric at moszumanska.debian.org
Sun Jul 24 21:40:16 UTC 2016
This is an automated email from the git hooks/post-receive script.
eric pushed a commit to branch master
in repository libp11.
commit 3f248533bbad437a103626ad3c6e5a37726dbf8f
Author: Doug Engert <deengert at gmail.com>
Date: Thu Jan 14 16:53:13 2016 -0600
OpenSSL-1.1 initial changes for libp11
---
examples/decrypt.c | 3 +-
src/libp11.exports | 1 +
src/libp11.h | 9 +++
src/p11_ec.c | 197 +++++++++++++++++++++++++++++++++++------------------
src/p11_key.c | 22 ++++++
src/p11_ops.c | 4 +-
src/p11_rsa.c | 9 +++
7 files changed, 177 insertions(+), 68 deletions(-)
diff --git a/examples/decrypt.c b/examples/decrypt.c
index d813972..5a9fb1d 100644
--- a/examples/decrypt.c
+++ b/examples/decrypt.c
@@ -218,7 +218,8 @@ loggedin:
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
- ERR_remove_state(0);
+/* TODO fix this */
+// ERR_remove_state(0);
printf("decryption successfull.\n");
return 0;
diff --git a/src/libp11.exports b/src/libp11.exports
index 8b6bb67..95213b6 100644
--- a/src/libp11.exports
+++ b/src/libp11.exports
@@ -39,3 +39,4 @@ PKCS11_get_rsa_method
PKCS11_get_ecdsa_method
PKCS11_ecdsa_method_free
ERR_load_PKCS11_strings
+PKCS11_get_ec_key_method
diff --git a/src/libp11.h b/src/libp11.h
index 602a9d7..3a6867f 100644
--- a/src/libp11.h
+++ b/src/libp11.h
@@ -24,8 +24,11 @@
#ifndef _LIB11_H
#define _LIB11_H
+#include <openssl/opensslv.h>
#include <openssl/bio.h>
#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
#include <openssl/x509.h>
#ifdef __cplusplus
@@ -410,8 +413,14 @@ extern int PKCS11_generate_random(PKCS11_SLOT *, unsigned char *r, unsigned int
/* using with openssl method mechanism */
RSA_METHOD *PKCS11_get_rsa_method(void);
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100002L
+EC_KEY_METHOD *PKCS11_get_ec_key_method(void);
+void PKCS11_ec_key_method_free(void);
+#else
ECDSA_METHOD *PKCS11_get_ecdsa_method(void);
void PKCS11_ecdsa_method_free(void);
+#endif
/**
* Load PKCS11 error strings
diff --git a/src/p11_ec.c b/src/p11_ec.c
index 96b1f14..a3c5486 100644
--- a/src/p11_ec.c
+++ b/src/p11_ec.c
@@ -30,60 +30,28 @@
#include <openssl/opensslconf.h>
#define LIBP11_BUILD_WITHOUT_ECDSA
-#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA)
+#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA)
#undef LIBP11_BUILD_WITHOUT_ECDSA
-
#include <openssl/evp.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
-
-/* To build this mode,
- * OpenSSL has ECDSA_METHOD defined in internal header file ecs_locl.h
- * Until this is resolved use something like:
- * CPPFLAGS="-DBUILD_WITH_ECS_LOCL_H -I/path.to.openssl-1.0.1e/src/crypto/ecdsa"
- * See OpenSSL bug report #2459 02/23/2011
- * Once OpenSSL addresses the issues this code will be changed.
- *
- * OpenSSL mods were submitted 09/2013 that will set ECDSA_F_ECDSA_METHOD_NEW
- * and define the ECDSA_METHOD_new and friends functions
- * These mods are in OpenSSL-1.0.2-beta
- * We will try both methods.
- */
-
-#if defined(ECDSA_F_ECDSA_METHOD_NEW) && defined(BUILD_WITH_ECS_LOCL_H)
- #warning "Both BUILD_WITH_ECS_LOCL_H and ECDSA_F_ECDSA_METHOD_NEW defined"
- #warning "Consider not using BUILD_WITH_ECS_LOCL_H"
+#include <openssl/bn.h>
#endif
#if defined(BUILD_WITH_ECS_LOCL_H)
- #warning "Consider not using BUILD_WITH_ECS_LOCL_H"
- #warning "newer version of OpenSSL >-1.0.2 does not need BUILD_WITH_ECS_LOCL_H"
- #include "ecs_locl.h"
-
- #if !defined(HEADER_ECS_LOCL_H)
- #warning "Unable to find OpenSSL src/crypto/ecs_locl.h"
- #warning "add to CPPFLAGS: -I/path/to/source/openssl-n.n.n/src/crypto/ecdsa"
- #warning "or copy ecs_locl.h or create symlink to it"
- #if defined(ECDSA_F_ECDSA_METHOD_NEW)
- #warning "Will build instead using ECDSA_F_ECDSA_METHOD_NEW"
- #else
- #error "Unable to build with ECDSA support"
- #endif
- #else
- #define LIBP11_BUILD_WITH_ECS_LOCL_H
- #endif
-#else
- #if !defined(ECDSA_F_ECDSA_METHOD_NEW)
- #define LIBP11_BUILD_WITHOUT_ECDSA
- #endif
+ #error "BUILD_WITH_ECS_LOCL_H is no longer supported"
#endif
-#endif /* OpenSSL EC tests and version */
-
#if !defined(LIBP11_BUILD_WITHOUT_ECDSA)
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+static EC_KEY_METHOD *ops = NULL;
+static int ec_key_ex_index = 0;
+#else
static ECDSA_METHOD *ops = NULL;
static int ecdsa_ex_index = 0;
+#endif
/*
* Get EC key material and stash pointer in ex_data
@@ -165,18 +133,36 @@ static EVP_PKEY *pkcs11_get_evp_key_ec(PKCS11_KEY * key)
* that will use the card's functions to sign & decrypt
*/
if (os)
- M_ASN1_OCTET_STRING_free(os);
+ ASN1_STRING_free(os);
if (ec_point)
OPENSSL_free(ec_point);
if (ec_params)
OPENSSL_free(ec_params);
- if (key->isPrivate)
+ if (sensitive || !extractable) {
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ EC_KEY_set_method(ec, PKCS11_get_ec_key_method());
+#else
+ ECDSA_set_method(ec, PKCS11_get_ecdsa_method());
+#endif
+ } else if (key->isPrivate) {
+ /* TODO: Extract the ECDSA private key */
+ /* In the meantime lets use the card anyway */
+ /* TODO we should do this early after EC_KEY_new */
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ EC_KEY_set_method(ec, PKCS11_get_ec_key_method());
+#else
ECDSA_set_method(ec, PKCS11_get_ecdsa_method());
/* TODO: Retrieve the ECDSA private key object attributes instead,
* unless the key has the "sensitive" attribute set */
+#endif
+ }
+#if OPENSSL_VERSION_NUMBER >= 0x10100002L
+ EC_KEY_set_ex_data(ec,ec_key_ex_index, key);
+#else
ECDSA_set_ex_data(ec, ecdsa_ex_index, key);
+#endif
EC_KEY_free(ec); /* drops our reference to it */
return pk;
}
@@ -198,6 +184,7 @@ static int pkcs11_ecdsa_sign_setup(EC_KEY *ec, BN_CTX *ctx_in,
static ECDSA_SIG * pkcs11_ecdsa_do_sign(const unsigned char *dgst, int dlen,
const BIGNUM *inv, const BIGNUM *r, EC_KEY * ec)
{
+
unsigned char sigret[512]; /* HACK for now */
ECDSA_SIG * sig = NULL;
PKCS11_KEY * key = NULL;
@@ -205,7 +192,11 @@ static ECDSA_SIG * pkcs11_ecdsa_do_sign(const unsigned char *dgst, int dlen,
int nLen = 48; /* HACK */
int rv;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ key = (PKCS11_KEY *) EC_KEY_get_ex_data(ec, ec_key_ex_index);
+#else
key = (PKCS11_KEY *) ECDSA_get_ex_data(ec, ecdsa_ex_index);
+#endif
if (key == NULL)
return NULL;
@@ -216,13 +207,55 @@ static ECDSA_SIG * pkcs11_ecdsa_do_sign(const unsigned char *dgst, int dlen,
if (rv > 0) {
sig = ECDSA_SIG_new();
if (sig) {
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ /*
+ * OpenSSL 1.1 does not have a way to alloc r and s
+ * the BN in ECDSA_SIG as it is now hidden.
+ * Will us dummy ASN1 seq to set it, then
+ * ECDSA_SIG_get0 to get access to r and s
+ */
+ const unsigned char *a;
+ unsigned char dasn1[8] =
+ {0x30, 0x06, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00};
+ BIGNUM *r;
+ BIGNUM *s;
+ a = dasn1;
+ d2i_ECDSA_SIG(&sig, &a, 8);
+ ECDSA_SIG_get0(&r, &s, sig);
+ BN_bin2bn(&sigret[0], nLen, r);
+ BN_bin2bn(&sigret[nLen], nLen, s);
+#else
BN_bin2bn(&sigret[0], nLen, sig->r);
BN_bin2bn(&sigret[nLen], nLen, sig->s);
+#if 0
+/* TODO remove this gdb debugging */
+ {
+ int ilen = 0;
+ unsigned char tmpsigbuff[512];
+ unsigned char **tmpsig = &tmpsigbuff;
+
+ ilen = i2d_ECDSA_SIG(sig,NULL);
+ ilen = i2d_ECDSA_SIG(sig, tmpsig);
+ printf("ilen=&d\n",ilen);
+ }
+#endif
+#endif
}
}
return sig;
}
+#if OPENSSL_VERSION_NUMBER >= 0x10100002L
+static void alloc_ec_key_ex_index() {
+ if (ec_key_ex_index == 0) {
+ while (ec_key_ex_index == 0) /* Workaround for OpenSSL RT3710 */
+ ec_key_ex_index = EC_KEY_get_ex_new_index(0, "libp11 ec_key",
+ NULL, NULL, NULL);
+ if (ec_key_ex_index < 0)
+ ec_key_ex_index = 0; /* Fallback to app_data */
+ }
+}
+#else
static void alloc_ecdsa_ex_index() {
if (ecdsa_ex_index == 0) {
while (ecdsa_ex_index == 0) /* Workaround for OpenSSL RT3710 */
@@ -232,7 +265,17 @@ static void alloc_ecdsa_ex_index() {
ecdsa_ex_index = 0; /* Fallback to app_data */
}
}
+#endif
+#if OPENSSL_VERSION_NUMBER >= 0x10100002L
+static void free_ec_key_ex_index() {
+ /* CRYPTO_free_ex_index requires OpenSSL version >= 1.1.0-pre1 */
+ if (ec_key_ex_index > 0) {
+ CRYPTO_free_ex_index(CRYPTO_EX_INDEX_EC_KEY, ec_key_ex_index);
+ ec_key_ex_index = 0;
+ }
+}
+#else
static void free_ecdsa_ex_index() {
/* CRYPTO_free_ex_index requires OpenSSL version >= 1.1.0-pre1 */
#if OPENSSL_VERSION_NUMBER >= 0x10100001L
@@ -242,59 +285,81 @@ static void free_ecdsa_ex_index() {
}
#endif
}
+#endif
/*
* Overload the default OpenSSL methods for ECDSA
* If OpenSSL supports ECDSA_METHOD_new we will use it.
- * Otherwise we expect the ecs_locl.h to be present.
+ * First introduced in 1.0.2, changed in 1.1-pre
*/
-#if !defined(LIBP11_BUILD_WITH_ECS_LOCL_H)
/* New way to allocate an ECDSA_METOD object */
-ECDSA_METHOD *PKCS11_get_ecdsa_method(void)
+/* OpenSSL 1.1 has single method EC_KEY_METHOD for ECDSA and ECDH */
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+EC_KEY_METHOD *PKCS11_get_ec_key_method(void)
{
- alloc_ecdsa_ex_index();
+ int (*orig_sign)(int type, const unsigned char *dgst,
+ int dlen, unsigned char *sig,
+ unsigned int *siglen,
+ const BIGNUM *kinv, const BIGNUM *r,
+ EC_KEY *eckey) = NULL;
+ int (*orig_sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
+ BIGNUM **kinvp, BIGNUM **rp) = NULL;
+ ECDSA_SIG *(*orig_sign_sig)(const unsigned char *dgst,
+ int dgst_len,
+ const BIGNUM *in_kinv,
+ const BIGNUM *in_r,
+ EC_KEY *eckey) = NULL;
+
+ alloc_ec_key_ex_index();
if (ops == NULL) {
- ops = ECDSA_METHOD_new((ECDSA_METHOD *)ECDSA_OpenSSL());
- ECDSA_METHOD_set_sign(ops, pkcs11_ecdsa_do_sign);
- ECDSA_METHOD_set_sign_setup(ops, pkcs11_ecdsa_sign_setup);
+ ops = EC_KEY_METHOD_new((EC_KEY_METHOD *)EC_KEY_OpenSSL());
+
+ EC_KEY_METHOD_get_sign(ops, &orig_sign,
+ &orig_sign_setup, &orig_sign_sig);
+
+/* TODO look at which routines to use */
+ EC_KEY_METHOD_set_sign(ops, orig_sign,
+ pkcs11_ecdsa_sign_setup,
+ pkcs11_ecdsa_do_sign);
}
return ops;
}
-void PKCS11_ecdsa_method_free(void)
+void PKCS11_EC_KEY_METHOD_free(void)
{
if (ops) {
- ECDSA_METHOD_free(ops);
+ EC_KEY_METHOD_free(ops);
ops = NULL;
}
- free_ecdsa_ex_index();
+ free_ec_key_ex_index();
}
-#else /* LIBP11_BUILD_WITH_ECS_LOCL_H */
-
-/* Old way using ecs_locl.h */
+#else /* OPENSSL_VERSION_NUMBER >= 0x1000200fL */
ECDSA_METHOD *PKCS11_get_ecdsa_method(void)
{
- static struct ecdsa_method sops;
-
- alloc_ecdsa_ex_index();
- if (!sops.ecdsa_do_sign) {
-/* question if compiler is copying each member of struct or not */
- sops = *ECDSA_get_default_method();
- sops.ecdsa_do_sign = pkcs11_ecdsa_do_sign;
- sops.ecdsa_sign_setup = pkcs11_ecdsa_sign_setup;
+
+ if (ops == NULL) {
+ alloc_ecdsa_ex_index();
+ ops = ECDSA_METHOD_new((ECDSA_METHOD *)ECDSA_OpenSSL());
+ ECDSA_METHOD_set_sign(ops, pkcs11_ecdsa_do_sign);
+ ECDSA_METHOD_set_sign_setup(ops, pkcs11_ecdsa_sign_setup);
}
- return &sops;
+ return ops;
}
void PKCS11_ecdsa_method_free(void)
{
/* It is static in the old method */
free_ecdsa_ex_index();
+ if (ops) {
+ ECDSA_METHOD_free(ops);
+ ops = NULL;
+ }
}
-#endif /* LIBP11_BUILD_WITH_ECS_LOCL_H */
+#endif /* OPENSSL_VERSION_NUMBER >= 0x1000200fL */
PKCS11_KEY_ops pkcs11_ec_ops_s = {
EVP_PKEY_EC,
diff --git a/src/p11_key.c b/src/p11_key.c
index d86a761..7cf1793 100644
--- a/src/p11_key.c
+++ b/src/p11_key.c
@@ -19,6 +19,7 @@
#include "libp11-int.h"
#include <string.h>
+#include <openssl/bn.h>
#ifdef _WIN32
#define strncasecmp strnicmp
@@ -144,6 +145,10 @@ PKCS11_generate_key(PKCS11_TOKEN * token, int algorithm, unsigned int bits,
EVP_PKEY *pk;
RSA *rsa;
BIO *err;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ BIGNUM *exp = NULL;
+ BN_GENCB *gencb = NULL;
+#endif
int rc;
if (algorithm != EVP_PKEY_RSA) {
@@ -152,7 +157,24 @@ PKCS11_generate_key(PKCS11_TOKEN * token, int algorithm, unsigned int bits,
}
err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ exp = BN_new();
+ rsa = RSA_new();
+ gencb = BN_GENCB_new();
+ if (gencb)
+ BN_GENCB_set(gencb, NULL, err);
+
+ if ( rsa == NULL || exp == NULL || gencb == NULL
+ || !BN_set_word(exp, RSA_F4) || !RSA_generate_key_ex(rsa, bits, exp, gencb)) {
+ RSA_free(rsa);
+ }
+ BN_GENCB_free(gencb);
+ BN_free(exp);
+
+#else
rsa = RSA_generate_key(bits, RSA_F4, NULL, err);
+#endif
BIO_free(err);
if (rsa == NULL) {
PKCS11err(PKCS11_F_PKCS11_GENERATE_KEY, PKCS11_KEYGEN_FAILED);
diff --git a/src/p11_ops.c b/src/p11_ops.c
index 60dec42..516bdec 100644
--- a/src/p11_ops.c
+++ b/src/p11_ops.c
@@ -22,6 +22,8 @@
#include "libp11-int.h"
#include <string.h>
+#include <openssl/ossl_typ.h>
+#include <openssl/asn1.h>
int
PKCS11_ecdsa_sign(const unsigned char *m, unsigned int m_len,
@@ -94,7 +96,7 @@ PKCS11_sign(int type, const unsigned char *m, unsigned int m_len,
int size;
/* Fetch the OID of the algorithm used */
if ((algor.algorithm = OBJ_nid2obj(type)) &&
- (algor.algorithm->length) &&
+ (algor.algorithm) &&
/* Get the size of the encoded DigestInfo */
(size = i2d_X509_SIG(&digest_info, NULL)) &&
/* Check that size is compatible with PKCS#11 padding */
diff --git a/src/p11_rsa.c b/src/p11_rsa.c
index 734c345..1745efb 100644
--- a/src/p11_rsa.c
+++ b/src/p11_rsa.c
@@ -106,7 +106,11 @@ static EVP_PKEY *pkcs11_get_evp_key_rsa(PKCS11_KEY * key)
/* TODO: Retrieve the RSA private key object attributes instead,
* unless the key has the "sensitive" attribute set */
+
+#if OPENSSL_VERSION_NUMBER < 0x01010000L
+ /* RSA_FLAG_SIGN_VER no longer in OpenSSL 1.1 */
rsa->flags |= RSA_FLAG_SIGN_VER;
+#endif
RSA_set_ex_data(rsa, rsa_ex_index, key);
RSA_free(rsa); /* Drops our reference to it */
return pk;
@@ -167,6 +171,7 @@ static int pkcs11_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
* is implemented externally as well.
* We work around this by temporarily cleaning the flag, and
* calling RSA_verify once more.
+ * OpenSSL-1.1 does not define or use the RSA_FLAG_SIGN_VER. No need for hack
*/
static int
pkcs11_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
@@ -175,6 +180,9 @@ pkcs11_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
RSA *r = (RSA *) rsa; /* Ugly hack to get rid of compiler warning */
int res;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ res = RSA_verify(type, m, m_len, signature, siglen, r);
+#else
if (r->flags & RSA_FLAG_SIGN_VER) {
r->flags &= ~RSA_FLAG_SIGN_VER;
res = RSA_verify(type, m, m_len, signature, siglen, r);
@@ -183,6 +191,7 @@ pkcs11_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
PKCS11err(PKCS11_F_PKCS11_RSA_VERIFY, PKCS11_NOT_SUPPORTED);
res = 0;
}
+#endif
return res;
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-opensc/libp11.git
More information about the pkg-opensc-commit
mailing list