From 884483282f0782f93cf1f171983f27e72eef252c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Sat, 6 Mar 2004 20:11:19 +0000 Subject: [PATCH] Preparing for a release --- ChangeLog | 6 ++ NEWS | 3 +- common/ChangeLog | 5 ++ common/Makefile.am | 3 +- common/asshelp.c | 166 +++++++++++++++++++++++++++++++++++++++++++++ common/asshelp.h | 36 ++++++++++ configure.ac | 14 ++-- m4/ChangeLog | 4 ++ m4/libgcrypt.m4 | 47 +++++++++++-- sm/ChangeLog | 15 ++++ sm/call-agent.c | 123 ++------------------------------- sm/call-dirmngr.c | 32 +++++++-- sm/certchain.c | 109 ++++++++++++++++++----------- sm/certdump.c | 37 +++++++++- sm/gpgsm.h | 3 +- 15 files changed, 423 insertions(+), 180 deletions(-) create mode 100644 common/asshelp.c create mode 100644 common/asshelp.h diff --git a/ChangeLog b/ChangeLog index 5fbf045d7..a70971759 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2004-03-06 Werner Koch + + Released 1.9.6. + + * configure.ac: Check the Libgcrypt API. + 2004-02-25 Werner Koch * configure.ac: New option --disable-threads to inhibit diff --git a/NEWS b/NEWS index 905c5852a..934bce740 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ -Noteworthy changes in version 1.9.6 +Noteworthy changes in version 1.9.6 (2004-03-06) ------------------------------------------------ + * Code cleanups and bug fixes. Noteworthy changes in version 1.9.5 (2004-02-21) diff --git a/common/ChangeLog b/common/ChangeLog index 6f02303e6..4889db4ec 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,8 @@ +2004-03-03 Werner Koch + + * asshelp.c, asshelp.h: New. + (send_pinentry_environment): New. Code taken from ../sm/call-agent.c. + 2004-02-19 Werner Koch * simple-pwquery.c (agent_open): Don't mangle INFOSTR. diff --git a/common/Makefile.am b/common/Makefile.am index a5d2a4e5d..4e7fd504c 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -39,6 +39,7 @@ libcommon_a_SOURCES = \ membuf.c membuf.h \ iobuf.c iobuf.h \ ttyio.c ttyio.h \ + asshelp.c asshelp.h \ signal.c \ dynload.h @@ -46,7 +47,7 @@ libcommon_a_SOURCES = \ libcommon_a_LIBADD = @LIBOBJS@ libsimple_pwquery_a_SOURCES = \ - simple-pwquery.c simple-pwquery.h + simple-pwquery.c simple-pwquery.h asshelp.c asshelp.h libsimple_pwquery_a_LIBADD = @LIBOBJS@ diff --git a/common/asshelp.c b/common/asshelp.c new file mode 100644 index 000000000..23feca507 --- /dev/null +++ b/common/asshelp.c @@ -0,0 +1,166 @@ +/* asshelp.c - Helper functions for Assuan + * Copyright (C) 2002, 2004 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 +#include +#include +#include +#include +#include +#ifdef HAVE_LOCALE_H +#include +#endif + +#include "util.h" + +#include "asshelp.h" + +/* Send the assuan command pertaining to the pinenry environment. The + OPT_* arguments are optional and may be used to overide the + defaults taken from the current locale. */ +gpg_error_t +send_pinentry_environment (assuan_context_t ctx, + const char *opt_display, + const char *opt_ttyname, + const char *opt_ttytype, + const char *opt_lc_ctype, + const char *opt_lc_messages) +{ + int rc = 0; + char *dft_display = NULL; + char *dft_ttyname = NULL; + char *dft_ttytype = NULL; + char *old_lc = NULL; + char *dft_lc = NULL; + + dft_display = getenv ("DISPLAY"); + if (opt_display || dft_display) + { + char *optstr; + if (asprintf (&optstr, "OPTION display=%s", + opt_display ? opt_display : dft_display) < 0) + return gpg_error_from_errno (errno); + rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + free (optstr); + if (rc) + return map_assuan_err (rc); + } + if (!opt_ttyname) + { + dft_ttyname = getenv ("GPG_TTY"); + if ((!dft_ttyname || !*dft_ttyname) && ttyname (0)) + dft_ttyname = ttyname (0); + } + if (opt_ttyname || dft_ttyname) + { + char *optstr; + if (asprintf (&optstr, "OPTION ttyname=%s", + opt_ttyname ? opt_ttyname : dft_ttyname) < 0) + return gpg_error_from_errno (errno); + rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + free (optstr); + if (rc) + return map_assuan_err (rc); + } + dft_ttytype = getenv ("TERM"); + if (opt_ttytype || (dft_ttyname && dft_ttytype)) + { + char *optstr; + if (asprintf (&optstr, "OPTION ttytype=%s", + opt_ttyname ? opt_ttytype : dft_ttytype) < 0) + return gpg_error_from_errno (errno); + rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + free (optstr); + if (rc) + return map_assuan_err (rc); + } +#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) + old_lc = setlocale (LC_CTYPE, NULL); + if (old_lc) + { + old_lc = strdup (old_lc); + if (!old_lc) + return gpg_error_from_errno (errno); + } + dft_lc = setlocale (LC_CTYPE, ""); +#endif + if (opt_lc_ctype || (dft_ttyname && dft_lc)) + { + char *optstr; + if (asprintf (&optstr, "OPTION lc-ctype=%s", + opt_lc_ctype ? opt_lc_ctype : dft_lc) < 0) + rc = gpg_error_from_errno (errno); + else + { + rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + free (optstr); + if (rc) + rc = map_assuan_err (rc); + } + } +#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) + if (old_lc) + { + setlocale (LC_CTYPE, old_lc); + free (old_lc); + } +#endif + if (rc) + return rc; +#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) + old_lc = setlocale (LC_MESSAGES, NULL); + if (old_lc) + { + old_lc = strdup (old_lc); + if (!old_lc) + return gpg_error_from_errno (errno); + } + dft_lc = setlocale (LC_MESSAGES, ""); +#endif + if (opt_lc_messages || (dft_ttyname && dft_lc)) + { + char *optstr; + if (asprintf (&optstr, "OPTION lc-messages=%s", + opt_lc_messages ? opt_lc_messages : dft_lc) < 0) + rc = gpg_error_from_errno (errno); + else + { + rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + free (optstr); + if (rc) + rc = map_assuan_err (rc); + } + } +#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) + if (old_lc) + { + setlocale (LC_MESSAGES, old_lc); + free (old_lc); + } +#endif + + return rc; +} + diff --git a/common/asshelp.h b/common/asshelp.h new file mode 100644 index 000000000..993594882 --- /dev/null +++ b/common/asshelp.h @@ -0,0 +1,36 @@ +/* asshelp.h - Helper functions for Assuan + * Copyright (C) 2004 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_COMMON_ASSHELP_H +#define GNUPG_COMMON_ASSHELP_H + +#include +#include + +gpg_error_t +send_pinentry_environment (assuan_context_t ctx, + const char *opt_display, + const char *opt_ttyname, + const char *opt_ttytype, + const char *opt_lc_ctype, + const char *opt_lc_messages); + + +#endif /*GNUPG_COMMON_ASSHELP_H*/ diff --git a/configure.ac b/configure.ac index aed97fd8f..a8e84dc39 100644 --- a/configure.ac +++ b/configure.ac @@ -24,18 +24,24 @@ min_automake_version="1.7.6" # Version number: Remember to change it immediately *after* a release. # Add a "-cvs" prefix for non-released code. -AC_INIT(gnupg, 1.9.6-cvs, gnupg-devel@gnupg.org) +AC_INIT(gnupg, 1.9.6, gnupg-devel@gnupg.org) # Set development_version to yes if the minor number is odd or you # feel that the default check for a development version is not # sufficient. development_version=yes NEED_GPG_ERROR_VERSION=0.6 -NEED_LIBGCRYPT_VERSION=1.1.92 + +NEED_LIBGCRYPT_API=1 +NEED_LIBGCRYPT_VERSION=1.1.93 + NEED_LIBASSUAN_VERSION=0.6.4 + NEED_KSBA_VERSION=0.9.4 + NEED_OPENSC_VERSION=0.8.0 + PACKAGE=$PACKAGE_NAME VERSION=$PACKAGE_VERSION @@ -411,7 +417,7 @@ AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION", # # Libgcrypt is our generic crypto library # -AM_PATH_LIBGCRYPT("$NEED_LIBGCRYPT_VERSION", +AM_PATH_LIBGCRYPT("$NEED_LIBGCRYPT_API:$NEED_LIBGCRYPT_VERSION", have_libgcrypt=yes,have_libgcrypt=no) @@ -1022,7 +1028,7 @@ if test "$have_libgcrypt" = "no"; then *** You need libgcrypt to build this program. ** This library is for example available at *** ftp://ftp.gnupg.org/gcrypt/alpha/libgcrypt/ -*** (at least version $NEED_LIBGCRYPT_VERSION is required.) +*** (at least version $NEED_LIBGCRYPT_VERSION using API $NEED_LIBGCRYPT_API) is required.) ***]]) fi if test "$have_libassuan" = "no"; then diff --git a/m4/ChangeLog b/m4/ChangeLog index d6ac513e5..efcded757 100644 --- a/m4/ChangeLog +++ b/m4/ChangeLog @@ -1,3 +1,7 @@ +2004-03-06 Werner Koch + + * libgcrypt.m4: Updated. + 2004-02-18 Werner Koch * gpg-error.m4, libgcrypt.m4, libassuan.m4, ksba.m4: New. diff --git a/m4/libgcrypt.m4 b/m4/libgcrypt.m4 index 0e8ab5803..e5f2a43c0 100644 --- a/m4/libgcrypt.m4 +++ b/m4/libgcrypt.m4 @@ -1,5 +1,5 @@ dnl Autoconf macros for libgcrypt -dnl Copyright (C) 2002 Free Software Foundation, Inc. +dnl Copyright (C) 2002, 2004 Free Software Foundation, Inc. dnl dnl This file is free software; as a special exception the author gives dnl unlimited permission to copy and/or distribute it, with or without @@ -12,7 +12,13 @@ dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION, dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for liblibgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS +dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS. +dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed +dnl with the API version to also check the API compatibility. Example: +dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed +dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using +dnl this features allows to prevent build against newer versions of libgcrypt +dnl with a changed API. dnl AC_DEFUN(AM_PATH_LIBGCRYPT, [ AC_ARG_WITH(libgcrypt-prefix, @@ -26,7 +32,15 @@ AC_DEFUN(AM_PATH_LIBGCRYPT, fi AC_PATH_PROG(LIBGCRYPT_CONFIG, libgcrypt-config, no) - min_libgcrypt_version=ifelse([$1], ,0.4.4,$1) + tmp=ifelse([$1], ,1:1.2.0,$1) + if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then + req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` + min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` + else + req_libgcrypt_api=0 + min_libgcrypt_version="$tmp" + fi + AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version) ok=no if test "$LIBGCRYPT_CONFIG" != "no" ; then @@ -36,7 +50,7 @@ AC_DEFUN(AM_PATH_LIBGCRYPT, sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` req_micro=`echo $min_libgcrypt_version | \ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` - libgcrypt_config_version=`$LIBGCRYPT_CONFIG $libgcrypt_config_args --version` + libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version` major=`echo $libgcrypt_config_version | \ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` minor=`echo $libgcrypt_config_version | \ @@ -60,14 +74,33 @@ AC_DEFUN(AM_PATH_LIBGCRYPT, fi fi if test $ok = yes; then - LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG $libgcrypt_config_args --cflags` - LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG $libgcrypt_config_args --libs` AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + if test $ok = yes; then + # If we have a recent libgcrypt, we should also check that the + # API is compatible + if test "$req_libgcrypt_api" -gt 0 ; then + tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0` + if test "$tmp" -gt 0 ; then + AC_MSG_CHECKING([LIBGCRYPT API version]) + if test "$req_libgcrypt_api" -eq "$tmp" ; then + AC_MSG_RESULT(okay) + else + ok=no + AC_MSG_RESULT([does not match (want=$req_libgcrypt_api got=$tmp)]) + fi + fi + fi + fi + if test $ok = yes; then + LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags` + LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs` ifelse([$2], , :, [$2]) else LIBGCRYPT_CFLAGS="" LIBGCRYPT_LIBS="" - AC_MSG_RESULT(no) ifelse([$3], , :, [$3]) fi AC_SUBST(LIBGCRYPT_CFLAGS) diff --git a/sm/ChangeLog b/sm/ChangeLog index 545f93d1a..eb1c608dc 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,5 +1,20 @@ +2004-03-04 Werner Koch + + * call-dirmngr.c (gpgsm_dirmngr_isvalid): New arg ISSUER_CERT. + + * certchain.c (is_cert_still_valid): New. Code moved from ... + (gpgsm_validate_chain): ... here because we now need to check at + two places and at a later stage, so that we can pass the issuer + cert down to the dirmngr. + 2004-03-03 Werner Koch + * call-agent.c (start_agent): Replaced pinentry setup code by a + call to a new common function. + + * certdump.c (gpgsm_format_keydesc): Make sure the string is + returned as utf-8. + * export.c (gpgsm_export): Make sure that we don't export more than one certificate. diff --git a/sm/call-agent.c b/sm/call-agent.c index 053959b2c..15ae5eacc 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -34,6 +34,7 @@ #include #include #include "i18n.h" +#include "asshelp.h" #include "keydb.h" /* fixme: Move this to import.c */ #include "../common/membuf.h" @@ -68,12 +69,7 @@ start_agent (void) { int rc = 0; char *infostr, *p; - ASSUAN_CONTEXT ctx; - char *dft_display = NULL; - char *dft_ttyname = NULL; - char *dft_ttytype = NULL; - char *old_lc = NULL; - char *dft_lc = NULL; + assuan_context_t ctx; if (agent_ctx) return 0; /* fixme: We need a context for each thread or serialize @@ -170,118 +166,9 @@ start_agent (void) if (rc) return map_assuan_err (rc); - dft_display = getenv ("DISPLAY"); - if (opt.display || dft_display) - { - char *optstr; - if (asprintf (&optstr, "OPTION display=%s", - opt.display ? opt.display : dft_display) < 0) - return OUT_OF_CORE (errno); - rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); - } - if (!opt.ttyname) - { - dft_ttyname = getenv ("GPG_TTY"); - if ((!dft_ttyname || !*dft_ttyname) && ttyname (0)) - dft_ttyname = ttyname (0); - } - if (opt.ttyname || dft_ttyname) - { - char *optstr; - if (asprintf (&optstr, "OPTION ttyname=%s", - opt.ttyname ? opt.ttyname : dft_ttyname) < 0) - return OUT_OF_CORE (errno); - rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); - } - dft_ttytype = getenv ("TERM"); - if (opt.ttytype || (dft_ttyname && dft_ttytype)) - { - char *optstr; - if (asprintf (&optstr, "OPTION ttytype=%s", - opt.ttyname ? opt.ttytype : dft_ttytype) < 0) - return OUT_OF_CORE (errno); - rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); - } -#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) - old_lc = setlocale (LC_CTYPE, NULL); - if (old_lc) - { - old_lc = strdup (old_lc); - if (!old_lc) - return OUT_OF_CORE (errno); - } - dft_lc = setlocale (LC_CTYPE, ""); -#endif - if (opt.lc_ctype || (dft_ttyname && dft_lc)) - { - char *optstr; - if (asprintf (&optstr, "OPTION lc-ctype=%s", - opt.lc_ctype ? opt.lc_ctype : dft_lc) < 0) - rc = OUT_OF_CORE (errno); - else - { - rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - rc = map_assuan_err (rc); - } - } -#if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) - if (old_lc) - { - setlocale (LC_CTYPE, old_lc); - free (old_lc); - } -#endif - if (rc) - return rc; -#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) - old_lc = setlocale (LC_MESSAGES, NULL); - if (old_lc) - { - old_lc = strdup (old_lc); - if (!old_lc) - return OUT_OF_CORE (errno); - } - dft_lc = setlocale (LC_MESSAGES, ""); -#endif - if (opt.lc_messages || (dft_ttyname && dft_lc)) - { - char *optstr; - if (asprintf (&optstr, "OPTION lc-messages=%s", - opt.lc_messages ? opt.lc_messages : dft_lc) < 0) - rc = OUT_OF_CORE (errno); - else - { - rc = assuan_transact (agent_ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - rc = map_assuan_err (rc); - } - } -#if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) - if (old_lc) - { - setlocale (LC_MESSAGES, old_lc); - free (old_lc); - } -#endif - - return rc; + return send_pinentry_environment (agent_ctx, + opt.display, opt.ttyname, opt.ttytype, + opt.lc_ctype, opt.lc_messages); } diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index ba96df499..4f07fec24 100644 --- a/sm/call-dirmngr.c +++ b/sm/call-dirmngr.c @@ -49,6 +49,7 @@ static int force_pipe_server = 0; struct inq_certificate_parm_s { ASSUAN_CONTEXT ctx; ksba_cert_t cert; + ksba_cert_t issuer_cert; }; struct lookup_parm_s { @@ -239,27 +240,45 @@ inq_certificate (void *opaque, const char *line) AssuanError rc; const unsigned char *der; size_t derlen; + int issuer_mode = 0; - if (!(!strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]))) + if (!strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8])) + { + line += 8; + } + else if (!strncmp (line, "SENDISSUERCERT", 14) + && (line[14] == ' ' || !line[14])) + { + line += 14; + issuer_mode = 1; + } + else { log_error ("unsupported inquiry `%s'\n", line); return ASSUAN_Inquire_Unknown; } - line += 8; if (!*line) - { /* send the current certificate */ - der = ksba_cert_get_image (parm->cert, &derlen); + { /* Send the current certificate. */ + der = ksba_cert_get_image (issuer_mode? parm->issuer_cert : parm->cert, + &derlen); if (!der) rc = ASSUAN_Inquire_Error; else rc = assuan_send_data (parm->ctx, der, derlen); } + else if (issuer_mode) + { + log_error ("sending specific issuer certificate back " + "is not yet implemented\n"); + rc = ASSUAN_Inquire_Error; + } else - { /* send the given certificate */ + { /* Send the given certificate. */ int err; ksba_cert_t cert; + err = gpgsm_find_cert (line, &cert); if (err) { @@ -293,7 +312,7 @@ inq_certificate (void *opaque, const char *line) request first. */ int -gpgsm_dirmngr_isvalid (ksba_cert_t cert, int use_ocsp) +gpgsm_dirmngr_isvalid (ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp) { int rc; char *certid; @@ -328,6 +347,7 @@ gpgsm_dirmngr_isvalid (ksba_cert_t cert, int use_ocsp) parm.ctx = dirmngr_ctx; parm.cert = cert; + parm.issuer_cert = issuer_cert; /* FIXME: If --disable-crl-checks has been set, we should pass an option to dirmngr, so that no fallback CRL check is done after an diff --git a/sm/certchain.c b/sm/certchain.c index bb3fd0339..2904680ea 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -347,7 +347,7 @@ find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next) if (opt.verbose) log_info (_("looking up issuer at external location\n")); - /* dirmngr is confused about unknown attributes so has a quick + /* dirmngr is confused about unknown attributes so as a quick and ugly hack we locate the CN and use this and the following. Fixme: we should have far better parsing in the dirmngr. */ @@ -469,6 +469,55 @@ gpgsm_is_root_cert (ksba_cert_t cert) return yes; } + +/* This is a helper for gpgsm_validate_chain. */ +static gpg_error_t +is_cert_still_valid (ctrl_t ctrl, int lm, FILE *fp, + ksba_cert_t subject_cert, ksba_cert_t issuer_cert, + int *any_revoked, int *any_no_crl, int *any_crl_too_old) +{ + if (!opt.no_crl_check || ctrl->use_ocsp) + { + gpg_error_t err; + + err = gpgsm_dirmngr_isvalid (subject_cert, ctrl->use_ocsp); + if (err) + { + /* Fixme: We should change the wording because we may + have used OCSP. */ + switch (gpg_err_code (err)) + { + case GPG_ERR_CERT_REVOKED: + do_list (1, lm, fp, _("certificate has been revoked")); + *any_revoked = 1; + /* Store that in the keybox so that key listings are + able to return the revoked flag. We don't care + about error, though. */ + keydb_set_cert_flags (subject_cert, KEYBOX_FLAG_VALIDITY, 0, + VALIDITY_REVOKED); + break; + case GPG_ERR_NO_CRL_KNOWN: + do_list (1, lm, fp, _("no CRL found for certificate")); + *any_no_crl = 1; + break; + case GPG_ERR_CRL_TOO_OLD: + do_list (1, lm, fp, _("the available CRL is too old")); + if (!lm) + log_info (_("please make sure that the " + "\"dirmngr\" is properly installed\n")); + *any_crl_too_old = 1; + break; + default: + do_list (1, lm, fp, _("checking the CRL failed: %s"), + gpg_strerror (rc)); + return err; + } + } + } + return 0; +} + + /* Validate a chain and optionally return the nearest expiration time in R_EXPTIME. With LISTMODE set to 1 a special listmode is @@ -597,46 +646,10 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, goto leave; } - if (!opt.no_crl_check || ctrl->use_ocsp) - { - rc = gpgsm_dirmngr_isvalid (subject_cert, ctrl->use_ocsp); - if (rc) - { - /* Fixme: We should change the wording because we may - have used OCSP. */ - switch (gpg_err_code (rc)) - { - case GPG_ERR_CERT_REVOKED: - do_list (1, lm, fp, _("certificate has been revoked")); - any_revoked = 1; - /* Store that in the keybox so that key listings are - able to return the revoked flag. We don't care - about error, though. */ - keydb_set_cert_flags (subject_cert, KEYBOX_FLAG_VALIDITY, 0, - VALIDITY_REVOKED); - break; - case GPG_ERR_NO_CRL_KNOWN: - do_list (1, lm, fp, _("no CRL found for certificate")); - any_no_crl = 1; - break; - case GPG_ERR_CRL_TOO_OLD: - do_list (1, lm, fp, _("the available CRL is too old")); - if (!lm) - log_info (_("please make sure that the " - "\"dirmngr\" is properly installed\n")); - any_crl_too_old = 1; - break; - default: - do_list (1, lm, fp, _("checking the CRL failed: %s"), - gpg_strerror (rc)); - goto leave; - } - rc = 0; - } - } + /* Is this a self-signed certificate? */ if (subject && !strcmp (issuer, subject)) - { + { /* Yes. */ if (gpgsm_check_cert_sig (subject_cert, subject_cert) ) { do_list (1, lm, fp, @@ -684,7 +697,15 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, gpg_strerror (rc)); } - break; /* okay, a self-signed certicate is an end-point */ + /* Check for revocations etc. */ + rc = is_cert_still_valid (ctrl, lm, fp, + subject_cert, subject_cert, + &any_revoked, &any_no_crl, + &any_crl_too_old); + if (rc) + goto leave; + + break; /* Okay: a self-signed certicate is an end-point. */ } depth++; @@ -801,6 +822,14 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, } } + /* Check for revocations etc. */ + rc = is_cert_still_valid (ctrl, lm, fp, + subject_cert, issuer_cert, + &any_revoked, &any_no_crl, &any_crl_too_old); + if (rc) + goto leave; + + if (opt.verbose && !listmode) log_info ("certificate is good\n"); diff --git a/sm/certdump.c b/sm/certdump.c index f2c21f7fa..30cd0bd53 100644 --- a/sm/certdump.c +++ b/sm/certdump.c @@ -26,6 +26,12 @@ #include #include #include +#ifdef HAVE_LOCALE_H +#include +#endif +#ifdef HAVE_LANGINFO_CODESET +#include +#endif #include "gpgsm.h" #include @@ -601,12 +607,14 @@ gpgsm_format_name (const char *name) char * gpgsm_format_keydesc (ksba_cert_t cert) { + int rc; char *name, *subject, *buffer, *p; const char *s; ksba_isotime_t t; char created[20]; char *sn; ksba_sexp_t sexp; + char *orig_codeset = NULL; name = ksba_cert_get_subject (cert, 0); subject = name? gpgsm_format_name (name) : NULL; @@ -622,7 +630,24 @@ gpgsm_format_keydesc (ksba_cert_t cert) else *created = 0; - if ( asprintf (&name, + +#ifdef ENABLE_NLS + /* The Assuan agent protol requires us to transmit utf-8 strings */ + orig_codeset = bind_textdomain_codeset (PACKAGE, NULL); +#ifdef HAVE_LANGINFO_CODESET + if (!orig_codeset) + orig_codeset = nl_langinfo (CODESET); +#endif + if (orig_codeset) + { /* We only switch when we are able to restore the codeset later. */ + orig_codeset = xstrdup (orig_codeset); + if (!bind_textdomain_codeset (PACKAGE, "utf-8")) + orig_codeset = NULL; + } +#endif + + + rc = asprintf (&name, _("Please enter the passphrase to unlock the" " secret key for:\n" "\"%s\"\n" @@ -630,7 +655,15 @@ gpgsm_format_keydesc (ksba_cert_t cert) subject? subject:"?", sn? sn: "?", gpgsm_get_short_fingerprint (cert), - created) < 0) + created); + +#ifdef ENABLE_NLS + if (orig_codeset) + bind_textdomain_codeset (PACKAGE, orig_codeset); +#endif + xfree (orig_codeset); + + if (rc < 0) { int save_errno = errno; xfree (subject); diff --git a/sm/gpgsm.h b/sm/gpgsm.h index c0434d79c..62bc05354 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -288,7 +288,8 @@ int gpgsm_agent_learn (void); int gpgsm_agent_passwd (const char *hexkeygrip, const char *desc); /*-- call-dirmngr.c --*/ -int gpgsm_dirmngr_isvalid (ksba_cert_t cert, int use_ocsp); +int gpgsm_dirmngr_isvalid (ksba_cert_t cert, ksba_cert_t issuer_cert, + int use_ocsp); int gpgsm_dirmngr_lookup (ctrl_t ctrl, STRLIST names, void (*cb)(void*, ksba_cert_t), void *cb_value); int gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command,