Working with Spanish DNIe code, I've received some feedback [1] from Dirección
General
de la Policía about removal of "user consent" code on signature process
Afaik this theme has been discussed at OpenSC [2]. As a result, user consent
code
was removed from OpenSC. Same was for opensc-signer module
But here comes a problem: Spanish authorities certification rules requires that
every
signing procedure must be notified to the user by mean the middleware,
regardless
the behaviour of main application. Removal of User Consent (as Martin did in
github [3])
lies into an un-certificable code
[1] http://www.kriptopolis.org/opensc-cenatic#comment-58751
[2] http://www.opensc-project.org/opensc/ticket/232
[3] http://github.com/martinpaljak/OpenSC/tree/dnie
So, as a Solomon's solution, based on OpenSC-0.11.14's "dialog.c", I've written
a new
code (attached) that makes user consent configurable (at this moment for DNIe
code)
What's your feelings on this?
Thanks in advance
Juan Antonio
/*
* User consent function
* Based on dialog.c from opensc-0.11.14
* And original code from DGP's DNIe module
*/
/*
* IMPORTANT NOTICE:
* This code may don't work on:
* - Headless systems
* - Sites without pinentry / libassuan properly installed
* So to handle this, we provide several flags at /etc/opensc.conf:
* ....
* module dnie {
* # Enable/Disable user consent on signing (default: enable)
* user_consent_enabled = true;
* # Program to be used for ask confirmation (default: pinentry)
* user_consent_app = /usr/bin/pinentry;
* }
* .....
* NOTICE that disable User Consent may result on unnoticed signing if
* used on unsecure environments and/or with bad designed/uncertified apps
*
*/
#include <assuan.h>
#include <stdarg.h>
#include <stdlib.h>
#include "../opensc.h"
#include "../errors.h"
#include "../log.h"
#ifndef PIN_ENTRY
#define PIN_ENTRY "/usr/bin/pinentry"
#endif
static char *user_consent_app=PIN_ENTRY;
static int user_consent_enabled=1; /* default true */
/**
* Parse configuration file to extract user consent flags
*/
static int get_user_consent_env(sc_context_t *ctx) {
int i;
scconf_block **blocks, *blk;
for (i = 0; ctx->conf_blocks[i]; i++) {
blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],"card_driver","dnie");
if (!blocks) continue;
blk=blocks[0];
free(blocks);
if (blk==NULL) continue;
user_consent_app = scconf_get_str(blk,"user_consent_app",PIN_ENTRY);
user_consent_enabled = scconf_get_bool(blk,"user_consent_enabled",1);
}
return SC_SUCCESS;
}
int ask_user_consent(sc_card_t *card) {
int res;
const char *argv[3];
ASSUAN_CONTEXT ctx;
if ( (card!=NULL) && (card->ctx!=NULL)) return SC_ERROR_INVALID_ARGUMENTS;
get_user_consent_env(card->ctx);
argv[0]=user_consent_app;
argv[1]=NULL;
argv[2]=NULL;
res = assuan_pipe_connect(&ctx,user_consent_app,argv,0);
if (res!=0) {
sc_debug(card->ctx,SC_LOG_DEBUG_NORMAL,"Can't connect to the User Consent module: %s\n",assuan_strerror((AssuanError) res));
res=SC_ERROR_INVALID_ARGUMENTS; /* invalid or not available pinentry */
goto exit;
}
res = assuan_transact(
ctx,
"SETDESC Está a punto de realizar una firma electrónica\n con su clave de FIRMA del DNI electrónico.\n\n¿Desea permitir esta operación?",
NULL, NULL, NULL, NULL, NULL, NULL);
if (res!=0) {
sc_debug(card->ctx,SC_LOG_DEBUG_NORMAL,"SETDESC: %s\n", assuan_strerror((AssuanError) res));
res=SC_ERROR_CARD_CMD_FAILED; /* perhaps should use a better errcode */
goto exit;
}
res = assuan_transact(ctx,"CONFIRM",NULL,NULL,NULL,NULL,NULL,NULL);
if (res == ASSUAN_Canceled) {
sc_debug(card->ctx,SC_LOG_DEBUG_VERBOSE,"Sign cancelled by user");
res= SC_ERROR_NOT_ALLOWED;
goto exit;
}
if (res) {
sc_debug(card->ctx,SC_LOG_DEBUG_NORMAL,"SETERROR: %s\n", assuan_strerror((AssuanError) res));
res=SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
} else {
res=SC_SUCCESS;
}
exit:
assuan_disconnect(ctx);
return res;
}
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel