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