mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-07 08:27:03 +03:00
Added a S/MIME certificates list to User settings #259
This commit is contained in:
parent
a22ae5fcf4
commit
3f08051e37
8 changed files with 172 additions and 219 deletions
|
|
@ -35,6 +35,7 @@ import { AccountUserStore } from 'Stores/User/Account';
|
||||||
import { ContactUserStore } from 'Stores/User/Contact';
|
import { ContactUserStore } from 'Stores/User/Contact';
|
||||||
import { FolderUserStore } from 'Stores/User/Folder';
|
import { FolderUserStore } from 'Stores/User/Folder';
|
||||||
import { PgpUserStore } from 'Stores/User/Pgp';
|
import { PgpUserStore } from 'Stores/User/Pgp';
|
||||||
|
import { SMimeUserStore } from 'Stores/User/SMime';
|
||||||
import { MessagelistUserStore } from 'Stores/User/Messagelist';
|
import { MessagelistUserStore } from 'Stores/User/Messagelist';
|
||||||
import { ThemeStore, initThemes } from 'Stores/Theme';
|
import { ThemeStore, initThemes } from 'Stores/Theme';
|
||||||
import { LanguageStore } from 'Stores/Language';
|
import { LanguageStore } from 'Stores/Language';
|
||||||
|
|
@ -216,6 +217,7 @@ export class AppUser extends AbstractApp {
|
||||||
setInterval(reloadTime, 60000);
|
setInterval(reloadTime, 60000);
|
||||||
|
|
||||||
PgpUserStore.init();
|
PgpUserStore.init();
|
||||||
|
SMimeUserStore.loadCertificates();
|
||||||
|
|
||||||
setTimeout(() => mailToHelper(SettingsGet('mailToEmail')), 500);
|
setTimeout(() => mailToHelper(SettingsGet('mailToEmail')), 500);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ import { showScreenPopup } from 'Knoin/Knoin';
|
||||||
import { OpenPgpImportPopupView } from 'View/Popup/OpenPgpImport';
|
import { OpenPgpImportPopupView } from 'View/Popup/OpenPgpImport';
|
||||||
import { OpenPgpGeneratePopupView } from 'View/Popup/OpenPgpGenerate';
|
import { OpenPgpGeneratePopupView } from 'View/Popup/OpenPgpGenerate';
|
||||||
|
|
||||||
|
import { SMimeUserStore } from 'Stores/User/SMime';
|
||||||
|
|
||||||
import Remote from 'Remote/User/Fetch';
|
import Remote from 'Remote/User/Fetch';
|
||||||
|
|
||||||
export class UserSettingsSecurity extends AbstractViewSettings {
|
export class UserSettingsSecurity extends AbstractViewSettings {
|
||||||
|
|
@ -43,6 +45,8 @@ export class UserSettingsSecurity extends AbstractViewSettings {
|
||||||
this.openpgpkeysPublic = OpenPGPUserStore.publicKeys;
|
this.openpgpkeysPublic = OpenPGPUserStore.publicKeys;
|
||||||
this.openpgpkeysPrivate = OpenPGPUserStore.privateKeys;
|
this.openpgpkeysPrivate = OpenPGPUserStore.privateKeys;
|
||||||
|
|
||||||
|
this.smimeCertificates = SMimeUserStore;
|
||||||
|
|
||||||
this.canOpenPGP = SettingsCapa('OpenPGP');
|
this.canOpenPGP = SettingsCapa('OpenPGP');
|
||||||
this.canGnuPG = GnuPGUserStore.isSupported();
|
this.canGnuPG = GnuPGUserStore.isSupported();
|
||||||
this.canMailvelope = !!window.mailvelope;
|
this.canMailvelope = !!window.mailvelope;
|
||||||
|
|
|
||||||
17
dev/Stores/User/SMime.js
Normal file
17
dev/Stores/User/SMime.js
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { addObservablesTo, koArrayWithDestroy } from 'External/ko';
|
||||||
|
import Remote from 'Remote/User/Fetch';
|
||||||
|
|
||||||
|
export const SMimeUserStore = koArrayWithDestroy();
|
||||||
|
|
||||||
|
addObservablesTo(SMimeUserStore, {
|
||||||
|
loading: false
|
||||||
|
});
|
||||||
|
|
||||||
|
SMimeUserStore.loadCertificates = () => {
|
||||||
|
SMimeUserStore([]);
|
||||||
|
SMimeUserStore.loading(true);
|
||||||
|
Remote.request('SMimeGetCertificates', (iError, oData) => {
|
||||||
|
SMimeUserStore.loading(false);
|
||||||
|
iError || SMimeUserStore(oData.Result);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -1124,7 +1124,7 @@ trait Messages
|
||||||
|
|
||||||
$detached = true;
|
$detached = true;
|
||||||
|
|
||||||
$SMIME = new \SnappyMail\SMime\OpenSSL;
|
$SMIME = $this->SMIME();
|
||||||
$SMIME->setCertificate($sCertificate);
|
$SMIME->setCertificate($sCertificate);
|
||||||
$SMIME->setPrivateKey($sPrivateKey, $sPassphrase);
|
$SMIME->setPrivateKey($sPrivateKey, $sPassphrase);
|
||||||
$sSignature = $SMIME->sign($tmp, $detached);
|
$sSignature = $SMIME->sign($tmp, $detached);
|
||||||
|
|
@ -1186,8 +1186,7 @@ trait Messages
|
||||||
$oMessage->SubParts->Clear();
|
$oMessage->SubParts->Clear();
|
||||||
$oMessage->Attachments()->Clear();
|
$oMessage->Attachments()->Clear();
|
||||||
|
|
||||||
// $SMIME = new \SnappyMail\SMime(/*$homedir*/);
|
$SMIME = $this->SMIME();
|
||||||
$SMIME = new \SnappyMail\SMime\OpenSSL;
|
|
||||||
/*
|
/*
|
||||||
foreach ($aCertificates as $sCertificate) {
|
foreach ($aCertificates as $sCertificate) {
|
||||||
$SMIME->addEncryptKey($sCertificate);
|
$SMIME->addEncryptKey($sCertificate);
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,32 @@ use MailSo\Imap\Enumerations\FetchType;
|
||||||
|
|
||||||
trait SMime
|
trait SMime
|
||||||
{
|
{
|
||||||
|
private $SMIME = null;
|
||||||
|
public function SMIME() : OpenSSL
|
||||||
|
{
|
||||||
|
if (!$this->SMIME) {
|
||||||
|
$oAccount = $this->getMainAccountFromToken();
|
||||||
|
if (!$oAccount) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$homedir = \rtrim($this->StorageProvider()->GenerateFilePath(
|
||||||
|
$oAccount,
|
||||||
|
\RainLoop\Providers\Storage\Enumerations\StorageType::ROOT
|
||||||
|
), '/') . '/.smime';
|
||||||
|
|
||||||
|
if (!\is_dir($homedir)) {
|
||||||
|
\mkdir($homedir, 0700, true);
|
||||||
|
}
|
||||||
|
if (!\is_writable($homedir)) {
|
||||||
|
throw new \Exception("smime homedir '{$homedir}' not writable");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->SMIME = new OpenSSL($homedir);
|
||||||
|
}
|
||||||
|
return $this->SMIME;
|
||||||
|
}
|
||||||
|
|
||||||
public function DoGetSMimeCertificate() : array
|
public function DoGetSMimeCertificate() : array
|
||||||
{
|
{
|
||||||
$result = [
|
$result = [
|
||||||
|
|
@ -18,18 +44,35 @@ trait SMime
|
||||||
return $this->DefaultResponse(\array_values(\array_unique($result)));
|
return $this->DefaultResponse(\array_values(\array_unique($result)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Like DoGnupgGetKeys
|
||||||
|
public function DoSMimeGetCertificates() : array
|
||||||
|
{
|
||||||
|
return $this->DefaultResponse(
|
||||||
|
$this->SMIME()->certificates()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
DoGetPGPKeys() : array
|
||||||
|
DoPgpSearchKey() : array
|
||||||
|
DoGnupgDecrypt() : array
|
||||||
|
DoGnupgGetKeys() : array
|
||||||
|
DoGnupgExportKey() : array
|
||||||
|
DoGnupgGenerateKey() : array
|
||||||
|
DoGnupgDeleteKey() : array
|
||||||
|
DoPgpImportKey() : array
|
||||||
|
DoGetStoredPGPKeys() : array
|
||||||
|
DoPgpStoreKeyPair() : array
|
||||||
|
DoStorePGPKey() : array
|
||||||
|
DoPgpVerifyMessage() : array
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can be use by Identity
|
* Can be use by Identity
|
||||||
*/
|
*/
|
||||||
public function DoSMimeCreateCertificate() : array
|
public function DoSMimeCreateCertificate() : array
|
||||||
{
|
{
|
||||||
$oAccount = $this->getAccountFromToken();
|
$oAccount = $this->getAccountFromToken();
|
||||||
/*
|
|
||||||
$homedir = \rtrim($this->StorageProvider()->GenerateFilePath(
|
|
||||||
$oAccount,
|
|
||||||
\RainLoop\Providers\Storage\Enumerations\StorageType::ROOT
|
|
||||||
), '/') . '/.smime';
|
|
||||||
*/
|
|
||||||
$sName = $this->GetActionParam('name', '') ?: $oAccount->Name();
|
$sName = $this->GetActionParam('name', '') ?: $oAccount->Name();
|
||||||
$sEmail = $this->GetActionParam('email', '') ?: $oAccount->Email();
|
$sEmail = $this->GetActionParam('email', '') ?: $oAccount->Email();
|
||||||
$sPassphrase = $this->GetActionParam('passphrase', '');
|
$sPassphrase = $this->GetActionParam('passphrase', '');
|
||||||
|
|
@ -72,8 +115,7 @@ trait SMime
|
||||||
}
|
}
|
||||||
$sBody .= $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$sPartId.']');
|
$sBody .= $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$sPartId.']');
|
||||||
|
|
||||||
$SMIME = new OpenSSL;
|
$result = $this->SMIME()->verify($sBody, null, !$bDetached);
|
||||||
$result = $SMIME->verify($sBody, null, !$bDetached);
|
|
||||||
|
|
||||||
return $this->DefaultResponse($result);
|
return $this->DefaultResponse($result);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,199 +0,0 @@
|
||||||
<?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 */
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -10,6 +10,7 @@ use SnappyMail\File\Temporary;
|
||||||
|
|
||||||
class OpenSSL
|
class OpenSSL
|
||||||
{
|
{
|
||||||
|
private string $homedir;
|
||||||
private array $headers = [];
|
private array $headers = [];
|
||||||
private int $flags = 0;
|
private int $flags = 0;
|
||||||
private int $cipher_algo = \OPENSSL_CIPHER_AES_128_CBC;
|
private int $cipher_algo = \OPENSSL_CIPHER_AES_128_CBC;
|
||||||
|
|
@ -19,6 +20,61 @@ class OpenSSL
|
||||||
private $certificate; // OpenSSLCertificate|array|string
|
private $certificate; // OpenSSLCertificate|array|string
|
||||||
private $privateKey; // OpenSSLAsymmetricKey|OpenSSLCertificate|array|string
|
private $privateKey; // OpenSSLAsymmetricKey|OpenSSLCertificate|array|string
|
||||||
|
|
||||||
|
function __construct(string $homedir)
|
||||||
|
{
|
||||||
|
$this->homedir = $homedir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function certificates() : array
|
||||||
|
{
|
||||||
|
$keys = [];
|
||||||
|
foreach (\glob("{$this->homedir}/*.key") as $file) {
|
||||||
|
$data = \file_get_contents($file);
|
||||||
|
// Can't check ENCRYPTED PRIVATE KEY
|
||||||
|
if (\str_contains($data, '-----BEGIN PRIVATE KEY-----')) {
|
||||||
|
$keys[] = [\basename($file), $data];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$result = [];
|
||||||
|
foreach (\glob("{$this->homedir}/*.crt") as $file) {
|
||||||
|
$name = \basename($file);
|
||||||
|
$certificate = \file_get_contents($file);
|
||||||
|
$data = \openssl_x509_parse($certificate);
|
||||||
|
if ($data) {
|
||||||
|
$short = [
|
||||||
|
'file' => \basename($file),
|
||||||
|
'CN' => $data['subject']['CN'],
|
||||||
|
'emailAddress' => $data['subject']['emailAddress'],
|
||||||
|
'validTo' => \gmdate('Y-m-d\\TH:i:s\\Z', $data['validTo_time_t']),
|
||||||
|
'smimesign' => false,
|
||||||
|
'smimeencrypt' => false,
|
||||||
|
'privateKey' => null // not found or encrypted
|
||||||
|
];
|
||||||
|
foreach ($data['purposes'] as $purpose) {
|
||||||
|
if ('smimesign' === $purpose[2] || 'smimeencrypt' === $purpose[2]) {
|
||||||
|
// [general availability, tested purpose]
|
||||||
|
$short[$purpose[2]] = $purpose[0] || $purpose[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
if (\openssl_x509_check_private_key($certificate, $key[1])) {
|
||||||
|
$short['privateKey'] = $key[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$result[] = $short;
|
||||||
|
} else {
|
||||||
|
\error_log("OpenSSL parse({$file}): " . \openssl_error_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function privateKeys() : array
|
||||||
|
{
|
||||||
|
// \glob("{$this->homedir}/*.key");
|
||||||
|
}
|
||||||
|
|
||||||
public static function isSupported() : bool
|
public static function isSupported() : bool
|
||||||
{
|
{
|
||||||
return \defined('PKCS7_DETACHED');
|
return \defined('PKCS7_DETACHED');
|
||||||
|
|
@ -110,7 +166,7 @@ class OpenSSL
|
||||||
$this->certificate,
|
$this->certificate,
|
||||||
$this->privateKey,
|
$this->privateKey,
|
||||||
$this->headers,
|
$this->headers,
|
||||||
$detached ? \PKCS7_DETACHED | \PKCS7_BINARY : \PKCS7_BINARY, // | PKCS7_NOCERTS | PKCS7_NOATTR
|
$detached ? \PKCS7_DETACHED | \PKCS7_BINARY : 0, // | PKCS7_NOCERTS | PKCS7_NOATTR
|
||||||
$this->untrusted_certificates_filename
|
$this->untrusted_certificates_filename
|
||||||
)) {
|
)) {
|
||||||
throw new \RuntimeException('OpenSSL sign: ' . \openssl_error_string());
|
throw new \RuntimeException('OpenSSL sign: ' . \openssl_error_string());
|
||||||
|
|
@ -153,16 +209,20 @@ class OpenSSL
|
||||||
throw new \RuntimeException('OpenSSL sign: failed to find p7s');
|
throw new \RuntimeException('OpenSSL sign: failed to find p7s');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function verify(/*string|Temporary*/$input, ?string $signers_certificates_filename = null, bool $returnBody)
|
/**
|
||||||
|
* $opaque = true, when the message is not detached
|
||||||
|
*/
|
||||||
|
public function verify(/*string|Temporary*/$input, ?string $signers_certificates_filename = null, bool $opaque = false)
|
||||||
{
|
{
|
||||||
if (\is_string($input)) {
|
if (\is_string($input)) {
|
||||||
$tmp = new Temporary('smimein-');
|
$tmp = new Temporary('smimein-');
|
||||||
if (!$tmp->putContents($input)) {
|
if (!$tmp->putContents($input)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
$opaque |= \str_contains($input, 'application/pkcs7-mime') || \str_contains($input, 'application/x-pkcs7-mime');
|
||||||
$input = $tmp;
|
$input = $tmp;
|
||||||
}
|
}
|
||||||
$output = $returnBody ? new Temporary('smimeout-') : null;
|
$output = $opaque ? new Temporary('smimeout-') : null;
|
||||||
if (true !== \openssl_pkcs7_verify(
|
if (true !== \openssl_pkcs7_verify(
|
||||||
$input->filename(),
|
$input->filename(),
|
||||||
// $flags = 0, // \PKCS7_NOVERIFY | \PKCS7_NOCHAIN | \PKCS7_NOSIGS
|
// $flags = 0, // \PKCS7_NOVERIFY | \PKCS7_NOCHAIN | \PKCS7_NOSIGS
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@
|
||||||
<!-- /ko -->
|
<!-- /ko -->
|
||||||
|
|
||||||
<!-- ko if: canGnuPG -->
|
<!-- ko if: canGnuPG -->
|
||||||
<details>
|
<details style="margin:1em 0">
|
||||||
<summary class="legend">GnuPG</summary>
|
<summary style="font-size:larger;font-weight:bold">GnuPG</summary>
|
||||||
<table class="table table-hover list-table">
|
<table class="table table-hover list-table">
|
||||||
<tbody><tr><th colspan="4" data-i18n="SETTINGS_OPENPGP/TITLE_PRIVATE">Private keys</th></tr></tbody>
|
<tbody><tr><th colspan="4" data-i18n="SETTINGS_OPENPGP/TITLE_PRIVATE">Private keys</th></tr></tbody>
|
||||||
<tbody data-bind="foreach: gnupgPrivateKeys, i18nUpdate: gnupgPrivateKeys">
|
<tbody data-bind="foreach: gnupgPrivateKeys, i18nUpdate: gnupgPrivateKeys">
|
||||||
|
|
@ -71,8 +71,8 @@
|
||||||
<!-- /ko -->
|
<!-- /ko -->
|
||||||
|
|
||||||
<!-- ko if: canOpenPGP -->
|
<!-- ko if: canOpenPGP -->
|
||||||
<details>
|
<details style="margin:1em 0">
|
||||||
<summary class="legend">OpenPGP.js</summary>
|
<summary style="font-size:larger;font-weight:bold">OpenPGP.js</summary>
|
||||||
<table class="table table-hover list-table">
|
<table class="table table-hover list-table">
|
||||||
<tbody><tr><th colspan="4" data-i18n="SETTINGS_OPENPGP/TITLE_PRIVATE">Private keys</th></tr></tbody>
|
<tbody><tr><th colspan="4" data-i18n="SETTINGS_OPENPGP/TITLE_PRIVATE">Private keys</th></tr></tbody>
|
||||||
<tbody data-bind="foreach: openpgpkeysPrivate, i18nUpdate: openpgpkeysPrivate">
|
<tbody data-bind="foreach: openpgpkeysPrivate, i18nUpdate: openpgpkeysPrivate">
|
||||||
|
|
@ -117,8 +117,36 @@
|
||||||
</details>
|
</details>
|
||||||
<!-- /ko -->
|
<!-- /ko -->
|
||||||
|
|
||||||
<details>
|
<details style="margin:1em 0">
|
||||||
<summary class="legend">Mailvelope</summary>
|
<summary style="font-size:larger;font-weight:bold">Mailvelope</summary>
|
||||||
<a data-bind="visible: !canMailvelope" href="https://mailvelope.com/en/help" target="_blank" data-i18n="SETTINGS_OPENPGP/GET_MAILVELOPE"></a>
|
<a data-bind="visible: !canMailvelope" href="https://mailvelope.com/en/help" target="_blank" data-i18n="SETTINGS_OPENPGP/GET_MAILVELOPE"></a>
|
||||||
<div id="mailvelope-settings" style="height:40em" data-bind="visible: canMailvelope"></div>
|
<div id="mailvelope-settings" style="height:40em" data-bind="visible: canMailvelope"></div>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary class="legend">S/MIME Certificates</summary>
|
||||||
|
<table class="table table-hover list-table">
|
||||||
|
<tbody data-bind="foreach: smimeCertificates">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<span data-bind="visible: smimesign" class="fontastic" data-i18n="[title]CRYPTO/VERIFY">✔</span>
|
||||||
|
<span data-bind="visible: smimeencrypt" class="fontastic" data-i18n="[title]CRYPTO/ENCRYPT">🔒</span>
|
||||||
|
<span class="key-name" data-bind="text: CN"></span>
|
||||||
|
<span class="key-user" data-bind="text: emailAddress"></span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<time data-time-format="FULL" data-bind="attr:{datetime:validTo}"></time>
|
||||||
|
</td>
|
||||||
|
<!--
|
||||||
|
<td>
|
||||||
|
<a class="btn btn-small btn-danger button-confirm-delete" data-bind="css: {'delete-access': askDelete()}, click: remove"
|
||||||
|
data-i18n="GLOBAL/ARE_YOU_SURE"></a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span class="delete-key fontastic" data-bind="visible: !askDelete(), click: openForDeletion">🗑</span>
|
||||||
|
</td>
|
||||||
|
-->
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</details>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue