diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index eb1a6279..7bfc910e 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -2,7 +2,7 @@ include $(top_srcdir)/win32/ltrc.inc MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -EXTRA_DIST = Makefile.mak +EXTRA_DIST = Makefile.mak lib_LTLIBRARIES = libopensc.la noinst_HEADERS = cards.h ctbcs.h internal.h esteid.h muscle.h muscle-filesystem.h \ @@ -22,8 +22,8 @@ libopensc_la_SOURCES = \ asn1.c base64.c sec.c card.c iso7816.c dir.c ef-atr.c padding.c apdu.c \ \ pkcs15.c pkcs15-cert.c pkcs15-data.c pkcs15-pin.c \ - pkcs15-prkey.c pkcs15-pubkey.c pkcs15-sec.c \ - pkcs15-algo.c pkcs15-cache.c pkcs15-syn.c \ + pkcs15-prkey.c pkcs15-pubkey.c pkcs15-skey.c \ + pkcs15-sec.c pkcs15-algo.c pkcs15-cache.c pkcs15-syn.c \ \ muscle.c muscle-filesystem.c \ \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 55d2ceec..eac3c0c9 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -6,8 +6,8 @@ OBJECTS = \ asn1.obj base64.obj sec.obj card.obj iso7816.obj dir.obj ef-atr.obj padding.obj apdu.obj \ \ pkcs15.obj pkcs15-cert.obj pkcs15-data.obj pkcs15-pin.obj \ - pkcs15-prkey.obj pkcs15-pubkey.obj pkcs15-sec.obj \ - pkcs15-algo.obj pkcs15-cache.obj pkcs15-syn.obj \ + pkcs15-prkey.obj pkcs15-pubkey.obj pkcs15-skey.obj \ + pkcs15-sec.obj pkcs15-algo.obj pkcs15-cache.obj pkcs15-syn.obj \ \ muscle.obj muscle-filesystem.obj \ \ diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 9bfac2b7..35bd4759 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -145,6 +145,7 @@ sc_pkcs15_decode_pubkey_rsa sc_pkcs15_decode_pubkey_ec sc_pkcs15_decode_pubkey_gostr3410 sc_pkcs15_decode_pukdf_entry +sc_pkcs15_decode_skdf_entry sc_pkcs15_encode_aodf_entry sc_pkcs15_encode_cdf_entry sc_pkcs15_encode_df @@ -172,6 +173,7 @@ sc_pkcs15_find_prkey_by_id sc_pkcs15_find_prkey_by_id_usage sc_pkcs15_find_prkey_by_reference sc_pkcs15_find_pubkey_by_id +sc_pkcs15_find_skey_by_id sc_pkcs15_find_so_pin sc_pkcs15_fix_ec_parameters sc_pkcs15_format_id diff --git a/src/libopensc/pkcs15-skey.c b/src/libopensc/pkcs15-skey.c new file mode 100644 index 00000000..0749e3e3 --- /dev/null +++ b/src/libopensc/pkcs15-skey.c @@ -0,0 +1,196 @@ +/* + * pkcs15-skey.c: PKCS #15 secret key functions + * + * Copyright (C) 2002 Juha Yrjölä + * Copyright (C) 2011 Viktor Tarasov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "internal.h" +#include "pkcs15.h" +#include "asn1.h" +#include +#include +#include +#include + +#define C_ASN1_COM_KEY_ATTR_SIZE 6 +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 }, + { NULL, 0, 0, 0, NULL, NULL } +}; + +#define C_ASN1_COM_SKEY_ATTR_SIZE 2 +static const struct sc_asn1_entry c_asn1_com_skey_attr[C_ASN1_COM_SKEY_ATTR_SIZE] = { + { "keyLen", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL}, + { 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}, + { 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 }, + { NULL, 0, 0, 0, NULL, NULL } +}; + +#define C_ASN1_SKEY_SIZE 2 +static const struct sc_asn1_entry c_asn1_skey[C_ASN1_SKEY_SIZE] = { + { "secretKey", SC_ASN1_CHOICE, 0, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + + +int +sc_pkcs15_decode_skdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj, + const u8 ** buf, size_t *buflen) +{ + struct sc_context *ctx = p15card->card->ctx; + struct sc_pkcs15_skey_info info; + int r; + 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_skey_choice[C_ASN1_SKEY_CHOICE_SIZE]; + struct sc_asn1_entry asn1_skey[C_ASN1_SKEY_SIZE]; + struct sc_asn1_pkcs15_object skey_des_obj = { + 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_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_format_asn1_entry(asn1_skey + 0, asn1_skey_choice, NULL, 0); + sc_format_asn1_entry(asn1_skey_choice + 0, &skey_des_obj, NULL, 0); + sc_format_asn1_entry(asn1_skey_choice + 1, &skey_des_obj, NULL, 0); + sc_format_asn1_entry(asn1_skey_choice + 2, &skey_des_obj, NULL, 0); + sc_format_asn1_entry(asn1_skey_choice + 3, &skey_des_obj, NULL, 0); + + sc_format_asn1_entry(asn1_com_key_attr + 0, &info.id, NULL, 0); + sc_format_asn1_entry(asn1_com_key_attr + 1, &info.usage, &usage_len, 0); + 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); + + 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); + + /* Fill in defaults */ + memset(&info, 0, sizeof(info)); + + r = sc_asn1_decode(ctx, asn1_skey, *buf, *buflen, buf, buflen); + 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) + obj->type = SC_PKCS15_TYPE_SKEY_DES; + else if (asn1_skey_choice[2].flags & SC_ASN1_PRESENT) + obj->type = SC_PKCS15_TYPE_SKEY_2DES; + else if (asn1_skey_choice[3].flags & SC_ASN1_PRESENT) + obj->type = SC_PKCS15_TYPE_SKEY_3DES; + 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); + memcpy(obj->data, &info, sizeof(info)); + + LOG_FUNC_RETURN(ctx, SC_SUCCESS); +} + + +int sc_pkcs15_encode_skdf_entry(struct sc_context *ctx, + const struct sc_pkcs15_object *obj, + u8 **buf, size_t *buflen) +{ +#if 0 + struct sc_asn1_entry asn1_com_key_attr[6], asn1_com_skey_attr[1]; + struct sc_asn1_entry asn1_skey_des_attr[4], asn1_skey_des_type_attr[2]; + struct sc_asn1_entry asn1_skey_choice[5]; + struct sc_asn1_entry asn1_skey[2]; + struct sc_pkcs15_skey_info *skey = (struct sc_pkcs15_skey_info *) obj->data; + struct sc_asn1_pkcs15_object skey_des_obj = { + (struct sc_pkcs15_object *) obj, + asn1_com_key_attr, + asn1_com_skey_attr, + asn1_skey_des_type_attr + }; + int r; + size_t af_len, usage_len; + + 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_skey_des_type_attr, asn1_skey_des_type_attr); + sc_copy_asn1_entry(c_asn1_skey_des_attr, asn1_skey_des_attr); + sc_copy_asn1_entry(c_asn1_com_skey_attr, asn1_com_skey_attr); + sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr); + + switch (obj->type) { + case SC_PKCS15_TYPE_SKEY_DES: + case SC_PKCS15_TYPE_SKEY_2DES: + case SC_PKCS15_TYPE_SKEY_3DES: + sc_format_asn1_entry(asn1_skey_choice + 0, &skey_des_obj, NULL, 1); + + sc_format_asn1_entry(asn1_skey_des_type_attr + 0, asn1_skey_des_attr, NULL, 1); + + sc_format_asn1_entry(asn1_skey_des_attr + 0, &skey->path, NULL, 1); + sc_format_asn1_entry(asn1_skey_des_attr + 1, &skey->type, NULL, 1); + sc_format_asn1_entry(asn1_skey_des_attr + 2, &skey->size, NULL, 1); + break; + + default: + sc_log(ctx, "Unsupported skey type: %X\n", obj->type); + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); + break; + } + + sc_format_asn1_entry(asn1_com_key_attr + 0, &skey->id, NULL, 1); + usage_len = sizeof(skey->usage); + sc_format_asn1_entry(asn1_com_key_attr + 1, &skey->usage, &usage_len, 1); + if (skey->access_flags) { + af_len = sizeof(skey->access_flags); + sc_format_asn1_entry(asn1_com_key_attr + 3, &skey->access_flags, &af_len, 1); + } + sc_format_asn1_entry(asn1_skey + 0, asn1_skey_choice, NULL, 1); + + r = sc_asn1_encode(ctx, asn1_skey, buf, buflen); + + return r; +#else + LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); +#endif +} diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 01136e21..83b2dd38 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1926,11 +1926,9 @@ int sc_pkcs15_parse_df(struct sc_pkcs15_card *p15card, case SC_PKCS15_PUKDF: func = sc_pkcs15_decode_pukdf_entry; break; -/* case SC_PKCS15_SKDF: func = sc_pkcs15_decode_skdf_entry; break; -*/ case SC_PKCS15_CDF: case SC_PKCS15_CDF_TRUSTED: case SC_PKCS15_CDF_USEFUL: