mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-08 17:07:03 +03:00
Added more code for S/MIME #259
This commit is contained in:
parent
dceb5fca41
commit
53940e64ab
7 changed files with 491 additions and 11 deletions
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of MailSo.
|
||||||
|
*
|
||||||
|
* (c) 2024 SnappyMail
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace MailSo\Mime\Enumerations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category MailSo
|
||||||
|
* @package Mime
|
||||||
|
* @subpackage Enumerations
|
||||||
|
*/
|
||||||
|
abstract class ContentType
|
||||||
|
{
|
||||||
|
const SIGNED = 'multipart/signed';
|
||||||
|
const ENCRYPTED = 'multipart/encrypted';
|
||||||
|
const PGP_ENCRYPTED = 'application/pgp-encrypted';
|
||||||
|
const PGP_SIGNATURE = 'application/pgp-signature';
|
||||||
|
const PKCS7_SIGNATURE = 'application/pkcs7-signature';
|
||||||
|
const PKCS7_MIME = 'application/pkcs7-mime';
|
||||||
|
}
|
||||||
|
|
@ -192,14 +192,14 @@ class Part
|
||||||
return \MailSo\Base\StreamWrappers\SubStreams::CreateStream($aSubStreams);
|
return \MailSo\Base\StreamWrappers\SubStreams::CreateStream($aSubStreams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addPgpEncrypted(string $sEncrypted)
|
public function addEncrypted(string $sEncrypted, string $sType)
|
||||||
{
|
{
|
||||||
$oPart = new self;
|
$oPart = new self;
|
||||||
$oPart->Headers->AddByName(Enumerations\Header::CONTENT_TYPE, 'multipart/encrypted; protocol="application/pgp-encrypted"');
|
$oPart->Headers->AddByName(Enumerations\Header::CONTENT_TYPE, 'multipart/encrypted; protocol="'.$sType.'"');
|
||||||
$this->SubParts->append($oPart);
|
$this->SubParts->append($oPart);
|
||||||
|
|
||||||
$oSubPart = new self;
|
$oSubPart = new self;
|
||||||
$oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_TYPE, 'application/pgp-encrypted');
|
$oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_TYPE, $sType);
|
||||||
$oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_DISPOSITION, 'attachment');
|
$oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_DISPOSITION, 'attachment');
|
||||||
$oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_TRANSFER_ENCODING, '7Bit');
|
$oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_TRANSFER_ENCODING, '7Bit');
|
||||||
$oSubPart->Body = \MailSo\Base\ResourceRegistry::CreateMemoryResourceFromString('Version: 1');
|
$oSubPart->Body = \MailSo\Base\ResourceRegistry::CreateMemoryResourceFromString('Version: 1');
|
||||||
|
|
@ -207,12 +207,27 @@ class Part
|
||||||
|
|
||||||
$oSubPart = new self;
|
$oSubPart = new self;
|
||||||
$oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_TYPE, 'application/octet-stream');
|
$oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_TYPE, 'application/octet-stream');
|
||||||
$oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_DISPOSITION, 'inline; filename="msg.asc"');
|
if ('application/pgp-encrypted' === $sType) {
|
||||||
|
$oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_DISPOSITION, 'inline; filename="msg.asc"');
|
||||||
|
}
|
||||||
|
if ('application/pkcs7-mime' === $sType) {
|
||||||
|
$oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_DISPOSITION, 'inline; filename="msg.p7m"');
|
||||||
|
}
|
||||||
$oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_TRANSFER_ENCODING, '7Bit');
|
$oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_TRANSFER_ENCODING, '7Bit');
|
||||||
$oSubPart->Body = \MailSo\Base\ResourceRegistry::CreateMemoryResourceFromString($sEncrypted);
|
$oSubPart->Body = \MailSo\Base\ResourceRegistry::CreateMemoryResourceFromString($sEncrypted);
|
||||||
$oPart->SubParts->append($oSubPart);
|
$oPart->SubParts->append($oSubPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addPgpEncrypted(string $sEncrypted)
|
||||||
|
{
|
||||||
|
$this->addEncrypted($sEncrypted, 'application/pgp-encrypted');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addSMimepEncrypted(string $sEncrypted)
|
||||||
|
{
|
||||||
|
$this->addEncrypted($sEncrypted, 'application/pkcs7-mime');
|
||||||
|
}
|
||||||
|
|
||||||
public function addPlain(string $sPlain)
|
public function addPlain(string $sPlain)
|
||||||
{
|
{
|
||||||
$oPart = new self;
|
$oPart = new self;
|
||||||
|
|
|
||||||
|
|
@ -976,6 +976,9 @@ trait Messages
|
||||||
return $oMessage;
|
return $oMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* called by DoSaveMessage and DoSendMessage
|
||||||
|
*/
|
||||||
private function buildMessage(Account $oAccount, bool $bWithDraftInfo = true) : \MailSo\Mime\Message
|
private function buildMessage(Account $oAccount, bool $bWithDraftInfo = true) : \MailSo\Mime\Message
|
||||||
{
|
{
|
||||||
$oMessage = new \MailSo\Mime\Message();
|
$oMessage = new \MailSo\Mime\Message();
|
||||||
|
|
@ -1048,11 +1051,14 @@ trait Messages
|
||||||
$aSigned = \explode("\r\n\r\n", $sSigned, 2);
|
$aSigned = \explode("\r\n\r\n", $sSigned, 2);
|
||||||
// $sBoundary = \preg_replace('/^.+boundary="([^"]+)".+$/Dsi', '$1', $aSigned[0]);
|
// $sBoundary = \preg_replace('/^.+boundary="([^"]+)".+$/Dsi', '$1', $aSigned[0]);
|
||||||
$sBoundary = $this->GetActionParam('boundary', '');
|
$sBoundary = $this->GetActionParam('boundary', '');
|
||||||
|
// \preg_match('/protocol="(application/[^"]+)"/', $aSigned[0], $match);
|
||||||
|
// $sProtocol = $match[1][0];
|
||||||
|
$sProtocol = 'application/pgp-signature';
|
||||||
|
|
||||||
$oPart = new MimePart;
|
$oPart = new MimePart;
|
||||||
$oPart->Headers->AddByName(
|
$oPart->Headers->AddByName(
|
||||||
MimeEnumHeader::CONTENT_TYPE,
|
MimeEnumHeader::CONTENT_TYPE,
|
||||||
'multipart/signed; micalg="pgp-sha256"; protocol="application/pgp-signature"; boundary="'.$sBoundary.'"'
|
'multipart/signed; micalg="pgp-sha256"; protocol="'.$sProtocol.'"; boundary="'.$sBoundary.'"'
|
||||||
);
|
);
|
||||||
$oPart->Body = $aSigned[1];
|
$oPart->Body = $aSigned[1];
|
||||||
$oMessage->SubParts->append($oPart);
|
$oMessage->SubParts->append($oPart);
|
||||||
|
|
@ -1176,8 +1182,9 @@ trait Messages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sFingerprint = $this->GetActionParam('signFingerprint', '');
|
|
||||||
$sPassphrase = $this->GetActionParam('signPassphrase', '');
|
$sPassphrase = $this->GetActionParam('signPassphrase', '');
|
||||||
|
|
||||||
|
$sFingerprint = $this->GetActionParam('signFingerprint', '');
|
||||||
if ($sFingerprint) {
|
if ($sFingerprint) {
|
||||||
$GPG = $this->GnuPG();
|
$GPG = $this->GnuPG();
|
||||||
$oBody = $oMessage->GetRootPart();
|
$oBody = $oMessage->GetRootPart();
|
||||||
|
|
@ -1216,13 +1223,53 @@ trait Messages
|
||||||
$oSignaturePart->Headers->AddByName(MimeEnumHeader::CONTENT_TRANSFER_ENCODING, '7Bit');
|
$oSignaturePart->Headers->AddByName(MimeEnumHeader::CONTENT_TRANSFER_ENCODING, '7Bit');
|
||||||
$oSignaturePart->Body = $sSignature;
|
$oSignaturePart->Body = $sSignature;
|
||||||
$oPart->SubParts->append($oSignaturePart);
|
$oPart->SubParts->append($oSignaturePart);
|
||||||
|
} else {
|
||||||
|
$sCertificate = $this->GetActionParam('signCertificate', '');
|
||||||
|
$sPrivateKey = $this->GetActionParam('signPrivateKey', '');
|
||||||
|
if ($sCertificate && $sPrivateKey) {
|
||||||
|
$oBody = $oMessage->GetRootPart();
|
||||||
|
|
||||||
|
$resource = $oBody->ToStream();
|
||||||
|
\MailSo\Base\StreamFilters\LineEndings::appendTo($resource);
|
||||||
|
$tmp = new \SnappyMail\File\Temporary;
|
||||||
|
$tmp->writeFromStream($resource);
|
||||||
|
|
||||||
|
$oBody->Body = null;
|
||||||
|
$oBody->SubParts->Clear();
|
||||||
|
$oMessage->SubParts->Clear();
|
||||||
|
$oMessage->Attachments()->Clear();
|
||||||
|
|
||||||
|
$SMIME = new \SnappyMail\SMime\OpenSSL;
|
||||||
|
$SMIME->setPrivateKey($sPrivateKey, $sPassphrase);
|
||||||
|
$sSignature = $SMIME->sign($tmp, $sCertificate);
|
||||||
|
|
||||||
|
if (!$sSignature) {
|
||||||
|
throw new \Exception('GnuPG sign() failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
$oPart = new MimePart;
|
||||||
|
$oPart->Headers->AddByName(
|
||||||
|
MimeEnumHeader::CONTENT_TYPE,
|
||||||
|
'multipart/signed; micalg="sha-512"; protocol="application/pkcs7-signature"'
|
||||||
|
);
|
||||||
|
$oMessage->SubParts->append($oPart);
|
||||||
|
|
||||||
|
$fp = $tmp->fopen();
|
||||||
|
\rewind($fp);
|
||||||
|
$oBody->Raw = $fp;
|
||||||
|
$oPart->SubParts->append($oBody);
|
||||||
|
|
||||||
|
$oSignaturePart = new MimePart;
|
||||||
|
$oSignaturePart->Headers->AddByName(MimeEnumHeader::CONTENT_TYPE, 'application/pkcs7-signature; name="signature.p7s"');
|
||||||
|
$oSignaturePart->Headers->AddByName(MimeEnumHeader::CONTENT_TRANSFER_ENCODING, '7Bit');
|
||||||
|
$oSignaturePart->Body = $sSignature;
|
||||||
|
$oPart->SubParts->append($oSignaturePart);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$aFingerprints = \json_decode($this->GetActionParam('encryptFingerprints', ''), true);
|
$aFingerprints = \json_decode($this->GetActionParam('encryptFingerprints', ''), true);
|
||||||
if ($aFingerprints) {
|
if ($aFingerprints) {
|
||||||
$GPG = $this->GnuPG();
|
$resource = $oMessage->GetRootPart()->ToStream();
|
||||||
$oBody = $oMessage->GetRootPart();
|
|
||||||
$resource = $oBody->ToStream();
|
|
||||||
$fp = \fopen('php://temp', 'r+b');
|
$fp = \fopen('php://temp', 'r+b');
|
||||||
// \stream_copy_to_stream($resource, $fp); // Fails
|
// \stream_copy_to_stream($resource, $fp); // Fails
|
||||||
while (!\feof($resource)) \fwrite($fp, \fread($resource, 8192));
|
while (!\feof($resource)) \fwrite($fp, \fread($resource, 8192));
|
||||||
|
|
@ -1230,11 +1277,30 @@ trait Messages
|
||||||
$oMessage->SubParts->Clear();
|
$oMessage->SubParts->Clear();
|
||||||
$oMessage->Attachments()->Clear();
|
$oMessage->Attachments()->Clear();
|
||||||
|
|
||||||
|
$GPG = $this->GnuPG();
|
||||||
foreach ($aFingerprints as $sFingerprint) {
|
foreach ($aFingerprints as $sFingerprint) {
|
||||||
$GPG->addEncryptKey($sFingerprint);
|
$GPG->addEncryptKey($sFingerprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
$oMessage->addPgpEncrypted($GPG->encryptStream($fp));
|
$oMessage->addPgpEncrypted($GPG->encryptStream($fp));
|
||||||
|
} else {
|
||||||
|
$aCertificates = \json_decode($this->GetActionParam('encryptCertificates', ''), true);
|
||||||
|
if ($aCertificates) {
|
||||||
|
$tmp = new \SnappyMail\File\Temporary;
|
||||||
|
$tmp->writeFromStream($oMessage->GetRootPart()->ToStream());
|
||||||
|
|
||||||
|
$oMessage->SubParts->Clear();
|
||||||
|
$oMessage->Attachments()->Clear();
|
||||||
|
|
||||||
|
// $SMIME = new \SnappyMail\SMime(/*$homedir*/);
|
||||||
|
$SMIME = new \SnappyMail\SMime\OpenSSL;
|
||||||
|
/*
|
||||||
|
foreach ($aCertificates as $sCertificate) {
|
||||||
|
$SMIME->addEncryptKey($sCertificate);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
$sEncrypted = $SMIME->encrypt($tmp, $aCertificates);
|
||||||
|
$oMessage->addSMimepEncrypted($sEncrypted);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->Plugins()->RunHook('filter.build-message', array($oMessage));
|
$this->Plugins()->RunHook('filter.build-message', array($oMessage));
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ trait Pgp
|
||||||
// First try a symbolic link
|
// First try a symbolic link
|
||||||
$tmpdir = \sys_get_temp_dir() . '/snappymail';
|
$tmpdir = \sys_get_temp_dir() . '/snappymail';
|
||||||
// if (\RainLoop\Utils::inOpenBasedir($tmpdir) &&
|
// if (\RainLoop\Utils::inOpenBasedir($tmpdir) &&
|
||||||
is_dir($tmpdir) || \mkdir($tmpdir, 0700);
|
\is_dir($tmpdir) || \mkdir($tmpdir, 0700);
|
||||||
if (\is_dir($tmpdir) && \is_writable($tmpdir)) {
|
if (\is_dir($tmpdir) && \is_writable($tmpdir)) {
|
||||||
$link = $tmpdir . '/' . \md5($homedir);
|
$link = $tmpdir . '/' . \md5($homedir);
|
||||||
if (\is_link($link) || \symlink($homedir, $link)) {
|
if (\is_link($link) || \symlink($homedir, $link)) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SnappyMail\File;
|
||||||
|
|
||||||
|
class Temporary
|
||||||
|
{
|
||||||
|
protected static string $filename = '';
|
||||||
|
|
||||||
|
function __construct(string $name, bool $prefix = true)
|
||||||
|
{
|
||||||
|
$tmpdir = \sys_get_temp_dir() . '/snappymail';
|
||||||
|
// if (\RainLoop\Utils::inOpenBasedir($tmpdir) &&
|
||||||
|
\is_dir($tmpdir) || \mkdir($tmpdir, 0700);
|
||||||
|
if (!\is_dir($tmpdir)) {
|
||||||
|
throw new \Exception("Failed to create directory {$tmpdir}");
|
||||||
|
}
|
||||||
|
if (!\is_writable($tmpdir)) {
|
||||||
|
throw new \Exception("Failed to access directory {$tmpdir}");
|
||||||
|
}
|
||||||
|
if ($prefix) {
|
||||||
|
$this->filename = \tempnam($tmpdir, $name);
|
||||||
|
} else {
|
||||||
|
$this->filename = $tmpdir . '/' . $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function __destruct()
|
||||||
|
{
|
||||||
|
$this->filename && \unlink($this->filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
function __toString() : string
|
||||||
|
{
|
||||||
|
$this->filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filename() : string
|
||||||
|
{
|
||||||
|
return $this->filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
private $fp = null;
|
||||||
|
public function fopen()/* : resource|false*/
|
||||||
|
{
|
||||||
|
if (!$fp) {
|
||||||
|
$fp = \fopen($this->filename, 'r+b');
|
||||||
|
}
|
||||||
|
return $fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function writeFromStream(/*resource*/ $from)/* : int|false*/
|
||||||
|
{
|
||||||
|
$fp = $this->fopen();
|
||||||
|
// return \stream_copy_to_stream($from, $fp); // Fails
|
||||||
|
$bytes = 0;
|
||||||
|
while (!\feof($from)) $bytes += \fwrite($fp, \fread($from, 8192));
|
||||||
|
return $bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function putContents($data, int $flags = 0)/* : int|false*/
|
||||||
|
{
|
||||||
|
return \file_put_contents($this->filename, $data /*, $flags, $context*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getContents()/* : string|false*/
|
||||||
|
{
|
||||||
|
return \file_get_contents($this->filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
199
snappymail/v/0.0.0/app/libraries/snappymail/smime.php
Normal file
199
snappymail/v/0.0.0/app/libraries/snappymail/smime.php
Normal file
|
|
@ -0,0 +1,199 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SnappyMail;
|
||||||
|
|
||||||
|
class SMime
|
||||||
|
{
|
||||||
|
private
|
||||||
|
$homedir,
|
||||||
|
// Instance of SnappyMail\SMime\OpenSSL
|
||||||
|
$OpenSSL,
|
||||||
|
// Instance of \SnappyMail\GPG\SMIME
|
||||||
|
$GPGSM;
|
||||||
|
|
||||||
|
function __construct(string $homedir)
|
||||||
|
{
|
||||||
|
$homedir = \rtrim($homedir, '/\\');
|
||||||
|
// BSD 4.4 max length
|
||||||
|
if (104 <= \strlen($homedir . '/S.gpg-agent.extra')) {
|
||||||
|
throw new \Exception('socket name for S.gpg-agent.extra is too long');
|
||||||
|
}
|
||||||
|
$this->homedir = $homedir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isSupported() : bool
|
||||||
|
{
|
||||||
|
return SMime\OpenSSL::isSupported() || GPG\SMIME::isSupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static $instance;
|
||||||
|
public static function getInstance(string $homedir) : ?self
|
||||||
|
{
|
||||||
|
if (!static::$instance) {
|
||||||
|
static::$instance = new self($homedir);
|
||||||
|
}
|
||||||
|
return static::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handler()
|
||||||
|
{
|
||||||
|
return $this->OpenSSL ?: $this->GPGSM;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getGPGSM(bool $throw = true) : ?GPG\SMIME
|
||||||
|
{
|
||||||
|
if (!$this->GPGSM) {
|
||||||
|
if (GPG\SMIME::isSupported()) {
|
||||||
|
$this->GPGSM = new GPG\SMIME($this->homedir);
|
||||||
|
} else if ($throw) {
|
||||||
|
throw new \Exception('GnuPG not supported');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->GPGSM;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addDecryptKey(string $fingerprint,
|
||||||
|
#[\SensitiveParameter]
|
||||||
|
string $passphrase
|
||||||
|
) : bool
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addEncryptKey(string $fingerprint) : bool
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addSignKey(string $fingerprint,
|
||||||
|
#[\SensitiveParameter]
|
||||||
|
?string $passphrase
|
||||||
|
) : bool
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clearDecryptKeys() : bool
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clearEncryptKeys() : bool
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clearSignKeys() : bool
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function decrypt(string $text) /*: string|false */
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function decryptFile(string $filename) /*: string|false */
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function decryptStream(/*resource*/ $fp, /*string|resource*/ $output = null) /*: string|false */
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function decryptVerify(string $text, string &$plaintext) /*: array|false*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function decryptVerifyFile(string $filename, string &$plaintext) /*: array|false*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteKey(string $keyId, bool $private) : bool
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function encrypt(string $plaintext) /*: string|false*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function encryptFile(string $filename) /*: string|false*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function encryptStream(/*resource*/ $fp, /*string|resource*/ $output = null) /*: string|false*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function export(string $fingerprint,
|
||||||
|
#[\SensitiveParameter]
|
||||||
|
string $passphrase = ''
|
||||||
|
) /*: string|false*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEngineInfo() : array
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getError() /*: string|false*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getErrorInfo() : array
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getProtocol() : int
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function generateKey(string $uid,
|
||||||
|
#[\SensitiveParameter]
|
||||||
|
string $passphrase
|
||||||
|
) /*: string|false*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function import(string $keydata) /*: array|false*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function importFile(string $filename) /*: array|false*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function keyInfo(string $pattern) : array
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setArmor(bool $armor = true) : bool
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setErrorMode(int $errormode) : void
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setSignMode(int $signmode) : bool
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sign(string $plaintext) /*: string|false*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function signFile(string $filename) /*: string|false*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function signStream($fp, /*string|resource*/ $output = null) /*: array|false*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function verify(string $signed_text, string $signature, string &$plaintext = null) /*: array|false*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function verifyFile(string $filename, string $signature, string &$plaintext = null) /*: array|false*/
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function verifyStream(/*resource*/ $fp, string $signature, string &$plaintext = null) /*: string|false */
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
104
snappymail/v/0.0.0/app/libraries/snappymail/smime/openssl.php
Normal file
104
snappymail/v/0.0.0/app/libraries/snappymail/smime/openssl.php
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SnappyMail\SMime;
|
||||||
|
|
||||||
|
use SnappyMail\File\Temporary;
|
||||||
|
|
||||||
|
class OpenSSL
|
||||||
|
{
|
||||||
|
private array $headers = [];
|
||||||
|
private int $flags = 0;
|
||||||
|
private int $cipher_algo = \OPENSSL_CIPHER_AES_128_CBC;
|
||||||
|
private ?string $untrusted_certificates_filename = null;
|
||||||
|
private $certificate; // OpenSSLCertificate|array|string
|
||||||
|
private $private_key; // OpenSSLAsymmetricKey|OpenSSLCertificate|array|string
|
||||||
|
|
||||||
|
public static function isSupported() : bool
|
||||||
|
{
|
||||||
|
return \defined('PKCS7_DETACHED');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPrivateKey($private_key = null,
|
||||||
|
#[\SensitiveParameter]
|
||||||
|
?string $passphrase = null
|
||||||
|
) : void
|
||||||
|
{
|
||||||
|
$this->private_key = \openssl_pkey_get_private($private_key, $passphrase);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function decrypt(string $data, $certificate = null, $private_key = null) : ?string
|
||||||
|
{
|
||||||
|
$input = new Temporary('smimein-');
|
||||||
|
$output = new Temporary('smimeout-');
|
||||||
|
return ($input->putContents($data) && \openssl_pkcs7_decrypt(
|
||||||
|
$input->filename(),
|
||||||
|
$output->filename(),
|
||||||
|
$certificate ?: $this->certificate, // \openssl_pkey_get_public();
|
||||||
|
$private_key ?: $this->private_key // \openssl_pkey_get_private($private_key, ?string $passphrase = null);
|
||||||
|
)) ? $output->getContents() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function encrypt(/*string|Temporary*/$input, array $certificates) : ?string
|
||||||
|
{
|
||||||
|
if (\is_string($input)) {
|
||||||
|
$input = new Temporary('smimein-');
|
||||||
|
if (!$input->putContents($data)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$output = new Temporary('smimeout-');
|
||||||
|
$flags = \defined('PKCS7_NOOLDMIMETYPE') ? \PKCS7_NOOLDMIMETYPE : 0;
|
||||||
|
return \openssl_pkcs7_encrypt(
|
||||||
|
$input->filename(),
|
||||||
|
$output->filename(),
|
||||||
|
$certificates,
|
||||||
|
$this->headers,
|
||||||
|
$flags,
|
||||||
|
$this->cipher_algo
|
||||||
|
) ? $output->getContents() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sign(/*string|Temporary*/$input, $certificate = null, $private_key = null)
|
||||||
|
{
|
||||||
|
if (\is_string($input)) {
|
||||||
|
$input = new Temporary('smimein-');
|
||||||
|
if (!$input->putContents($data)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$output = new Temporary('smimeout-');
|
||||||
|
if (!$input->putContents($data) || !\openssl_pkcs7_sign(
|
||||||
|
$input->filename(),
|
||||||
|
$output->filename(),
|
||||||
|
$certificate ?: $this->certificate, // \openssl_pkey_get_public();
|
||||||
|
$private_key ?: $this->private_key, // \openssl_pkey_get_private($private_key, ?string $passphrase = null);
|
||||||
|
$this->headers,
|
||||||
|
\PKCS7_DETACHED, // | PKCS7_NOCERTS | PKCS7_NOATTR
|
||||||
|
$this->untrusted_certificates_filename
|
||||||
|
)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
$body = $output->getContents();
|
||||||
|
// The message returned by openssl contains both headers and body, so need to split them up
|
||||||
|
$parts = explode("\n\n", $body, 2);
|
||||||
|
$this->MIMEHeader .= $parts[0] . static::$LE . static::$LE;
|
||||||
|
$body = $parts[1];
|
||||||
|
*/
|
||||||
|
return $output->getContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function verify(string $data, $signers_certificates_filename = null)
|
||||||
|
{
|
||||||
|
$input = new Temporary('smimein-');
|
||||||
|
return $input->putContents($data) && true === \openssl_pkcs7_verify(
|
||||||
|
$input->filename(),
|
||||||
|
$flags = 0,
|
||||||
|
$signers_certificates_filename ?: null,
|
||||||
|
$ca_info = [],
|
||||||
|
$this->untrusted_certificates_filename,
|
||||||
|
$content = null,
|
||||||
|
$output_filename = null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue