From 20ed53942acc3b30576bae70826cced13bc84f4e Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Sat, 27 Sep 2003 19:37:53 +0000 Subject: [PATCH] First bits of a card support backport from 1.9. It is not enabled by default and tehre is not yet much more than a new configure option. * configure.ac (LIBUSB_LIBS,HAVE_LIBUSB): Check for Libusb. (--enable-card-support): New. * sign.c (do_sign) [ENABLE_CARD_SUPPORT]: Divert to card. * cardglue.c, cardglue.h: New. * Makefile.am (gpg_LDADD): Added. (card_support_sources): New. * memory.h (xmalloc): Define xmalloc macros in terms of m_alloc. --- ChangeLog | 5 +++ configure.ac | 27 ++++++++++++ g10/ChangeLog | 8 ++++ g10/Makefile.am | 7 +++- g10/cardglue.c | 82 ++++++++++++++++++++++++++++++++++++ g10/cardglue.h | 104 ++++++++++++++++++++++++++++++++++++++++++++++ g10/sign.c | 39 ++++++++++++++--- include/ChangeLog | 4 ++ include/memory.h | 9 ++++ 9 files changed, 278 insertions(+), 7 deletions(-) create mode 100644 g10/cardglue.c create mode 100644 g10/cardglue.h diff --git a/ChangeLog b/ChangeLog index 77a5f9055..901e60c92 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2003-09-27 Werner Koch + + * configure.ac (LIBUSB_LIBS,HAVE_LIBUSB): Check for Libusb. + (--enable-card-support): New. + 2003-09-04 David Shaw * configure.ac: Drop TIGER/192 support. Check for UINT64_C to go diff --git a/configure.ac b/configure.ac index c37c61aa2..cb393c829 100644 --- a/configure.ac +++ b/configure.ac @@ -103,6 +103,16 @@ if test "$use_m_guard" = yes ; then AC_DEFINE(M_GUARD,1,[Define to use the (obsolete) malloc guarding feature]) fi +AC_MSG_CHECKING([whether OpenPGP card support is requested]) +AC_ARG_ENABLE(card-support, + [ --enable-card-support enable OpenPGP card support], + card_support=$enableval, card_support=no) +AC_MSG_RESULT($card_support) +if test "$card_support" = yes ; then + AC_DEFINE(ENABLE_CARD_SUPPORT,1, + [Define to include the OpenPGP card support]) +fi + dnl See if we are disabling any algorithms or features for a smaller dnl binary @@ -971,6 +981,23 @@ fi AC_SUBST(ZLIBS) +# +# libusb allows us to use the integrated CCID smartcard reader driver. +# +# Note, that we need the CVS (unstable) version. +# +LIBUSB_LIBS="" +if test "$card_support" = yes; then + AC_CHECK_LIB(usb, usb_find_device, + [ LIBUSB_LIBS="$LIBUSB_LIBS -lusb" + AC_DEFINE(HAVE_LIBUSB,1, + [defined if libusb is available]) + ]) +fi +AC_SUBST(LIBUSB_LIBS) + + + # Allow users to append something to the version string without # flagging it as development version. The user version parts is # considered everything after a dash. diff --git a/g10/ChangeLog b/g10/ChangeLog index c357254bc..4c71b2e21 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,11 @@ +2003-09-27 Werner Koch + + * sign.c (do_sign) [ENABLE_CARD_SUPPORT]: Divert to card. + * cardglue.c, cardglue.h: New. + * Makefile.am (gpg_LDADD): Added. + (card_support_sources): New. + + 2003-09-25 David Shaw * options.h, g10.c (main), keylist.c (list_keyblock_print): Add diff --git a/g10/Makefile.am b/g10/Makefile.am index 07d6ea5e1..4105a7e6c 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -63,8 +63,13 @@ common_source = \ keylist.c \ signal.c +card_support_source = \ + cardglue.c cardclue.h + + gpg_SOURCES = g10.c \ $(common_source) \ + $(card_support_source) \ pkclist.c \ skclist.c \ pubkey-enc.c \ @@ -108,7 +113,7 @@ gpgv_SOURCES = gpgv.c \ LDADD = $(needed_libs) @INTLLIBS@ @CAPLIBS@ @ZLIBS@ @W32LIBS@ # gpg gets LIBOBJS to add in mkdtemp if the platform doesn't have it -gpg_LDADD = @LIBOBJS@ $(LDADD) @DLLIBS@ @NETLIBS@ +gpg_LDADD = @LIBOBJS@ $(LDADD) @DLLIBS@ @NETLIBS@ @LIBUSB_LIBS@ $(PROGRAMS): $(needed_libs) diff --git a/g10/cardglue.c b/g10/cardglue.c new file mode 100644 index 000000000..ca47cefd5 --- /dev/null +++ b/g10/cardglue.c @@ -0,0 +1,82 @@ +/* cardglue.c - mainly dispatcher for card related functions. + * Copyright (C) 2003 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 + */ + +#include +#ifdef ENABLE_CARD_SUPPORT +/* + Note, that most card related code has been taken from 1.9.x branch + and is maintained over there if at all possible. Thus, if you make + changes here, please check that a similar change has been commited + to the 1.9.x branch. +*/ +#include +#include +#include +#include +#include + +#include "options.h" +#include "packet.h" +#include "errors.h" +#include "memory.h" +#include "util.h" +#include "main.h" +#include "status.h" +#include "i18n.h" + +#include "cardglue.h" + + + + +/* Create a serialno/fpr string from the serial number and the secret + key. caller must free the returned string. There is no error + return. [Taken from 1.9's keyid.c]*/ +char * +serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen, + PKT_secret_key *sk) +{ + unsigned char fpr[MAX_FINGERPRINT_LEN]; + size_t fprlen; + char *buffer, *p; + int i; + + fingerprint_from_sk (sk, fpr, &fprlen); + buffer = p = xmalloc (snlen*2 + 1 + fprlen*2 + 1); + for (i=0; i < snlen; i++, p+=2) + sprintf (p, "%02X", sn[i]); + *p++ = '/'; + for (i=0; i < fprlen; i++, p+=2) + sprintf (p, "%02X", fpr[i]); + *p = 0; + return buffer; +} + + + + + + + + + + +#endif /*ENABLE_CARD_SUPPORT*/ + diff --git a/g10/cardglue.h b/g10/cardglue.h new file mode 100644 index 000000000..03b40a077 --- /dev/null +++ b/g10/cardglue.h @@ -0,0 +1,104 @@ +/* call-agent.h - Divert operations to the agent + * Copyright (C) 2003 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 + */ +#ifndef GNUPG_G10_CARDGLUE_H +#define GNUPG_G10_CARDGLUE_H + +#ifdef ENABLE_CARD_SUPPORT +/* + Note, that most card related code has been taken from 1.9.x branch + and is maintained over there if at all possible. Thus, if you make + changes here, please check that a similar change has been commited + to the 1.9.x branch. +*/ + + +struct agent_card_info_s { + int error; /* private. */ + char *serialno; /* malloced hex string. */ + char *disp_name; /* malloced. */ + char *disp_lang; /* malloced. */ + int disp_sex; /* 0 = unspecified, 1 = male, 2 = female */ + char *pubkey_url; /* malloced. */ + char *login_data; /* malloced. */ + char fpr1valid; + char fpr2valid; + char fpr3valid; + char fpr1[20]; + char fpr2[20]; + char fpr3[20]; + unsigned long sig_counter; + int chv1_cached; /* True if a PIN is not required for each + signing. Note that the gpg-agent might cache + it anyway. */ + int chvmaxlen[3]; /* Maximum allowed length of a CHV. */ + int chvretry[3]; /* Allowed retries for the CHV; 0 = blocked. */ +}; + +struct agent_card_genkey_s { + char fprvalid; + char fpr[20]; + u32 created_at; + MPI n; + MPI e; +}; + + + + + +char *serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen, + PKT_secret_key *sk); + + + + +/* Release the card info structure. */ +void agent_release_card_info (struct agent_card_info_s *info); + +/* Return card info. */ +int agent_learn (struct agent_card_info_s *info); + +/* Check whether the secret key for the key identified by HEXKEYGRIP + is available. Return 0 for yes or an error code. */ +int agent_havekey (const char *hexkeygrip); + +/* Send a SETATTR command to the SCdaemon. */ +int agent_scd_setattr (const char *name, + const unsigned char *value, size_t valuelen); + +/* Send a GENKEY command to the SCdaemon. */ +int agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force); + +/* Send a PKSIGN command to the SCdaemon. */ +int agent_scd_pksign (const char *keyid, int hashalgo, + const unsigned char *indata, size_t indatalen, + char **r_buf, size_t *r_buflen); + +/* Send a PKDECRYPT command to the SCdaemon. */ +int agent_scd_pkdecrypt (const char *serialno, + const unsigned char *indata, size_t indatalen, + char **r_buf, size_t *r_buflen); + +/* Change the PIN of an OpenPGP card or reset the retry counter. */ +int agent_scd_change_pin (int chvno); + +#endif /*ENABLE_CARD_SUPPORT*/ +#endif /*GNUPG_G10_CARDGLUE_H*/ + diff --git a/g10/sign.c b/g10/sign.c index ab9d1a38f..d1d981480 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -40,6 +40,7 @@ #include "trustdb.h" #include "status.h" #include "i18n.h" +#include "cardglue.h" #ifdef HAVE_DOSISH_SYSTEM @@ -305,12 +306,38 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig, sig->digest_algo = digest_algo; sig->digest_start[0] = dp[0]; sig->digest_start[1] = dp[1]; - frame = encode_md_value( sk->pubkey_algo, md, - digest_algo, mpi_get_nbits(sk->skey[0]), 0 ); - if (!frame) - return G10ERR_GENERAL; - rc = pubkey_sign( sk->pubkey_algo, sig->data, frame, sk->skey ); - mpi_free(frame); +#ifdef ENABLE_CARD_SUPPORT + if (sk->is_protected && sk->protect.s2k.mode == 1002) + { + char *rbuf; + size_t rbuflen; + char *snbuf; + + snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen,sk); + rc = G10ERR_GENERAL; +/* agent_scd_pksign (snbuf, digest_algo, */ +/* gcry_md_read (md, digest_algo), */ +/* gcry_md_get_algo_dlen (digest_algo), */ +/* &rbuf, &rbuflen); */ + xfree (snbuf); + if (!rc) + { +/* if (gcry_mpi_scan (&sig->data[0], GCRYMPI_FMT_USG, */ +/* rbuf, rbuflen, NULL)) */ + BUG (); + } + } + else +#endif /* ENABLE_CARD_SUPPORT */ + { + frame = encode_md_value( sk->pubkey_algo, md, + digest_algo, mpi_get_nbits(sk->skey[0]), 0 ); + if (!frame) + return G10ERR_GENERAL; + rc = pubkey_sign( sk->pubkey_algo, sig->data, frame, sk->skey ); + mpi_free(frame); + } + if (!rc && !opt.no_sig_create_check) { /* check that the signature verification worked and nothing is * fooling us e.g. by a bug in the signature create diff --git a/include/ChangeLog b/include/ChangeLog index 9c2b65312..f83aae32b 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2003-09-27 Werner Koch + + * memory.h (xmalloc): Define xmalloc macros in terms of m_alloc. + 2003-09-04 David Shaw * cipher.h: Drop TIGER/192 support. diff --git a/include/memory.h b/include/memory.h index 959f2999e..2482d083f 100644 --- a/include/memory.h +++ b/include/memory.h @@ -90,4 +90,13 @@ unsigned secmem_get_flags(void); EXTERN_UNLESS_MAIN_MODULE int memory_debug_mode; EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; +/* To prepare a migration to the xmalloc suite of function as used in + 1.9 we define a couple of macros. */ +#define xmalloc(n) m_alloc ((n)) +#define xcalloc(n,m) m_alloc_clear ((n)*(m)) +#define xmalloc_secure(n) m_alloc_secure (n) +#define xcalloc_secure(n) m_alloc_secure_clear ((n)*(m)) +#define xfree(a) m_free (a) + + #endif /*G10_MEMORY_H*/