[pkg-opensc-commit] [opensc] 277/295: Imporve SKDF decoding and implement encoding

Eric Dorland eric at moszumanska.debian.org
Sat Jun 24 21:11:40 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 2632b616d9a365c1c4e0b9925a0a6b76c561bb75
Author: Timo Teräs <timo.teras at iki.fi>
Date:   Fri Apr 14 10:24:41 2017 +0300

    Imporve SKDF decoding and implement encoding
    
    - fixes decoding of SecretKeyAttributes
    - adds support for algorithmReferences
    - adds support for algIndependentKeys (PKCS#15 Generic keys)
    - implements encoding of SKDF
---
 src/libopensc/pkcs15-skey.c | 128 +++++++++++++++++++++++++++++++++++++++-----
 src/libopensc/pkcs15.c      |   3 ++
 src/libopensc/pkcs15.h      |   3 ++
 3 files changed, 120 insertions(+), 14 deletions(-)

diff --git a/src/libopensc/pkcs15-skey.c b/src/libopensc/pkcs15-skey.c
index 353226c..006dfa1 100644
--- a/src/libopensc/pkcs15-skey.c
+++ b/src/libopensc/pkcs15-skey.c
@@ -26,13 +26,30 @@
 #include <stdio.h>
 #include <assert.h>
 
-#define C_ASN1_COM_KEY_ATTR_SIZE 6
+/*
+ * in src/libopensc/types.h SC_MAX_SUPPORTED_ALGORITHMS  defined as 8
+ */
+#define C_ASN1_SUPPORTED_ALGORITHMS_SIZE (SC_MAX_SUPPORTED_ALGORITHMS + 1)
+static const struct sc_asn1_entry c_asn1_supported_algorithms[C_ASN1_SUPPORTED_ALGORITHMS_SIZE] = {
+	{ "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
+	{ "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
+	{ "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
+	{ "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
+	{ "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
+	{ "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
+	{ "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
+	{ "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
+	{ NULL, 0, 0, 0, NULL, NULL }
+};
+
+#define C_ASN1_COM_KEY_ATTR_SIZE 7
 static const struct sc_asn1_entry c_asn1_com_key_attr[C_ASN1_COM_KEY_ATTR_SIZE] = {
 	{ "iD",		 SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, 0, NULL, NULL},
 	{ "usage",	 SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL},
 	{ "native",      SC_ASN1_BOOLEAN, SC_ASN1_TAG_BOOLEAN, SC_ASN1_OPTIONAL, NULL, NULL },
 	{ "accessFlags", SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL, NULL, NULL},
 	{ "keyReference",SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
+	{ "algReference", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_CTX | 1, SC_ASN1_OPTIONAL, NULL, NULL },
 	{ NULL, 0, 0, 0, NULL, NULL }
 };
 
@@ -42,18 +59,24 @@ static const struct sc_asn1_entry c_asn1_com_skey_attr[C_ASN1_COM_SKEY_ATTR_SIZE
 	{ NULL, 0, 0, 0, NULL, NULL }
 };
 
-#define C_ASN1_COM_GENERIC_SKEY_ATTR_SIZE 2
-static const struct sc_asn1_entry c_asn1_generic_skey_attr[C_ASN1_COM_GENERIC_SKEY_ATTR_SIZE] = {
-	{ "value",	SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL},
+#define C_ASN1_COM_SKEY_GENERIC_VALUE_ATTR_SIZE 2
+static const struct sc_asn1_entry c_asn1_generic_skey_value_attr[C_ASN1_COM_SKEY_GENERIC_VALUE_ATTR_SIZE] = {
+	{ "path",	SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL},
+	{ NULL, 0, 0, 0, NULL, NULL }
+};
+
+#define C_ASN1_COM_SKEY_GENERIC_ATTR_SIZE 2
+static const struct sc_asn1_entry c_asn1_generic_skey_attr[C_ASN1_COM_SKEY_GENERIC_ATTR_SIZE] = {
+	{ "secretKeyAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL},
 	{ NULL, 0, 0, 0, NULL, NULL }
 };
 
 #define C_ASN1_SKEY_CHOICE_SIZE 5
 static const struct sc_asn1_entry c_asn1_skey_choice[C_ASN1_SKEY_CHOICE_SIZE] = {
-        { "genericSecretKey", SC_ASN1_PKCS15_OBJECT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
-        { "desKey",	SC_ASN1_PKCS15_OBJECT, SC_ASN1_CTX | 2 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
-        { "des2Key",	SC_ASN1_PKCS15_OBJECT, SC_ASN1_CTX | 3 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
-        { "des3Key",	SC_ASN1_PKCS15_OBJECT, SC_ASN1_CTX | 4 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
+	{ "genericSecretKey", SC_ASN1_PKCS15_OBJECT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
+	{ "desKey",	SC_ASN1_PKCS15_OBJECT, SC_ASN1_CTX | 2 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
+	{ "des2Key",	SC_ASN1_PKCS15_OBJECT, SC_ASN1_CTX | 3 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
+	{ "des3Key",	SC_ASN1_PKCS15_OBJECT, SC_ASN1_CTX | 4 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
 	{ NULL, 0, 0, 0, NULL, NULL }
 };
 
@@ -70,14 +93,16 @@ sc_pkcs15_decode_skdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obj
 {
         struct sc_context *ctx = p15card->card->ctx;
         struct sc_pkcs15_skey_info info;
-	int r;
+	int r, i;
 	size_t usage_len = sizeof(info.usage);
 	size_t af_len = sizeof(info.access_flags);
 	struct sc_asn1_entry asn1_com_key_attr[C_ASN1_COM_KEY_ATTR_SIZE];
 	struct sc_asn1_entry asn1_com_skey_attr[C_ASN1_COM_SKEY_ATTR_SIZE];
-	struct sc_asn1_entry asn1_generic_skey_attr[C_ASN1_COM_GENERIC_SKEY_ATTR_SIZE];
+	struct sc_asn1_entry asn1_generic_skey_attr[C_ASN1_COM_SKEY_GENERIC_ATTR_SIZE];
+	struct sc_asn1_entry asn1_generic_skey_value_attr[C_ASN1_COM_SKEY_GENERIC_VALUE_ATTR_SIZE];
 	struct sc_asn1_entry asn1_skey_choice[C_ASN1_SKEY_CHOICE_SIZE];
 	struct sc_asn1_entry asn1_skey[C_ASN1_SKEY_SIZE];
+	struct sc_asn1_entry asn1_supported_algorithms[C_ASN1_SUPPORTED_ALGORITHMS_SIZE];
 	struct sc_asn1_pkcs15_object skey_des_obj = {
 		obj, asn1_com_key_attr, asn1_com_skey_attr, asn1_generic_skey_attr
 	};
@@ -86,10 +111,12 @@ sc_pkcs15_decode_skdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obj
 
 	sc_copy_asn1_entry(c_asn1_skey, asn1_skey);
 	sc_copy_asn1_entry(c_asn1_skey_choice, asn1_skey_choice);
+	sc_copy_asn1_entry(c_asn1_supported_algorithms, asn1_supported_algorithms);
 
 	sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr);
 	sc_copy_asn1_entry(c_asn1_com_skey_attr, asn1_com_skey_attr);
 	sc_copy_asn1_entry(c_asn1_generic_skey_attr, asn1_generic_skey_attr);
+	sc_copy_asn1_entry(c_asn1_generic_skey_value_attr, asn1_generic_skey_value_attr);
 
 	sc_format_asn1_entry(asn1_skey + 0, asn1_skey_choice, NULL, 0);
 	sc_format_asn1_entry(asn1_skey_choice + 0, &skey_des_obj, NULL, 0);
@@ -102,10 +129,14 @@ sc_pkcs15_decode_skdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obj
 	sc_format_asn1_entry(asn1_com_key_attr + 2, &info.native, NULL, 0);
 	sc_format_asn1_entry(asn1_com_key_attr + 3, &info.access_flags, &af_len, 0);
 	sc_format_asn1_entry(asn1_com_key_attr + 4, &info.key_reference, NULL, 0);
+	for (i=0; i<SC_MAX_SUPPORTED_ALGORITHMS && (asn1_supported_algorithms + i)->name; i++)
+		sc_format_asn1_entry(asn1_supported_algorithms + i, &info.algo_refs[i], NULL, 0);
+	sc_format_asn1_entry(asn1_com_key_attr + 5, asn1_supported_algorithms, NULL, 0);
 
 	sc_format_asn1_entry(asn1_com_skey_attr + 0, &info.value_len, NULL, 0);
 
-	sc_format_asn1_entry(asn1_generic_skey_attr + 0, &info.path, NULL, 0);
+	sc_format_asn1_entry(asn1_generic_skey_attr + 0, asn1_generic_skey_value_attr, NULL, 0);
+	sc_format_asn1_entry(asn1_generic_skey_value_attr + 0, &info.path, NULL, 0);
 
         /* Fill in defaults */
 	memset(&info, 0, sizeof(info));
@@ -114,7 +145,9 @@ sc_pkcs15_decode_skdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obj
 	if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
 		return r;
 	LOG_TEST_RET(ctx, r, "ASN.1 decoding failed");
-	if (asn1_skey_choice[1].flags & SC_ASN1_PRESENT)
+	if (asn1_skey_choice[0].flags & SC_ASN1_PRESENT)
+		obj->type = SC_PKCS15_TYPE_SKEY_GENERIC;
+	else if (asn1_skey_choice[1].flags & SC_ASN1_PRESENT)
 		obj->type = SC_PKCS15_TYPE_SKEY_DES;
 	else if (asn1_skey_choice[2].flags & SC_ASN1_PRESENT)
 		obj->type = SC_PKCS15_TYPE_SKEY_2DES;
@@ -123,7 +156,6 @@ sc_pkcs15_decode_skdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obj
 	else
 		LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "unsupported secret key type");
 
-
 	obj->data = malloc(sizeof(info));
 	if (obj->data == NULL)
 		LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
@@ -137,5 +169,73 @@ int sc_pkcs15_encode_skdf_entry(struct sc_context *ctx,
 				 const struct sc_pkcs15_object *obj,
 				 u8 **buf, size_t *buflen)
 {
-	LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
+	struct sc_pkcs15_skey_info *skey = (struct sc_pkcs15_skey_info *) obj->data;
+	int r, i;
+	size_t usage_len = sizeof(skey->usage);
+	size_t af_len = sizeof(skey->access_flags);
+	struct sc_asn1_entry asn1_com_key_attr[C_ASN1_COM_KEY_ATTR_SIZE];
+	struct sc_asn1_entry asn1_com_skey_attr[C_ASN1_COM_SKEY_ATTR_SIZE];
+	struct sc_asn1_entry asn1_generic_skey_attr[C_ASN1_COM_SKEY_GENERIC_ATTR_SIZE];
+	struct sc_asn1_entry asn1_generic_skey_value_attr[C_ASN1_COM_SKEY_GENERIC_VALUE_ATTR_SIZE];
+	struct sc_asn1_entry asn1_skey_choice[C_ASN1_SKEY_CHOICE_SIZE];
+	struct sc_asn1_entry asn1_skey[C_ASN1_SKEY_SIZE];
+	struct sc_asn1_entry asn1_supported_algorithms[C_ASN1_SUPPORTED_ALGORITHMS_SIZE];
+	struct sc_asn1_pkcs15_object skey_obj = {
+		(struct sc_pkcs15_object *) obj, asn1_com_key_attr,
+		asn1_com_skey_attr, asn1_generic_skey_attr
+	};
+
+	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_ASN1);
+
+	sc_copy_asn1_entry(c_asn1_skey, asn1_skey);
+	sc_copy_asn1_entry(c_asn1_skey_choice, asn1_skey_choice);
+	sc_copy_asn1_entry(c_asn1_supported_algorithms, asn1_supported_algorithms);
+
+	sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr);
+	sc_copy_asn1_entry(c_asn1_com_skey_attr, asn1_com_skey_attr);
+	sc_copy_asn1_entry(c_asn1_generic_skey_attr, asn1_generic_skey_attr);
+	sc_copy_asn1_entry(c_asn1_generic_skey_value_attr, asn1_generic_skey_value_attr);
+
+	sc_format_asn1_entry(asn1_skey + 0, asn1_skey_choice, NULL, 1);
+	switch (obj->type) {
+	case SC_PKCS15_TYPE_SKEY_GENERIC:
+		sc_format_asn1_entry(asn1_skey_choice + 0, &skey_obj, NULL, 1);
+		break;
+	case SC_PKCS15_TYPE_SKEY_DES:
+		sc_format_asn1_entry(asn1_skey_choice + 1, &skey_obj, NULL, 1);
+		break;
+	case SC_PKCS15_TYPE_SKEY_2DES:
+		sc_format_asn1_entry(asn1_skey_choice + 2, &skey_obj, NULL, 1);
+		break;
+	case SC_PKCS15_TYPE_SKEY_3DES:
+		sc_format_asn1_entry(asn1_skey_choice + 3, &skey_obj, NULL, 1);
+		break;
+	default:
+		sc_log(ctx, "Invalid secret key type: %X", obj->type);
+		LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
+		break;
+	}
+
+	sc_format_asn1_entry(asn1_com_key_attr + 0, &skey->id, NULL, 1);
+	sc_format_asn1_entry(asn1_com_key_attr + 1, &skey->usage, &usage_len, 1);
+	if (skey->native == 0)
+		sc_format_asn1_entry(asn1_com_key_attr + 2, &skey->native, NULL, 1);
+	if (skey->access_flags)
+		sc_format_asn1_entry(asn1_com_key_attr + 3, &skey->access_flags, &af_len, 1);
+	if (skey->key_reference >= 0)
+		sc_format_asn1_entry(asn1_com_key_attr + 4, &skey->key_reference, NULL, 1);
+	for (i=0; i<SC_MAX_SUPPORTED_ALGORITHMS && i<C_ASN1_SUPPORTED_ALGORITHMS_SIZE && skey->algo_refs[i]; i++)
+		sc_format_asn1_entry(asn1_supported_algorithms + i, &skey->algo_refs[i], NULL, 1);
+	sc_format_asn1_entry(asn1_com_key_attr + 5, asn1_supported_algorithms, NULL, skey->algo_refs[0] != 0);
+
+	sc_format_asn1_entry(asn1_com_skey_attr + 0, &skey->value_len, NULL, 1);
+
+	sc_format_asn1_entry(asn1_generic_skey_attr + 0, asn1_generic_skey_value_attr, NULL, 1);
+
+	sc_format_asn1_entry(asn1_generic_skey_value_attr + 0, &skey->path, NULL, 1);
+
+	r = sc_asn1_encode(ctx, asn1_skey, buf, buflen);
+
+	sc_log(ctx, "Key path %s", sc_print_path(&skey->path));
+	LOG_FUNC_RETURN(ctx, r);
 }
diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c
index a31abb4..2ce34b6 100644
--- a/src/libopensc/pkcs15.c
+++ b/src/libopensc/pkcs15.c
@@ -1955,6 +1955,9 @@ sc_pkcs15_encode_df(struct sc_context *ctx, struct sc_pkcs15_card *p15card, stru
 	case SC_PKCS15_PUKDF_TRUSTED:
 		func = sc_pkcs15_encode_pukdf_entry;
 		break;
+	case SC_PKCS15_SKDF:
+		func = sc_pkcs15_encode_skdf_entry;
+		break;
 	case SC_PKCS15_CDF:
 	case SC_PKCS15_CDF_TRUSTED:
 	case SC_PKCS15_CDF_USEFUL:
diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h
index 5352f9f..dd46d24 100644
--- a/src/libopensc/pkcs15.h
+++ b/src/libopensc/pkcs15.h
@@ -828,6 +828,9 @@ int sc_pkcs15_encode_prkdf_entry(struct sc_context *ctx,
 int sc_pkcs15_encode_pukdf_entry(struct sc_context *ctx,
 			const struct sc_pkcs15_object *obj, u8 **buf,
 			size_t *bufsize);
+int sc_pkcs15_encode_skdf_entry(struct sc_context *ctx,
+			const struct sc_pkcs15_object *obj, u8 **buf,
+			size_t *buflen);
 int sc_pkcs15_encode_dodf_entry(struct sc_context *ctx,
 			const struct sc_pkcs15_object *obj, u8 **buf,
 			size_t *bufsize);

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