[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