Better GPG error handling

This commit is contained in:
the-djmaze 2024-03-04 11:02:12 +01:00
parent 464d22d69a
commit d57300dd75
4 changed files with 30 additions and 43 deletions

View file

@ -362,9 +362,10 @@ abstract class Base
$result = $this->exec([
'--dry-run',
'--passwd',
$fingerprint
$passphrase
]);
*/
*/
// $this->export($keyId, $passphrase);
$this->pinentries[$keyId] = $passphrase;
// $this->pinentries[\substr($keyId, -16)] = $passphrase;
return $this;

View file

@ -238,14 +238,19 @@ class PGP extends Base implements \SnappyMail\PGP\PGPInterface
return false;
}
protected function _exportKey($keyId, bool $private = false)
/**
* Exports a public or private key
*/
public function export(string $fingerprint, ?SensitiveString $passphrase = null) /*: string|false*/
{
$keys = $this->keyInfo($keyId, $private);
// \SnappyMail\Log::debug('GnuPG', "export({$fingerprint}, {$passphrase})");
$private = null !== $passphrase;
$keys = $this->keyInfo($fingerprint, $private);
if (!$keys) {
throw new \Exception(($private ? 'Private' : 'Public') . ' key not found: ' . $keyId);
throw new \Exception(($private ? 'Private' : 'Public') . ' key not found: ' . $fingerprint);
}
if ($private && $this->pinentries) {
$_ENV['PINENTRY_USER_DATA'] = \json_encode(\array_map('strval', $this->pinentries));
if ($private) {
$_ENV['PINENTRY_USER_DATA'] = \json_encode([$fingerprint => \strval($passphrase)]);
}
$result = $this->exec([
$private ? '--export-secret-keys' : '--export',
@ -255,20 +260,6 @@ class PGP extends Base implements \SnappyMail\PGP\PGPInterface
return $result['output'];
}
/**
* Exports a public or private key
*/
public function export(string $fingerprint, ?SensitiveString $passphrase = null) /*: string|false*/
{
// \SnappyMail\Log::debug('GnuPG', "export({$fingerprint}, {$passphrase})");
if (null !== $passphrase) {
return $this
->addPinentry($fingerprint, $passphrase)
->_exportKey($fingerprint, true);
}
return $this->_exportKey($fingerprint);
}
/**
* Returns the errortext, if a function fails
*/
@ -1121,8 +1112,11 @@ class PGP extends Base implements \SnappyMail\PGP\PGPInterface
if (\in_array($fdError, $inputStreams, true)) {
$this->_debug('error stream ready for reading');
foreach ($this->_openPipes->readPipeLines(self::FD_ERROR) as $line) {
$errors[] = $line;
$this->_debug("\t{$line}");
$errors[] = \preg_replace('/^gpg: /', '', $line);
}
if ($throw && $errors) {
break;
}
}
@ -1188,7 +1182,7 @@ class PGP extends Base implements \SnappyMail\PGP\PGPInterface
$this->_output = null;
if ($throw && $exitCode && $errors) {
throw new \RuntimeException(\implode("\n", $errors), $exitCode);
throw new \RuntimeException(\implode(".\n", $errors), $exitCode);
}
return [

View file

@ -237,14 +237,18 @@ class SMIME extends Base
return false;
}
protected function _exportKey($keyId, bool $private = false)
/**
* Exports a public or private key
*/
public function export(string $fingerprint, ?SensitiveString $passphrase = null) /*: string|false*/
{
$keys = $this->keyInfo($keyId, $private);
$private = null !== $passphrase;
$keys = $this->keyInfo($fingerprint, $private);
if (!$keys) {
throw new \Exception(($private ? 'Private' : 'Public') . ' key not found: ' . $keyId);
throw new \Exception(($private ? 'Private' : 'Public') . ' key not found: ' . $fingerprint);
}
if ($private && $this->pinentries) {
$_ENV['PINENTRY_USER_DATA'] = \json_encode($this->pinentries);
if ($private) {
$_ENV['PINENTRY_USER_DATA'] = \json_encode([$fingerprint => \strval($passphrase)]);
}
$result = $this->exec([
$private ? '--export-secret-key-p12' : '--export',
@ -254,19 +258,6 @@ class SMIME extends Base
return $result['output'];
}
/**
* Exports a public or private key
*/
public function export(string $fingerprint, ?SensitiveString $passphrase = null) /*: string|false*/
{
if ($passphrase) {
return $this
->addPinentry($fingerprint, $passphrase)
->_exportKey($fingerprint, true);
}
return $this->_exportKey($fingerprint);
}
protected function _importKey($input) /*: array|false*/
{
$arguments = ['--import'];
@ -666,7 +657,7 @@ class SMIME extends Base
return $info['ENC_TO'];
}
private function exec(array $arguments) /*: array|false*/
private function exec(array $arguments, bool $throw = true) /*: array|false*/
{
if (\version_compare($this->version, '2.2.5', '<')) {
\SnappyMail\Log::error('GPG', "{$this->version} too old");

View file

@ -7,7 +7,8 @@ use SnappyMail\SensitiveString;
interface PGPInterface
{
public static function isSupported() : bool;
// public function addPinentry(string $keyId, SensitiveString $passphrase) : bool;
// public function addPinentry(string $keyId, SensitiveString $passphrase);
// public function clearPinentries() : bool
public function addDecryptKey(string $fingerprint, SensitiveString $passphrase) : bool;
public function addEncryptKey(string $fingerprint) : bool;
public function addSignKey(string $fingerprint, SensitiveString $passphrase) : bool;