diff options
Diffstat (limited to '')
-rw-r--r-- | scd/ChangeLog | 14 | ||||
-rw-r--r-- | scd/app-openpgp.c | 27 | ||||
-rw-r--r-- | scd/app-p15.c | 128 | ||||
-rw-r--r-- | scd/ccid-driver.c | 3 | ||||
-rw-r--r-- | scd/ccid-driver.h | 3 | ||||
-rw-r--r-- | scd/iso7816.c | 3 | ||||
-rw-r--r-- | scd/iso7816.h | 3 | ||||
-rw-r--r-- | scd/pcsc-wrapper.c | 1 |
8 files changed, 170 insertions, 12 deletions
diff --git a/scd/ChangeLog b/scd/ChangeLog index df22c6bfd..207670072 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,15 @@ +2005-09-09 Werner Koch <[email protected]> + + * pcsc-wrapper.c (main): Removed bogus free. + + * app-p15.c (do_auth): New. + (do_getattr): New attribs $AUTHKEYID and $DISPSERIALNO. + * app-openpgp.c (do_getattr): Ditto. + +2005-09-08 Werner Koch <[email protected]> + + * app-openpgp.c (do_getattr): New key $AUTHKEYID. + 2005-09-06 Werner Koch <[email protected]> * app-p15.c (do_sign): Tweaked for BELPIC cards. @@ -8,7 +20,7 @@ * iso7816.c (iso7816_select_path): New. * app-p15.c (select_ef_by_path): Allow for direct path selection. - (app_select_p15): Try using the beigian variant of pkcs#15. + (app_select_p15): Try using the Belgian variant of pkcs#15. (read_home_df): New. (read_ef_odf): Generalized. (read_ef_tokeninfo): New. diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index bd56fb99d..5625c729b 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -696,6 +696,8 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) { "PRIVATE-DO-2", 0x0102 }, { "PRIVATE-DO-3", 0x0103 }, { "PRIVATE-DO-4", 0x0104 }, + { "$AUTHKEYID", 0x0000, -3 }, + { "$DISPSERIALNO",0x0000, -4 }, { NULL, 0 } }; int idx, i, rc; @@ -742,6 +744,29 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name) send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0); return 0; } + if (table[idx].special == -3) + { + char const tmp[] = "OPENPGP.3"; + send_status_info (ctrl, table[idx].name, tmp, strlen (tmp), NULL, 0); + return 0; + } + if (table[idx].special == -4) + { + char *serial; + time_t stamp; + + if (!app_get_serial_and_stamp (app, &serial, &stamp)) + { + if (strlen (serial) > 16+12) + { + send_status_info (ctrl, table[idx].name, serial+16, 12, NULL, 0); + xfree (serial); + return 0; + } + xfree (serial); + } + return gpg_error (GPG_ERR_INV_NAME); + } relptr = get_one_do (app, table[idx].tag, &value, &valuelen, &rc); if (relptr) @@ -2203,7 +2228,7 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, fingerprint delimited by a slash. Optionally the id OPENPGP.3 may be given. - Note that this fucntion may return the error code + Note that this function may return the error code GPG_ERR_WRONG_CARD to indicate that the card currently present does not match the one required for the requested action (e.g. the serial number does not match). */ diff --git a/scd/app-p15.c b/scd/app-p15.c index bf3c4dc1e..739a9ef95 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -2629,7 +2629,6 @@ readcert_by_cdf (app_t app, cdf_object_t cdf, } - /* Handler for the READCERT command. Read the certificate with id CERTID (as returned by learn_status in @@ -2653,6 +2652,95 @@ do_readcert (app_t app, const char *certid, } + +/* Implement the GETATTR command. This is similar to the LEARN + command but returns just one value via the status interface. */ +static gpg_error_t +do_getattr (app_t app, ctrl_t ctrl, const char *name) +{ + gpg_error_t err; + int i; + + if (!strcmp (name, "$AUTHKEYID")) + { + char *buf, *p; + prkdf_object_t prkdf; + + /* We return the ID of the first private keycapable of + signing. */ + for (prkdf = app->app_local->private_key_info; prkdf; + prkdf = prkdf->next) + if (prkdf->usageflags.sign) + break; + if (prkdf) + { + buf = xtrymalloc (9 + prkdf->objidlen*2 + 1); + if (!buf) + return gpg_error_from_errno (errno); + p = stpcpy (buf, "P15"); + if (app->app_local->home_df) + { + sprintf (p, "-%04hX", (app->app_local->home_df & 0xffff)); + p += 5; + } + p = stpcpy (p, "."); + for (i=0; i < prkdf->objidlen; i++) + { + sprintf (p, "%02X", prkdf->objid[i]); + p += 2; + } + + send_status_info (ctrl, name, buf, strlen (buf), NULL, 0); + xfree (buf); + return 0; + } + } + else if (!strcmp (name, "$DISPSERIALNO")) + { + /* For certain cards we return special IDs. There is no + general rule for it so we need to decide case by case. */ + if (app->app_local->card_type == CARD_TYPE_BELPIC) + { + /* The eID card has a card number printed on the fron matter + which seems to be a good indication. */ + unsigned char *buffer; + const unsigned char *p; + size_t buflen, n; + unsigned short path[] = { 0x3F00, 0xDF01, 0x4031 }; + + err = select_ef_by_path (app, path, DIM(path) ); + if (!err) + err = iso7816_read_binary (app->slot, 0, 0, &buffer, &buflen); + if (err) + { + log_error ("error accessing EF(ID): %s\n", gpg_strerror (err)); + return err; + } + + p = find_tlv (buffer, buflen, 1, &n); + if (p && n == 12) + { + char tmp[12+2+1]; + memcpy (tmp, p, 3); + tmp[3] = '-'; + memcpy (tmp+4, p+3, 7); + tmp[11] = '-'; + memcpy (tmp+12, p+10, 2); + tmp[14] = 0; + send_status_info (ctrl, name, tmp, strlen (tmp), NULL, 0); + xfree (buffer); + return 0; + } + xfree (buffer); + } + + } + return gpg_error (GPG_ERR_INV_NAME); +} + + + + /* Micardo cards require special treatment. This is a helper for the crypto functions to manage the security environment. We expect that the key file has already been selected. FID is the one of the @@ -3086,6 +3174,38 @@ do_sign (app_t app, const char *keyidstr, int hashalgo, } +/* Handler for the PKAUTH command. + + This is basically the same as the PKSIGN command but we firstcheck + that the requested key is suitable for authentication; that is, it + must match the criteria used for the attribute $AUTHKEYID. See + do_sign for calling conventions; there is no HASHALGO, though. */ +static gpg_error_t +do_auth (app_t app, const char *keyidstr, + gpg_error_t (*pincb)(void*, const char *, char **), + void *pincb_arg, + const void *indata, size_t indatalen, + unsigned char **outdata, size_t *outdatalen ) +{ + gpg_error_t err; + prkdf_object_t prkdf; + + if (!keyidstr || !*keyidstr) + return gpg_error (GPG_ERR_INV_VALUE); + + err = prkdf_object_from_keyidstr (app, keyidstr, &prkdf); + if (err) + return err; + if (!prkdf->usageflags.sign) + { + log_error ("key %s may not be used for authentication\n", keyidstr); + return gpg_error (GPG_ERR_WRONG_KEY_USAGE); + } + return do_sign (app, keyidstr, GCRY_MD_SHA1, pincb, pincb_arg, + indata, indatalen, outdata, outdatalen); +} + + /* Assume that EF(DIR) has been selected. Read its content and figure out the home EF of pkcs#15. Return that home DF or 0 if not found @@ -3270,11 +3390,11 @@ app_select_p15 (app_t app) app->fnc.deinit = do_deinit; app->fnc.learn_status = do_learn_status; app->fnc.readcert = do_readcert; - app->fnc.getattr = NULL; + app->fnc.getattr = do_getattr; app->fnc.setattr = NULL; app->fnc.genkey = NULL; app->fnc.sign = do_sign; - app->fnc.auth = NULL; + app->fnc.auth = do_auth; app->fnc.decipher = NULL; app->fnc.change_pin = NULL; app->fnc.check_pin = NULL; @@ -3286,5 +3406,3 @@ app_select_p15 (app_t app) return rc; } - - diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 096a6811b..f82d93b00 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * ALTERNATIVELY, this file may be distributed under the terms of the * following license, in which case the provisions of this license are diff --git a/scd/ccid-driver.h b/scd/ccid-driver.h index 82feed5c9..1b9ac2f85 100644 --- a/scd/ccid-driver.h +++ b/scd/ccid-driver.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * ALTERNATIVELY, this file may be distributed under the terms of the * following license, in which case the provisions of this license are diff --git a/scd/iso7816.c b/scd/iso7816.c index 484906251..5b985324f 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * $Id$ */ diff --git a/scd/iso7816.h b/scd/iso7816.h index 828fabb01..04c7ae63e 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * $Id$ */ diff --git a/scd/pcsc-wrapper.c b/scd/pcsc-wrapper.c index f149e785a..23e8442f7 100644 --- a/scd/pcsc-wrapper.c +++ b/scd/pcsc-wrapper.c @@ -819,7 +819,6 @@ main (int argc, char **argv) fprintf (stderr, PGM ": invalid request 0x%02X\n", c); exit (1); } - free (argbuffer); } return 0; } |