[pkg-opensc-commit] [opensc] 119/295: Pkcs11-tool.c changes to accommodate ECDH operations using SoftHSM. (#901)
Eric Dorland
eric at moszumanska.debian.org
Sat Jun 24 21:11:22 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 3ff730952095c927a4b90f88cb47acedf23f6157
Author: Doug Engert <deengert at gmail.com>
Date: Sun Nov 20 09:28:42 2016 -0800
Pkcs11-tool.c changes to accommodate ECDH operations using SoftHSM. (#901)
PKCS#11 v2.20 in not clear on the format of the public key of the other party
pased during ECDH key derivation. Some implementations (OpenSC) pass just the value
of the public key (RAW), while others (SoftHSM) pass an ASN.1 DER encoded OCTET_STRING.
PKCS$11 v2.40 points out this problem and says implementations must support the
RAW format and may also support the DER format.
To allow pkcs11-tool.c to work with ECDH derivation and using the current libSoftHSM2.so
a new parameter was added to pkcs11-tool, --derive-pass-der.
Also added to teh template fot the new key were:
CKA_SENSITIVE = false
CKA_EXTRACTABLE = true
CKA_VALUE_LEN = size of key to be derived.
OpenSC currently only support derivation of ECDH session keys, (CKA_TOKEN = false)
The derived key must be CK_KEY_TYPE = CKK_GENERIC_SECRET
Additional changes could be made to support AES or DES3 keys.
It is not clear if there is a need to support CKA_TOKEN = true which says the
derived key must be on the hardware token. For ECDH, these keys are short lived.
On branch pkcs11-tool-simple-ecdh
Changes to be committed:
modified: src/tools/pkcs11-tool.c
---
src/tools/pkcs11-tool.c | 67 ++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 58 insertions(+), 9 deletions(-)
diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c
index b22eb95..7758b61 100644
--- a/src/tools/pkcs11-tool.c
+++ b/src/tools/pkcs11-tool.c
@@ -140,6 +140,7 @@ enum {
OPT_LOGIN_TYPE,
OPT_TEST_EC,
OPT_DERIVE,
+ OPT_DERIVE_PASS_DER,
OPT_DECRYPT,
OPT_TEST_FORK,
OPT_GENERATE_KEY,
@@ -157,6 +158,7 @@ static const struct option options[] = {
{ "decrypt", 0, NULL, OPT_DECRYPT },
{ "hash", 0, NULL, 'h' },
{ "derive", 0, NULL, OPT_DERIVE },
+ { "derive-pass-der", 0, NULL, OPT_DERIVE_PASS_DER },
{ "mechanism", 1, NULL, 'm' },
{ "login", 0, NULL, 'l' },
@@ -220,6 +222,7 @@ static const char *option_help[] = {
"Decrypt some data",
"Hash some data",
"Derive a secret key using another key and some data",
+ "Derive ECDHpass DER encoded pubkey for compatibility with some PKCS#11 implementations"
"Specify mechanism (use -M for a list of supported mechanisms)",
"Log into the token first",
@@ -308,6 +311,7 @@ static int opt_key_usage_sign = 0;
static int opt_key_usage_decrypt = 0;
static int opt_key_usage_derive = 0;
static int opt_key_usage_default = 1; /* uses defaults if no opt_key_usage options */
+static int opt_derive_pass_der = 0;
static void *module = NULL;
static CK_FUNCTION_LIST_PTR p11 = NULL;
@@ -728,6 +732,9 @@ int main(int argc, char * argv[])
do_test_ec = 1;
action_count++;
break;
+ case OPT_DERIVE_PASS_DER:
+ opt_derive_pass_der = 1;
+ /* fall through */
case OPT_DERIVE:
need_session |= NEED_SESSION_RW;
do_derive = 1;
@@ -2931,22 +2938,31 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE
CK_BBOOL true = TRUE;
CK_BBOOL false = FALSE;
CK_OBJECT_HANDLE newkey = 0;
- CK_ATTRIBUTE newkey_template[] = {
+ CK_ATTRIBUTE newkey_template[20] = {
{CKA_TOKEN, &false, sizeof(false)}, /* session only object */
{CKA_CLASS, &newkey_class, sizeof(newkey_class)},
{CKA_KEY_TYPE, &newkey_type, sizeof(newkey_type)},
+ {CKA_SENSITIVE, &false, sizeof(false)},
+ {CKA_EXTRACTABLE, &true, sizeof(true)},
{CKA_ENCRYPT, &true, sizeof(true)},
- {CKA_DECRYPT, &true, sizeof(true)}
+ {CKA_DECRYPT, &true, sizeof(true)},
+ {CKA_WRAP, &true, sizeof(true)},
+ {CKA_UNWRAP, &true, sizeof(true)}
};
+ int n_attrs = 9;
CK_ECDH1_DERIVE_PARAMS ecdh_parms;
CK_RV rv;
BIO *bio_in = NULL;
EC_KEY *eckey = NULL;
const EC_GROUP *ecgroup = NULL;
const EC_POINT *ecpoint = NULL;
- unsigned char buf[512];
+ unsigned char *buf = NULL;
size_t buf_size = 0;
- int len;
+ CK_ULONG key_len = 0;
+ ASN1_OCTET_STRING *octet = NULL;
+ unsigned char * der = NULL;
+ unsigned char * derp = NULL;
+ size_t der_size = 0;
printf("Using derive algorithm 0x%8.8lx %s\n", opt_mechanism, p11_mechanism_to_name(mech_mech));
memset(&mech, 0, sizeof(mech));
@@ -2963,11 +2979,32 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE
ecpoint = EC_KEY_get0_public_key(eckey);
ecgroup = EC_KEY_get0_group(eckey);
+
if (!ecpoint || !ecgroup)
util_fatal("Failed to parse other EC key from %s", opt_input);
- buf_size = sizeof(buf);
- len = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, buf, buf_size, NULL);
+ /* both eckeys must be same curve */
+ key_len = (EC_GROUP_get_degree(ecgroup) + 7) / 8;
+ FILL_ATTR(newkey_template[n_attrs], CKA_VALUE_LEN, &key_len, sizeof(key_len));
+ n_attrs++;
+
+ buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
+ buf = (unsigned char *)malloc(buf_size);
+ if (buf == NULL)
+ util_fatal("malloc() failure\n");
+ buf_size = EC_POINT_point2oct(ecgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, buf, buf_size, NULL);
+
+ if (opt_derive_pass_der) {
+ octet = ASN1_OCTET_STRING_new();
+ if (octet == NULL)
+ util_fatal("ASN1_OCTET_STRING_new failure\n");
+ ASN1_OCTET_STRING_set(octet, buf, buf_size);
+ der_size = i2d_ASN1_OCTET_STRING(octet, NULL);
+ derp = der = (unsigned char *) malloc(der_size);
+ if (der == NULL)
+ util_fatal("malloc() failure\n");
+ der_size = i2d_ASN1_OCTET_STRING(octet, &derp);
+ }
BIO_free(bio_in);
EC_KEY_free(eckey);
@@ -2976,15 +3013,27 @@ derive_ec_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_MECHANISM_TYPE
ecdh_parms.kdf = CKD_NULL;
ecdh_parms.ulSharedDataLen = 0;
ecdh_parms.pSharedData = NULL;
- ecdh_parms.ulPublicDataLen = len;
- ecdh_parms.pPublicData = buf;
+ if (opt_derive_pass_der) {
+ ecdh_parms.ulPublicDataLen = der_size;
+ ecdh_parms.pPublicData = der;
+ } else {
+ ecdh_parms.ulPublicDataLen = buf_size;
+ ecdh_parms.pPublicData = buf;
+ }
mech.pParameter = &ecdh_parms;
mech.ulParameterLen = sizeof(ecdh_parms);
- rv = p11->C_DeriveKey(session, &mech, key, newkey_template, 5, &newkey);
+ rv = p11->C_DeriveKey(session, &mech, key, newkey_template, n_attrs, &newkey);
if (rv != CKR_OK)
p11_fatal("C_DeriveKey", rv);
+ if (der)
+ OPENSSL_free(der);
+ if (buf)
+ free(buf);
+ if (octet)
+ ASN1_OCTET_STRING_free(octet);
+
return newkey;
#else
util_fatal("Derive EC key not supported");
--
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