summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor Gnatenko <ignatenko@redhat.com>2016-07-25 11:59:35 +0200
committerIgor Gnatenko <ignatenko@redhat.com>2016-07-25 11:59:35 +0200
commitffc545a8fdafac6e77f8d0d518b925b38abf9b59 (patch)
treed9ac4bdc6e6932ec384350912e0a2d3c7b0e00ca
parentd4df7f7b7c82faac474450f2149c5a5351c89a54 (diff)
downloadgpgme-ffc545a8fdafac6e77f8d0d518b925b38abf9b59.zip
gpgme-ffc545a8fdafac6e77f8d0d518b925b38abf9b59.tar.gz
gpgme-ffc545a8fdafac6e77f8d0d518b925b38abf9b59.tar.xz
Backport patch for STATUS_KEY_CONSIDERED (RHBZ #1359521)
Signed-off-by: Igor Gnatenko <ignatenko@redhat.com>
-rw-r--r--0001-Return-dedicated-error-code-for-all-subkeys-expired-.patch335
-rw-r--r--gpgme-1.4.3-no_gpgsm_t-verify.patch25
-rw-r--r--gpgme.spec58
3 files changed, 364 insertions, 54 deletions
diff --git a/0001-Return-dedicated-error-code-for-all-subkeys-expired-.patch b/0001-Return-dedicated-error-code-for-all-subkeys-expired-.patch
new file mode 100644
index 0000000..8d183ba
--- /dev/null
+++ b/0001-Return-dedicated-error-code-for-all-subkeys-expired-.patch
@@ -0,0 +1,335 @@
+From e09f681427d700282988885a80dc2bc8d4573718 Mon Sep 17 00:00:00 2001
+From: Werner Koch <wk@gnupg.org>
+Date: Tue, 17 May 2016 20:21:01 +0200
+Subject: [PATCH] Return dedicated error code for all subkeys expired or
+ revoked.
+
+* src/gpgme.h.in (GPGME_STATUS_KEY_CONSIDERED): New.
+(GPGME_SIGSUM_TOFU_CONFLICT): New.
+* src/status-table.c (KEY_CONSIDERED): New.
+* src/op-support.c (_gpgme_parse_inv_recp): Add argc KC_FPR and
+KC_FLAGS. Use calloc. Detect all expired or revoked subkeys.
+(_gpgme_parse_key_considered): New.
+* src/sign.c (op_data_t): Add fields KC_FPR and KC_FLAGS.
+(release_op_data): Free KC_FPR.
+(_gpgme_sign_status_handler): Handle STATUS_KEY_CONSIDERED.
+* src/encrypt.c (op_data_t): Add fields KC_FPR and KC_FLAGS.
+(release_op_data): Free KC_FPR.
+(_gpgme_encrypt_status_handler): Handle STATUS_KEY_CONSIDERED.
+
+Signed-off-by: Werner Koch <wk@gnupg.org>
+(cherry picked from commit 315fb73d4a774e2c699ac1804f5377559b4d0027)
+---
+ src/encrypt.c | 26 ++++++++++++++++++++--
+ src/gpgme.h.in | 10 +++++++--
+ src/op-support.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++-------
+ src/ops.h | 8 ++++++-
+ src/sign.c | 25 ++++++++++++++++++++-
+ src/status-table.c | 1 +
+ 6 files changed, 121 insertions(+), 14 deletions(-)
+
+diff --git a/src/encrypt.c b/src/encrypt.c
+index 9f5134d..8672cd3 100644
+--- a/src/encrypt.c
++++ b/src/encrypt.c
+@@ -39,6 +39,12 @@ typedef struct
+ /* The error code from a FAILURE status line or 0. */
+ gpg_error_t failure_code;
+
++ /* The fingerprint from the last KEY_CONSIDERED status line. */
++ char *kc_fpr;
++
++ /* The flags from the last KEY_CONSIDERED status line. */
++ unsigned int kc_flags;
++
+ /* A pointer to the next pointer of the last invalid recipient in
+ the list. This makes appending new invalid recipients painless
+ while preserving the order. */
+@@ -60,6 +66,8 @@ release_op_data (void *hook)
+ free (invalid_recipient);
+ invalid_recipient = next;
+ }
++
++ free (opd->kc_fpr);
+ }
+
+
+@@ -128,12 +136,26 @@ _gpgme_encrypt_status_handler (void *priv, gpgme_status_code_t code,
+ return opd->failure_code;
+ break;
+
++ case GPGME_STATUS_KEY_CONSIDERED:
++ /* This is emitted during gpg's key lookup to give information
++ * about the lookup results. We store the last one so it can be
++ * used in connection with INV_RECP. */
++ free (opd->kc_fpr);
++ opd->kc_fpr = NULL;
++ err = _gpgme_parse_key_considered (args, &opd->kc_fpr, &opd->kc_flags);
++ if (err)
++ return err;
++ break;
++
+ case GPGME_STATUS_INV_RECP:
+- err = _gpgme_parse_inv_recp (args, opd->lastp);
++ err = _gpgme_parse_inv_recp (args, 0, opd->kc_fpr, opd->kc_flags,
++ opd->lastp);
+ if (err)
+- return err;
++ return err;
+
+ opd->lastp = &(*opd->lastp)->next;
++ free (opd->kc_fpr);
++ opd->kc_fpr = NULL;
+ break;
+
+ case GPGME_STATUS_NO_RECP:
+diff --git a/src/gpgme.h.in b/src/gpgme.h.in
+index 6cea2c7..cad95f3 100644
+--- a/src/gpgme.h.in
++++ b/src/gpgme.h.in
+@@ -531,7 +531,8 @@ typedef enum
+ GPGME_STATUS_BEGIN_SIGNING = 90,
+ GPGME_STATUS_KEY_NOT_CREATED = 91,
+ GPGME_STATUS_INQUIRE_MAXLEN = 92,
+- GPGME_STATUS_FAILURE = 93
++ GPGME_STATUS_FAILURE = 93,
++ GPGME_STATUS_KEY_CONSIDERED = 94
+ }
+ gpgme_status_code_t;
+
+@@ -860,7 +861,12 @@ typedef struct _gpgme_key *gpgme_key_t;
+ struct _gpgme_invalid_key
+ {
+ struct _gpgme_invalid_key *next;
++
++ /* The string used to request the key. Despite the name this may
++ * not be a fingerprint. */
+ char *fpr;
++
++ /* The error code. */
+ gpgme_error_t reason;
+ };
+ typedef struct _gpgme_invalid_key *gpgme_invalid_key_t;
+@@ -1539,7 +1545,7 @@ struct _gpgme_signature
+ /* Signature creation time. */
+ unsigned long timestamp;
+
+- /* Signature exipration time or 0. */
++ /* Signature expiration time or 0. */
+ unsigned long exp_timestamp;
+
+ /* Key should not have been used for signing. */
+diff --git a/src/op-support.c b/src/op-support.c
+index 02940ef..d51d643 100644
+--- a/src/op-support.c
++++ b/src/op-support.c
+@@ -33,6 +33,11 @@
+ #include "util.h"
+ #include "debug.h"
+
++#if GPG_ERROR_VERSION_NUMBER < 0x011700 /* 1.23 */
++# define GPG_ERR_SUBKEYS_EXP_REV 217
++#endif
++
++
+
+ gpgme_error_t
+ _gpgme_op_data_lookup (gpgme_ctx_t ctx, ctx_op_data_id_t type, void **hook,
+@@ -190,16 +195,19 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type)
+ }
+
+
+-/* Parse the INV_RECP or INV-SNDR status line in ARGS and return the
+- result in KEY. */
++/* Parse the INV_RECP or INV_SNDR status line in ARGS and return the
++ result in KEY. If KC_FPR (from the KEY_CONSIDERED status line) is
++ not NULL take the KC_FLAGS in account. */
+ gpgme_error_t
+-_gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key)
++_gpgme_parse_inv_recp (char *args, int for_signing,
++ const char *kc_fpr, unsigned int kc_flags,
++ gpgme_invalid_key_t *key)
+ {
+ gpgme_invalid_key_t inv_key;
+ char *tail;
+ long int reason;
+
+- inv_key = malloc (sizeof (*inv_key));
++ inv_key = calloc (1, sizeof (*inv_key));
+ if (!inv_key)
+ return gpg_error_from_syserror ();
+ inv_key->next = NULL;
+@@ -214,9 +222,11 @@ _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key)
+
+ switch (reason)
+ {
+- default:
+ case 0:
+- inv_key->reason = gpg_error (GPG_ERR_GENERAL);
++ if (kc_fpr && (kc_flags & 2))
++ inv_key->reason = gpg_error (GPG_ERR_SUBKEYS_EXP_OR_REV);
++ else
++ inv_key->reason = gpg_error (GPG_ERR_GENERAL);
+ break;
+
+ case 1:
+@@ -274,6 +284,10 @@ _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key)
+ case 14:
+ inv_key->reason = gpg_error (GPG_ERR_INV_USER_ID);
+ break;
++
++ default:
++ inv_key->reason = gpg_error (GPG_ERR_GENERAL);
++ break;
+ }
+
+ while (*tail && *tail == ' ')
+@@ -287,14 +301,49 @@ _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key)
+ return gpg_error_from_syserror ();
+ }
+ }
+- else
+- inv_key->fpr = NULL;
+
+ *key = inv_key;
+ return 0;
+ }
+
+
++
++/* Parse a KEY_CONSIDERED status line in ARGS and store the
++ * fingerprint and the flags at R_FPR and R_FLAGS. The caller must
++ * free the value at R_FPR on success. */
++gpgme_error_t
++_gpgme_parse_key_considered (const char *args,
++ char **r_fpr, unsigned int *r_flags)
++{
++ char *pend;
++ size_t n;
++
++ *r_fpr = NULL;
++
++ pend = strchr (args, ' ');
++ if (!pend || pend == args)
++ return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Bogus status line. */
++ n = pend - args;
++ *r_fpr = malloc (n + 1);
++ if (!*r_fpr)
++ return gpg_error_from_syserror ();
++ memcpy (*r_fpr, args, n);
++ (*r_fpr)[n] = 0;
++ args = pend + 1;
++
++ gpg_err_set_errno (0);
++ *r_flags = strtoul (args, &pend, 0);
++ if (errno || args == pend || (*pend && *pend != ' '))
++ {
++ free (*r_fpr);
++ *r_fpr = NULL;
++ return trace_gpg_error (GPG_ERR_INV_ENGINE);
++ }
++
++ return 0;
++}
++
++
+ /* Parse the PLAINTEXT status line in ARGS and return the result in
+ FILENAMEP. */
+ gpgme_error_t
+diff --git a/src/ops.h b/src/ops.h
+index 3662d57..9c27529 100644
+--- a/src/ops.h
++++ b/src/ops.h
+@@ -57,9 +57,15 @@ gpgme_error_t _gpgme_op_data_lookup (gpgme_ctx_t ctx, ctx_op_data_id_t type,
+ /* Prepare a new operation on CTX. */
+ gpgme_error_t _gpgme_op_reset (gpgme_ctx_t ctx, int synchronous);
+
++/* Parse the KEY_CONSIDERED status line. */
++gpgme_error_t _gpgme_parse_key_considered (const char *args,
++ char **r_fpr, unsigned int *r_flags);
++
+ /* Parse the INV_RECP status line in ARGS and return the result in
+ KEY. */
+-gpgme_error_t _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key);
++gpgme_error_t _gpgme_parse_inv_recp (char *args, int for_signing,
++ const char *kc_fpr, unsigned int kc_flags,
++ gpgme_invalid_key_t *key);
+
+ /* Parse the PLAINTEXT status line in ARGS and return the result in
+ FILENAMEP. */
+diff --git a/src/sign.c b/src/sign.c
+index 6c9fc03..d8650a9 100644
+--- a/src/sign.c
++++ b/src/sign.c
+@@ -42,6 +42,12 @@ typedef struct
+ /* The error code from a FAILURE status line or 0. */
+ gpg_error_t failure_code;
+
++ /* The fingerprint from the last KEY_CONSIDERED status line. */
++ char *kc_fpr;
++
++ /* The flags from the last KEY_CONSIDERED status line. */
++ unsigned int kc_flags;
++
+ /* A pointer to the next pointer of the last invalid signer in
+ the list. This makes appending new invalid signers painless
+ while preserving the order. */
+@@ -86,6 +92,7 @@ release_op_data (void *hook)
+ }
+
+ release_signatures (opd->result.signatures);
++ free (opd->kc_fpr);
+ }
+
+
+@@ -316,6 +323,17 @@ _gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
+ opd->last_sig_p = &(*opd->last_sig_p)->next;
+ break;
+
++ case GPGME_STATUS_KEY_CONSIDERED:
++ /* This is emitted during gpg's key lookup to give information
++ * about the lookup results. We store the last one so it can be
++ * used in connection with INV_RECP. */
++ free (opd->kc_fpr);
++ opd->kc_fpr = NULL;
++ err = _gpgme_parse_key_considered (args, &opd->kc_fpr, &opd->kc_flags);
++ if (err)
++ return err;
++ break;
++
+ case GPGME_STATUS_INV_RECP:
+ if (opd->inv_sgnr_seen && opd->ignore_inv_recp)
+ break;
+@@ -323,11 +341,16 @@ _gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
+ case GPGME_STATUS_INV_SGNR:
+ if (code == GPGME_STATUS_INV_SGNR)
+ opd->inv_sgnr_seen = 1;
+- err = _gpgme_parse_inv_recp (args, opd->last_signer_p);
++ free (opd->kc_fpr);
++ opd->kc_fpr = NULL;
++ err = _gpgme_parse_inv_recp (args, 1, opd->kc_fpr, opd->kc_flags,
++ opd->last_signer_p);
+ if (err)
+ return err;
+
+ opd->last_signer_p = &(*opd->last_signer_p)->next;
++ free (opd->kc_fpr);
++ opd->kc_fpr = NULL;
+ break;
+
+ case GPGME_STATUS_FAILURE:
+diff --git a/src/status-table.c b/src/status-table.c
+index 6d428d7..e70cb8b 100644
+--- a/src/status-table.c
++++ b/src/status-table.c
+@@ -84,6 +84,7 @@ static struct status_table_s status_table[] =
+ { "INQUIRE_MAXLEN", GPGME_STATUS_INQUIRE_MAXLEN },
+ { "INV_RECP", GPGME_STATUS_INV_RECP },
+ { "INV_SGNR", GPGME_STATUS_INV_SGNR },
++ { "KEY_CONSIDERED", GPGME_STATUS_KEY_CONSIDERED },
+ { "KEY_CREATED", GPGME_STATUS_KEY_CREATED },
+ { "KEY_NOT_CREATED", GPGME_STATUS_KEY_NOT_CREATED },
+ { "KEYEXPIRED", GPGME_STATUS_KEYEXPIRED },
+--
+2.7.4
+
diff --git a/gpgme-1.4.3-no_gpgsm_t-verify.patch b/gpgme-1.4.3-no_gpgsm_t-verify.patch
deleted file mode 100644
index 758fe3e..0000000
--- a/gpgme-1.4.3-no_gpgsm_t-verify.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-diff -up gpgme-1.4.3/tests/gpgsm/Makefile.in.no_t-verify gpgme-1.4.3/tests/gpgsm/Makefile.in
---- gpgme-1.4.3/tests/gpgsm/Makefile.in.no_t-verify 2013-08-12 07:36:10.000000000 -0500
-+++ gpgme-1.4.3/tests/gpgsm/Makefile.in 2013-10-09 10:28:52.991728837 -0500
-@@ -72,8 +72,8 @@ POST_UNINSTALL = :
- build_triplet = @build@
- host_triplet = @host@
- TESTS = t-import$(EXEEXT) t-keylist$(EXEEXT) t-encrypt$(EXEEXT) \
-- t-verify$(EXEEXT) t-decrypt$(EXEEXT) t-sign$(EXEEXT) \
-- t-export$(EXEEXT)
-+ t-decrypt$(EXEEXT) t-sign$(EXEEXT) \
-+ t-export$(EXEEXT) # t-verify$(EXEEXT)
- noinst_PROGRAMS = $(am__EXEEXT_1) t-genkey$(EXEEXT) \
- cms-keylist$(EXEEXT) cms-decrypt$(EXEEXT)
- subdir = tests/gpgsm
-@@ -94,8 +94,8 @@ CONFIG_HEADER = $(top_builddir)/config.h
- CONFIG_CLEAN_FILES =
- CONFIG_CLEAN_VPATH_FILES =
- am__EXEEXT_1 = t-import$(EXEEXT) t-keylist$(EXEEXT) t-encrypt$(EXEEXT) \
-- t-verify$(EXEEXT) t-decrypt$(EXEEXT) t-sign$(EXEEXT) \
-- t-export$(EXEEXT)
-+ t-decrypt$(EXEEXT) t-sign$(EXEEXT) \
-+ t-export$(EXEEXT) # t-verify$(EXEEXT)
- PROGRAMS = $(noinst_PROGRAMS)
- cms_decrypt_SOURCES = cms-decrypt.c
- cms_decrypt_OBJECTS = cms-decrypt.$(OBJEXT)
diff --git a/gpgme.spec b/gpgme.spec
index 2e6683d..8b38ccc 100644
--- a/gpgme.spec
+++ b/gpgme.spec
@@ -1,40 +1,41 @@
-
# trim changelog included in binary rpms
%global _changelog_trimtime %(date +%s -d "1 year ago")
-Name: gpgme
-Summary: GnuPG Made Easy - high level crypto API
-Version: 1.6.0
-Release: 1%{?dist}
+# STATUS_KEY_CONSIDERED from Patch101 has been added in 2.1.13
+%global gnupg2_min_ver 2.1.13
-License: LGPLv2+
-URL: http://www.gnupg.org/related_software/gpgme/
-Source0: ftp://ftp.gnupg.org/gcrypt/gpgme/gpgme-%{version}.tar.bz2
-Source1: ftp://ftp.gnupg.org/gcrypt/gpgme/gpgme-%{version}.tar.bz2.sig
-Source2: gpgme-multilib.h
+Name: gpgme
+Summary: GnuPG Made Easy - high level crypto API
+Version: 1.6.0
+Release: 2%{?dist}
-Patch1: gpgme-1.3.2-config_extras.patch
+License: LGPLv2+
+URL: http://www.gnupg.org/related_software/gpgme/
+Source0: ftp://ftp.gnupg.org/gcrypt/gpgme/gpgme-%{version}.tar.bz2
+Source2: gpgme-multilib.h
-# gpgsm t-verify check/test hangs if using gnupg2 < 2.0.22
-# see http://bugs.g10code.com/gnupg/issue1493
-Patch2: gpgme-1.4.3-no_gpgsm_t-verify.patch
+Patch1: gpgme-1.3.2-config_extras.patch
# add -D_FILE_OFFSET_BITS... to gpgme-config, upstreamable
-Patch3: gpgme-1.3.2-largefile.patch
+Patch3: gpgme-1.3.2-largefile.patch
+
+# https://bugzilla.redhat.com/show_bug.cgi?id=1359521
+# https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gpgme.git;a=commit;h=315fb73d4a774e2c699ac1804f5377559b4d0027
+Patch101: 0001-Return-dedicated-error-code-for-all-subkeys-expired-.patch
-BuildRequires: gcc
-BuildRequires: gawk
+BuildRequires: gcc
+BuildRequires: gawk
# see patch2 above, else we only need 2.0.4
-BuildRequires: gnupg2 >= 2.0.22
-BuildRequires: gnupg2-smime
-BuildRequires: libgpg-error-devel >= 1.8
-BuildRequires: pth-devel
-BuildRequires: libassuan-devel >= 2.0.2
+BuildRequires: gnupg2 >= %{gnupg2_min_ver}
+BuildRequires: gnupg2-smime
+BuildRequires: libgpg-error-devel >= 1.8
+BuildRequires: pth-devel
+BuildRequires: libassuan-devel >= 2.0.2
# to remove RPATH
-BuildRequires: chrpath
+BuildRequires: chrpath
-Requires: gnupg2
+Requires: gnupg2 >= %{gnupg2_min_ver}
# On the following architectures workaround multiarch conflict of -devel packages:
%define multilib_arches %{ix86} x86_64 ia64 ppc ppc64 s390 s390x %{sparc}
@@ -60,11 +61,7 @@ Requires(postun): /sbin/install-info
%prep
-%setup -q
-
-%patch1 -p1 -b .config_extras
-#patch2 -p1 -b .no_gpgsm_t-verify
-%patch3 -p1 -b .largefile
+%autosetup -p1
## HACK ALERT
# The config script already suppresses the -L if it's /usr/lib, so cheat and
@@ -133,6 +130,9 @@ fi
%{_infodir}/gpgme.info*
%changelog
+* Mon Jul 25 2016 Igor Gnatenko <ignatenko@redhat.com> - 1.6.0-2
+- Backport patch for STATUS_KEY_CONSIDERED (RHBZ #1359521)
+
* Wed Jul 13 2016 Igor Gnatenko <ignatenko@redhat.com> - 1.6.0-1
- Update to 1.6.0 (RHBZ #1167656)