From 64c62eb0db4ec3f26216c531a1df02b3724d51cd Mon Sep 17 00:00:00 2001 From: okir Date: Wed, 16 Jul 2003 15:17:57 +0000 Subject: [PATCH] - patch for synthetic p15 cards by Nils Larsch git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@1268 c6295689-39f2-0310-b995-f0e70906c6a9 --- etc/opensc.conf.example | 4 +++ src/libopensc/errors.c | 1 + src/libopensc/errors.h | 1 + src/libopensc/module.c | 65 +++++++++++++++++++++++++++++++++++-- src/libopensc/pkcs15.c | 72 +++++++++++++++++++++++++++++++++++++++-- 5 files changed, 138 insertions(+), 5 deletions(-) diff --git a/etc/opensc.conf.example b/etc/opensc.conf.example index 10928ee8..b3fa7f2d 100644 --- a/etc/opensc.conf.example +++ b/etc/opensc.conf.example @@ -132,6 +132,10 @@ app default { # Default: false # use_caching = true; + # Use the following dynamic libraries for a read-only + # PKCS#15 emulation of non pkcs15 cards. + # + # pkcs15_syn = p15_starcert.so; } } diff --git a/src/libopensc/errors.c b/src/libopensc/errors.c index aff9b224..b48cc203 100644 --- a/src/libopensc/errors.c +++ b/src/libopensc/errors.c @@ -85,6 +85,7 @@ const char *sc_strerror(int error) "The key is extractable", "Decryption failed", "Wrong padding", + "Wrong card", }; const int int_base = -SC_ERROR_INTERNAL; const char *p15i_errors[] = { diff --git a/src/libopensc/errors.h b/src/libopensc/errors.h index 2d3d0f21..07136c20 100644 --- a/src/libopensc/errors.h +++ b/src/libopensc/errors.h @@ -85,6 +85,7 @@ extern "C" { #define SC_ERROR_EXTRACTABLE_KEY -1410 #define SC_ERROR_DECRYPT_FAILED -1411 #define SC_ERROR_WRONG_PADDING -1412 +#define SC_ERROR_WRONG_CARD -1413 /* Relating to PKCS #15 init stuff */ #define SC_ERROR_PKCS15INIT -1500 diff --git a/src/libopensc/module.c b/src/libopensc/module.c index 06edc51a..b4107134 100644 --- a/src/libopensc/module.c +++ b/src/libopensc/module.c @@ -40,7 +40,7 @@ int sc_module_open(struct sc_context *ctx, void **mod_handle, const char *filena if ((error = dlerror()) != NULL) { if (ctx->debug) - debug(ctx, "sc_module_open: %s", error); + debug(ctx, "sc_module_open: %s\n", error); return SC_ERROR_UNKNOWN; } *mod_handle = handle; @@ -60,7 +60,7 @@ int sc_module_close(struct sc_context *ctx, void *mod_handle) if ((error = dlerror()) != NULL) { if (ctx->debug) - debug(ctx, "sc_module_close: %s", error); + debug(ctx, "sc_module_close: %s\n", error); return SC_ERROR_UNKNOWN; } return SC_SUCCESS; @@ -89,7 +89,66 @@ int sc_module_get_address(struct sc_context *ctx, void *mod_handle, void **sym_a if ((error = dlerror()) != NULL) { if (ctx->debug) - debug(ctx, "sc_module_get_address: %s", error); + debug(ctx, "sc_module_get_address: %s\n", error); + return SC_ERROR_UNKNOWN; + } + *sym_address = address; + return SC_SUCCESS; +} + +#elif defined(_WIN32) +#include + +int sc_module_open(struct sc_context *ctx, void **mod_handle, const char *filename) +{ + void *handle; + + assert(ctx != NULL); + + if (!filename) + return SC_ERROR_UNKNOWN; + + handle = LoadLibrary(filename); + + if (handle == NULL) { + if (ctx->debug) + /* TODO: GetLastError */ + debug(ctx, "sc_module_open: unknown error"); + return SC_ERROR_UNKNOWN; + } + *mod_handle = handle; + return SC_SUCCESS; +} + +int sc_module_close(struct sc_context *ctx, void *mod_handle) +{ + assert(ctx != NULL); + + if (!mod_handle) + return SC_ERROR_UNKNOWN; + + FreeLibrary(mod_handle); + /* TODO: GetLastError */ + + return SC_SUCCESS; +} + +int sc_module_get_address(struct sc_context *ctx, void *mod_handle, void **sym_address, const char *sym_name) +{ + void *address; + + assert(ctx != NULL); + + if (!mod_handle || !sym_name) + return SC_ERROR_UNKNOWN; + + + address = GetProcAddress(mod_handle, sym_name); + + if (address == NULL) { + if (ctx->debug) + /* TODO: GetLastError */ + debug(ctx, "sc_module_get_address: unknown error"); return SC_ERROR_UNKNOWN; } *sym_address = address; diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index c06d2ae6..86df228e 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -598,8 +598,76 @@ error: int sc_pkcs15_bind_synthetic(struct sc_pkcs15_card *p15card) { - /* Code to bind non pkcs15 cards as read-only will go here */ - return SC_ERROR_PKCS15_APP_NOT_FOUND; + int ret = SC_ERROR_INTERNAL, i; + struct sc_context *ctx = p15card->card->ctx; + const scconf_list *clist, *tmp; + scconf_block *conf_block = NULL, **blocks; + + SC_FUNC_CALLED(ctx, 1); + + assert(p15card); + + for (i = 0; ctx->conf_blocks[i] != NULL; i++) { + blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], + "framework", "pkcs15"); + if (blocks[0] != NULL) + conf_block = blocks[0]; + free(blocks); + } + if (!conf_block) + return SC_ERROR_INTERNAL; + /* get the pkcs15_syn libs from the conf file */ + clist = scconf_find_list(conf_block, "pkcs15_syn"); + if (!clist) + return SC_ERROR_INTERNAL; + + /* iterate trough the list given in the config file */ + for (tmp = clist; tmp != NULL; tmp = tmp->next) { + int r, tmp_r; + void *handle = NULL, *func_handle; + int (*init_func)(sc_pkcs15_card_t *); + + if (ctx->debug >= 4) { + debug(ctx, "Loading: %s\n", tmp->data); + } + /* try to open dynamic library */ + r = sc_module_open(ctx, &handle, tmp->data); + if (r != SC_SUCCESS) + /* ignore error, try next one */ + continue; + /* get a handle to the pkcs15 init function + * XXX the init_func should not modify the contents of + * sc_pkcs15_card_t unless the card is really the one + * the driver is intended for -- Nils + */ + r = sc_module_get_address(ctx, handle, &func_handle, + "sc_pkcs15_init_func"); + init_func = (int (*)(sc_pkcs15_card_t *))func_handle; + if (r != SC_SUCCESS || !init_func) + return r; + /* try to initialize synthetic pkcs15 structures */ + tmp_r = init_func(p15card); + r = sc_module_close(ctx, handle); + if (r != SC_SUCCESS) + return r; + if (tmp_r == SC_SUCCESS) { + p15card->flags |= SC_PKCS15_CARD_FLAG_READONLY; + p15card->magic = 0x10203040; + ret = SC_SUCCESS; + break; + } + else if (tmp_r == SC_ERROR_WRONG_CARD) { + /* wrong init_func => try next one (if existing) */ + if (ctx->debug >= 4) { + debug(ctx, "init_func failed => trying next one\n"); + } + continue; + } + /* some internal/card error occured => exit */ + return tmp_r; + } + + return ret; } int sc_pkcs15_detect(struct sc_card *card)