mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
GPG use pinentries for decrypt, sign and export
This commit is contained in:
parent
7d485813e5
commit
464d22d69a
4 changed files with 62 additions and 36 deletions
|
|
@ -43,10 +43,8 @@ abstract class Base
|
||||||
protected
|
protected
|
||||||
$binary,
|
$binary,
|
||||||
$version = '2.0',
|
$version = '2.0',
|
||||||
$passphrases = [],
|
$pinentries = [],
|
||||||
$signKeys = [],
|
|
||||||
$encryptKeys = [],
|
$encryptKeys = [],
|
||||||
$decryptKeys = [],
|
|
||||||
// Create PEM encoded output
|
// Create PEM encoded output
|
||||||
$armor = true,
|
$armor = true,
|
||||||
|
|
||||||
|
|
@ -284,8 +282,7 @@ abstract class Base
|
||||||
*/
|
*/
|
||||||
public function addDecryptKey(string $fingerprint, SensitiveString $passphrase) : bool
|
public function addDecryptKey(string $fingerprint, SensitiveString $passphrase) : bool
|
||||||
{
|
{
|
||||||
$this->decryptKeys[$fingerprint] = $passphrase;
|
$this->addPinentry($fingerprint, $passphrase);
|
||||||
// $this->decryptKeys[\substr($fingerprint, -16)] = $passphrase;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -303,9 +300,15 @@ abstract class Base
|
||||||
*/
|
*/
|
||||||
public function addSignKey(string $fingerprint, SensitiveString $passphrase) : bool
|
public function addSignKey(string $fingerprint, SensitiveString $passphrase) : bool
|
||||||
{
|
{
|
||||||
$this->signKeys[$fingerprint] = $passphrase;
|
$this->addPinentry($fingerprint, $passphrase);
|
||||||
// $this->signKeys[\substr($fingerprint, -16)] = $passphrase;
|
return true;
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
public function clear() : bool
|
||||||
|
{
|
||||||
|
$this->clearPinentries();
|
||||||
|
$this->clearEncryptKeys();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -313,8 +316,7 @@ abstract class Base
|
||||||
*/
|
*/
|
||||||
public function clearDecryptKeys() : bool
|
public function clearDecryptKeys() : bool
|
||||||
{
|
{
|
||||||
$this->decryptKeys = [];
|
return $this->clearPinentries();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -331,8 +333,7 @@ abstract class Base
|
||||||
*/
|
*/
|
||||||
public function clearSignKeys() : bool
|
public function clearSignKeys() : bool
|
||||||
{
|
{
|
||||||
$this->signKeys = [];
|
return $this->clearPinentries();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -348,12 +349,36 @@ abstract class Base
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addPassphrase($keyId, SensitiveString $passphrase)
|
/**
|
||||||
|
* Add private key passphrase for decrypt, sign or export
|
||||||
|
* $keyId or fingerprint
|
||||||
|
*/
|
||||||
|
public function addPinentry(string $keyId, SensitiveString $passphrase)
|
||||||
{
|
{
|
||||||
$this->passphrases[$keyId] = $passphrase;
|
/**
|
||||||
|
* Test first?
|
||||||
|
* gpg --dry-run --passwd <your-user-id>
|
||||||
|
$_ENV['PINENTRY_USER_DATA'] = \json_encode(\array_map('strval', [$keyId => $passphrase]));
|
||||||
|
$result = $this->exec([
|
||||||
|
'--dry-run',
|
||||||
|
'--passwd',
|
||||||
|
$fingerprint
|
||||||
|
]);
|
||||||
|
*/
|
||||||
|
$this->pinentries[$keyId] = $passphrase;
|
||||||
|
// $this->pinentries[\substr($keyId, -16)] = $passphrase;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all keys which were set for decryption, signing and export
|
||||||
|
*/
|
||||||
|
public function clearPinentries() : bool
|
||||||
|
{
|
||||||
|
$this->pinentries = [];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle the armored output
|
* Toggle the armored output
|
||||||
* When true the output is ASCII
|
* When true the output is ASCII
|
||||||
|
|
|
||||||
|
|
@ -96,8 +96,8 @@ class PGP extends Base implements \SnappyMail\PGP\PGPInterface
|
||||||
|
|
||||||
$fclose = $this->setOutput($output);
|
$fclose = $this->setOutput($output);
|
||||||
|
|
||||||
if ($this->decryptKeys) {
|
if ($this->pinentries) {
|
||||||
$_ENV['PINENTRY_USER_DATA'] = \json_encode(\array_map('strval', $this->decryptKeys));
|
$_ENV['PINENTRY_USER_DATA'] = \json_encode(\array_map('strval', $this->pinentries));
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->exec(['--decrypt','--skip-verify']);
|
$result = $this->exec(['--decrypt','--skip-verify']);
|
||||||
|
|
@ -244,8 +244,8 @@ class PGP extends Base implements \SnappyMail\PGP\PGPInterface
|
||||||
if (!$keys) {
|
if (!$keys) {
|
||||||
throw new \Exception(($private ? 'Private' : 'Public') . ' key not found: ' . $keyId);
|
throw new \Exception(($private ? 'Private' : 'Public') . ' key not found: ' . $keyId);
|
||||||
}
|
}
|
||||||
if ($private && $this->passphrases) {
|
if ($private && $this->pinentries) {
|
||||||
$_ENV['PINENTRY_USER_DATA'] = \json_encode(\array_map('strval', $this->passphrases));
|
$_ENV['PINENTRY_USER_DATA'] = \json_encode(\array_map('strval', $this->pinentries));
|
||||||
}
|
}
|
||||||
$result = $this->exec([
|
$result = $this->exec([
|
||||||
$private ? '--export-secret-keys' : '--export',
|
$private ? '--export-secret-keys' : '--export',
|
||||||
|
|
@ -263,7 +263,7 @@ class PGP extends Base implements \SnappyMail\PGP\PGPInterface
|
||||||
// \SnappyMail\Log::debug('GnuPG', "export({$fingerprint}, {$passphrase})");
|
// \SnappyMail\Log::debug('GnuPG', "export({$fingerprint}, {$passphrase})");
|
||||||
if (null !== $passphrase) {
|
if (null !== $passphrase) {
|
||||||
return $this
|
return $this
|
||||||
->addPassphrase($fingerprint, $passphrase)
|
->addPinentry($fingerprint, $passphrase)
|
||||||
->_exportKey($fingerprint, true);
|
->_exportKey($fingerprint, true);
|
||||||
}
|
}
|
||||||
return $this->_exportKey($fingerprint);
|
return $this->_exportKey($fingerprint);
|
||||||
|
|
@ -365,8 +365,8 @@ class PGP extends Base implements \SnappyMail\PGP\PGPInterface
|
||||||
{
|
{
|
||||||
$arguments = ['--import'];
|
$arguments = ['--import'];
|
||||||
|
|
||||||
if ($this->passphrases) {
|
if ($this->pinentries) {
|
||||||
$_ENV['PINENTRY_USER_DATA'] = \json_encode(\array_map('strval', $this->passphrases));
|
$_ENV['PINENTRY_USER_DATA'] = \json_encode(\array_map('strval', $this->pinentries));
|
||||||
} else {
|
} else {
|
||||||
$arguments[] = '--batch';
|
$arguments[] = '--batch';
|
||||||
}
|
}
|
||||||
|
|
@ -618,7 +618,7 @@ class PGP extends Base implements \SnappyMail\PGP\PGPInterface
|
||||||
|
|
||||||
protected function _sign(/*string|resource*/ $input, /*string|resource*/ $output = null, bool $textmode = true) /*: string|false*/
|
protected function _sign(/*string|resource*/ $input, /*string|resource*/ $output = null, bool $textmode = true) /*: string|false*/
|
||||||
{
|
{
|
||||||
if (empty($this->signKeys)) {
|
if (empty($this->pinentries)) {
|
||||||
throw new \Exception('No signing keys specified.');
|
throw new \Exception('No signing keys specified.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -649,11 +649,11 @@ class PGP extends Base implements \SnappyMail\PGP\PGPInterface
|
||||||
$arguments[] = '--textmode';
|
$arguments[] = '--textmode';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->signKeys) {
|
if ($this->pinentries) {
|
||||||
foreach ($this->signKeys as $fingerprint => $pass) {
|
foreach ($this->pinentries as $fingerprint => $pass) {
|
||||||
$arguments[] = '--local-user ' . \escapeshellarg($fingerprint);
|
$arguments[] = '--local-user ' . \escapeshellarg($fingerprint);
|
||||||
}
|
}
|
||||||
$_ENV['PINENTRY_USER_DATA'] = \json_encode(\array_map('strval', $this->signKeys));
|
$_ENV['PINENTRY_USER_DATA'] = \json_encode(\array_map('strval', $this->pinentries));
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->exec($arguments);
|
$result = $this->exec($arguments);
|
||||||
|
|
|
||||||
|
|
@ -97,8 +97,8 @@ class SMIME extends Base
|
||||||
|
|
||||||
$fclose = $this->setOutput($output);
|
$fclose = $this->setOutput($output);
|
||||||
|
|
||||||
if ($this->decryptKeys) {
|
if ($this->pinentries) {
|
||||||
$_ENV['PINENTRY_USER_DATA'] = \json_encode($this->decryptKeys);
|
$_ENV['PINENTRY_USER_DATA'] = \json_encode($this->pinentries);
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->exec(['--decrypt','--skip-verify']);
|
$result = $this->exec(['--decrypt','--skip-verify']);
|
||||||
|
|
@ -243,8 +243,8 @@ class SMIME extends Base
|
||||||
if (!$keys) {
|
if (!$keys) {
|
||||||
throw new \Exception(($private ? 'Private' : 'Public') . ' key not found: ' . $keyId);
|
throw new \Exception(($private ? 'Private' : 'Public') . ' key not found: ' . $keyId);
|
||||||
}
|
}
|
||||||
if ($private && $this->passphrases) {
|
if ($private && $this->pinentries) {
|
||||||
$_ENV['PINENTRY_USER_DATA'] = \json_encode($this->passphrases);
|
$_ENV['PINENTRY_USER_DATA'] = \json_encode($this->pinentries);
|
||||||
}
|
}
|
||||||
$result = $this->exec([
|
$result = $this->exec([
|
||||||
$private ? '--export-secret-key-p12' : '--export',
|
$private ? '--export-secret-key-p12' : '--export',
|
||||||
|
|
@ -261,7 +261,7 @@ class SMIME extends Base
|
||||||
{
|
{
|
||||||
if ($passphrase) {
|
if ($passphrase) {
|
||||||
return $this
|
return $this
|
||||||
->addPassphrase($fingerprint, $passphrase)
|
->addPinentry($fingerprint, $passphrase)
|
||||||
->_exportKey($fingerprint, true);
|
->_exportKey($fingerprint, true);
|
||||||
}
|
}
|
||||||
return $this->_exportKey($fingerprint);
|
return $this->_exportKey($fingerprint);
|
||||||
|
|
@ -271,8 +271,8 @@ class SMIME extends Base
|
||||||
{
|
{
|
||||||
$arguments = ['--import'];
|
$arguments = ['--import'];
|
||||||
|
|
||||||
if ($this->passphrases) {
|
if ($this->pinentries) {
|
||||||
$_ENV['PINENTRY_USER_DATA'] = \json_encode($this->passphrases);
|
$_ENV['PINENTRY_USER_DATA'] = \json_encode($this->pinentries);
|
||||||
} else {
|
} else {
|
||||||
$arguments[] = '--batch';
|
$arguments[] = '--batch';
|
||||||
}
|
}
|
||||||
|
|
@ -482,7 +482,7 @@ class SMIME extends Base
|
||||||
|
|
||||||
protected function _sign(/*string|resource*/ $input, /*string|resource*/ $output = null) /*: string|false*/
|
protected function _sign(/*string|resource*/ $input, /*string|resource*/ $output = null) /*: string|false*/
|
||||||
{
|
{
|
||||||
if (empty($this->signKeys)) {
|
if (empty($this->pinentries)) {
|
||||||
throw new \Exception('No signing keys specified.');
|
throw new \Exception('No signing keys specified.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -498,11 +498,11 @@ class SMIME extends Base
|
||||||
$arguments[] = '--armor';
|
$arguments[] = '--armor';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->signKeys) {
|
if ($this->pinentries) {
|
||||||
foreach ($this->signKeys as $fingerprint => $pass) {
|
foreach ($this->pinentries as $fingerprint => $pass) {
|
||||||
$arguments[] = '--local-user ' . \escapeshellarg($fingerprint);
|
$arguments[] = '--local-user ' . \escapeshellarg($fingerprint);
|
||||||
}
|
}
|
||||||
$_ENV['PINENTRY_USER_DATA'] = \json_encode($this->signKeys);
|
$_ENV['PINENTRY_USER_DATA'] = \json_encode($this->pinentries);
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $this->exec($arguments);
|
$result = $this->exec($arguments);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ use SnappyMail\SensitiveString;
|
||||||
interface PGPInterface
|
interface PGPInterface
|
||||||
{
|
{
|
||||||
public static function isSupported() : bool;
|
public static function isSupported() : bool;
|
||||||
|
// public function addPinentry(string $keyId, SensitiveString $passphrase) : bool;
|
||||||
public function addDecryptKey(string $fingerprint, SensitiveString $passphrase) : bool;
|
public function addDecryptKey(string $fingerprint, SensitiveString $passphrase) : bool;
|
||||||
public function addEncryptKey(string $fingerprint) : bool;
|
public function addEncryptKey(string $fingerprint) : bool;
|
||||||
public function addSignKey(string $fingerprint, SensitiveString $passphrase) : bool;
|
public function addSignKey(string $fingerprint, SensitiveString $passphrase) : bool;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue