mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-08 08:57:03 +03:00
Added DoGnupgDecrypt(), DoGetStoredPGPKeys() and DoStorePGPKey() for #89
This commit is contained in:
parent
897c150b1e
commit
8dc949f15c
3 changed files with 138 additions and 2 deletions
|
|
@ -696,12 +696,14 @@ trait Messages
|
||||||
'text' => \preg_replace('/\\R/s', "\r\n",
|
'text' => \preg_replace('/\\R/s', "\r\n",
|
||||||
$oFetchResponse->GetFetchValue(FetchType::BODY.'['.$sBodyPartId.']')
|
$oFetchResponse->GetFetchValue(FetchType::BODY.'['.$sBodyPartId.']')
|
||||||
),
|
),
|
||||||
'signature' => false
|
'signature' => ''
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (\class_exists('gnupg')) {
|
$GPG = $this->GnuPG();
|
||||||
|
if ($GPG) {
|
||||||
$info = $this->GnuPG()->verify($result['text'], $result['signature'])[0];
|
$info = $this->GnuPG()->verify($result['text'], $result['signature'])[0];
|
||||||
|
// $info = $this->GnuPG()->verifyStream($fp, $result['signature'])[0];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://code.woboq.org/qt5/include/gpg-error.h.html
|
* https://code.woboq.org/qt5/include/gpg-error.h.html
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,10 @@ namespace RainLoop\Actions;
|
||||||
|
|
||||||
trait Pgp
|
trait Pgp
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Also see trait Messages::DoMessagePgpVerify
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \MailSo\Base\Exceptions\Exception
|
* @throws \MailSo\Base\Exceptions\Exception
|
||||||
*/
|
*/
|
||||||
|
|
@ -46,6 +50,43 @@ trait Pgp
|
||||||
return \SnappyMail\PGP\GnuPG::getInstance($homedir);
|
return \SnappyMail\PGP\GnuPG::getInstance($homedir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function DoGnupgDecrypt() : array
|
||||||
|
{
|
||||||
|
$GPG = $this->GnuPG();
|
||||||
|
if (!$GPG) {
|
||||||
|
return $this->FalseResponse(__FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
$GPG->addDecryptKey(
|
||||||
|
$this->GetActionParam('KeyId', ''),
|
||||||
|
$this->GetActionParam('Passphrase', '')
|
||||||
|
);
|
||||||
|
|
||||||
|
$sData = $this->GetActionParam('Data', '');
|
||||||
|
$oPart = null;
|
||||||
|
if ($sData) {
|
||||||
|
$result = $GPG->decrypt($sData);
|
||||||
|
$oPart = \MailSo\Mime\Part::FromString($result);
|
||||||
|
} else {
|
||||||
|
$this->initMailClientConnection();
|
||||||
|
$this->MailClient()->MessageMimeStream(
|
||||||
|
function ($rResource) use ($GPG, $oPart) {
|
||||||
|
if (\is_resource($rResource)) {
|
||||||
|
$result = $GPG->decryptStream($rResource);
|
||||||
|
$oPart = \MailSo\Mime\Part::FromString($result);
|
||||||
|
// $GPG->decryptStream($rResource, $rStreamHandle);
|
||||||
|
// $oPart = \MailSo\Mime\Part::FromStream($rStreamHandle);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
$this->GetActionParam('Folder', ''),
|
||||||
|
(int) $this->GetActionParam('Uid', ''),
|
||||||
|
$this->GetActionParam('PartId', '')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->DefaultResponse(__FUNCTION__, $oPart);
|
||||||
|
}
|
||||||
|
|
||||||
public function DoGnupgGetKeys() : array
|
public function DoGnupgGetKeys() : array
|
||||||
{
|
{
|
||||||
$GPG = $this->GnuPG();
|
$GPG = $this->GnuPG();
|
||||||
|
|
@ -113,4 +154,74 @@ trait Pgp
|
||||||
? $this->DefaultResponse(__FUNCTION__, $GPG->import($sKey))
|
? $this->DefaultResponse(__FUNCTION__, $GPG->import($sKey))
|
||||||
: $this->FalseResponse(__FUNCTION__);
|
: $this->FalseResponse(__FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to import keys in OpenPGP.js
|
||||||
|
* Handy when using multiple browsers
|
||||||
|
*/
|
||||||
|
public function DoGetStoredPGPKeys() : array
|
||||||
|
{
|
||||||
|
$oAccount = $this->getMainAccountFromToken();
|
||||||
|
if (!$oAccount) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dir = $this->StorageProvider()->GenerateFilePath(
|
||||||
|
$oAccount,
|
||||||
|
\RainLoop\Providers\Storage\Enumerations\StorageType::PGP
|
||||||
|
);
|
||||||
|
|
||||||
|
$keys = [];
|
||||||
|
foreach (\glob("{$dir}/*") as $file) {
|
||||||
|
if (\is_file($file)) {
|
||||||
|
if ('.asc' === \substr($file, -4)) {
|
||||||
|
$keys[] = \file_get_contents($file);
|
||||||
|
} else if ('.key' === \substr($file, -4)) {
|
||||||
|
$data = \json_decode(\file_get_contents($file), true);
|
||||||
|
$mac = \array_pop($sKey);
|
||||||
|
$hash = $oAccount->CryptKey();
|
||||||
|
if ($mac === \hash_hmac('sha1', $data[2], $hash)) {
|
||||||
|
$keys[] = \SnappyMail\Crypt::Decrypt($data, $hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->DefaultResponse(__FUNCTION__, $keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to store key from OpenPGP.js
|
||||||
|
* Handy when using multiple browsers
|
||||||
|
*/
|
||||||
|
public function DoStorePGPKey() : array
|
||||||
|
{
|
||||||
|
$oAccount = $this->getMainAccountFromToken();
|
||||||
|
if (!$oAccount) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$key = $this->GetActionParam('Key', '');
|
||||||
|
$keyId = $this->GetActionParam('KeyId', '');
|
||||||
|
$result = false;
|
||||||
|
if ($key && $keyId) {
|
||||||
|
$dir = $this->StorageProvider()->GenerateFilePath(
|
||||||
|
$oAccount,
|
||||||
|
\RainLoop\Providers\Storage\Enumerations\StorageType::PGP
|
||||||
|
);
|
||||||
|
if (\str_contains($key, 'PGP PRIVATE KEY')) {
|
||||||
|
$hash = $oAccount->CryptKey();
|
||||||
|
$key = \SnappyMail\Crypt::Encrypt($key, $hash);
|
||||||
|
$key[] = \hash_hmac('sha1', $key[2], $hash);
|
||||||
|
$result = \file_put_contents("{$dir}/0x{$keyId}.key", \json_encode($key));
|
||||||
|
} else if (\str_contains($key, 'PGP PUBLIC KEY')) {
|
||||||
|
$result = \file_put_contents("{$dir}/0x{$keyId}_public.asc", $key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result
|
||||||
|
? $this->TrueResponse(__FUNCTION__)
|
||||||
|
: $this->FalseResponse(__FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,17 @@ class GnuPG
|
||||||
: $this->GPG->decryptFile($filename);
|
: $this->GPG->decryptFile($filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrypts a given resource
|
||||||
|
*/
|
||||||
|
public function decryptStream(/*resource*/ $fp, /*string|resource*/ $output = null) /*: string|false */
|
||||||
|
{
|
||||||
|
if (!$fp || !\is_resource($fp)) {
|
||||||
|
throw new \Exception('Invalid stream resource');
|
||||||
|
}
|
||||||
|
return $this->getGPG()->decryptStream($fp, $output);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrypts and verifies a given text
|
* Decrypts and verifies a given text
|
||||||
*/
|
*/
|
||||||
|
|
@ -404,4 +415,16 @@ class GnuPG
|
||||||
? $this->GnuPG->verify(\file_get_contents($filename), $signature, $plaintext)
|
? $this->GnuPG->verify(\file_get_contents($filename), $signature, $plaintext)
|
||||||
: $this->GPG->verifyFile($filename, $signature, $plaintext);
|
: $this->GPG->verifyFile($filename, $signature, $plaintext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies a given resource
|
||||||
|
*/
|
||||||
|
public function verifyStream(/*resource*/ $fp, string $signature, string &$plaintext = null) /*: string|false */
|
||||||
|
{
|
||||||
|
if (!$fp || !\is_resource($fp)) {
|
||||||
|
throw new \Exception('Invalid stream resource');
|
||||||
|
}
|
||||||
|
return $this->getGPG()->verifyStream($fp, $signature, $plaintext);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue