From 983f91937c7401c3ce575eee25ba8be8b41857d3 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 3 Sep 2009 10:57:23 +0000 Subject: [PATCH] Fix for extended length Le in decipher --- scd/ChangeLog | 11 ++++++++++- scd/apdu.c | 2 -- scd/app-geldkarte.c | 2 +- scd/app-nks.c | 5 +++-- scd/app-openpgp.c | 20 ++++++++++++-------- scd/iso7816.c | 32 ++++++++++++++++++-------------- scd/iso7816.h | 8 +++----- 7 files changed, 47 insertions(+), 33 deletions(-) diff --git a/scd/ChangeLog b/scd/ChangeLog index e7bf65339..3a421ccfb 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,12 @@ +2009-09-03 Werner Koch + + * app-openpgp.c (do_decipher): Compute required Le. + * iso7816.c (iso7816_decipher): Add new arg LE. + * app-nks.c (do_decipher): Adjust for change. + + * iso7816.c (iso7816_put_data, iso7816_put_data_odd): Turn DATA + into a void ptr. + 2009-08-05 Werner Koch * app-openpgp.c (change_keyattr_from_string): New. @@ -138,7 +147,7 @@ (iso7816_generate_keypair, iso7816_read_public_key): Ditto. Changed all callers. * apdu.c (send_le): Implement extended length return values. - + * ccid-driver.c (bulk_in): Retry on EAGAIN. (abort_cmd): Change seqno handling. diff --git a/scd/apdu.c b/scd/apdu.c index d114b6eca..f382aea85 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -15,8 +15,6 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, see . - * - * $Id$ */ /* NOTE: This module is also used by other software, thus the use of diff --git a/scd/app-geldkarte.c b/scd/app-geldkarte.c index 34ce08f6e..6e8d07725 100644 --- a/scd/app-geldkarte.c +++ b/scd/app-geldkarte.c @@ -274,7 +274,7 @@ bcd_to_int (const unsigned char *string, size_t length, int *result) gpg_error_t app_select_geldkarte (app_t app) { - static unsigned char const aid[] = + static char const aid[] = { 0xD2, 0x76, 0x00, 0x00, 0x25, 0x45, 0x50, 0x02, 0x00 }; gpg_error_t err; int slot = app->slot; diff --git a/scd/app-nks.c b/scd/app-nks.c index 1f3aad209..076b9139f 100644 --- a/scd/app-nks.c +++ b/scd/app-nks.c @@ -271,7 +271,8 @@ get_chv_status (app_t app, int sigg, int pwid) command[2] = 0x00; command[3] = pwid; - if (apdu_send_direct (app->slot, 0, command, 4, 0, &result, &resultlen)) + if (apdu_send_direct (app->slot, 0, (unsigned char *)command, + 4, 0, &result, &resultlen)) rc = -1; /* Error. */ else if (resultlen < 2) rc = -1; /* Error. */ @@ -1055,7 +1056,7 @@ do_decipher (app_t app, const char *keyidstr, Command chaining does not work. */ if (!rc) rc = iso7816_decipher (app->slot, app->app_local->nks_version > 2? 1:0, - indata, indatalen, 0x81, + indata, indatalen, 0, 0x81, outdata, outdatalen); return rc; } diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 2c10cd9bf..d4685916e 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -16,8 +16,6 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, see . - * - * $Id$ */ /* Some notes: @@ -3316,7 +3314,7 @@ do_decipher (app_t app, const char *keyidstr, const char *s; int n; const char *fpr = NULL; - int exmode; + int exmode, le_value; if (!keyidstr || !*keyidstr || !indatalen) return gpg_error (GPG_ERR_INV_VALUE); @@ -3399,16 +3397,22 @@ do_decipher (app_t app, const char *keyidstr, indatalen = fixuplen + indatalen; padind = -1; /* Already padded. */ } - + if (app->app_local->cardcap.ext_lc_le && indatalen > 254 ) - exmode = 1; /* Extended length w/o a limit. */ + { + exmode = 1; /* Extended length w/o a limit. */ + le_value = app->app_local->extcap.max_rsp_data; + } else if (app->app_local->cardcap.cmd_chaining && indatalen > 254) - exmode = -254; /* Command chaining with max. 254 bytes. */ + { + exmode = -254; /* Command chaining with max. 254 bytes. */ + le_value = 0; + } else - exmode = 0; + exmode = le_value = 0; rc = iso7816_decipher (app->slot, exmode, - indata, indatalen, padind, + indata, indatalen, le_value, padind, outdata, outdatalen); xfree (fixbuf); } diff --git a/scd/iso7816.c b/scd/iso7816.c index f1ee0daef..e3f2c1beb 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -15,8 +15,6 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, see . - * - * $Id$ */ #include @@ -460,7 +458,7 @@ iso7816_get_data (int slot, int extended_mode, int tag, bytes. */ gpg_error_t iso7816_put_data (int slot, int extended_mode, int tag, - const unsigned char *data, size_t datalen) + const void *data, size_t datalen) { int sw; @@ -473,7 +471,7 @@ iso7816_put_data (int slot, int extended_mode, int tag, /* Same as iso7816_put_data but uses an odd instruction byte. */ gpg_error_t iso7816_put_data_odd (int slot, int extended_mode, int tag, - const unsigned char *data, size_t datalen) + const void *data, size_t datalen) { int sw; @@ -545,10 +543,11 @@ iso7816_compute_ds (int slot, int extended_mode, indicator to be used. It should be 0 if no padding is required, a value of -1 suppresses the padding byte. On success 0 is returned and the plaintext is available in a newly allocated buffer stored - at RESULT with its length stored at RESULTLEN. */ + at RESULT with its length stored at RESULTLEN. For LE see + do_generate_keypair. */ gpg_error_t iso7816_decipher (int slot, int extended_mode, - const unsigned char *data, size_t datalen, + const unsigned char *data, size_t datalen, int le, int padind, unsigned char **result, size_t *resultlen) { int sw; @@ -559,6 +558,11 @@ iso7816_decipher (int slot, int extended_mode, *result = NULL; *resultlen = 0; + if (!extended_mode) + le = 256; /* Ignore provided Le and use what apdu_send uses. */ + else if (le >= 0 && le < 256) + le = 256; + if (padind >= 0) { /* We need to prepend the padding indicator. */ @@ -568,18 +572,18 @@ iso7816_decipher (int slot, int extended_mode, *buf = padind; /* Padding indicator. */ memcpy (buf+1, data, datalen); - sw = apdu_send (slot, extended_mode, - 0x00, CMD_PSO, 0x80, 0x86, - datalen+1, (char*)buf, - result, resultlen); + sw = apdu_send_le (slot, extended_mode, + 0x00, CMD_PSO, 0x80, 0x86, + datalen+1, (char*)buf, le, + result, resultlen); xfree (buf); } else { - sw = apdu_send (slot, extended_mode, - 0x00, CMD_PSO, 0x80, 0x86, - datalen, (const char *)data, - result, resultlen); + sw = apdu_send_le (slot, extended_mode, + 0x00, CMD_PSO, 0x80, 0x86, + datalen, (const char *)data, le, + result, resultlen); } if (sw != SW_SUCCESS) { diff --git a/scd/iso7816.h b/scd/iso7816.h index 4e7a344ab..85197124d 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -15,8 +15,6 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, see . - * - * $Id$ */ #ifndef ISO7816_H @@ -87,9 +85,9 @@ gpg_error_t iso7816_reset_retry_counter_with_rc (int slot, int chvno, gpg_error_t iso7816_get_data (int slot, int extended_mode, int tag, unsigned char **result, size_t *resultlen); gpg_error_t iso7816_put_data (int slot, int extended_mode, int tag, - const unsigned char *data, size_t datalen); + const void *data, size_t datalen); gpg_error_t iso7816_put_data_odd (int slot, int extended_mode, int tag, - const unsigned char *data, size_t datalen); + const void *data, size_t datalen); gpg_error_t iso7816_manage_security_env (int slot, int p1, int p2, const unsigned char *data, size_t datalen); @@ -99,7 +97,7 @@ gpg_error_t iso7816_compute_ds (int slot, int extended_mode, unsigned char **result, size_t *resultlen); gpg_error_t iso7816_decipher (int slot, int extended_mode, const unsigned char *data, size_t datalen, - int padind, + int le, int padind, unsigned char **result, size_t *resultlen); gpg_error_t iso7816_internal_authenticate (int slot, int extended_mode, const unsigned char *data, size_t datalen,