diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7aa4a7e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/gnupg-2.3.1.tar.bz2
diff --git a/.gnupg2.metadata b/.gnupg2.metadata
new file mode 100644
index 0000000..3f09c34
--- /dev/null
+++ b/.gnupg2.metadata
@@ -0,0 +1 @@
+a8f66ba4f7dcb2e7322aef786f942ce5ccca6f14 SOURCES/gnupg-2.3.1.tar.bz2
diff --git a/SOURCES/gnupg-2.1.1-fips-algo.patch b/SOURCES/gnupg-2.1.1-fips-algo.patch
new file mode 100644
index 0000000..b8e0129
--- /dev/null
+++ b/SOURCES/gnupg-2.1.1-fips-algo.patch
@@ -0,0 +1,54 @@
+diff -up gnupg-2.1.1/g10/mainproc.c.fips gnupg-2.1.1/g10/mainproc.c
+--- gnupg-2.1.1/g10/mainproc.c.fips	2015-01-29 17:19:49.266031504 +0100
++++ gnupg-2.1.1/g10/mainproc.c	2015-01-29 17:27:13.938088122 +0100
+@@ -719,7 +719,8 @@ proc_plaintext( CTX c, PACKET *pkt )
+          according to 2440, so hopefully it won't come up that often.
+          There is no good way to specify what algorithms to use in
+          that case, so these there are the historical answer. */
+-	gcry_md_enable (c->mfx.md, DIGEST_ALGO_RMD160);
++	if (!gcry_fips_mode_active())
++            gcry_md_enable (c->mfx.md, DIGEST_ALGO_RMD160);
+ 	gcry_md_enable (c->mfx.md, DIGEST_ALGO_SHA1);
+     }
+   if (DBG_HASHING)
+diff --git a/common/t-sexputil.c b/common/t-sexputil.c
+index d75090c5b..be5eb2122 100644
+--- a/common/t-sexputil.c
++++ b/common/t-sexputil.c
+@@ -291,36 +291,6 @@ test_ecc_uncompress (void)
+     const char *b;  /* Compressed.    */
+   }
+   tests[] = {
+-  {
+-    "(public-key"
+-    " (ecc"
+-    " (curve brainpoolP256r1)"
+-    " (q #042ECD8679930BE2DB4AD42B8600BA3F80"
+-    /*   */"2D4D539BFF2F69B83EC9B7BBAA7F3406"
+-    /*   */"436DD11A1756AFE56CD93408410FCDA9"
+-    /*   */"BA95024EB613BD481A14FCFEC27A448A#)))",
+-    /* The same in compressed form.  */
+-    "(public-key"
+-    " (ecc"
+-    " (curve brainpoolP256r1)"
+-    " (q #022ECD8679930BE2DB4AD42B8600BA3F80"
+-    /*   */"2D4D539BFF2F69B83EC9B7BBAA7F3406#)))"
+-  },
+-  {
+-    "(public-key"
+-    " (ecc"
+-    " (curve brainpoolP256r1)"
+-    " (q #045B784CA008EE64AB3D85017EE0D2BE87"
+-    /*   */"558762C7300E0C8E06B1F9AF7C031458"
+-    /*   */"9EBBA41915313417BA54218EB0569C59"
+-    /*   */"0B156C76DBCAB6E84575E6EF68CE7B87#)))",
+-    /* The same in compressed form.  */
+-    "(public-key"
+-    " (ecc"
+-    " (curve brainpoolP256r1)"
+-    " (q #035B784CA008EE64AB3D85017EE0D2BE87"
+-    /*   */"558762C7300E0C8E06B1F9AF7C031458#)))"
+-  },
+   { /* A key which does not require a conversion.  */
+     "(public-key"
+     " (ecdsa"
diff --git a/SOURCES/gnupg-2.1.10-secmem.patch b/SOURCES/gnupg-2.1.10-secmem.patch
new file mode 100644
index 0000000..e263509
--- /dev/null
+++ b/SOURCES/gnupg-2.1.10-secmem.patch
@@ -0,0 +1,33 @@
+diff -up gnupg-2.1.10/g10/gpg.c.secmem gnupg-2.1.10/g10/gpg.c
+--- gnupg-2.1.10/g10/gpg.c.secmem	2015-12-04 10:53:27.000000000 +0100
++++ gnupg-2.1.10/g10/gpg.c	2015-12-07 15:32:38.922812652 +0100
+@@ -889,7 +889,7 @@ make_libversion (const char *libname, co
+ 
+   if (maybe_setuid)
+     {
+-      gcry_control (GCRYCTL_INIT_SECMEM, 0, 0);  /* Drop setuid. */
++      gcry_control (GCRYCTL_INIT_SECMEM, 4096, 0);  /* Drop setuid. */
+       maybe_setuid = 0;
+     }
+   s = getfnc (NULL);
+@@ -1041,7 +1041,7 @@ build_list (const char *text, char lette
+   char *string;
+ 
+   if (maybe_setuid)
+-    gcry_control (GCRYCTL_INIT_SECMEM, 0, 0);  /* Drop setuid. */
++    gcry_control (GCRYCTL_INIT_SECMEM, 4096, 0);  /* Drop setuid. */
+ 
+   indent = utf8_charcount (text, -1);
+   len = 0;
+diff -up gnupg-2.1.10/sm/gpgsm.c.secmem gnupg-2.1.10/sm/gpgsm.c
+--- gnupg-2.1.10/sm/gpgsm.c.secmem	2015-11-30 17:39:52.000000000 +0100
++++ gnupg-2.1.10/sm/gpgsm.c	2015-12-07 15:31:17.226884207 +0100
+@@ -530,7 +530,7 @@ make_libversion (const char *libname, co
+ 
+   if (maybe_setuid)
+     {
+-      gcry_control (GCRYCTL_INIT_SECMEM, 0, 0);  /* Drop setuid. */
++      gcry_control (GCRYCTL_INIT_SECMEM, 4096, 0);  /* Drop setuid. */
+       maybe_setuid = 0;
+     }
+   s = getfnc (NULL);
diff --git a/SOURCES/gnupg-2.2.16-ocsp-keyusage.patch b/SOURCES/gnupg-2.2.16-ocsp-keyusage.patch
new file mode 100644
index 0000000..eeed053
--- /dev/null
+++ b/SOURCES/gnupg-2.2.16-ocsp-keyusage.patch
@@ -0,0 +1,17 @@
+diff -up gnupg-2.2.16/sm/certlist.c.keyusage gnupg-2.2.16/sm/certlist.c
+--- gnupg-2.2.16/sm/certlist.c.keyusage	2019-07-01 17:17:06.925254065 +0200
++++ gnupg-2.2.16/sm/certlist.c	2019-07-01 17:24:15.665759322 +0200
+@@ -147,10 +147,9 @@ cert_usage_p (ksba_cert_t cert, int mode
+ 
+   if (mode == 5)
+     {
+-      if (use != ~0
+-          && (have_ocsp_signing
+-              || (use & (KSBA_KEYUSAGE_KEY_CERT_SIGN
+-                         |KSBA_KEYUSAGE_CRL_SIGN))))
++      if (have_ocsp_signing
++          || (use & (KSBA_KEYUSAGE_KEY_CERT_SIGN
++                     |KSBA_KEYUSAGE_CRL_SIGN)))
+         return 0;
+       if (!silent)
+         log_info (_("certificate should not have "
diff --git a/SOURCES/gnupg-2.2.18-gpg-accept-subkeys-with-a-good-revocation-but-no-self-sig.patch b/SOURCES/gnupg-2.2.18-gpg-accept-subkeys-with-a-good-revocation-but-no-self-sig.patch
new file mode 100644
index 0000000..a617396
--- /dev/null
+++ b/SOURCES/gnupg-2.2.18-gpg-accept-subkeys-with-a-good-revocation-but-no-self-sig.patch
@@ -0,0 +1,32 @@
+From: Vincent Breitmoser <look@my.amazin.horse>
+Date: Thu, 13 Jun 2019 21:27:43 +0200
+Subject: gpg: accept subkeys with a good revocation but no self-sig during
+ import
+
+* g10/import.c (chk_self_sigs): Set the NODE_GOOD_SELFSIG flag when we
+encounter a valid revocation signature. This allows import of subkey
+revocation signatures, even in the absence of a corresponding subkey
+binding signature.
+
+--
+
+This fixes the remaining test in import-incomplete.scm.
+
+GnuPG-Bug-id: 4393
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+---
+ g10/import.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/g10/import.c b/g10/import.c
+index f9acf95..9217911 100644
+--- a/g10/import.c
++++ b/g10/import.c
+@@ -3602,6 +3602,7 @@ chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, int *non_self)
+                   /* It's valid, so is it newer? */
+                   if (sig->timestamp >= rsdate)
+                     {
++                      knode->flag |= NODE_GOOD_SELFSIG; /* Subkey is valid.  */
+                       if (rsnode)
+                         {
+                           /* Delete the last revocation sig since
diff --git a/SOURCES/gnupg-2.2.18-gpg-allow-import-of-previously-known-keys-even-without-UI.patch b/SOURCES/gnupg-2.2.18-gpg-allow-import-of-previously-known-keys-even-without-UI.patch
new file mode 100644
index 0000000..98dda54
--- /dev/null
+++ b/SOURCES/gnupg-2.2.18-gpg-allow-import-of-previously-known-keys-even-without-UI.patch
@@ -0,0 +1,107 @@
+From: Vincent Breitmoser <look@my.amazin.horse>
+Date: Thu, 13 Jun 2019 21:27:42 +0200
+Subject: gpg: allow import of previously known keys, even without UIDs
+
+* g10/import.c (import_one): Accept an incoming OpenPGP certificate that
+has no user id, as long as we already have a local variant of the cert
+that matches the primary key.
+
+--
+
+This fixes two of the three broken tests in import-incomplete.scm.
+
+GnuPG-Bug-id: 4393
+Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+---
+ g10/import.c | 44 +++++++++++---------------------------------
+ 1 file changed, 11 insertions(+), 33 deletions(-)
+
+diff --git a/g10/import.c b/g10/import.c
+index 5d3162c..f9acf95 100644
+--- a/g10/import.c
++++ b/g10/import.c
+@@ -1788,7 +1788,6 @@ import_one_real (ctrl_t ctrl,
+   size_t an;
+   char pkstrbuf[PUBKEY_STRING_SIZE];
+   int merge_keys_done = 0;
+-  int any_filter = 0;
+   KEYDB_HANDLE hd = NULL;
+ 
+   if (r_valid)
+@@ -1825,14 +1824,6 @@ import_one_real (ctrl_t ctrl,
+       log_printf ("\n");
+     }
+ 
+-
+-  if (!uidnode)
+-    {
+-      if (!silent)
+-        log_error( _("key %s: no user ID\n"), keystr_from_pk(pk));
+-      return 0;
+-    }
+-
+   if (screener && screener (keyblock, screener_arg))
+     {
+       log_error (_("key %s: %s\n"), keystr_from_pk (pk),
+@@ -1907,18 +1898,10 @@ import_one_real (ctrl_t ctrl,
+ 	  }
+     }
+ 
+-  /* Delete invalid parts and bail out if there are no user ids left.  */
+-  if (!delete_inv_parts (ctrl, keyblock, keyid, options))
+-    {
+-      if (!silent)
+-        {
+-          log_error ( _("key %s: no valid user IDs\n"), keystr_from_pk(pk));
+-          if (!opt.quiet)
+-            log_info(_("this may be caused by a missing self-signature\n"));
+-        }
+-      stats->no_user_id++;
+-      return 0;
+-    }
++  /* Delete invalid parts, and note if we have any valid ones left.
++   * We will later abort import if this key is new but contains
++   * no valid uids.  */
++  delete_inv_parts (ctrl, keyblock, keyid, options);
+ 
+   /* Get rid of deleted nodes.  */
+   commit_kbnode (&keyblock);
+@@ -1927,24 +1911,11 @@ import_one_real (ctrl_t ctrl,
+     {
+       apply_keep_uid_filter (ctrl, keyblock, import_filter.keep_uid);
+       commit_kbnode (&keyblock);
+-      any_filter = 1;
+     }
+   if (import_filter.drop_sig)
+     {
+       apply_drop_sig_filter (ctrl, keyblock, import_filter.drop_sig);
+       commit_kbnode (&keyblock);
+-      any_filter = 1;
+-    }
+-
+-  /* If we ran any filter we need to check that at least one user id
+-   * is left in the keyring.  Note that we do not use log_error in
+-   * this case. */
+-  if (any_filter && !any_uid_left (keyblock))
+-    {
+-      if (!opt.quiet )
+-        log_info ( _("key %s: no valid user IDs\n"), keystr_from_pk (pk));
+-      stats->no_user_id++;
+-      return 0;
+     }
+ 
+   /* The keyblock is valid and ready for real import.  */
+@@ -2002,6 +1973,13 @@ import_one_real (ctrl_t ctrl,
+       err = 0;
+       stats->skipped_new_keys++;
+     }
++  else if (err && !any_uid_left (keyblock))
++    {
++      if (!silent)
++        log_info( _("key %s: new key but contains no user ID - skipped\n"), keystr(keyid));
++      err = 0;
++      stats->no_user_id++;
++    }
+   else if (err)  /* Insert this key. */
+     {
+       /* Note: ERR can only be NO_PUBKEY or UNUSABLE_PUBKEY.  */
diff --git a/SOURCES/gnupg-2.2.18-tests-add-test-cases-for-import-without-uid.patch b/SOURCES/gnupg-2.2.18-tests-add-test-cases-for-import-without-uid.patch
new file mode 100644
index 0000000..37ddeea
--- /dev/null
+++ b/SOURCES/gnupg-2.2.18-tests-add-test-cases-for-import-without-uid.patch
@@ -0,0 +1,201 @@
+From: Vincent Breitmoser <look@my.amazin.horse>
+Date: Thu, 13 Jun 2019 21:27:41 +0200
+Subject: tests: add test cases for import without uid
+
+This commit adds a test case that does the following, in order:
+- Import of a primary key plus user id
+- Check that import of a subkey works, without a user id present in the
+imported key
+- Check that import of a subkey revocation works, without a user id or
+subkey binding signature present in the imported key
+- Check that import of a primary key revocation works, without a user id
+present in the imported key
+
+--
+
+Note that this test currently fails.  The following changesets will
+fix gpg so that the tests pass.
+
+GnuPG-Bug-id: 4393
+Signed-Off-By: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+---
+ tests/openpgp/Makefile.am                          |  1 +
+ tests/openpgp/import-incomplete.scm                | 68 ++++++++++++++++++++++
+ .../import-incomplete/primary+revocation.asc       |  9 +++
+ .../primary+subkey+sub-revocation.asc              | 10 ++++
+ .../import-incomplete/primary+subkey+sub-sig.asc   | 10 ++++
+ .../openpgp/import-incomplete/primary+uid-sig.asc  | 10 ++++
+ tests/openpgp/import-incomplete/primary+uid.asc    | 10 ++++
+ 7 files changed, 118 insertions(+)
+ create mode 100755 tests/openpgp/import-incomplete.scm
+ create mode 100644 tests/openpgp/import-incomplete/primary+revocation.asc
+ create mode 100644 tests/openpgp/import-incomplete/primary+subkey+sub-revocation.asc
+ create mode 100644 tests/openpgp/import-incomplete/primary+subkey+sub-sig.asc
+ create mode 100644 tests/openpgp/import-incomplete/primary+uid-sig.asc
+ create mode 100644 tests/openpgp/import-incomplete/primary+uid.asc
+
+diff --git a/tests/openpgp/Makefile.am b/tests/openpgp/Makefile.am
+index f6014c9..6423da1 100644
+--- a/tests/openpgp/Makefile.am
++++ b/tests/openpgp/Makefile.am
+@@ -78,6 +78,7 @@ XTESTS = \
+ 	gpgv-forged-keyring.scm \
+ 	armor.scm \
+ 	import.scm \
++	import-incomplete.scm \
+ 	import-revocation-certificate.scm \
+ 	ecc.scm \
+ 	4gb-packet.scm \
+diff --git a/tests/openpgp/import-incomplete.scm b/tests/openpgp/import-incomplete.scm
+new file mode 100755
+index 0000000..727a027
+--- /dev/null
++++ b/tests/openpgp/import-incomplete.scm
+@@ -0,0 +1,68 @@
++#!/usr/bin/env gpgscm
++
++;; Copyright (C) 2016 g10 Code GmbH
++;;
++;; 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 3 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, see <http://www.gnu.org/licenses/>.
++
++(load (in-srcdir "tests" "openpgp" "defs.scm"))
++(setup-environment)
++
++(call-check `(,(tool 'gpg) --import ,(in-srcdir "tests" "openpgp" "import-incomplete" "primary+uid.asc")))
++
++(info "Test import of new subkey, from a certificate without uid")
++(define keyid "573EA710367356BB")
++(call-check `(,(tool 'gpg) --import ,(in-srcdir "tests" "openpgp" "import-incomplete" "primary+subkey+sub-sig.asc")))
++(tr:do
++ (tr:pipe-do
++  (pipe:gpg `(--list-keys --with-colons ,keyid)))
++ (tr:call-with-content
++  (lambda (c)
++    ;; XXX we do not have a regexp library
++    (unless (any (lambda (line)
++		   (and (string-prefix? line "sub:")
++			(string-contains? line "573EA710367356BB")))
++		 (string-split-newlines c))
++	    (exit 1)))))
++
++(info "Test import of a subkey revocation, from a certificate without uid")
++(define keyid "573EA710367356BB")
++(call-check `(,(tool 'gpg) --import ,(in-srcdir "tests" "openpgp" "import-incomplete" "primary+subkey+sub-revocation.asc")))
++(tr:do
++ (tr:pipe-do
++  (pipe:gpg `(--list-keys --with-colons ,keyid)))
++ (tr:call-with-content
++  (lambda (c)
++    ;; XXX we do not have a regexp library
++    (unless (any (lambda (line)
++		   (and (string-prefix? line "sub:r:")
++			(string-contains? line "573EA710367356BB")))
++		 (string-split-newlines c))
++	    (exit 1)))))
++
++(info "Test import of revocation, from a certificate without uid")
++(call-check `(,(tool 'gpg) --import ,(in-srcdir "tests" "openpgp" "import-incomplete" "primary+revocation.asc")))
++(tr:do
++ (tr:pipe-do
++  (pipe:gpg `(--list-keys --with-colons ,keyid)))
++ (tr:call-with-content
++  (lambda (c)
++    ;; XXX we do not have a regexp library
++    (unless (any (lambda (line)
++		   (and (string-prefix? line "pub:r:")
++			(string-contains? line "0843DA969AA8DAFB")))
++		 (string-split-newlines c))
++	    (exit 1)))))
++
+diff --git a/tests/openpgp/import-incomplete/primary+revocation.asc b/tests/openpgp/import-incomplete/primary+revocation.asc
+new file mode 100644
+index 0000000..6b7b608
+--- /dev/null
++++ b/tests/openpgp/import-incomplete/primary+revocation.asc
+@@ -0,0 +1,9 @@
++-----BEGIN PGP PUBLIC KEY BLOCK-----
++Comment: [E] primary key, revocation signature over primary (no user ID)
++
++mDMEXNmUGRYJKwYBBAHaRw8BAQdA75R8VlchvmEd2Iz/8l07RoKUaUPDB71Ao1zZ
++631VAN2IeAQgFggAIBYhBLRpj5W82H/gSMzKKQhD2paaqNr7BQJc2ZQZAh0AAAoJ
++EAhD2paaqNr7qAwA/2jBUpnN0BxwRO/4CrxvrLIsL+C9aSXJUOTv8XkP4lvtAQD3
++XsDFfFNgEueiTfF7HtOGt5LPmRqVvUpQSMVgJJW6CQ==
++=tM90
++-----END PGP PUBLIC KEY BLOCK-----
+diff --git a/tests/openpgp/import-incomplete/primary+subkey+sub-revocation.asc b/tests/openpgp/import-incomplete/primary+subkey+sub-revocation.asc
+new file mode 100644
+index 0000000..83a51a5
+--- /dev/null
++++ b/tests/openpgp/import-incomplete/primary+subkey+sub-revocation.asc
+@@ -0,0 +1,10 @@
++-----BEGIN PGP PUBLIC KEY BLOCK-----
++Comment: [D] primary key, subkey, subkey revocation (no user ID)
++
++mDMEXNmUGRYJKwYBBAHaRw8BAQdA75R8VlchvmEd2Iz/8l07RoKUaUPDB71Ao1zZ
++631VAN24OARc2ZQhEgorBgEEAZdVAQUBAQdABsd5ha0AWXdXcSmfeiWIfrNcGqQK
++j++lwwWDAOlkVicDAQgHiHgEKBYIACAWIQS0aY+VvNh/4EjMyikIQ9qWmqja+wUC
++XNmnkAIdAgAKCRAIQ9qWmqja+ylaAQDmIKf86BJEq4OpDqU+V9D+wn2cyuxbyWVQ
++3r9LiL9qNwD/QAjyrhSN8L3Mfq+wdTHo5i0yB9ZCCpHLXSbhCqfWZwQ=
++=dwx2
++-----END PGP PUBLIC KEY BLOCK-----
+diff --git a/tests/openpgp/import-incomplete/primary+subkey+sub-sig.asc b/tests/openpgp/import-incomplete/primary+subkey+sub-sig.asc
+new file mode 100644
+index 0000000..dc47a02
+--- /dev/null
++++ b/tests/openpgp/import-incomplete/primary+subkey+sub-sig.asc
+@@ -0,0 +1,10 @@
++-----BEGIN PGP PUBLIC KEY BLOCK-----
++Comment: [B] primary key, subkey, subkey binding sig (no user ID)
++
++mDMEXNmUGRYJKwYBBAHaRw8BAQdA75R8VlchvmEd2Iz/8l07RoKUaUPDB71Ao1zZ
++631VAN24OARc2ZQhEgorBgEEAZdVAQUBAQdABsd5ha0AWXdXcSmfeiWIfrNcGqQK
++j++lwwWDAOlkVicDAQgHiHgEGBYIACAWIQS0aY+VvNh/4EjMyikIQ9qWmqja+wUC
++XNmUIQIbDAAKCRAIQ9qWmqja++vFAP98G1L+1/rWTGbsnxOAV2RocBYIroAvsbkR
++Ly6FdP8YNwEA7jOgT05CoKIe37MstpOz23mM80AK369Ca3JMmKKCQgg=
++=xuDu
++-----END PGP PUBLIC KEY BLOCK-----
+diff --git a/tests/openpgp/import-incomplete/primary+uid-sig.asc b/tests/openpgp/import-incomplete/primary+uid-sig.asc
+new file mode 100644
+index 0000000..134607d
+--- /dev/null
++++ b/tests/openpgp/import-incomplete/primary+uid-sig.asc
+@@ -0,0 +1,10 @@
++-----BEGIN PGP PUBLIC KEY BLOCK-----
++Comment: [C] primary key and self-sig expiring in 2024 (no user ID)
++
++mDMEXNmUGRYJKwYBBAHaRw8BAQdA75R8VlchvmEd2Iz/8l07RoKUaUPDB71Ao1zZ
++631VAN2IlgQTFggAPgIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBLRpj5W8
++2H/gSMzKKQhD2paaqNr7BQJc2ZR1BQkJZgHcAAoJEAhD2paaqNr79soA/0lWkUsu
++3NLwgbni6EzJxnTzgeNMpljqNpipHAwfix9hAP93AVtFdC8g7hdUZxawobl9lnSN
++9ohXOEBWvdJgVv2YAg==
++=KWIK
++-----END PGP PUBLIC KEY BLOCK-----
+diff --git a/tests/openpgp/import-incomplete/primary+uid.asc b/tests/openpgp/import-incomplete/primary+uid.asc
+new file mode 100644
+index 0000000..055f300
+--- /dev/null
++++ b/tests/openpgp/import-incomplete/primary+uid.asc
+@@ -0,0 +1,10 @@
++-----BEGIN PGP PUBLIC KEY BLOCK-----
++Comment: [A] primary key, user ID, and self-sig expiring in 2021
++
++mDMEXNmUGRYJKwYBBAHaRw8BAQdA75R8VlchvmEd2Iz/8l07RoKUaUPDB71Ao1zZ
++631VAN20CHRlc3Qga2V5iJYEExYIAD4WIQS0aY+VvNh/4EjMyikIQ9qWmqja+wUC
++XNmUGQIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRAIQ9qWmqja
+++0G1AQDdQiwhXxjXLMqoth+D4SigVHTJK8ORwifzsy3UE7mPGwD/aZ67XbAF/lgI
++kv2O1Jo0u9BL9RNNF+L0DM7rAFbfMAs=
++=1eII
++-----END PGP PUBLIC KEY BLOCK-----
diff --git a/SOURCES/gnupg-2.2.20-file-is-digest.patch b/SOURCES/gnupg-2.2.20-file-is-digest.patch
new file mode 100644
index 0000000..a85c9bd
--- /dev/null
+++ b/SOURCES/gnupg-2.2.20-file-is-digest.patch
@@ -0,0 +1,195 @@
+diff -up gnupg-2.2.20/g10/gpg.c.file-is-digest gnupg-2.2.20/g10/gpg.c
+--- gnupg-2.2.20/g10/gpg.c.file-is-digest	2020-04-14 16:33:42.630269318 +0200
++++ gnupg-2.2.20/g10/gpg.c	2020-04-14 16:34:46.455100086 +0200
+@@ -380,6 +380,7 @@ enum cmd_and_opt_values
+     oTTYtype,
+     oLCctype,
+     oLCmessages,
++    oFileIsDigest,
+     oXauthority,
+     oGroup,
+     oUnGroup,
+@@ -831,6 +832,7 @@ static ARGPARSE_OPTS opts[] = {
+   ARGPARSE_s_s (oTempDir,  "temp-directory", "@"),
+   ARGPARSE_s_s (oExecPath, "exec-path", "@"),
+   ARGPARSE_s_n (oExpert,      "expert", "@"),
++  ARGPARSE_s_n (oFileIsDigest, "file-is-digest", "@"),
+   ARGPARSE_s_n (oNoExpert, "no-expert", "@"),
+   ARGPARSE_s_n (oNoSecmemWarn, "no-secmem-warning", "@"),
+   ARGPARSE_s_n (oRequireSecmem, "require-secmem", "@"),
+@@ -2419,6 +2421,7 @@ main (int argc, char **argv)
+     opt.keyid_format = KF_NONE;
+     opt.def_sig_expire = "0";
+     opt.def_cert_expire = "0";
++    opt.file_is_digest = 0;
+     opt.passphrase_repeat = 1;
+     opt.emit_version = 0;
+     opt.weak_digests = NULL;
+@@ -2997,6 +3000,7 @@ main (int argc, char **argv)
+ 	  case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break;
+ 
+ 	  case oForceAEAD: opt.force_aead = 1; break;
++	  case oFileIsDigest: opt.file_is_digest = 1; break;
+ 
+           case oDisableSignerUID: opt.flags.disable_signer_uid = 1; break;
+           case oIncludeKeyBlock:  opt.flags.include_key_block = 1; break;
+diff -up gnupg-2.2.20/g10/options.h.file-is-digest gnupg-2.2.20/g10/options.h
+--- gnupg-2.2.20/g10/options.h.file-is-digest	2020-03-14 19:54:05.000000000 +0100
++++ gnupg-2.2.20/g10/options.h	2020-04-14 16:33:42.634269245 +0200
+@@ -202,6 +202,7 @@ struct
+   int no_auto_check_trustdb;
+   int preserve_permissions;
+   int no_homedir_creation;
++  int file_is_digest;
+   struct groupitem *grouplist;
+   int mangle_dos_filenames;
+   int enable_progress_filter;
+diff -up gnupg-2.2.20/g10/sign.c.file-is-digest gnupg-2.2.20/g10/sign.c
+--- gnupg-2.2.20/g10/sign.c.file-is-digest	2020-03-14 19:35:46.000000000 +0100
++++ gnupg-2.2.20/g10/sign.c	2020-04-14 16:36:54.661751422 +0200
+@@ -40,6 +40,7 @@
+ #include "pkglue.h"
+ #include "../common/sysutils.h"
+ #include "call-agent.h"
++#include "../common/host2net.h"
+ #include "../common/mbox-util.h"
+ #include "../common/compliance.h"
+ 
+@@ -834,6 +835,8 @@ write_signature_packets (ctrl_t ctrl,
+ 
+       if (pk->version >= 5)
+         sig->version = 5;  /* Required for v5 keys.  */
++      else if (opt.file_is_digest)
++        sig->version = 3;
+       else
+         sig->version = 4;  /* Required.  */
+ 
+@@ -860,8 +863,11 @@ write_signature_packets (ctrl_t ctrl,
+         err = mk_sig_subpkt_key_block (ctrl, sig, pk);
+       else
+         err = 0;
+-      hash_sigversion_to_magic (md, sig, extrahash);
+-      gcry_md_final (md);
++
++      if (!opt.file_is_digest) {
++        hash_sigversion_to_magic (md, sig, extrahash);
++        gcry_md_final (md);
++      }
+ 
+       if (!err)
+         err = do_sign (ctrl, pk, sig, md, hash_for (pk), cache_nonce, 0);
+@@ -924,6 +930,8 @@ sign_file (ctrl_t ctrl, strlist_t filena
+   SK_LIST sk_rover = NULL;
+   int multifile = 0;
+   u32 duration=0;
++  int sigclass = 0x00;
++  u32 timestamp = 0;
+   pt_extra_hash_data_t extrahash = NULL;
+ 
+   pfx = new_progress_context ();
+@@ -941,7 +949,16 @@ sign_file (ctrl_t ctrl, strlist_t filena
+     fname = NULL;
+ 
+   if (fname && filenames->next && (!detached || encryptflag))
+-    log_bug ("multiple files can only be detached signed");
++    log_bug ("multiple files can only be detached signed\n");
++
++  if (opt.file_is_digest && (multifile || !fname))
++    log_bug ("file-is-digest only works with one file\n");
++  if (opt.file_is_digest && !detached)
++    log_bug ("file-is-digest can only write detached signatures\n");
++  if (opt.file_is_digest && !opt.def_digest_algo)
++    log_bug ("file-is-digest needs --digest-algo\n");
++  if (opt.file_is_digest && opt.textmode)
++    log_bug ("file-is-digest doesn't work with --textmode\n");
+ 
+   if (encryptflag == 2
+       && (rc = setup_symkey (&efx.symkey_s2k, &efx.symkey_dek)))
+@@ -962,7 +979,7 @@ sign_file (ctrl_t ctrl, strlist_t filena
+     goto leave;
+ 
+   /* Prepare iobufs. */
+-  if (multifile)    /* have list of filenames */
++  if (multifile || opt.file_is_digest)  /* have list of filenames */
+     inp = NULL;     /* we do it later */
+   else
+     {
+@@ -1100,7 +1117,7 @@ sign_file (ctrl_t ctrl, strlist_t filena
+   for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
+     gcry_md_enable (mfx.md, hash_for (sk_rover->pk));
+ 
+-  if (!multifile)
++  if (!multifile && !opt.file_is_digest)
+     iobuf_push_filter (inp, md_filter, &mfx);
+ 
+   if (detached && !encryptflag)
+@@ -1155,6 +1172,8 @@ sign_file (ctrl_t ctrl, strlist_t filena
+ 
+   write_status_begin_signing (mfx.md);
+ 
++  sigclass = opt.textmode && !outfile? 0x01 : 0x00;
++
+   /* Setup the inner packet. */
+   if (detached)
+     {
+@@ -1195,6 +1214,49 @@ sign_file (ctrl_t ctrl, strlist_t filena
+           if (opt.verbose)
+             log_printf ("\n");
+ 	}
++      else if (opt.file_is_digest)
++        {
++          byte *mdb, ts[5];
++          size_t mdlen;
++          const char *fp;
++          int c, d;
++      
++          gcry_md_final(mfx.md);
++          /* this assumes gcry_md_read returns the same buffer */
++          mdb = gcry_md_read(mfx.md, opt.def_digest_algo);
++          mdlen = gcry_md_get_algo_dlen(opt.def_digest_algo);
++          if (strlen(fname) != mdlen * 2 + 11)
++            log_bug("digests must be %zu + @ + 5 bytes\n", mdlen);
++          d = -1;
++          for (fp = fname ; *fp; )
++            {
++      	     c = *fp++;
++      	     if (c >= '0' && c <= '9')
++      	         c -= '0';
++      	     else if (c >= 'a' && c <= 'f')
++      	         c -= 'a' - 10;
++      	     else if (c >= 'A' && c <= 'F')
++      	         c -= 'A' - 10;
++      	     else
++      	         log_bug("filename is not hex\n");
++      	     if (d >= 0)
++                {
++      	         *mdb++ = d << 4 | c;
++      	         c = -1;
++      	         if (--mdlen == 0)
++                    {
++      	             mdb = ts;
++      	             if (*fp++ != '@')
++      	               log_bug("missing time separator\n");
++      	           }
++      	       }
++      	     d = c;
++            }
++          sigclass = ts[0];
++          if (sigclass != 0x00 && sigclass != 0x01)
++            log_bug("bad cipher class\n");
++          timestamp = buf32_to_u32(ts + 1);
++        }
+       else
+         {
+           /* Read, so that the filter can calculate the digest. */
+@@ -1213,8 +1271,8 @@ sign_file (ctrl_t ctrl, strlist_t filena
+ 
+   /* Write the signatures. */
+   rc = write_signature_packets (ctrl, sk_list, out, mfx.md, extrahash,
+-                                opt.textmode && !outfile? 0x01 : 0x00,
+-                                0, duration, detached ? 'D':'S', NULL);
++                                sigclass,
++                                timestamp, duration, detached ? 'D':'S', NULL);
+   if (rc)
+     goto leave;
+ 
diff --git a/SOURCES/gnupg-2.2.21-coverity.patch b/SOURCES/gnupg-2.2.21-coverity.patch
new file mode 100644
index 0000000..edd5e67
--- /dev/null
+++ b/SOURCES/gnupg-2.2.21-coverity.patch
@@ -0,0 +1,1462 @@
+diff -up gnupg-2.2.21/common/server-help.c.coverity gnupg-2.2.21/common/server-help.c
+--- gnupg-2.2.21/common/server-help.c.coverity 2019-02-11 10:59:34.000000000 +0100
++++ gnupg-2.2.21/common/server-help.c  2020-07-20 17:09:57.416148768 +0200
+@@ -156,7 +156,7 @@ get_option_value (char *line, const char
+   *pend = 0;
+   *r_value = xtrystrdup (p);
+   *pend = c;
+-  if (!p)
++  if (!*r_value)
+     return my_error_from_syserror ();
+   return 0;
+ }
+
+
+From 912e77f07d8a42d7ad001eb3df76f6932ccfa857 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Wed, 7 Apr 2021 17:37:51 +0200
+Subject: [PATCH GnuPG 01/19] agent: Avoid memory leaks
+
+* agent/command.c (cmd_genkey): use goto leave instead of return
+* agent/cvt-openpgp.c (convert_from_openpgp_main): use goto leave
+  instead of return
+* agent/genkey.c (agent_ask_new_passphrase): fix typo to free correct
+  pointer
+  (agent_genkey): release memory
+* agent/gpg-agent.c (check_own_socket): free sockname
+* agent/protect-tool.c (read_key): free buf
+  (agent_askpin): free passphrase
+* agent/protect.c (merge_lists): free newlist
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ agent/command.c      |  2 +-
+ agent/cvt-openpgp.c  |  5 ++++-
+ agent/genkey.c       |  7 +++++--
+ agent/gpg-agent.c    | 10 ++++++++--
+ agent/protect-tool.c |  6 +++++-
+ agent/protect.c      |  5 ++++-
+ 6 files changed, 27 insertions(+), 8 deletions(-)
+
+diff --git a/agent/command.c b/agent/command.c
+index 93cd281e7..b9a1ed038 100644
+--- a/agent/command.c
++++ b/agent/command.c
+@@ -1021,7 +1021,7 @@ cmd_genkey (assuan_context_t ctx, char *line)
+   if (!rc)
+     rc = assuan_inquire (ctx, "KEYPARAM", &value, &valuelen, MAXLEN_KEYPARAM);
+   if (rc)
+-    return rc;
++    goto leave;
+ 
+   init_membuf (&outbuf, 512);
+ 
+diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c
+index 3da553f95..53c88154b 100644
+--- a/agent/cvt-openpgp.c
++++ b/agent/cvt-openpgp.c
+@@ -964,7 +964,10 @@ convert_from_openpgp_main (ctrl_t ctrl, gcry_sexp_t s_pgp, int dontcare_exist,
+ 
+       pi = xtrycalloc_secure (1, sizeof (*pi) + MAX_PASSPHRASE_LEN + 1);
+       if (!pi)
+-        return gpg_error_from_syserror ();
++        {
++          err = gpg_error_from_syserror ();
++          goto leave;
++        }
+       pi->max_length = MAX_PASSPHRASE_LEN + 1;
+       pi->min_digits = 0;  /* We want a real passphrase.  */
+       pi->max_digits = 16;
+diff --git a/agent/genkey.c b/agent/genkey.c
+index 9b47f0fac..c7cfc6910 100644
+--- a/agent/genkey.c
++++ b/agent/genkey.c
+@@ -363,7 +363,7 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
+   if (!pi2)
+     {
+       err = gpg_error_from_syserror ();
+-      xfree (pi2);
++      xfree (pi);
+       return err;
+     }
+   pi->max_length = MAX_PASSPHRASE_LEN + 1;
+@@ -465,7 +465,10 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce, time_t timestamp,
+                                         "protect your new key"),
+                                      &passphrase_buffer);
+       if (rc)
+-        return rc;
++        {
++          gcry_sexp_release (s_keyparam);
++          return rc;
++        }
+       passphrase = passphrase_buffer;
+     }
+ 
+diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
+index 1285db995..8f504191b 100644
+--- a/agent/gpg-agent.c
++++ b/agent/gpg-agent.c
+@@ -3214,11 +3214,17 @@ check_own_socket (void)
+ 
+   sockname = make_filename_try (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL);
+   if (!sockname)
+-    return; /* Out of memory.  */
++    {
++      xfree (sockname);
++      return; /* Out of memory.  */
++    }
+ 
+   err = npth_attr_init (&tattr);
+   if (err)
+-    return;
++    {
++      xfree (sockname);
++      return;
++    }
+   npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
+   err = npth_create (&thread, &tattr, check_own_socket_thread, sockname);
+   if (err)
+diff --git a/agent/protect-tool.c b/agent/protect-tool.c
+index 1fcbd119f..bb17033a8 100644
+--- a/agent/protect-tool.c
++++ b/agent/protect-tool.c
+@@ -319,6 +319,7 @@ read_key (const char *fname)
+   if (buflen >= 4 && !memcmp (buf, "Key:", 4))
+     {
+       log_error ("Extended key format is not supported by this tool\n");
++      xfree (buf);
+       return NULL;
+     }
+   key = make_canonical (fname, buf, buflen);
+@@ -793,7 +794,10 @@ agent_askpin (ctrl_t ctrl,
+   passphrase = get_passphrase (0);
+   size = strlen (passphrase);
+   if (size >= pininfo->max_length)
+-    return gpg_error (GPG_ERR_TOO_LARGE);
++    {
++      xfree (passphrase);
++      return gpg_error (GPG_ERR_TOO_LARGE);
++    }
+ 
+   memcpy (&pininfo->pin, passphrase, size);
+   xfree (passphrase);
+diff --git a/agent/protect.c b/agent/protect.c
+index 76ead444b..50b10eb26 100644
+--- a/agent/protect.c
++++ b/agent/protect.c
+@@ -949,7 +949,10 @@ merge_lists (const unsigned char *protectedkey,
+   /* Copy the cleartext.  */
+   s = cleartext;
+   if (*s != '(' && s[1] != '(')
+-    return gpg_error (GPG_ERR_BUG);  /*we already checked this */
++    {
++      xfree (newlist);
++      return gpg_error (GPG_ERR_BUG);  /*we already checked this */
++    }
+   s += 2;
+   startpos = s;
+   while ( *s == '(' )
+-- 
+2.30.2
+
+
+From 93dc0474ea35c0f8f93e0c5eee14cf0157b0d896 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Wed, 7 Apr 2021 18:54:02 +0200
+Subject: [PATCH GnuPG 02/19] dirmgr: clean up memory on error code paths
+
+* dirmgr/crlcache.c (finish_sig_check): goto leave instead of return
+* dirmgr/http.c (send_request): free authstr and proxy_authstr
+* dirmgr/ldap.c (start_cert_fetch_ldap): free proxy
+* dirmgr/ocsp.c (check_signature): release s_hash
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ dirmngr/crlcache.c | 9 ++++++---
+ dirmngr/http.c     | 6 +++++-
+ dirmngr/ldap.c     | 6 ++++--
+ dirmngr/ocsp.c     | 1 +
+ 4 files changed, 16 insertions(+), 6 deletions(-)
+
+diff --git a/dirmngr/crlcache.c b/dirmngr/crlcache.c
+index 9d18b721f..d508e173f 100644
+--- a/dirmngr/crlcache.c
++++ b/dirmngr/crlcache.c
+@@ -1725,7 +1725,8 @@ finish_sig_check (ksba_crl_t crl, gcry_md_hd_t md, int algo,
+         {
+           log_error ("hash algo mismatch: %d announced but %d used\n",
+                      algo, hashalgo);
+-          return gpg_error (GPG_ERR_INV_CRL);
++          err = gpg_error (GPG_ERR_INV_CRL);
++          goto leave;
+         }
+       /* Add some restrictions; see ../sm/certcheck.c for details.  */
+       switch (algo)
+@@ -1741,14 +1742,16 @@ finish_sig_check (ksba_crl_t crl, gcry_md_hd_t md, int algo,
+         default:
+           log_error ("PSS hash algorithm '%s' rejected\n",
+                      gcry_md_algo_name (algo));
+-          return gpg_error (GPG_ERR_DIGEST_ALGO);
++          err = gpg_error (GPG_ERR_DIGEST_ALGO);
++          goto leave;
+         }
+ 
+       if (gcry_md_get_algo_dlen (algo) != saltlen)
+         {
+           log_error ("PSS hash algorithm '%s' rejected due to salt length %u\n",
+                      gcry_md_algo_name (algo), saltlen);
+-          return gpg_error (GPG_ERR_DIGEST_ALGO);
++          err = gpg_error (GPG_ERR_DIGEST_ALGO);
++          goto leave;
+         }
+     }
+ 
+diff --git a/dirmngr/http.c b/dirmngr/http.c
+index f7f65303b..74ce5f465 100644
+--- a/dirmngr/http.c
++++ b/dirmngr/http.c
+@@ -2208,7 +2208,11 @@ send_request (ctrl_t ctrl, http_t hd, const char *httphost, const char *auth,
+ 
+   p = build_rel_path (hd->uri);
+   if (!p)
+-    return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
++    {
++      xfree (authstr);
++      xfree (proxy_authstr);
++      return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
++    }
+ 
+   if (http_proxy && *http_proxy)
+     {
+diff --git a/dirmngr/ldap.c b/dirmngr/ldap.c
+index ffe54bade..96abc89d0 100644
+--- a/dirmngr/ldap.c
++++ b/dirmngr/ldap.c
+@@ -563,8 +563,10 @@ start_cert_fetch_ldap (ctrl_t ctrl, cert_fetch_context_t *r_context,
+       use_ldaps = server->use_ldaps;
+     }
+   else /* Use a default server. */
+-    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+-
++    {
++      xfree (proxy);
++      return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
++    }
+ 
+   if (!base)
+     base = "";
+diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c
+index 6ed180955..6864f9854 100644
+--- a/dirmngr/ocsp.c
++++ b/dirmngr/ocsp.c
+@@ -534,6 +534,7 @@ check_signature (ctrl_t ctrl,
+       err = ksba_ocsp_get_responder_id (ocsp, &name, &keyid);
+       if (err)
+         {
++          gcry_sexp_release (s_hash);
+           log_error (_("error getting responder ID: %s\n"),
+                      gcry_strerror (err));
+           return err;
+-- 
+2.30.2
+
+
+From 7a707a3eff1c3fbe17a74337776871f408377cee Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Fri, 9 Apr 2021 16:13:07 +0200
+Subject: [PATCH GnuPG 03/19] g10: Fix memory leaks
+
+* g10/card-util.c (change_pin): free answer on errors
+  (ask_card_keyattr): free answer on error
+* g10/cpr.c (do_get_from_fd): free string
+* g10/gpg.c (check_permissions): free dir on weird error
+* g10/import.c (append_new_uid): release knode
+* g10/keyedit.c (menu_set_keyserver_url): free answer
+  (menu_set_keyserver_url): free user
+* g10/keygen.c (print_status_key_not_created): move allocation after
+  sanity check
+  (ask_expire_interval): free answer
+  (card_store_key_with_backup): goto leave instaed of return
+* g10/keyserver.c (parse_keyserver_uri): goto fail instead of return
+* g10/revoke.c (gen_desig_revoke): release kdbhd
+  (gen_desig_revoke): free answer
+* g10/tofu.c (ask_about_binding): free sqerr and response
+* g10/trustdb.c (ask_ownertrust): free pk
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ g10/card-util.c | 14 +++++++++++---
+ g10/cpr.c       |  6 +++++-
+ g10/gpg.c       |  1 +
+ g10/import.c    |  5 ++++-
+ g10/keyedit.c   |  8 +++++++-
+ g10/keygen.c    | 15 +++++++++++----
+ g10/keyserver.c |  2 +-
+ g10/revoke.c    |  6 +++++-
+ g10/tofu.c      |  4 ++++
+ g10/trustdb.c   |  1 +
+ 10 files changed, 50 insertions(+), 12 deletions(-)
+
+diff --git a/g10/card-util.c b/g10/card-util.c
+index 36f096f06..c7df8380d 100644
+--- a/g10/card-util.c
++++ b/g10/card-util.c
+@@ -127,7 +127,7 @@ change_pin (int unblock_v2, int allow_admin)
+   else
+     for (;;)
+       {
+-	char *answer;
++	char *answer = NULL;
+ 
+ 	tty_printf ("\n");
+ 	tty_printf ("1 - change PIN\n"
+@@ -140,7 +140,10 @@ change_pin (int unblock_v2, int allow_admin)
+ 	answer = cpr_get("cardutil.change_pin.menu",_("Your selection? "));
+ 	cpr_kill_prompt();
+ 	if (strlen (answer) != 1)
+-	  continue;
++          {
++            xfree (answer);
++            continue;
++          }
+ 
+ 	if (*answer == '1')
+ 	  {
+@@ -185,8 +188,10 @@ change_pin (int unblock_v2, int allow_admin)
+ 	  }
+ 	else if (*answer == 'q' || *answer == 'Q')
+ 	  {
++            xfree (answer);
+ 	    break;
+ 	  }
++        xfree (answer);
+       }
+ 
+   agent_release_card_info (&info);
+@@ -1450,7 +1455,10 @@ ask_card_keyattr (int keyno, const struct key_attr *current)
+       algo = *answer? atoi (answer) : 0;
+ 
+       if (!*answer || algo == 1 || algo == 2)
+-        break;
++        {
++          xfree (answer);
++          break;
++        }
+       else
+         tty_printf (_("Invalid selection.\n"));
+     }
+diff --git a/g10/cpr.c b/g10/cpr.c
+index 5a39913c5..002656b82 100644
+--- a/g10/cpr.c
++++ b/g10/cpr.c
+@@ -527,7 +527,11 @@ do_get_from_fd ( const char *keyword, int hidden, int getbool )
+   write_status (STATUS_GOT_IT);
+ 
+   if (getbool)	 /* Fixme: is this correct??? */
+-    return (string[0] == 'Y' || string[0] == 'y') ? "" : NULL;
++    {
++      char *rv = (string[0] == 'Y' || string[0] == 'y') ? "" : NULL;
++      xfree (string);
++      return rv;
++    }
+ 
+   return string;
+ }
+diff --git a/g10/gpg.c b/g10/gpg.c
+index f5623be76..186845cea 100644
+--- a/g10/gpg.c
++++ b/g10/gpg.c
+@@ -1601,6 +1601,7 @@ check_permissions (const char *path, int item)
+   if (gnupg_stat (dir,&dirbuf) || !S_ISDIR (dirbuf.st_mode))
+     {
+       /* Weird error */
++      xfree(dir);
+       ret=1;
+       goto end;
+     }
+diff --git a/g10/import.c b/g10/import.c
+index 821ddf0d4..951c33d81 100644
+--- a/g10/import.c
++++ b/g10/import.c
+@@ -4524,7 +4524,10 @@ append_new_uid (unsigned int options,
+           err = insert_key_origin_uid (n->pkt->pkt.user_id,
+                                        curtime, origin, url);
+           if (err)
+-            return err;
++            {
++              release_kbnode (n);
++              return err;
++            }
+         }
+ 
+       if (n_where)
+diff --git a/g10/keyedit.c b/g10/keyedit.c
+index 531d3e128..902741b5f 100644
+--- a/g10/keyedit.c
++++ b/g10/keyedit.c
+@@ -5307,7 +5307,10 @@ menu_set_keyserver_url (ctrl_t ctrl, const char *url, kbnode_t pub_keyblock)
+     }
+ 
+   if (ascii_strcasecmp (answer, "none") == 0)
+-    uri = NULL;
++    {
++      xfree (answer);
++      uri = NULL;
++    }
+   else
+     {
+       struct keyserver_spec *keyserver = NULL;
+@@ -5379,12 +5382,14 @@ menu_set_keyserver_url (ctrl_t ctrl, const char *url, kbnode_t pub_keyblock)
+                            uri
+                            ? _("Are you sure you want to replace it? (y/N) ")
+                            : _("Are you sure you want to delete it? (y/N) ")))
++	                xfree (user);
+ 			continue;
+ 		    }
+ 		  else if (uri == NULL)
+ 		    {
+ 		      /* There is no current keyserver URL, so there
+ 		         is no point in trying to un-set it. */
++	              xfree (user);
+ 		      continue;
+ 		    }
+ 
+@@ -5397,6 +5402,7 @@ menu_set_keyserver_url (ctrl_t ctrl, const char *url, kbnode_t pub_keyblock)
+ 		      log_error ("update_keysig_packet failed: %s\n",
+ 				 gpg_strerror (rc));
+ 		      xfree (uri);
++	              xfree (user);
+ 		      return 0;
+ 		    }
+ 		  /* replace the packet */
+diff --git a/g10/keygen.c b/g10/keygen.c
+index 5d85c05d4..f1e4d3638 100644
+--- a/g10/keygen.c
++++ b/g10/keygen.c
+@@ -237,12 +237,13 @@ print_status_key_not_created (const char *handle)
+ static gpg_error_t
+ write_uid (kbnode_t root, const char *s)
+ {
+-  PACKET *pkt = xmalloc_clear (sizeof *pkt);
++  PACKET *pkt = NULL;
+   size_t n = strlen (s);
+ 
+   if (n > MAX_UID_PACKET_LENGTH - 10)
+     return gpg_error (GPG_ERR_INV_USER_ID);
+ 
++  pkt = xmalloc_clear (sizeof *pkt);
+   pkt->pkttype = PKT_USER_ID;
+   pkt->pkt.user_id = xmalloc_clear (sizeof *pkt->pkt.user_id + n);
+   pkt->pkt.user_id->len = n;
+@@ -2860,7 +2861,10 @@ ask_expire_interval(int object,const char *def_expire)
+ 	    xfree(prompt);
+ 
+ 	    if(*answer=='\0')
+-	      answer=xstrdup(def_expire);
++              {
++                xfree (answer);
++	        answer = xstrdup (def_expire);
++              }
+ 	  }
+ 	cpr_kill_prompt();
+ 	trim_spaces(answer);
+@@ -5238,12 +5242,15 @@ card_store_key_with_backup (ctrl_t ctrl, PKT_public_key *sub_psk,
+   epoch2isotime (timestamp, (time_t)sk->timestamp);
+   err = hexkeygrip_from_pk (sk, &hexgrip);
+   if (err)
+-    return err;
++    goto leave;
+ 
+   memset(&info, 0, sizeof (info));
+   rc = agent_scd_getattr ("SERIALNO", &info);
+   if (rc)
+-    return (gpg_error_t)rc;
++    {
++      err = (gpg_error_t)rc;
++      goto leave;
++    }
+ 
+   rc = agent_keytocard (hexgrip, 2, 1, info.serialno, timestamp);
+   xfree (info.serialno);
+diff --git a/g10/keyserver.c b/g10/keyserver.c
+index c56021691..a20ebf24e 100644
+--- a/g10/keyserver.c
++++ b/g10/keyserver.c
+@@ -284,7 +284,7 @@ parse_keyserver_uri (const char *string,int require_scheme)
+   if(*idx=='\0' || *idx=='[')
+     {
+       if(require_scheme)
+-	return NULL;
++	goto fail;
+ 
+       /* Assume HKP if there is no scheme */
+       assume_hkp=1;
+diff --git a/g10/revoke.c b/g10/revoke.c
+index c0a003b6f..d6cbf93cb 100644
+--- a/g10/revoke.c
++++ b/g10/revoke.c
+@@ -435,6 +435,7 @@ gen_desig_revoke (ctrl_t ctrl, const char *uname, strlist_t locusr)
+ 	iobuf_close(out);
+     release_revocation_reason_info( reason );
+     release_armor_context (afx);
++    keydb_release (kdbhd);
+     return rc;
+ }
+ 
+@@ -804,7 +805,10 @@ ask_revocation_reason( int key_rev, int cert_rev, int hint )
+ 	    trim_spaces( answer );
+ 	    cpr_kill_prompt();
+ 	    if( *answer == 'q' || *answer == 'Q')
+-	      return NULL; /* cancel */
++              {
++                xfree (answer);
++                return NULL; /* cancel */
++              }
+ 	    if( hint && !*answer )
+ 		n = hint;
+ 	    else if(!digitp( answer ) )
+diff --git a/g10/tofu.c b/g10/tofu.c
+index f49083844..83786a08d 100644
+--- a/g10/tofu.c
++++ b/g10/tofu.c
+@@ -1687,6 +1687,8 @@ ask_about_binding (ctrl_t ctrl,
+          GPGSQL_ARG_END);
+       if (rc)
+         {
++          sqlite3_free (sqerr);
++          sqerr = NULL;
+           rc = gpg_error (GPG_ERR_GENERAL);
+           break;
+         }
+@@ -1972,6 +1974,7 @@ ask_about_binding (ctrl_t ctrl,
+       else if (!response[0])
+         /* Default to unknown.  Don't save it.  */
+         {
++          xfree (response);
+           tty_printf (_("Defaulting to unknown.\n"));
+           *policy = TOFU_POLICY_UNKNOWN;
+           break;
+@@ -1983,6 +1986,7 @@ ask_about_binding (ctrl_t ctrl,
+           if (choice)
+             {
+               int c = ((size_t) choice - (size_t) choices) / 2;
++              xfree (response);
+ 
+               switch (c)
+                 {
+diff --git a/g10/trustdb.c b/g10/trustdb.c
+index 43bce0769..9ef4644bf 100644
+--- a/g10/trustdb.c
++++ b/g10/trustdb.c
+@@ -1430,6 +1430,7 @@ ask_ownertrust (ctrl_t ctrl, u32 *kid, int minimum)
+     {
+       log_error (_("public key %s not found: %s\n"),
+                  keystr(kid), gpg_strerror (rc) );
++      free_public_key (pk);
+       return TRUST_UNKNOWN;
+     }
+ 
+-- 
+2.30.2
+
+
+From 0dabf0cffb1d67812c50a4f727398b59f93270a6 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Mon, 12 Apr 2021 14:05:17 +0200
+Subject: [PATCH GnuPG 04/19] sm: Avoid memory leaks and double double-free
+
+* sm/certcheck.c (extract_pss_params): Avoid double free
+* sm/decrypt.c (gpgsm_decrypt): goto leave instead of return
+* sm/encrypt.c (encrypt_dek): release s_pkey
+* sm/server.c (cmd_export): free list
+  (do_listkeys): free lists
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ sm/certcheck.c |  1 -
+ sm/decrypt.c   |  5 ++++-
+ sm/encrypt.c   |  1 +
+ sm/server.c    | 24 +++++++++++++++++++-----
+ 4 files changed, 24 insertions(+), 7 deletions(-)
+
+diff --git a/sm/certcheck.c b/sm/certcheck.c
+index fca45759b..f4db858c3 100644
+--- a/sm/certcheck.c
++++ b/sm/certcheck.c
+@@ -294,7 +294,6 @@ extract_pss_params (gcry_sexp_t s_sig, int *r_algo, unsigned int *r_saltlen)
+   if (*r_saltlen < 20)
+     {
+       log_error ("length of PSS salt too short\n");
+-      gcry_sexp_release (s_sig);
+       return gpg_error (GPG_ERR_DIGEST_ALGO);
+     }
+   if (!*r_algo)
+diff --git a/sm/decrypt.c b/sm/decrypt.c
+index aa91b370d..f7f91c466 100644
+--- a/sm/decrypt.c
++++ b/sm/decrypt.c
+@@ -755,7 +755,10 @@ gpgsm_decrypt (ctrl_t ctrl, int in_fd, estream_t out_fp)
+           dfparm.mode = mode;
+           dfparm.blklen = gcry_cipher_get_algo_blklen (algo);
+           if (dfparm.blklen > sizeof (dfparm.helpblock))
+-            return gpg_error (GPG_ERR_BUG);
++            {
++              rc = gpg_error (GPG_ERR_BUG);
++              goto leave;
++            }
+ 
+           rc = ksba_cms_get_content_enc_iv (cms,
+                                             dfparm.iv,
+diff --git a/sm/encrypt.c b/sm/encrypt.c
+index 92ca341f5..ba2428e9a 100644
+--- a/sm/encrypt.c
++++ b/sm/encrypt.c
+@@ -473,6 +473,7 @@ encrypt_dek (const DEK dek, ksba_cert_t cert, int pk_algo,
+       rc = encode_session_key (dek, &s_data);
+       if (rc)
+         {
++          gcry_sexp_release (s_pkey);
+           log_error ("encode_session_key failed: %s\n", gpg_strerror (rc));
+           return rc;
+         }
+diff --git a/sm/server.c b/sm/server.c
+index 874f0db89..871cc4b31 100644
+--- a/sm/server.c
++++ b/sm/server.c
+@@ -724,8 +724,13 @@ cmd_export (assuan_context_t ctx, char *line)
+ 
+   if (opt_secret)
+     {
+-      if (!list || !*list->d)
++      if (!list)
+         return set_error (GPG_ERR_NO_DATA, "No key given");
++      if (!*list->d)
++        {
++          free_strlist (list);
++          return set_error (GPG_ERR_NO_DATA, "No key given");
++        }
+       if (list->next)
+         return set_error (GPG_ERR_TOO_MANY, "Only one key allowed");
+   }
+@@ -1014,17 +1019,26 @@ do_listkeys (assuan_context_t ctx, char *line, int mode)
+       int outfd = translate_sys2libc_fd (assuan_get_output_fd (ctx), 1);
+ 
+       if ( outfd == -1 )
+-        return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
++        {
++          free_strlist (list);
++          return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
++        }
+       fp = es_fdopen_nc (outfd, "w");
+       if (!fp)
+-        return set_error (gpg_err_code_from_syserror (), "es_fdopen() failed");
++        {
++          free_strlist (list);
++          return set_error (gpg_err_code_from_syserror (), "es_fdopen() failed");
++        }
+     }
+   else
+     {
+       fp = es_fopencookie (ctx, "w", data_line_cookie_functions);
+       if (!fp)
+-        return set_error (GPG_ERR_ASS_GENERAL,
+-                          "error setting up a data stream");
++        {
++          free_strlist (list);
++          return set_error (GPG_ERR_ASS_GENERAL,
++                            "error setting up a data stream");
++        }
+     }
+ 
+   ctrl->with_colons = 1;
+-- 
+2.30.2
+
+
+From febbe77870b51e4e1158ae9efeaa0f3aad69a495 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Mon, 12 Apr 2021 14:48:59 +0200
+Subject: [PATCH GnuPG 05/19] tools: Avoid memory leak sfrom gpgspilt
+
+* tools/gpgsplit.c (write_part): free blob
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ tools/gpgsplit.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/gpgsplit.c b/tools/gpgsplit.c
+index cc7bf8ef5..93458068c 100644
+--- a/tools/gpgsplit.c
++++ b/tools/gpgsplit.c
+@@ -620,6 +620,7 @@ write_part (FILE *fpin, unsigned long pktlen,
+             }
+         }
+ 
++      xfree (blob);
+       goto ready;
+     }
+ 
+-- 
+2.30.2
+
+
+From 1cd048ba37786f46aabf3efdc3c245b75244dc26 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Mon, 12 Apr 2021 19:19:59 +0200
+Subject: [PATCH GnuPG 06/19] agent: Fix memory leaks
+
+* agent/call-daemon.c (daemon_start): free wctp
+* agent/call-scd.c (agent_card_pksign): return error instead of noop
+  (card_keyinfo_cb): free keyinfo
+* agent/protect.c (agent_get_shadow_info_type): allocate only as a last
+  action
+  (agent_is_tpm2_key): Free buf
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ agent/call-daemon.c |  2 ++
+ agent/call-scd.c    |  4 +++-
+ agent/protect.c     | 17 +++++++++--------
+ 3 files changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/agent/call-daemon.c b/agent/call-daemon.c
+index 144400875..3bf6bb793 100644
+--- a/agent/call-daemon.c
++++ b/agent/call-daemon.c
+@@ -512,6 +512,8 @@ daemon_start (enum daemon_type type, ctrl_t ctrl)
+           log_error ("error spawning wait_child_thread: %s\n", strerror (err));
+         npth_attr_destroy (&tattr);
+       }
++    else
++      xfree (wctp);
+   }
+ 
+  leave:
+diff --git a/agent/call-scd.c b/agent/call-scd.c
+index 3ede33c1d..f060541a3 100644
+--- a/agent/call-scd.c
++++ b/agent/call-scd.c
+@@ -487,7 +487,7 @@ agent_card_pksign (ctrl_t ctrl,
+   /* FIXME: In the mdalgo case (INDATA,INDATALEN) might be long and
+    * thus we can't convey it on a single Assuan line.  */
+   if (!mdalgo)
+-    gpg_error (GPG_ERR_NOT_IMPLEMENTED);
++    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ 
+   if (indatalen*2 + 50 > DIM(line))
+     return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
+@@ -941,6 +941,7 @@ card_keyinfo_cb (void *opaque, const char *line)
+       if (!keyinfo)
+         {
+         alloc_error:
++          xfree (keyinfo);
+           if (!parm->error)
+             parm->error = gpg_error_from_syserror ();
+           return 0;
+@@ -952,6 +953,7 @@ card_keyinfo_cb (void *opaque, const char *line)
+       if (n != 40)
+         {
+         parm_error:
++          xfree (keyinfo);
+           if (!parm->error)
+             parm->error = gpg_error (GPG_ERR_ASS_PARAMETER);
+           return 0;
+diff --git a/agent/protect.c b/agent/protect.c
+index 50b10eb26..72169429d 100644
+--- a/agent/protect.c
++++ b/agent/protect.c
+@@ -1663,13 +1663,6 @@ agent_get_shadow_info_type (const unsigned char *shadowkey,
+   n = snext (&s);
+   if (!n)
+     return gpg_error (GPG_ERR_INV_SEXP);
+-  if (shadow_type) {
+-    char *buf = xtrymalloc(n+1);
+-    memcpy(buf, s, n);
+-    buf[n] = '\0';
+-    *shadow_type = buf;
+-  }
+-
+   if (smatch (&s, n, "t1-v1") || smatch(&s, n, "tpm2-v1"))
+     {
+       if (*s != '(')
+@@ -1679,6 +1672,14 @@ agent_get_shadow_info_type (const unsigned char *shadowkey,
+     }
+   else
+     return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
++
++  if (shadow_type) {
++    char *buf = xtrymalloc(n+1);
++    memcpy(buf, s, n);
++    buf[n] = '\0';
++    *shadow_type = buf;
++  }
++
+   return 0;
+ }
+ 
+@@ -1704,9 +1705,9 @@ agent_is_tpm2_key (gcry_sexp_t s_skey)
+     return 0;
+ 
+   err = agent_get_shadow_info_type (buf, NULL, &type);
++  xfree (buf);
+   if (err)
+     return 0;
+-  xfree (buf);
+ 
+   err = strcmp (type, "tpm2-v1") == 0;
+   xfree (type);
+-- 
+2.30.2
+
+
+From 9d206e1dfabb965e97723dd799d0f7b3be04116d Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Mon, 12 Apr 2021 19:29:21 +0200
+Subject: [PATCH GnuPG 07/19] common: Avoid double-free
+
+* common/name-value.c (do_nvc_parse): reset to null after ownership
+  change
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ common/name-value.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/common/name-value.c b/common/name-value.c
+index 0bd205b7d..39c3244e9 100644
+--- a/common/name-value.c
++++ b/common/name-value.c
+@@ -724,6 +724,7 @@ do_nvc_parse (nvc_t *result, int *errlinep, estream_t stream,
+       if (raw_value)
+ 	{
+ 	  err = _nvc_add (*result, name, NULL, raw_value, 1);
++          name = NULL;
+ 	  if (err)
+ 	    goto leave;
+ 	}
+-- 
+2.30.2
+
+
+From 33317744850d10a03ad4215a329a7d4bc3837234 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Mon, 12 Apr 2021 19:48:31 +0200
+Subject: [PATCH GnuPG 08/19] dirmgr: Avoid double free
+
+* dirmgr/http.c (http_prepare_redirect): Avoid double free
+* dirmgr/ocsp.c (check_signature): Initialize pointer
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ dirmngr/http.c | 2 --
+ dirmngr/ocsp.c | 2 +-
+ 2 files changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/dirmngr/http.c b/dirmngr/http.c
+index 74ce5f465..c662b1b95 100644
+--- a/dirmngr/http.c
++++ b/dirmngr/http.c
+@@ -3681,7 +3681,6 @@ http_prepare_redirect (http_redir_info_t *info, unsigned int status_code,
+       if (!newurl)
+         {
+           err = gpg_error_from_syserror ();
+-          http_release_parsed_uri (locuri);
+           return err;
+         }
+     }
+@@ -3700,7 +3699,6 @@ http_prepare_redirect (http_redir_info_t *info, unsigned int status_code,
+       if (!newurl)
+         {
+           err = gpg_error_from_syserror ();
+-          http_release_parsed_uri (locuri);
+           return err;
+         }
+     }
+diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c
+index 6864f9854..6ec760d81 100644
+--- a/dirmngr/ocsp.c
++++ b/dirmngr/ocsp.c
+@@ -450,7 +450,7 @@ check_signature (ctrl_t ctrl,
+ {
+   gpg_error_t err;
+   int algo, cert_idx;
+-  gcry_sexp_t s_hash;
++  gcry_sexp_t s_hash = NULL;
+   ksba_cert_t cert;
+   const char *s;
+ 
+-- 
+2.30.2
+
+
+From c87d40395b8f24426645cc491dca5cf910755395 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Mon, 12 Apr 2021 20:05:48 +0200
+Subject: [PATCH GnuPG 09/19] g10: Avoid memory leaks
+
+* g10/call-agent.c (card_keyinfo_cb): free keyinfo
+* g10/keyedit.c (menu_set_keyserver_url): properly enclose the block
+* g10/keygen.c (gen_card_key): free pk and pkt
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ g10/call-agent.c |  2 ++
+ g10/keyedit.c    |  8 +++++---
+ g10/keygen.c     | 12 ++++++++++--
+ 3 files changed, 17 insertions(+), 5 deletions(-)
+
+diff --git a/g10/call-agent.c b/g10/call-agent.c
+index 83355454a..c9cbcd4e5 100644
+--- a/g10/call-agent.c
++++ b/g10/call-agent.c
+@@ -1729,6 +1729,7 @@ card_keyinfo_cb (void *opaque, const char *line)
+       if (!keyinfo)
+         {
+         alloc_error:
++          xfree (keyinfo);
+           if (!parm->error)
+             parm->error = gpg_error_from_syserror ();
+           return 0;
+@@ -1740,6 +1741,7 @@ card_keyinfo_cb (void *opaque, const char *line)
+       if (n != 40)
+         {
+         parm_error:
++          xfree (keyinfo);
+           if (!parm->error)
+             parm->error = gpg_error (GPG_ERR_ASS_PARAMETER);
+           return 0;
+diff --git a/g10/keyedit.c b/g10/keyedit.c
+index 902741b5f..91731a271 100644
+--- a/g10/keyedit.c
++++ b/g10/keyedit.c
+@@ -5382,14 +5382,16 @@ menu_set_keyserver_url (ctrl_t ctrl, const char *url, kbnode_t pub_keyblock)
+                            uri
+                            ? _("Are you sure you want to replace it? (y/N) ")
+                            : _("Are you sure you want to delete it? (y/N) ")))
+-	                xfree (user);
+-			continue;
++		        {
++			  xfree (user);
++			  continue;
++		        }
+ 		    }
+ 		  else if (uri == NULL)
+ 		    {
+ 		      /* There is no current keyserver URL, so there
+ 		         is no point in trying to un-set it. */
+-	              xfree (user);
++		      xfree (user);
+ 		      continue;
+ 		    }
+ 
+diff --git a/g10/keygen.c b/g10/keygen.c
+index f1e4d3638..82f6bb880 100644
+--- a/g10/keygen.c
++++ b/g10/keygen.c
+@@ -6140,12 +6140,20 @@ gen_card_key (int keyno, int algo, int is_primary, kbnode_t pub_root,
+      the self-signatures. */
+   err = agent_readkey (NULL, 1, keyid, &public);
+   if (err)
+-    return err;
++    {
++      xfree (pkt);
++      xfree (pk);
++      return err;
++    }
+   err = gcry_sexp_sscan (&s_key, NULL, public,
+                          gcry_sexp_canon_len (public, 0, NULL, NULL));
+   xfree (public);
+   if (err)
+-    return err;
++    {
++      xfree (pkt);
++      xfree (pk);
++      return err;
++    }
+ 
+   if (algo == PUBKEY_ALGO_RSA)
+     err = key_from_sexp (pk->pkey, s_key, "public-key", "ne");
+-- 
+2.30.2
+
+
+From bb6e1e13d9440816c60013a50d426b7ccd6c0288 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Mon, 12 Apr 2021 21:59:17 +0200
+Subject: [PATCH GnuPG 10/19] kbx: Avoid uninitialized read
+
+* kbx/kbx-client-util.c (datastream_thread): Initialize pointer
+* kbx/keybox-dump.c (_keybox_dump_cut_records): free blob
+* kbx/kbxserver.c (kbxd_start_command_handler): do not free passed ctrl
+* kbx/keyboxd.c (check_own_socket): free sockname
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ kbx/kbx-client-util.c | 2 +-
+ kbx/kbxserver.c       | 1 -
+ kbx/keybox-dump.c     | 4 +++-
+ kbx/keyboxd.c         | 5 ++++-
+ 4 files changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/kbx/kbx-client-util.c b/kbx/kbx-client-util.c
+index bd71cf2ba..07370319b 100644
+--- a/kbx/kbx-client-util.c
++++ b/kbx/kbx-client-util.c
+@@ -176,7 +176,7 @@ datastream_thread (void *arg)
+   int rc;
+   unsigned char lenbuf[4];
+   size_t nread, datalen;
+-  char *data, *tmpdata;
++  char *data = NULL, *tmpdata;
+ 
+   /* log_debug ("%s: started\n", __func__); */
+   while (kcd->fp)
+diff --git a/kbx/kbxserver.c b/kbx/kbxserver.c
+index 55b478586..0b76cde31 100644
+--- a/kbx/kbxserver.c
++++ b/kbx/kbxserver.c
+@@ -844,7 +844,6 @@ kbxd_start_command_handler (ctrl_t ctrl, gnupg_fd_t fd, unsigned int session_id)
+     {
+       log_error (_("can't allocate control structure: %s\n"),
+                  gpg_strerror (gpg_error_from_syserror ()));
+-      xfree (ctrl);
+       return;
+     }
+   ctrl->server_local->client_pid = ASSUAN_INVALID_PID;
+diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c
+index 3e66b72a1..38608ceaa 100644
+--- a/kbx/keybox-dump.c
++++ b/kbx/keybox-dump.c
+@@ -881,7 +881,7 @@ _keybox_dump_cut_records (const char *filename, unsigned long from,
+                           unsigned long to, FILE *outfp)
+ {
+   estream_t fp;
+-  KEYBOXBLOB blob;
++  KEYBOXBLOB blob = NULL;
+   int rc;
+   unsigned long recno = 0;
+ 
+@@ -902,6 +902,7 @@ _keybox_dump_cut_records (const char *filename, unsigned long from,
+             }
+         }
+       _keybox_release_blob (blob);
++      blob = NULL;
+       recno++;
+     }
+   if (rc == -1)
+@@ -909,6 +910,7 @@ _keybox_dump_cut_records (const char *filename, unsigned long from,
+   if (rc)
+     fprintf (stderr, "error reading '%s': %s\n", filename, gpg_strerror (rc));
+  leave:
++  _keybox_release_blob (blob);
+   if (fp != es_stdin)
+     es_fclose (fp);
+   return rc;
+diff --git a/kbx/keyboxd.c b/kbx/keyboxd.c
+index 76a0694a4..3f759e6f7 100644
+--- a/kbx/keyboxd.c
++++ b/kbx/keyboxd.c
+@@ -1795,7 +1795,10 @@ check_own_socket (void)
+ 
+   err = npth_attr_init (&tattr);
+   if (err)
+-    return;
++    {
++      xfree (sockname);
++      return;
++    }
+   npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
+   err = npth_create (&thread, &tattr, check_own_socket_thread, sockname);
+   if (err)
+-- 
+2.30.2
+
+
+From 7f54495586491b18b5e1088ecf5538c0343f90e7 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Tue, 13 Apr 2021 14:02:18 +0200
+Subject: [PATCH GnuPG 11/19] scd: avoid memory leaks
+
+* scd/app-p15.c (send_certinfo): free labelbuf
+  (do_sign): goto leave instead of return
+* scd/app-piv.c (do_sign): goto leave instead of return, fix typo in
+  variable name, avoid using uninitialized variables
+* scd/command.c (cmd_genkey): goto leave instead of return
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ scd/app-p15.c |  5 +++--
+ scd/app-piv.c |  6 +++---
+ scd/command.c | 10 ++++++++--
+ 3 files changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/scd/app-p15.c b/scd/app-p15.c
+index 90f6b4c99..9eeeed960 100644
+--- a/scd/app-p15.c
++++ b/scd/app-p15.c
+@@ -3851,6 +3851,7 @@ send_certinfo (app_t app, ctrl_t ctrl, const char *certtype,
+                         labelbuf, strlen (labelbuf),
+                         NULL, (size_t)0);
+       xfree (buf);
++      xfree (labelbuf);
+     }
+   return 0;
+ }
+@@ -5461,7 +5462,7 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo,
+   if (err)
+     {
+       log_error ("p15: MSE failed: %s\n", gpg_strerror (err));
+-      return err;
++      goto leave;
+     }
+ 
+   /* Now that we have all the information available run the actual PIN
+@@ -5500,7 +5501,7 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo,
+   if (err)
+     {
+       log_error ("p15: MSE failed: %s\n", gpg_strerror (err));
+-      return err;
++      goto leave;
+     }
+ 
+   if (prkdf->keyalgo == GCRY_PK_RSA && prkdf->keynbits > 2048)
+diff --git a/scd/app-piv.c b/scd/app-piv.c
+index ead1b1974..143cc047a 100644
+--- a/scd/app-piv.c
++++ b/scd/app-piv.c
+@@ -2175,7 +2175,7 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo,
+   unsigned char oidbuf[64];
+   size_t oidbuflen;
+   unsigned char *outdata = NULL;
+-  size_t outdatalen;
++  size_t outdatalen = 0;
+   const unsigned char *s;
+   size_t n;
+   int keyref, mechanism;
+@@ -2357,7 +2357,7 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo,
+   /* Now verify the Application PIN.  */
+   err = verify_chv (app, ctrl, 0x80, force_verify, pincb, pincb_arg);
+   if (err)
+-    return err;
++    goto leave;
+ 
+   /* Build the Dynamic Authentication Template.  */
+   err = concat_tlv_list (0, &apdudata, &apdudatalen,
+@@ -2403,7 +2403,7 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo,
+             goto bad_der;
+           log_assert (n >= (rval-s)+rlen);
+           sval = find_tlv (rval+rlen, n-((rval-s)+rlen), 0x02, &slen);
+-          if (!rval)
++          if (!sval)
+             goto bad_der;
+           rlenx = slenx = 0;
+           if (rlen > slen)
+diff --git a/scd/command.c b/scd/command.c
+index 11d61648b..cb0dd379a 100644
+--- a/scd/command.c
++++ b/scd/command.c
+@@ -1438,7 +1438,10 @@ cmd_genkey (assuan_context_t ctx, char *line)
+ 
+   line = skip_options (line);
+   if (!*line)
+-    return set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
++    {
++      err = set_error (GPG_ERR_ASS_PARAMETER, "no key number given");
++      goto leave;
++    }
+   keyref = line;
+   while (*line && !spacep (line))
+     line++;
+@@ -1448,7 +1451,10 @@ cmd_genkey (assuan_context_t ctx, char *line)
+     goto leave;
+ 
+   if (!ctrl->card_ctx)
+-    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
++    {
++      err = gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
++      goto leave;
++    }
+ 
+   keyref = keyref_buffer = xtrystrdup (keyref);
+   if (!keyref)
+-- 
+2.30.2
+
+
+From 3b2d9059b95ddb95a9e9fbaceb2f17c8be31d229 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Tue, 13 Apr 2021 14:50:13 +0200
+Subject: [PATCH GnuPG 12/19] tools: Intialize pointer to avoid double free
+
+* tools/gpg-card.c (cmd_salut): Initialize data pointer
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ tools/gpg-card.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/gpg-card.c b/tools/gpg-card.c
+index 1889fb45c..e84d2fbb0 100644
+--- a/tools/gpg-card.c
++++ b/tools/gpg-card.c
+@@ -1785,6 +1785,7 @@ cmd_salut (card_info_t info, const char *argstr)
+         {
+           tty_printf (_("Error: invalid response.\n"));
+           xfree (data);
++          data = NULL;
+           goto again;
+         }
+     }
+-- 
+2.30.2
+
+
+From 7c8048b686a6e811d0b24febf3c5e2528e7881f1 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Tue, 13 Apr 2021 16:23:31 +0200
+Subject: [PATCH GnuPG 14/19] dirmgr: Avoid memory leaks
+
+* dirmngr/domaininfo.c (insert_or_update): free di_new
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ dirmngr/domaininfo.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/dirmngr/domaininfo.c b/dirmngr/domaininfo.c
+index b41aef366..87782b4b1 100644
+--- a/dirmngr/domaininfo.c
++++ b/dirmngr/domaininfo.c
+@@ -193,6 +193,7 @@ insert_or_update (const char *domain,
+           log_error ("domaininfo: error allocating helper array: %s\n",
+                      gpg_strerror (gpg_err_code_from_syserror ()));
+           drop_extra = bucket;
++          xfree (di_new);
+           goto leave;
+         }
+       narray = 0;
+-- 
+2.30.2
+
+
+From ab3b8c53993b3305088efde756a44bac6e6492d4 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Tue, 13 Apr 2021 16:34:40 +0200
+Subject: [PATCH GnuPG 15/19] scd: Avoid memory leaks and uninitialized memory
+
+* scd/app-piv.c (do_decipher): goto leave, initialize outdatalen
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ scd/app-piv.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/scd/app-piv.c b/scd/app-piv.c
+index 143cc047a..94257f0ee 100644
+--- a/scd/app-piv.c
++++ b/scd/app-piv.c
+@@ -2483,7 +2483,7 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr,
+   gpg_error_t err;
+   data_object_t dobj;
+   unsigned char *outdata = NULL;
+-  size_t outdatalen;
++  size_t outdatalen = 0;
+   const unsigned char *s;
+   size_t n;
+   int keyref, mechanism;
+@@ -2582,7 +2582,7 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr,
+   /* Now verify the Application PIN.  */
+   err = verify_chv (app, ctrl, 0x80, 0, pincb, pincb_arg);
+   if (err)
+-    return err;
++    goto leave;
+ 
+   /* Build the Dynamic Authentication Template.  */
+   err = concat_tlv_list (0, &apdudata, &apdudatalen,
+-- 
+2.30.2
+
+
+From f182bf91443618323e34261039045a6bde269be5 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Tue, 13 Apr 2021 16:44:48 +0200
+Subject: [PATCH GnuPG 16/19] tools: Avoid memory leaks
+
+* tools/wks-util.c (wks_cmd_print_wkd_url): Free addrspec on error
+  (wks_cmd_print_wkd_hash): Free addrspec on error
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ tools/wks-util.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/tools/wks-util.c b/tools/wks-util.c
+index 516c7fe00..38dd194ff 100644
+--- a/tools/wks-util.c
++++ b/tools/wks-util.c
+@@ -1192,11 +1192,14 @@ gpg_error_t
+ wks_cmd_print_wkd_hash (const char *userid)
+ {
+   gpg_error_t err;
+-  char *addrspec, *fname;
++  char *addrspec = NULL, *fname;
+ 
+   err = wks_fname_from_userid (userid, 1, &fname, &addrspec);
+   if (err)
+-    return err;
++    {
++      xfree (addrspec);
++      return err;
++    }
+ 
+   es_printf ("%s %s\n", fname, addrspec);
+ 
+@@ -1211,12 +1214,15 @@ gpg_error_t
+ wks_cmd_print_wkd_url (const char *userid)
+ {
+   gpg_error_t err;
+-  char *addrspec, *fname;
++  char *addrspec = NULL, *fname;
+   char *domain;
+ 
+   err = wks_fname_from_userid (userid, 1, &fname, &addrspec);
+   if (err)
+-    return err;
++    {
++      xfree (addrspec);
++      return err;
++    }
+ 
+   domain = strchr (addrspec, '@');
+   if (domain)
+-- 
+2.30.2
+
+
+From 600fabd8268c765d45d48873e7a8610e6dae0966 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Wed, 14 Apr 2021 15:59:12 +0200
+Subject: [PATCH GnuPG 17/19] scd: Use the same allocator to free memory
+
+* scd/command.c (cmd_getinfo): Use free instead of gcry_free to match
+  the original allocator
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ scd/command.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/scd/command.c b/scd/command.c
+index cb0dd379a..9d85c5a41 100644
+--- a/scd/command.c
++++ b/scd/command.c
+@@ -1832,7 +1832,8 @@ cmd_getinfo (assuan_context_t ctx, char *line)
+         rc = assuan_send_data (ctx, p, strlen (p));
+       else
+         rc = gpg_error (GPG_ERR_NO_DATA);
+-      xfree (p);
++      /* allocated by scd/ccid-driver.c which is not using x*alloc/gcry_* */
++      free (p);
+     }
+   else if (!strcmp (line, "deny_admin"))
+     rc = opt.allow_admin? gpg_error (GPG_ERR_GENERAL) : 0;
+-- 
+2.30.2
+
+
+From f45f023495cb9947b2c31b5782a4063ad317c34c Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Wed, 14 Apr 2021 18:46:48 +0200
+Subject: [PATCH GnuPG 18/19] common: Mark identical branches as intential
+
+* common/tlv-builder.c (get_tlv_length): Mark identical branches as
+  inentional for coverity
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ common/tlv-builder.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/common/tlv-builder.c b/common/tlv-builder.c
+index 3b644ca24..59e2691e0 100644
+--- a/common/tlv-builder.c
++++ b/common/tlv-builder.c
+@@ -350,6 +350,7 @@ get_tlv_length (int class, int tag, int constructed, size_t length)
+ 
+   (void)constructed;  /* Not used, but passed for uniformity of such calls.  */
+ 
++  /* coverity[identical_branches] */
+   if (tag < 0x1f)
+     {
+       buflen++;
+-- 
+2.30.2
+
+
+From a94b0deab7c2ece2e512f87a52142454354d77b5 Mon Sep 17 00:00:00 2001
+From: Jakub Jelen <jjelen@redhat.com>
+Date: Wed, 14 Apr 2021 18:49:03 +0200
+Subject: [PATCH GnuPG 19/19] g10: Do not allocate memory when we can't return
+ it
+
+* g10/keyid.c (fpr20_from_pk): Do not allocate memory when we can't
+  return it
+
+--
+
+Signed-off-by: Jakub Jelen <jjelen@redhat.com>
+---
+ g10/keyid.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/g10/keyid.c b/g10/keyid.c
+index 522cc9cda..f1af2fd90 100644
+--- a/g10/keyid.c
++++ b/g10/keyid.c
+@@ -899,7 +899,7 @@ fpr20_from_pk (PKT_public_key *pk, byte array[20])
+     compute_fingerprint (pk);
+ 
+   if (!array)
+-    array = xmalloc (pk->fprlen);
++    return;
+ 
+   if (pk->fprlen == 32)         /* v5 fingerprint */
+     {
+-- 
+2.30.2
+
diff --git a/SOURCES/gnupg-2.2.23-large-rsa.patch b/SOURCES/gnupg-2.2.23-large-rsa.patch
new file mode 100644
index 0000000..47f861b
--- /dev/null
+++ b/SOURCES/gnupg-2.2.23-large-rsa.patch
@@ -0,0 +1,12 @@
+diff -up gnupg-2.2.23/g10/keygen.c.large-rsa gnupg-2.2.23/g10/keygen.c
+--- gnupg-2.2.23/g10/keygen.c.large-rsa	2020-09-04 13:53:42.030486671 +0200
++++ gnupg-2.2.23/g10/keygen.c	2020-09-04 13:55:52.896669542 +0200
+@@ -2262,7 +2262,7 @@ get_keysize_range (int algo, unsigned in
+ 
+     default:
+       *min = opt.compliance == CO_DE_VS ? 2048: 1024;
+-      *max = 4096;
++      *max = opt.flags.large_rsa == 1 ? 8192 : 4096;
+       def = 3072;
+       break;
+     }
diff --git a/SOURCES/gnupg-2.3.1-revert-default-eddsa.patch b/SOURCES/gnupg-2.3.1-revert-default-eddsa.patch
new file mode 100644
index 0000000..8a7776d
--- /dev/null
+++ b/SOURCES/gnupg-2.3.1-revert-default-eddsa.patch
@@ -0,0 +1,162 @@
+From ff31dde456f32950f0df6c974b4c41f1d650d68f Mon Sep 17 00:00:00 2001
+From: Werner Koch <wk@gnupg.org>
+Date: Mon, 5 Oct 2020 14:21:31 +0200
+Subject: [PATCH GnuPG] gpg: Switch to ed25519+cv25519 as default algo.
+
+* g10/keygen.c (DEFAULT_STD_KEY_PARAM): Change to former future
+default ago.
+(ask_algo): Change default and also the way we indicate the default
+algo in the list of algos.
+(ask_curve): Indicate the default curve.
+
+Signed-off-by: Werner Koch <wk@gnupg.org>
+---
+ g10/keygen.c | 57 ++++++++++++++++++++++++++--------------------------
+ 1 file changed, 29 insertions(+), 28 deletions(-)
+
+diff --git a/g10/keygen.c b/g10/keygen.c
+index 16e4e58ea..b510525e3 100644
+--- a/g10/keygen.c
++++ b/g10/keygen.c
+@@ -47,10 +47,11 @@
+ #include "../common/mbox-util.h"
+ 
+ 
+-/* The default algorithms.  If you change them, you should ensure the value
+-   is inside the bounds enforced by ask_keysize and gen_xxx.  See also
+-   get_keysize_range which encodes the allowed ranges.  */
+-#define DEFAULT_STD_KEY_PARAM  "rsa3072/cert,sign+rsa3072/encr"
++/* The default algorithms.  If you change them, you should ensure the
++   value is inside the bounds enforced by ask_keysize and gen_xxx.
++   See also get_keysize_range which encodes the allowed ranges.  The
++   default answer in ask_algo also needs to be adjusted.  */
++#define DEFAULT_STD_KEY_PARAM  "ed25519/cert,sign+cv25519/encr"
+ #define FUTURE_STD_KEY_PARAM   "ed25519/cert,sign+cv25519/encr"
+ 
+ /* When generating keys using the streamlined key generation dialog,
+@@ -2112,50 +2113,49 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
+ 
+ #if GPG_USE_RSA
+   if (!addmode)
+-    tty_printf (_("   (%d) RSA and RSA (default)\n"), 1 );
++    tty_printf (_("   (%d) RSA and RSA%s\n"), 1, "");
+ #endif
+ 
+   if (!addmode && opt.compliance != CO_DE_VS)
+-    tty_printf (_("   (%d) DSA and Elgamal\n"), 2 );
++    tty_printf (_("   (%d) DSA and Elgamal%s\n"), 2, "");
+ 
+   if (opt.compliance != CO_DE_VS)
+-    tty_printf (_("   (%d) DSA (sign only)\n"), 3 );
++    tty_printf (_("   (%d) DSA (sign only)%s\n"), 3, "");
+ #if GPG_USE_RSA
+-  tty_printf (_("   (%d) RSA (sign only)\n"), 4 );
++  tty_printf (_("   (%d) RSA (sign only)%s\n"), 4, "");
+ #endif
+ 
+   if (addmode)
+     {
+       if (opt.compliance != CO_DE_VS)
+-        tty_printf (_("   (%d) Elgamal (encrypt only)\n"), 5 );
++        tty_printf (_("   (%d) Elgamal (encrypt only)%s\n"), 5, "");
+ #if GPG_USE_RSA
+-      tty_printf (_("   (%d) RSA (encrypt only)\n"), 6 );
++      tty_printf (_("   (%d) RSA (encrypt only)%s\n"), 6, "");
+ #endif
+     }
+   if (opt.expert)
+     {
+       if (opt.compliance != CO_DE_VS)
+-        tty_printf (_("   (%d) DSA (set your own capabilities)\n"), 7 );
++        tty_printf (_("   (%d) DSA (set your own capabilities)%s\n"), 7, "");
+ #if GPG_USE_RSA
+-      tty_printf (_("   (%d) RSA (set your own capabilities)\n"), 8 );
++      tty_printf (_("   (%d) RSA (set your own capabilities)%s\n"), 8, "");
+ #endif
+     }
+ 
+ #if GPG_USE_ECDSA || GPG_USE_ECDH || GPG_USE_EDDSA
+-  if (opt.expert && !addmode)
+-    tty_printf (_("   (%d) ECC and ECC\n"), 9 );
+-  if (opt.expert)
+-    tty_printf (_("  (%d) ECC (sign only)\n"), 10 );
++  if (!addmode)
++    tty_printf (_("   (%d) ECC (sign and encrypt)%s\n"), 9, _(" *default*") );
++  tty_printf (_("  (%d) ECC (sign only)\n"), 10 );
+   if (opt.expert)
+-    tty_printf (_("  (%d) ECC (set your own capabilities)\n"), 11 );
+-  if (opt.expert && addmode)
+-    tty_printf (_("  (%d) ECC (encrypt only)\n"), 12 );
++    tty_printf (_("  (%d) ECC (set your own capabilities)%s\n"), 11, "");
++  if (addmode)
++    tty_printf (_("  (%d) ECC (encrypt only)%s\n"), 12, "");
+ #endif
+ 
+   if (opt.expert && r_keygrip)
+-    tty_printf (_("  (%d) Existing key\n"), 13 );
++    tty_printf (_("  (%d) Existing key%s\n"), 13, "");
+   if (r_keygrip)
+-    tty_printf (_("  (%d) Existing key from card\n"), 14 );
++    tty_printf (_("  (%d) Existing key from card%s\n"), 14, "");
+ 
+   for (;;)
+     {
+@@ -2164,7 +2164,7 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
+       xfree (answer);
+       answer = cpr_get ("keygen.algo", _("Your selection? "));
+       cpr_kill_prompt ();
+-      algo = *answer? atoi (answer) : 1;
++      algo = *answer? atoi (answer) : 9;  /* Default algo is 9 */
+ 
+       if (opt.compliance == CO_DE_VS
+           && (algo == 2 || algo == 3 || algo == 5 || algo == 7))
+@@ -2220,13 +2220,13 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
+           break;
+ 	}
+       else if ((algo == 9 || !strcmp (answer, "ecc+ecc"))
+-               && opt.expert && !addmode)
++               && !addmode)
+         {
+           algo = PUBKEY_ALGO_ECDSA;
+           *r_subkey_algo = PUBKEY_ALGO_ECDH;
+           break;
+ 	}
+-      else if ((algo == 10 || !strcmp (answer, "ecc/s")) && opt.expert)
++      else if ((algo == 10 || !strcmp (answer, "ecc/s")))
+         {
+           algo = PUBKEY_ALGO_ECDSA;
+           *r_usage = PUBKEY_USAGE_SIG;
+@@ -2239,7 +2239,7 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
+           break;
+ 	}
+       else if ((algo == 12 || !strcmp (answer, "ecc/e"))
+-               && opt.expert && addmode)
++               && addmode)
+         {
+           algo = PUBKEY_ALGO_ECDH;
+           *r_usage = PUBKEY_USAGE_ENC;
+@@ -2616,7 +2616,7 @@ ask_curve (int *algo, int *subkey_algo, const char *current)
+     { "NIST P-256",      NULL, NULL,               MY_USE_ECDSADH,  0, 1, 0 },
+     { "NIST P-384",      NULL, NULL,               MY_USE_ECDSADH,  0, 0, 0 },
+     { "NIST P-521",      NULL, NULL,               MY_USE_ECDSADH,  0, 1, 0 },
+-    { "brainpoolP256r1", NULL, "Brainpool P-256",  MY_USE_ECDSADH,  1, 1, 0 },
++    { "brainpoolP256r1", NULL, "Brainpool P-256",  MY_USE_ECDSADH,  1, 0, 0 },
+     { "brainpoolP384r1", NULL, "Brainpool P-384",  MY_USE_ECDSADH,  1, 1, 0 },
+     { "brainpoolP512r1", NULL, "Brainpool P-512",  MY_USE_ECDSADH,  1, 1, 0 },
+     { "secp256k1",       NULL, NULL,               MY_USE_ECDSADH,  0, 1, 0 },
+@@ -2672,9 +2672,10 @@ ask_curve (int *algo, int *subkey_algo, const char *current)
+         }
+ 
+       curves[idx].available = 1;
+-      tty_printf ("   (%d) %s\n", idx + 1,
++      tty_printf ("   (%d) %s%s\n", idx + 1,
+                   curves[idx].pretty_name?
+-                  curves[idx].pretty_name:curves[idx].name);
++                  curves[idx].pretty_name:curves[idx].name,
++                  idx == 0? _(" *default*"):"");
+     }
+   gcry_sexp_release (keyparms);
+ 
+-- 
+2.31.1
+
diff --git a/SOURCES/gnupg-2.3.1.tar.bz2.sig b/SOURCES/gnupg-2.3.1.tar.bz2.sig
new file mode 100644
index 0000000..300a3fc
Binary files /dev/null and b/SOURCES/gnupg-2.3.1.tar.bz2.sig differ
diff --git a/SPECS/gnupg2.spec b/SPECS/gnupg2.spec
new file mode 100644
index 0000000..4ad1985
--- /dev/null
+++ b/SPECS/gnupg2.spec
@@ -0,0 +1,877 @@
+%if 0%{?fedora} && 0%{?fedora} < 30
+%bcond_with unversioned_gpg
+%else
+%bcond_without unversioned_gpg
+%endif
+
+Summary: Utility for secure communication and data storage
+Name:    gnupg2
+Version: 2.3.1
+Release: 3%{?dist}
+
+License: GPLv3+
+Source0: https://gnupg.org/ftp/gcrypt/%{?pre:alpha/}gnupg/gnupg-%{version}%{?pre}.tar.bz2
+Source1: https://gnupg.org/ftp/gcrypt/%{?pre:alpha/}gnupg/gnupg-%{version}%{?pre}.tar.bz2.sig
+# needed for compatibility with system FIPS mode
+Patch3:  gnupg-2.1.10-secmem.patch
+# non-upstreamable patch adding file-is-digest option needed for Copr
+# https://dev.gnupg.org/T1646
+Patch4:  gnupg-2.2.20-file-is-digest.patch
+# fix handling of missing key usage on ocsp replies - upstream T1333
+Patch5:  gnupg-2.2.16-ocsp-keyusage.patch
+Patch6:  gnupg-2.1.1-fips-algo.patch
+# allow 8192 bit RSA keys in keygen UI with large RSA
+Patch9:  gnupg-2.2.23-large-rsa.patch
+# fix missing uid on refresh from keys.openpgp.org
+# https://salsa.debian.org/debian/gnupg2/commit/f292beac1171c6c77faf41d1f88c2e0942ed4437
+Patch20: gnupg-2.2.18-tests-add-test-cases-for-import-without-uid.patch
+Patch21: gnupg-2.2.18-gpg-allow-import-of-previously-known-keys-even-without-UI.patch
+Patch22: gnupg-2.2.18-gpg-accept-subkeys-with-a-good-revocation-but-no-self-sig.patch
+# Fixes for issues found in Coverity scan - reported upstream
+Patch30: gnupg-2.2.21-coverity.patch
+# Revert default EdDSA key types
+Patch31: gnupg-2.3.1-revert-default-eddsa.patch
+
+
+URL:     https://www.gnupg.org/
+
+#BuildRequires: automake libtool texinfo transfig
+BuildRequires: gcc
+BuildRequires: bzip2-devel
+BuildRequires: curl-devel
+BuildRequires: docbook-utils
+BuildRequires: gettext
+BuildRequires: libassuan-devel >= 2.1.0
+BuildRequires: libgcrypt-devel >= 1.9.1
+BuildRequires: libgpg-error-devel >= 1.38
+BuildRequires: libksba-devel >= 1.3.0
+BuildRequires: openldap-devel
+BuildRequires: libusb-devel
+BuildRequires: pcsc-lite-libs
+BuildRequires: npth-devel
+BuildRequires: readline-devel ncurses-devel
+BuildRequires: zlib-devel
+BuildRequires: gnutls-devel
+BuildRequires: sqlite-devel
+BuildRequires: fuse
+BuildRequires: make
+
+Requires: libgcrypt >= 1.7.0
+Requires: libgpg-error >= 1.38
+
+Suggests: pinentry
+
+Suggests: gnupg2-smime
+
+%if %{with unversioned_gpg}
+# pgp-tools, perl-GnuPG-Interface requires 'gpg' (not sure why) -- Rex
+Provides: gpg = %{version}-%{release}
+# Obsolete GnuPG-1 package
+Provides: gnupg = %{version}-%{release}
+Obsoletes: gnupg < 1.4.24
+%endif
+
+Provides: dirmngr = %{version}-%{release}
+Obsoletes: dirmngr < 1.2.0-1
+
+%{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/%{name}-%{version}}
+
+%package smime
+Summary: CMS encryption and signing tool and smart card support for GnuPG
+Requires: gnupg2%{?_isa} = %{version}-%{release}
+
+
+%description
+GnuPG is GNU's tool for secure communication and data storage.  It can
+be used to encrypt data and to create digital signatures.  It includes
+an advanced key management facility and is compliant with the proposed
+OpenPGP Internet standard as described in RFC2440 and the S/MIME
+standard as described by several RFCs.
+
+GnuPG 2.0 is a newer version of GnuPG with additional support for
+S/MIME.  It has a different design philosophy that splits
+functionality up into several modules. The S/MIME and smartcard functionality
+is provided by the gnupg2-smime package.
+
+%description smime
+GnuPG is GNU's tool for secure communication and data storage. This
+package adds support for smart cards and S/MIME encryption and signing
+to the base GnuPG package 
+
+%prep
+%setup -q -n gnupg-%{version}
+
+%patch3 -p1 -b .secmem
+%patch4 -p1 -b .file-is-digest
+%patch5 -p1 -b .keyusage
+%patch6 -p1 -b .fips
+%patch9 -p1 -b .large-rsa
+
+%patch20 -p1 -b .test_missing_uid
+%patch21 -p1 -b .prev_known_key
+%patch22 -p1 -b .good_revoc
+
+%patch30 -p1 -b .coverity
+%patch31 -p1 -R -b .eddsa
+
+# pcsc-lite library major: 0 in 1.2.0, 1 in 1.2.9+ (dlopen()'d in pcsc-wrapper)
+# Note: this is just the name of the default shared lib to load in scdaemon,
+# it can use other implementations too (including non-pcsc ones).
+%global pcsclib %(basename $(ls -1 %{_libdir}/libpcsclite.so.? 2>/dev/null ) 2>/dev/null )
+
+sed -i -e 's/"libpcsclite\.so"/"%{pcsclib}"/' scd/scdaemon.c
+
+
+%build
+# can not regenerate makefiles because of automake-1.16.3 requirement
+# ./autogen.sh
+%configure \
+%if %{without unversioned_gpg}
+  --enable-gpg-is-gpg2 \
+%endif
+  --disable-rpath \
+  --enable-g13 \
+  --enable-large-secmem
+
+# need scratch gpg database for tests
+mkdir -p $HOME/.gnupg
+
+%make_build
+
+
+%install
+%make_install \
+  docdir=%{_pkgdocdir}
+
+%if %{without unversioned_gpg}
+# rename file conflicting with gnupg-1.x
+rename gnupg.7 gnupg2.7 %{buildroot}%{_mandir}/man7/gnupg.7*
+%endif
+
+%find_lang %{name}
+
+# gpgconf.conf
+mkdir -p %{buildroot}%{_sysconfdir}/gnupg
+touch %{buildroot}%{_sysconfdir}/gnupg/gpgconf.conf
+
+# more docs
+install -m644 -p AUTHORS NEWS THANKS TODO \
+  %{buildroot}%{_pkgdocdir}
+
+%if %{with unversioned_gpg}
+# compat symlinks
+ln -sf gpg %{buildroot}%{_bindir}/gpg2
+ln -sf gpgv %{buildroot}%{_bindir}/gpgv2
+ln -sf gpg.1 %{buildroot}%{_mandir}/man1/gpg2.1
+ln -sf gpgv.1 %{buildroot}%{_mandir}/man1/gpgv2.1
+ln -sf gnupg.7 %{buildroot}%{_mandir}/man7/gnupg2.7
+%endif
+
+# info dir
+rm -f %{buildroot}%{_infodir}/dir
+
+# drop the gpg scheme interpreter
+rm -f %{buildroot}%{_bindir}/gpgscm
+
+# Move the systemd user units to appropriate directory
+install -d -m755 %{buildroot}%{_userunitdir}
+mv %{buildroot}%{_pkgdocdir}/examples/systemd-user/*.socket %{buildroot}%{_userunitdir}
+mv %{buildroot}%{_pkgdocdir}/examples/systemd-user/*.service %{buildroot}%{_userunitdir}
+
+%check
+# need scratch gpg database for tests
+mkdir -p $HOME/.gnupg
+make -k check
+
+
+%files -f %{name}.lang
+%license COPYING
+#doc AUTHORS NEWS README THANKS TODO
+%{_pkgdocdir}
+%dir %{_sysconfdir}/gnupg
+%ghost %config(noreplace) %{_sysconfdir}/gnupg/gpgconf.conf
+## docs say to install suid root, but fedora/rh security folk say not to
+%{_bindir}/gpg2
+%{_bindir}/gpgv2
+%{_bindir}/gpg-card
+%{_bindir}/gpg-connect-agent
+%{_bindir}/gpg-agent
+%{_bindir}/gpg-wks-client
+%{_bindir}/gpgconf
+%{_bindir}/gpgparsemail
+%{_bindir}/gpgtar
+%{_bindir}/g13
+%{_bindir}/dirmngr
+%{_bindir}/dirmngr-client
+%if %{with unversioned_gpg}
+%{_bindir}/gpg
+%{_bindir}/gpgv
+%{_bindir}/gpgsplit
+%endif
+%{_bindir}/watchgnupg
+%{_bindir}/gpg-wks-server
+%{_sbindir}/*
+%{_datadir}/gnupg/
+%{_libexecdir}/*
+%{_infodir}/*.info*
+%{_mandir}/man?/*
+%{_userunitdir}/*
+%exclude %{_mandir}/man?/gpgsm*
+
+%files smime
+%{_bindir}/gpgsm*
+%{_bindir}/kbxutil
+%{_mandir}/man?/gpgsm*
+
+
+%changelog
+* Wed Sep 08 2021 Jakub Jelen <jjelen@redhat.com> - 2.3.1-3
+- Revernt default key type back to RSA for FIPS compatibility (#2001937)
+
+* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 2.3.1-2
+- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
+  Related: rhbz#1991688
+
+* Wed Apr 21 2021 Jakub Jelen <jjelen@redhat.com> - 2.3.1-1
+- New upstream release (#1947159)
+
+* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 2.2.27-5
+- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
+
+* Mon Mar 29 2021 Jakub Jelen <jjelen@redhat.com> - 2.2.27-4
+- Add a configuration to not require exclusive access to PCSC
+
+* Thu Feb 18 2021 Jakub Jelen <jjelen@redhat.com> - 2.2.27-3
+- Bump required libgpg-error version (#1930110)
+
+* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.27-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
+
+* Tue Jan 12 2021 Jakub Jelen <jjelen@redhat.com> - 2.2.27-1
+- New upstream release (#1909825)
+
+* Mon Jan 04 2021 Jakub Jelen <jjelen@redhat.com> - 2.2.26-1
+- New upstream release (#1909825)
+
+* Tue Nov 24 2020 Jakub Jelen <jjelen@redhat.com> - 2.2.25-2
+- Enable gpgtar (#1901103)
+
+* Tue Nov 24 2020 Jakub Jelen <jjelen@redhat.com> - 2.2.25-1
+- Update to 2.2.25 (#1900815)
+
+* Thu Nov 19 2020 Jakub Jelen <jjelen@redhat.com> - 2.2.24-1
+- Update to 2.2.24 (#1898504)
+
+* Fri Sep  4 2020 Tomáš Mráz <tmraz@redhat.com> - 2.2.23-1
+- upgrade to 2.2.23
+
+* Sat Aug 01 2020 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.21-4
+- Second attempt - Rebuilt for
+  https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
+
+* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.21-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
+
+* Tue Jul 21 2020 Tom Stellard <tstellar@redhat.com> - 2.2.21-2
+- Use make macros
+- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
+
+* Mon Jul 20 2020 Tomáš Mráz <tmraz@redhat.com> - 2.2.21-1
+- upgrade to 2.2.21
+
+* Mon May  4 2020 Tomáš Mráz <tmraz@redhat.com> - 2.2.20-3
+- fixes for issues found in Coverity scan
+
+* Thu Apr 30 2020 Tomáš Mráz <tmraz@redhat.com> - 2.2.20-2
+- move systemd user units to _userunitdir (no activation by default)
+
+* Tue Apr 14 2020 Tomáš Mráz <tmraz@redhat.com> - 2.2.20-1
+- upgrade to 2.2.20
+
+* Wed Jan 29 2020 Tomáš Mráz <tmraz@redhat.com> - 2.2.19-1
+- upgrade to 2.2.19
+
+* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.18-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
+
+* Sat Jan  4 2020 Marcel Härry <mh+fedora@scrit.ch> - 2.2.18-3
+- Add patches to be able to deal with keys without uids (#1787708)
+
+* Fri Dec  6 2019 Tomáš Mráz <tmraz@redhat.com> - 2.2.18-2
+- fix abort when decrypting data with anonymous recipient (#1780057)
+
+* Tue Dec  3 2019 Tomáš Mráz <tmraz@redhat.com> - 2.2.18-1
+- upgrade to 2.2.18
+
+* Wed Nov  6 2019 Tomáš Mráz <tmraz@redhat.com> - 2.2.17-3
+- fix the gnupg(7) manual page (#1769072)
+
+* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.17-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
+
+* Mon Jul 15 2019 Tomáš Mráz <tmraz@redhat.com> - 2.2.17-1
+- upgrade to 2.2.17
+
+* Mon Jul  1 2019 Tomáš Mráz <tmraz@redhat.com> - 2.2.16-1
+- upgrade to 2.2.16
+
+* Tue Feb 26 2019 Tomáš Mráz <tmraz@redhat.com> - 2.2.13-1
+- upgrade to 2.2.13
+
+* Sun Feb 17 2019 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 2.2.12-3
+- Rebuild for readline 8.0
+
+* Mon Feb  4 2019 Tomáš Mráz <tmraz@redhat.com> - 2.2.12-2
+- make it build with gcc-9
+
+* Tue Jan  8 2019 Tomáš Mráz <tmraz@redhat.com> - 2.2.12-1
+- upgrade to 2.2.12
+
+* Sat Dec 08 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 2.2.11-2
+- Provide unversioned GPG on F30+
+
+* Fri Nov 30 2018 Tomáš Mráz <tmraz@redhat.com> - 2.2.11-1
+- upgrade to 2.2.11
+
+* Wed Aug  1 2018 Tomáš Mráz <tmraz@redhat.com> - 2.2.9-1
+- upgrade to 2.2.9
+
+* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.8-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
+
+* Mon Jun 11 2018 Tomáš Mráz <tmraz@redhat.com> - 2.2.8-1
+- upgrade to 2.2.8 fixing CVE 2018-12020
+
+* Wed Apr 11 2018 Tomáš Mráz <tmraz@redhat.com> - 2.2.6-1
+- upgrade to 2.2.6
+
+* Fri Mar  2 2018 Tomáš Mráz <tmraz@redhat.com> - 2.2.5-1
+- upgrade to 2.2.5
+
+* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.4-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Fri Jan 12 2018 Tomáš Mráz <tmraz@redhat.com> - 2.2.4-1
+- upgrade to 2.2.4
+
+* Tue Nov 21 2017 Tomáš Mráz <tmraz@redhat.com> - 2.2.3-1
+- upgrade to 2.2.3
+
+* Wed Nov  8 2017 Tomáš Mráz <tmraz@redhat.com> - 2.2.2-1
+- upgrade to 2.2.2
+
+* Tue Oct  3 2017 Tomáš Mráz <tmraz@redhat.com> - 2.2.1-1
+- upgrade to 2.2.1
+
+* Tue Sep  5 2017 Tomáš Mráz <tmraz@redhat.com> - 2.2.0-1
+- upgrade to 2.2.0
+
+* Wed Aug  9 2017 Tomáš Mráz <tmraz@redhat.com> - 2.1.22-1
+- upgrade to 2.1.22
+
+* Wed Aug 02 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.21-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Fri Jul 28 2017 Tomáš Mráz <tmraz@redhat.com> - 2.1.21-4
+- explictly remove gpgscm from the buildroot
+
+* Tue Jul 18 2017 Tomáš Mráz <tmraz@redhat.com> - 2.1.21-3
+- rebase the insttools patch
+- enable large secure memory support
+
+* Tue May 16 2017 Tomáš Mráz <tmraz@redhat.com> - 2.1.21-2
+- scdaemon is now needed by gpg
+
+* Tue May 16 2017 Tomáš Mráz <tmraz@redhat.com> - 2.1.21-1
+- upgrade to 2.1.21
+
+* Tue Apr 25 2017 Tomáš Mráz <tmraz@redhat.com> - 2.1.20-2
+- libdns aliasing issues fixed
+
+* Mon Apr 24 2017 Tomáš Mráz <tmraz@redhat.com> - 2.1.20-1
+- upgrade to 2.1.20
+- disable bundled libdns for now (#1444352)
+
+* Fri Mar 24 2017 Tomáš Mráz <tmraz@redhat.com> - 2.1.19-1
+- upgrade to 2.1.19
+- shorten time waiting on gpg-agent/dirmngr to start by exponential
+  backoff (#1431749)
+
+* Wed Mar  1 2017 Tomáš Mráz <tmraz@redhat.com> - 2.1.18-2
+- upgrade to 2.1.18
+
+* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.17-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Thu Jan 12 2017 Igor Gnatenko <ignatenko@redhat.com> - 2.1.17-2
+- Rebuild for readline 7.x
+
+* Thu Dec 22 2016 Tomáš Mráz <tmraz@redhat.com> - 2.1.17-1
+- upgrade to 2.1.17
+
+* Mon Nov 28 2016 Tomáš Mráz <tmraz@redhat.com> - 2.1.16-1
+- upgrade to 2.1.16
+
+* Mon Aug 22 2016 Tomáš Mráz <tmraz@redhat.com> - 2.1.13-2
+- avoid using libgcrypt without initialization (#1366909)
+
+* Tue Jul 12 2016 Tomáš Mráz <tmraz@redhat.com> - 2.1.13-1
+- upgrade to 2.1.13
+
+* Thu May  5 2016 Tomáš Mráz <tmraz@redhat.com> - 2.1.12-1
+- upgrade to 2.1.12
+
+* Tue Apr 12 2016 Tomáš Mráz <tmraz@redhat.com> - 2.1.11-4
+- make the pinentry dependency weak as for the public-key operations it
+  is not needed (#1324595)
+
+* Mon Mar  7 2016 Tomáš Mráz <tmraz@redhat.com> - 2.1.11-3
+- add recommends weak dependency for gnupg2-smime
+
+* Sat Mar  5 2016 Peter Robinson <pbrobinson@fedoraproject.org> 2.1.11-2
+- Don't ship ChangeLog, core details already covered in NEWS
+
+* Tue Feb 16 2016 Tomáš Mráz <tmraz@redhat.com> - 2.1.11-1
+- upgrade to 2.1.11
+
+* Wed Feb 03 2016 Fedora Release Engineering <releng@fedoraproject.org> - 2.1.10-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Wed Jan 13 2016 Dan Horák <dan[at]danny.cz> - 2.1.10-3
+- fix the insttools patch
+
+* Wed Jan 13 2016 Tomáš Mráz <tmraz@redhat.com> - 2.1.10-2
+- rebase the insttools patch needed for full gpgv1 replacement
+
+* Mon Dec  7 2015 Tomáš Mráz <tmraz@redhat.com> - 2.1.10-1
+- upgrade to 2.1.10
+
+* Mon Oct 12 2015 Tomáš Mráz <tmraz@redhat.com> - 2.1.9-1
+- upgrade to 2.1.9
+
+* Fri Sep 11 2015 Tomáš Mráz <tmraz@redhat.com> - 2.1.8-1
+- upgrade to 2.1.8
+
+* Thu Aug 13 2015 Tomáš Mráz <tmraz@redhat.com> - 2.1.7-1
+- upgrade to 2.1.7
+
+* Tue Aug 11 2015 Tomáš Mráz <tmraz@redhat.com> - 2.1.6-1
+- upgrade to 2.1.6
+
+* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.1.5-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Fri Jun 12 2015 Tomáš Mráz <tmraz@redhat.com> - 2.1.5-1
+- upgrade to 2.1.5
+
+* Tue May 26 2015 Tomáš Mráz <tmraz@redhat.com> - 2.1.4-2
+- use gnutls for TLS support in dirmngr (#1224816)
+
+* Fri May 15 2015 Robert Scheck <robert@fedoraproject.org> - 2.1.4-1
+- upgrade to 2.1.4 (#1192353)
+
+* Thu Apr 16 2015 Tomáš Mráz <tmraz@redhat.com> - 2.1.3-1
+- new upstream release fixing minor bugs
+
+* Sat Feb 21 2015 Till Maas <opensource@till.name> - 2.1.2-2
+- Rebuilt for Fedora 23 Change
+  https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code
+
+* Wed Feb 18 2015 Tomáš Mráz <tmraz@redhat.com> - 2.1.2-1
+- new upstream release fixing two minor security issues
+
+* Fri Jan 30 2015 Tomáš Mráz <tmraz@redhat.com> - 2.1.1-2
+- resolve conflict with gnupg by renaming conflicting manual page (#1187472)
+
+* Thu Jan 29 2015 Tomáš Mráz <tmraz@redhat.com> - 2.1.1-1
+- new upstream release
+- this release now includes the dirmngr which is obsoleted as separate package
+
+* Sat Aug 16 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.0.25-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Tue Aug  5 2014 Tomáš Mráz <tmraz@redhat.com> - 2.0.25-1
+- new upstream release fixing a minor regression introduced by the previous one
+- add --file-is-digest option needed for copr
+
+* Sat Jul 12 2014 Tom Callaway <spot@fedoraproject.org> - 2.0.24-2
+- fix license handling
+
+* Wed Jun 25 2014 Tomáš Mráz <tmraz@redhat.com> - 2.0.24-1
+- new upstream release fixing CVE-2014-4617
+
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.0.22-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Wed May  7 2014 Tomáš Mráz <tmraz@redhat.com> - 2.0.22-3
+- do not dump core if hash algorithm not available in the FIPS mode
+
+* Tue Mar  4 2014 Tomáš Mráz <tmraz@redhat.com> - 2.0.22-2
+- rebuilt against new libgcrypt
+
+* Tue Oct  8 2013 Tomáš Mráz <tmraz@redhat.com> - 2.0.22-1
+- new upstream release fixing CVE-2013-4402
+
+* Fri Aug 23 2013 Tomáš Mráz <tmraz@redhat.com> - 2.0.21-1
+- new upstream release
+
+* Wed Aug  7 2013 Tomas Mraz <tmraz@redhat.com> - 2.0.20-3
+- adjust to the unversioned docdir change (#993785)
+
+* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.0.20-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
+* Wed May 15 2013 Tomas Mraz <tmraz@redhat.com> - 2.0.20-1
+- new upstream release
+
+* Thu Feb 14 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.0.19-8
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
+* Wed Jan  2 2013 Tomas Mraz <tmraz@redhat.com> - 2.0.19-7
+- fix CVE-2012-6085 - skip invalid key packets (#891142)
+
+* Thu Nov 22 2012 Tomas Mraz <tmraz@redhat.com> - 2.0.19-6
+- use AES as default crypto algorithm in FIPS mode (#879047)
+
+* Fri Nov 16 2012 Jamie Nguyen <jamielinux@fedoraproject.org> - 2.0.19-5
+- rebuild for <f18 (#877106)
+
+* Fri Jul 27 2012 Tomas Mraz <tmraz@redhat.com> - 2.0.19-4
+- fix negated condition (#843842)
+
+* Thu Jul 26 2012 Tomas Mraz <tmraz@redhat.com> - 2.0.19-3
+- add compat symlinks and provides if built on RHEL
+
+* Thu Jul 19 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.0.19-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Tue Apr 24 2012 Tomas Mraz <tmraz@redhat.com> - 2.0.19-1
+- new upstream release
+- set environment in protect-tool (#548528)
+- do not reject OCSP signing certs without keyUsage (#720174)
+
+* Fri Jan 13 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.0.18-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Wed Oct 12 2011 Rex Dieter <rdieter@fedoraproject.org> 2.0.18-2
+- build with --enable-standard-socket
+
+* Wed Aug 17 2011 Tomas Mraz <tmraz@redhat.com> - 2.0.18-1
+- new upstream release (#728481)
+
+* Mon Jul 25 2011 Tomas Mraz <tmraz@redhat.com> - 2.0.17-2
+- fix a bug that shows up with the new libgcrypt release (#725369)
+
+* Thu Jan 20 2011 Tomas Mraz <tmraz@redhat.com> - 2.0.17-1
+- new upstream release (#669611)
+
+* Tue Aug 17 2010 Tomas Mraz <tmraz@redhat.com> - 2.0.16-3
+- drop the provides/obsoletes for gnupg
+- drop the man page file conflicting with gnupg-1.x
+
+* Fri Aug 13 2010 Tomas Mraz <tmraz@redhat.com> - 2.0.16-2
+- drop the compat symlinks as gnupg-1.x is revived
+
+* Tue Jul 27 2010 Rex Dieter <rdieter@fedoraproject.org> - 2.0.16-1
+- gnupg-2.0.16
+
+* Fri Jul 23 2010 Rex Dieter <rdieter@fedoraproject.org> - 2.0.14-4
+- gpgsm realloc patch (#617706)
+
+* Fri Jun 18 2010 Tomas Mraz <tmraz@redhat.com> - 2.0.14-3
+- initialize small amount of secmem for list of algorithms in help (#598847)
+  (necessary in the FIPS mode of libgcrypt)
+
+* Tue Feb  9 2010 Tomas Mraz <tmraz@redhat.com> - 2.0.14-2
+- disable selinux support - it is too rudimentary and restrictive (#562982)
+
+* Mon Jan 11 2010 Tomas Mraz <tmraz@redhat.com> - 2.0.14-1
+- new upstream version
+- fix a few tests so they do not need to execute gpg-agent
+
+* Tue Dec  8 2009 Michael Schwendt <mschwendt@fedoraproject.org> - 2.0.13-4
+- Explicitly BR libassuan-static in accordance with the Packaging
+  Guidelines (libassuan-devel is still static-only).
+
+* Fri Oct 23 2009 Tomas Mraz <tmraz@redhat.com> - 2.0.13-3
+- drop s390 specific ifnarchs as all the previously missing dependencies
+  are now there
+- split out gpgsm into a smime subpackage to reduce main package dependencies
+
+* Wed Oct 21 2009 Tomas Mraz <tmraz@redhat.com> - 2.0.13-2
+- provide/obsolete gnupg-1 and add compat symlinks to be able to drop
+  gnupg-1
+
+* Fri Sep 04 2009 Rex Dieter <rdieter@fedoraproject.org> - 2.0.13-1
+- gnupg-2.0.13
+- Unable to use gpg-agent + input methods (#228953)
+
+* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.0.12-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Wed Jun 17 2009 Rex Dieter <rdieter@fedoraproject.org> - 2.0.12-1
+- gnupg-2.0.12
+
+* Wed Mar 04 2009 Rex Dieter <rdieter@fedoraproject.org> - 2.0.11-1
+- gnupg-2.0.11
+
+* Tue Feb 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.0.10-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Sat Jan 31 2009 Karsten Hopp <karsten@redhat.com> 2.0.10-1
+- don't require pcsc-lite-libs and libusb on mainframe where
+  we don't have those packages as there's no hardware for that
+
+* Tue Jan 13 2009 Rex Dieter <rdieter@fedoraproject.org> 2.0.10-1
+- gnupg-2.0.10
+
+* Mon Aug 04 2008 Rex Dieter <rdieter@fedoraproject.org> 2.0.9-3
+- workaround rpm quirks 
+
+* Sat May 24 2008 Tom "spot" Callaway <tcallawa@redhat.com> 2.0.9-2
+- Patch from upstream to fix curl 7.18.1+ and gcc4.3+ compile error
+
+* Mon May 19 2008 Tom "spot" Callaway <tcallawa@redhat.com> 2.0.9-1.1
+- minor release bump for sparc rebuild
+
+* Wed Mar 26 2008 Rex Dieter <rdieter@fedoraproject.org> 2.0.9-1
+- gnupg2-2.0.9
+- drop Provides: openpgp
+- versioned Provides: gpg
+- own %%_sysconfdir/gnupg
+
+* Fri Feb 08 2008 Rex Dieter <rdieter@fedoraproject.org> 2.0.8-3 
+- respin (gcc43)
+
+* Wed Jan 23 2008 Rex Dieter <rdieter@fedoraproject.org> 2.0.8-2
+- avoid kde-filesystem dep (#427316)
+
+* Thu Dec 20 2007 Rex Dieter <rdieter[AT]fedoraproject.org> 2.0.8-1
+- gnupg2-2.0.8
+
+* Mon Dec 17 2007 Rex Dieter <rdieter[AT]fedoraproject.org> 2.0.8-0.1.rc1
+- gnupg2-2.0.8rc1
+
+* Tue Dec 04 2007 Rex Dieter <rdieter[AT]fedoraproject.org> 2.0.7-5
+- respin for openldap
+
+* Mon Nov 12 2007 Rex Dieter <rdieter[AT]fedoraproject.org> 2.0.7-4
+- Requires: kde-filesystem (#377841)
+
+* Wed Oct 03 2007 Rex Dieter <rdieter[AT]fedoraproject.org> 2.0.7-3
+- %%build: (re)add mkdir -p $HOME/.gnupg
+
+* Wed Oct 03 2007 Rex Dieter <rdieter[AT]fedoraproject.org> 2.0.7-2
+- Requires: dirmngr (#312831)
+
+* Mon Sep 10 2007 Rex Dieter <rdieter[AT]fedoraproject.org> 2.0.7-1
+- gnupg-2.0.7
+
+* Fri Aug 24 2007 Rex Dieter <rdieter[AT]fedoraproject.org> 2.0.6-2
+- respin (libassuan)
+
+* Thu Aug 16 2007 Rex Dieter <rdieter[AT]fedoraproject.org> 2.0.6-1
+- gnupg-2.0.6
+- License: GPLv3+
+
+* Thu Aug 02 2007 Rex Dieter <rdieter[AT]fedoraproject.org> 2.0.5-4
+- License: GPLv3
+
+* Mon Jul 16 2007 Rex Dieter <rdieter[AT]fedoraproject.org> 2.0.5-3
+- 2.0.5 too many open files fix
+
+* Fri Jul 06 2007 Rex Dieter <rdieter[AT]fedoraproject.org> 2.0.5-2
+- gnupg-2.0.5
+- gpg-agent not restarted after kde session crash/killed (#196327)
+- BR: libassuan-devel > 1.0.2, libksba-devel > 1.0.2
+
+* Fri May 18 2007 Rex Dieter <rdieter[AT]fedoraproject.org> 2.0.4-1
+- gnupg-2.0.4
+
+* Thu Mar 08 2007 Rex Dieter <rdieter[AT]fedoraproject.org> 2.0.3-1
+- gnupg-2.0.3
+
+* Fri Feb 02 2007 Rex Dieter <rdieter[AT]fedoraproject.org> 2.0.2-1
+- gnupg-2.0.2
+
+* Wed Dec 06 2006 Rex Dieter <rexdieter[AT]users.sf.net> 2.0.1-2
+- CVE-2006-6235 (#219934)
+
+* Wed Nov 29 2006 Rex Dieter <rexdieter[AT]users.sf.net> 2.0.1-1
+- gnupg-2.0.1
+- CVE-2006-6169 (#217950)
+
+* Sat Nov 25 2006 Rex Dieter <rexdieter[AT]users.sf.net> 2.0.1-0.3.rc1
+- gnupg-2.0.1rc1 
+
+* Thu Nov 16 2006 Rex Dieter <rexdieter[AT]users.sf.net> 2.0.0-4
+- update %%description
+- drop dearmor patch
+
+* Mon Nov 13 2006 Rex Dieter <rexdieter[AT]users.sf.net> 2.0.0-3
+- BR: libassuan-static >= 1.0.0
+
+* Mon Nov 13 2006 Rex Dieter <rexdieter[AT]users.sf.net> 2.0.0-2
+- gnupg-2.0.0
+
+* Fri Nov 10 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.95-3
+- upstream 64bit patch
+
+* Mon Nov 06 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.95-2
+- fix (more) file conflicts with gnupg
+
+* Mon Nov 06 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.95-1
+- 1.9.95
+
+* Wed Oct 25 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.94-1
+- 1.9.94
+
+* Wed Oct 18 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.93-1
+- 1.9.93
+
+* Wed Oct 11 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.92-2
+- fix file conflicts with gnupg
+
+* Wed Oct 11 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.92-1
+- 1.9.92
+
+* Tue Oct 10 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.91-4
+- make check ||: (apparently checks return err even on success?)
+
+* Tue Oct 10 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.91-3
+- --enable-selinux-support
+- x86_64: --disable-optimization (to avoid gpg2 segfaults), for now
+
+* Thu Oct 05 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.91-1
+- 1.9.91
+
+* Wed Oct 04 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.22-8
+- respin
+
+* Tue Sep 26 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.90-1
+- 1.9.90 (doesn't build, not released)
+
+* Mon Sep 18 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.23-1
+- 1.9.23 (doesn't build, not released)
+
+* Mon Sep 18 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.22-7
+- gpg-agent-startup.sh: fix case where valid .gpg-agent-info exists
+
+* Mon Sep 18 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.22-6
+- fix "syntax error in gpg-agent-startup.sh" (#206887)
+
+* Thu Sep 07 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.22-3
+- fc6 respin (for libksba-1.0)
+
+* Tue Aug 29 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.22-2
+- fc6 respin
+
+* Fri Jul 28 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.22-1
+- 1.9.22
+
+* Thu Jun 22 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.21-3
+- fix "gpg-agent not restarted after kde session crash/killed (#196327)
+
+* Thu Jun 22 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.21-2
+- 1.9.21
+- omit gpg2 binary to address CVS-2006-3082 (#196190)
+
+* Mon Mar  6 2006 Ville Skyttä <ville.skytta at iki.fi>> 1.9.20-3
+- Don't hardcode pcsc-lite lib name (#184123)
+
+* Thu Feb 16 2006 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.20-2
+- fc4+: use /etc/kde/(env|shutdown) for scripts (#175744)
+
+* Fri Feb 10 2006 Rex Dieter <rexdieter[AT]users.sf.net>
+- fc5: gcc/glibc respin
+
+* Tue Dec 20 2005 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.20-1
+- 1.9.20
+
+* Thu Dec 01 2005 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.19-8
+- include gpg-agent-(startup|shutdown) scripts (#136533)
+- BR: libksba-devel >= 1.9.12 
+- %%check: be permissive about failures (for now)
+
+* Wed Nov 30 2005 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.19-3
+- BR: libksba-devel >= 1.9.13
+
+* Tue Oct 11 2005 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.19-2
+- back to BR: libksba-devel = 1.9.11
+
+* Tue Oct 11 2005 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.19-1
+- 1.9.19
+
+* Fri Aug 26 2005 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.18-9
+- configure: NEED_KSBA_VERSION=0.9.12 -> 0.9.11
+
+* Fri Aug 26 2005 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.18-7
+- re-enable 'make check', rebuild against (older) libksba-0.9.11
+
+* Tue Aug  9 2005 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.18-6
+- don't 'make check' by default (regular builds pass, but FC4/5+plague fails)
+
+* Mon Aug  8 2005 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.18-5
+- 1.9.18
+- drop pth patch (--enable-gpg build fixed)
+- update description (from README)
+
+* Fri Jul  1 2005 Ville Skyttä <ville.skytta at iki.fi> - 1.9.17-1
+- 1.9.17, signal info patch applied upstream (#162264).
+- Patch to fix lvalue build error with gcc4 (upstream #485).
+- Patch scdaemon and pcsc-wrapper to load the versioned (non-devel)
+  pcsc-lite lib by default.
+
+* Fri May 13 2005 Michael Schwendt <mschwendt[AT]users.sf.net> - 1.9.16-3
+- Include upstream's patch for signal.c.
+
+* Tue May 10 2005 Michael Schwendt <mschwendt[AT]users.sf.net> - 1.9.16-1
+- Merge changes from Rex's 1.9.16-1 (Thu Apr 21):
+-   opensc support unconditional
+-   remove hard-coded .gz from %%post/%%postun
+-   add %%check section
+-   add pth patch
+- Put back patch modified from 1.9.15-4 to make tests verbose
+  and change signal.c to describe received signals better.
+
+* Sun May  8 2005 Michael Schwendt <mschwendt[AT]users.sf.net>
+- Drop patch0 again.
+
+* Sun May  8 2005 Michael Schwendt <mschwendt[AT]users.sf.net> - 1.9.15-4
+- Add patch0 temporarily to get some output from failing test.
+
+* Sat May  7 2005 David Woodhouse <dwmw2@infradead.org> 1.9.15-3
+- Rebuild.
+
+* Thu Apr  7 2005 Michael Schwendt <mschwendt[AT]users.sf.net>
+- rebuilt
+
+* Tue Feb  1 2005 Michael Schwendt <mschwendt[AT]users.sf.net> - 0:1.9.15-1
+- Make install-info in scriptlets less noisy.
+
+* Tue Jan 18 2005 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.15-0.fdr.1
+- 1.9.15
+
+* Fri Jan 07 2005 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.14-0.fdr.2
+- note patch/hack to build against older ( <1.0) libgpg-error-devel
+
+* Thu Jan 06 2005 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.14-0.fdr.1
+- 1.9.14
+- enable opensc support
+- BR: libassuan-devel >= 0.6.9
+
+* Thu Oct 21 2004 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.11-0.fdr.4
+- remove suid.
+
+* Thu Oct 21 2004 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.11-0.fdr.3
+- remove Provides: newpg
+
+* Wed Oct 20 2004 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.11-0.fdr.2
+- Requires: pinentry
+- gpg2 suid
+- update description
+
+* Tue Oct 19 2004 Rex Dieter <rexdieter[AT]users.sf.net> 1.9.11-0.fdr.1
+- first try
+- leave out opensc support (for now), enable --with-opensc
+