From 71b85d15e4eeca4af1e75164c793436ba5de3583 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 6 Mar 2019 13:10:34 +0100 Subject: [PATCH] opensc.conf: Configure handling of private_certificate possible choices: ignore, protect, declassify fixes https://github.com/OpenSC/OpenSC/issues/1430 --- doc/files/opensc.conf.5.xml.in | 35 +++++++++++++++++++++++----------- etc/opensc.conf.example.in | 9 +++++++-- src/libopensc/pkcs15-cert.c | 10 ++++++++++ src/libopensc/pkcs15.c | 23 ++++++++++++++++++---- src/libopensc/pkcs15.h | 6 ++++++ 5 files changed, 66 insertions(+), 17 deletions(-) diff --git a/doc/files/opensc.conf.5.xml.in b/doc/files/opensc.conf.5.xml.in index 33ac08bb..4493fb87 100644 --- a/doc/files/opensc.conf.5.xml.in +++ b/doc/files/opensc.conf.5.xml.in @@ -1142,6 +1142,30 @@ app application { some cards (Default: false). + + + + + + How to handle a PIN-protected certificate. Known + parameters: + + + protect: The certificate stays PIN-protected. + + + declassify: Allow + reading the certificate without + enforcing verification of the PIN. + + + ignore: Ignore PIN-protected certificates. + + + (Default: ignore in Tokend, + protect otherwise). + + @@ -1311,17 +1335,6 @@ app application { the highest score shall be used. - - - - - - Tokend ignore to read PIN protected certificate - that is set - SC_PKCS15_CO_FLAG_PRIVATE flag - (Default: true). - - diff --git a/etc/opensc.conf.example.in b/etc/opensc.conf.example.in index 3d54098f..36bdf0b4 100644 --- a/etc/opensc.conf.example.in +++ b/etc/opensc.conf.example.in @@ -873,7 +873,7 @@ app default { # (with certificate check) where $HOME is not set # Default: path in user home # file_cache_dir = /var/lib/opensc/cache - # + # Use PIN caching? # Default: true # use_pin_caching = false; @@ -886,7 +886,12 @@ app default { # may need to set this to get signatures to work with some cards. # Default: false # pin_cache_ignore_user_consent = true; - # + + # How to handle a PIN-protected certificate + # Valid values: protect, declassify, ignore. + # Default: ignore in tokend, protect otherwise + # private_certificate = declassify; + # Enable pkcs15 emulation. # Default: yes # enable_pkcs15_emulation = no; diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index 5a05d14c..1a187f41 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -488,6 +488,16 @@ sc_pkcs15_decode_cdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_obje } sc_log(ctx, "Certificate path '%s'", sc_print_path(&info.path)); + switch (p15card->opts.private_certificate) { + case SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY: + sc_log(ctx, "Declassifying certificate"); + obj->flags &= ~SC_PKCS15_CO_FLAG_PRIVATE; + break; + case SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE: + sc_log(ctx, "Ignoring certificate"); + return 0; + } + obj->type = SC_PKCS15_TYPE_CERT_X509; obj->data = malloc(sizeof(info)); if (obj->data == NULL) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 85e7ecc7..eca16adc 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1192,6 +1192,7 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, struct sc_context *ctx = card->ctx; scconf_block *conf_block = NULL; int r, emu_first, enable_emu; + const char *private_certificate; LOG_FUNC_CALLED(ctx); sc_log(ctx, "application(aid:'%s')", aid ? sc_dump_hex(aid->value, aid->len) : "empty"); @@ -1208,19 +1209,33 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid, p15card->opts.use_pin_cache = 1; p15card->opts.pin_cache_counter = 10; p15card->opts.pin_cache_ignore_user_consent = 0; + if(0 == strcmp(ctx->app_name, "tokend")) { + private_certificate = "ignore"; + p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE; + } else { + private_certificate = "protect"; + p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT; + } conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1); - if (conf_block) { p15card->opts.use_file_cache = scconf_get_bool(conf_block, "use_file_caching", p15card->opts.use_file_cache); p15card->opts.use_pin_cache = scconf_get_bool(conf_block, "use_pin_caching", p15card->opts.use_pin_cache); p15card->opts.pin_cache_counter = scconf_get_int(conf_block, "pin_cache_counter", p15card->opts.pin_cache_counter); - p15card->opts.pin_cache_ignore_user_consent = scconf_get_bool(conf_block, "pin_cache_ignore_user_consent", + p15card->opts.pin_cache_ignore_user_consent = scconf_get_bool(conf_block, "pin_cache_ignore_user_consent", p15card->opts.pin_cache_ignore_user_consent); + private_certificate = scconf_get_str(conf_block, "private_certificate", private_certificate); } - sc_log(ctx, "PKCS#15 options: use_file_cache=%d use_pin_cache=%d pin_cache_counter=%d pin_cache_ignore_user_consent=%d", + if (0 == strcmp(private_certificate, "protect")) { + p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT; + } else if (0 == strcmp(private_certificate, "ignore")) { + p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE; + } else if (0 == strcmp(private_certificate, "declassify")) { + p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY; + } + sc_log(ctx, "PKCS#15 options: use_file_cache=%d use_pin_cache=%d pin_cache_counter=%d pin_cache_ignore_user_consent=%d private_certificate=%d", p15card->opts.use_file_cache, p15card->opts.use_pin_cache,p15card->opts.pin_cache_counter, - p15card->opts.pin_cache_ignore_user_consent); + p15card->opts.pin_cache_ignore_user_consent, p15card->opts.private_certificate); r = sc_lock(card); if (r) { diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 8d2e5411..60af524b 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -593,6 +593,7 @@ typedef struct sc_pkcs15_card { int use_pin_cache; int pin_cache_counter; int pin_cache_ignore_user_consent; + int private_certificate; } opts; unsigned int magic; @@ -613,6 +614,11 @@ typedef struct sc_pkcs15_card { /* flags suitable for struct sc_pkcs15_card */ #define SC_PKCS15_CARD_FLAG_EMULATED 0x02000000 +/* suitable for struct sc_pkcs15_card.opts.private_certificate */ +#define SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT 0 +#define SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE 1 +#define SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY 2 + /* X509 bits for certificate usage extension */ #define SC_X509_DIGITAL_SIGNATURE 0x0001UL #define SC_X509_NON_REPUDIATION 0x0002UL