From f43d52476ec8e8365861182101b379e58e8e5ab6 Mon Sep 17 00:00:00 2001 From: sth Date: Thu, 18 Aug 2005 13:55:36 +0000 Subject: [PATCH] The lengths of the ASN.1 entries are used outside the if blocks -> declare them outside the blocks git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@2494 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/card-belpic.c | 4 +-- src/libopensc/pkcs15-sec.c | 58 ++++++++++++++++++++++++++++++++++++- src/libopensc/pkcs15.c | 13 +++++---- 3 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index 9a378d71..b1960df4 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -1506,9 +1506,7 @@ static int belpic_set_security_env(sc_card_t *card, sc_error(card->ctx, "Verify PIN in SET command returned %d\n", r); else sc_debug(card->ctx, "Verify PIN in SET command returned %d\n", r); -#else - sc_debug(card->ctx, "No GUI for NonRep key present, signature cancelled\n"); - return SC_ERROR_NOT_SUPPORTED; + #endif } diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 6f3809db..035a6afe 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -28,6 +28,8 @@ #include #endif +static int sc_askpin_login(sc_pkcs15_card_t *p15card, const sc_pkcs15_object_t *key_obj); + static int select_key_file(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_prkey_info *prkey, sc_security_env_t *senv) @@ -158,6 +160,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, u8 buf[512], *tmpin, *tmpout, *help; size_t tmpoutlen; unsigned long pad_flags = 0; + int first_try = 1; SC_FUNC_CALLED(ctx, 1); /* If the key is extractable, the caller should extract the @@ -306,6 +309,8 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, } } +try_again: + r = sc_set_security_env(p15card->card, &senv, 0); if (r < 0) { sc_unlock(p15card->card); @@ -321,14 +326,65 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, * always have algorithm RSA_PURE_SIG so the input buffer * is padded and has the same length as the signature. --okir */ - if (tmpin == out) { + if (tmpin == out && first_try) { memcpy(tmpout, tmpin, inlen); tmpin = tmpout; } + r = sc_compute_signature(p15card->card, tmpin, inlen, out, outlen); + + /* Handling a UserConsent key */ + if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED && first_try && + obj->user_consent != 0) { + r = sc_askpin_login(p15card, obj); + if (r >= 0) { + first_try = 0; + goto try_again; + } + } + memset(buf, 0, sizeof(buf)); sc_unlock(p15card->card); SC_TEST_RET(ctx, r, "sc_compute_signature() failed"); return r; } + +static int sc_askpin_login(sc_pkcs15_card_t *p15card, const sc_pkcs15_object_t *key_obj) +{ + int r; + char prompt[200]; + char *pincode = NULL; + sc_ui_hints_t hints; + sc_pkcs15_object_t *pin_obj; + sc_pkcs15_pin_info_t *pin_info; + + r = sc_pkcs15_find_pin_by_auth_id(p15card, &key_obj->auth_id, &pin_obj); + SC_TEST_RET(p15card->card->ctx, r, "sc_pkcs15_find_pin_by_auth_id() failed"); + pin_info = (sc_pkcs15_pin_info_t *) pin_obj->data; + + memset(&hints, 0, sizeof(hints)); + hints.dialog_name = "Enter PIN"; + sprintf("Enter your PIN (called \"%s\" in order to make\na signature with your \"%s\" key.\nNOTE, this may be a (legally) binding signature!\n", + pin_obj->label, key_obj->label); + hints.prompt = prompt; + hints.obj_label = pin_obj->label; + hints.usage = SC_UI_USAGE_OTHER; + hints.card = p15card->card; + hints.p15card = p15card; + + r = sc_ui_get_pin(&hints, &pincode); + SC_TEST_RET(p15card->card->ctx, r, "sc_ui_get_pin() failed"); + if (pincode == NULL) + return SC_ERROR_KEYPAD_CANCELLED; + if (strlen(pincode) == 0) { + free(pincode); + return SC_ERROR_KEYPAD_CANCELLED; + } + + r = sc_pkcs15_verify_pin(p15card, pin_info, pincode, strlen(pincode)); + free(pincode); + SC_TEST_RET(p15card->card->ctx, r, "sc_pkcs15_verify_pin() failed"); + + return r; +} diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 95f59a16..edc2b1da 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -130,6 +130,7 @@ int sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, { int r; int version = card->version; + size_t serial_len, mnfid_len, label_len, flags_len, last_upd_len; struct sc_asn1_entry asn1_toki[13], asn1_tokeninfo[2]; @@ -139,7 +140,7 @@ int sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, sc_format_asn1_entry(asn1_toki + 0, &version, NULL, 1); if (card->serial_number != NULL) { u8 serial[128]; - size_t serial_len = 0; + serial_len = 0; if (strlen(card->serial_number)/2 > sizeof(serial)) return SC_ERROR_BUFFER_TOO_SMALL; serial_len = sizeof(serial); @@ -149,17 +150,17 @@ int sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, } else sc_format_asn1_entry(asn1_toki + 1, NULL, NULL, 0); if (card->manufacturer_id != NULL) { - size_t mnfid_len = strlen(card->manufacturer_id); + mnfid_len = strlen(card->manufacturer_id); sc_format_asn1_entry(asn1_toki + 2, card->manufacturer_id, &mnfid_len, 1); } else sc_format_asn1_entry(asn1_toki + 2, NULL, NULL, 0); if (card->label != NULL) { - size_t label_len = strlen(card->label); + label_len = strlen(card->label); sc_format_asn1_entry(asn1_toki + 3, card->label, &label_len, 1); } else sc_format_asn1_entry(asn1_toki + 3, NULL, NULL, 0); if (card->flags) { - size_t flags_len = sizeof(card->flags); + flags_len = sizeof(card->flags); sc_format_asn1_entry(asn1_toki + 4, &card->flags, &flags_len, 1); } else sc_format_asn1_entry(asn1_toki + 4, NULL, NULL, 0); @@ -169,8 +170,8 @@ int sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, sc_format_asn1_entry(asn1_toki + 8, NULL, NULL, 0); sc_format_asn1_entry(asn1_toki + 9, NULL, NULL, 0); if (card->last_update != NULL) { - size_t len = strlen(card->last_update); - sc_format_asn1_entry(asn1_toki + 10, card->last_update, &len, 1); + last_upd_len = strlen(card->last_update); + sc_format_asn1_entry(asn1_toki + 10, card->last_update, &last_upd_len, 1); } else sc_format_asn1_entry(asn1_toki + 10, NULL, NULL, 0); sc_format_asn1_entry(asn1_toki + 11, NULL, NULL, 0);