From 5f0c7e7b7a3dc7b6a8a3e9ba1e085be7a94d3477 Mon Sep 17 00:00:00 2001
From: Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
Date: Mon, 23 Nov 2020 11:45:43 +0100
Subject: [PATCH] Horde_Crypt_Pgp_Backend: Fix generateKey() method with GnuPG
2.2 onwards.
The batch macros %secring and %pubring have been deprecated since GnuPG
2.1 and, in fact, %secring% is not available anymore starting with
GnuPG 2.2.x.
With GnuPG 2.1 and above, in the generateKey() method, we now don't
obtain the pub/secret keys directly from the ASCII keyring files
anymore, but generate the pub/secret key pair in the keyrings of the
ephemeral home directory and then export/obtain them from there (via
capturing stdout), instead.
See:
https://www.gnupg.org/documentation/manuals/gnupg/Unattended-GPG-key-generation.html
---
lib/Horde/Crypt/Pgp/Backend/Binary.php | 88 +++++++++++++++++++++-----
1 file changed, 73 insertions(+), 15 deletions(-)
diff --git a/lib/Horde/Crypt/Pgp/Backend/Binary.php b/lib/Horde/Crypt/Pgp/Backend/Binary.php
index 3116bfe..2c95877 100644
--- a/lib/Horde/Crypt/Pgp/Backend/Binary.php
+++ b/lib/Horde/Crypt/Pgp/Backend/Binary.php
@@ -119,21 +119,42 @@ extends Horde_Crypt_Pgp_Backend
? 0
: 'seconds=' . ($opts['expire'] - time());
+ $input = array();
+
+ if (!$this->_gnupg21) {
+ /*
+ * %secring and %pubring have been deprecated since GnuPG 2.1 and %secring% is not available
+ * anymore starting with GnuPG 2.2. For GnuPG 2.1 and above, we need to export
+ * the secret and the public key from the keyrings in the ephemeral home directory
+ * instead. See:
+ * https://www.gnupg.org/documentation/manuals/gnupg/Unattended-GPG-key-generation.html
+ */
+ $input = array_merge(
+ $input,
+ array(
+ '%secring '. $sec_file,
+ '%pubring ' . $pub_file,
+ )
+ );
+ }
+
/* Create the config file necessary for GnuPG to run in batch mode. */
/* TODO: Sanitize input, More user customizable? */
- $input = array(
- '%pubring ' . $pub_file,
- '%secring ' . $secret_file,
- 'Key-Type: ' . $opts['key_type'],
- 'Key-Length: ' . $opts['keylength'],
- 'Subkey-Type: ' . $opts['subkey_type'],
- 'Subkey-Length: ' . $opts['keylength'],
- 'Name-Real: ' . $opts['name'],
- 'Name-Email: ' . $opts['email'],
- 'Expire-Date: ' . $expire,
- 'Passphrase: ' . $opts['passphrase'],
- 'Preferences: AES256 AES192 AES CAST5 3DES SHA256 SHA512 SHA384 SHA224 SHA1 ZLIB BZIP2 ZIP Uncompressed'
+ $input = array_merge (
+ $input,
+ array(
+ 'Key-Type: ' . $opts['key_type'],
+ 'Key-Length: ' . $opts['keylength'],
+ 'Subkey-Type: ' . $opts['subkey_type'],
+ 'Subkey-Length: ' . $opts['keylength'],
+ 'Name-Real: ' . $opts['name'],
+ 'Name-Email: ' . $opts['email'],
+ 'Expire-Date: ' . $expire,
+ 'Passphrase: ' . $opts['passphrase'],
+ 'Preferences: AES256 AES192 AES CAST5 3DES SHA256 SHA512 SHA384 SHA224 SHA1 ZLIB BZIP2 ZIP Uncompressed'
+ )
);
+
if (!empty($opts['comment'])) {
$input[] = 'Name-Comment: ' . $opts['comment'];
}
@@ -152,9 +173,46 @@ extends Horde_Crypt_Pgp_Backend
true
);
- /* Get the keys from the temp files. */
- $public_key = file_get_contents($pub_file);
- $secret_key = file_get_contents($secret_file);
+ if ($this->_gnupg21) {
+
+ /* Export public key from the ephemeral home dir (see comment above for details). */
+
+ $result = $this->_callGpg(
+ array(
+ '--export',
+ '--armor'
+ ),
+ 'r',
+ array(),
+ true,
+ true
+ );
+ $this->_ensureResult($result);
+ $public_key = $result->output;
+
+ /* Export secret key from the ephemeral home dir (see comment above for details). */
+
+ $result = $this->_callGpg(
+ array(
+ '--export-secret-key',
+ '--passphrase "'.$opts['passphrase'].'"',
+ '--armor'
+ ),
+ 'r',
+ array(),
+ true,
+ true
+ );
+ $this->_ensureResult($result);
+ $secret_key = $result->output;
+
+ } else {
+
+ /* Get the keys from the temp files. */
+ $public_key = file_get_contents($pub_file);
+ $secret_key = file_get_contents($secret_file);
+
+ }
/* If either key is empty, something went wrong. */
if (empty($public_key) || empty($secret_key)) {
--
2.20.1