Ask password to generate S/MIME self signed #259

This commit is contained in:
the-djmaze 2024-02-20 01:01:15 +01:00
parent 3f08051e37
commit 568caed3c7
43 changed files with 147 additions and 62 deletions

View file

@ -14,6 +14,8 @@ import { folderListOptionsBuilder } from 'Common/Folders';
import { i18n } from 'Common/Translator';
import { defaultOptionsAfterRender } from 'Common/Utils';
import { AskPopupView } from 'View/Popup/Ask';
export class IdentityPopupView extends AbstractViewPopup {
constructor() {
super('Identity');
@ -42,16 +44,21 @@ export class IdentityPopupView extends AbstractViewPopup {
this.createSelfSigned = this.createSelfSigned.bind(this);
}
createSelfSigned() {
let identity = this.identity();
Remote.request('SMimeCreateCertificate', (iError, oData) => {
if (oData.Result.x509) {
identity.smimeKey(oData.Result.pkey);
identity.smimeCertificate(oData.Result.x509);
}
}, {
email: identity.email()
});
async createSelfSigned() {
const identity = this.identity(),
pass = await AskPopupView.password('', 'CRYPTO/CREATE_SELF_SIGNED');
if (pass) {
Remote.request('SMimeCreateCertificate', (iError, oData) => {
if (oData.Result.x509) {
identity.smimeKey(oData.Result.pkey);
identity.smimeCertificate(oData.Result.x509);
}
}, {
name: identity.name(),
email: identity.email(),
passphrase: pass.password
});
}
}
submitForm(form) {

View file

@ -55,7 +55,7 @@ class Certificate
/**
* Verifies if a certificate can be used for a particular purpose
*/
public function checkPurpose($purpose, array $cainfo = array(), $untrustedfile = null)/*: bool|int*/
public function checkPurpose(int $purpose, array $cainfo = array(), ?string $untrustedfile = null)/*: bool|int*/
{
if ($this->x509) {
return \openssl_x509_checkpurpose($this->x509, $purpose, $cainfo, $untrustedfile);
@ -80,7 +80,7 @@ class Certificate
/**
* Returns the certificate in a PEM encoded format string
*/
public function export($notext = true) : ?string
public function export(bool $notext = true) : ?string
{
if ($this->x509) {
$output = '';
@ -94,7 +94,7 @@ class Certificate
/**
* Returns the fingerprint or digest of the certificate
*/
public function fingerprint($hash_algorithm = 'sha1', $raw_output = false)/*: string|bool*/
public function fingerprint(string $hash_algorithm = 'sha1', bool $raw_output = false)/*: string|bool*/
{
return $this->x509 ? \openssl_x509_fingerprint($this->x509, $hash_algorithm, $raw_output) : false;
}
@ -102,17 +102,17 @@ class Certificate
/**
* Returns the certificate information as an array
*/
public function info($shortnames = true) /*: array|bool*/
public function info(bool $shortnames = true) /*: array|bool*/
{
return $this->x509 ? \openssl_x509_parse($this->x509, $shortnames) : false;
}
public static function getCipherMethods($aliases = false) : array
public static function getCipherMethods(bool $aliases = false) : array
{
return \openssl_get_cipher_methods($aliases);
}
public function createSelfSigned($passphrase = null) : array
public function createSelfSigned(string $passphrase = '') : array
{
$options = array(
'config' => __DIR__ . '/openssl.cnf',
@ -144,6 +144,7 @@ class Certificate
$options
);
if ($this->x509/* && $this->canSign() && $this->canEncrypt()*/) {
$this->pkey = $pkey;
$privatekey = '';
$certificate = '';
$csrStr = '';
@ -166,10 +167,10 @@ class Certificate
}
// returns binary data
public function asPKCS12($priv_key, $pass = null, array $args = array()) : string
public function asPKCS12(string $pass = '', array $args = array()) : string
{
$out = '';
\openssl_pkcs12_export($this->x509, $out, $priv_key, $pass, $args);
\openssl_pkcs12_export($this->x509, $out, $this->pkey, $pass, $args);
return $out;
}
}

View file

@ -45,7 +45,8 @@ class OpenSSL
'file' => \basename($file),
'CN' => $data['subject']['CN'],
'emailAddress' => $data['subject']['emailAddress'],
'validTo' => \gmdate('Y-m-d\\TH:i:s\\Z', $data['validTo_time_t']),
// 'validTo' => \gmdate('Y-m-d\\TH:i:s\\Z', $data['validTo_time_t']),
'validTo_time_t' => $data['validTo_time_t'],
'smimesign' => false,
'smimeencrypt' => false,
'privateKey' => null // not found or encrypted

View file

@ -280,7 +280,9 @@
"DECRYPT": "فك تشفير",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "توقيع جيد من %USER%",
"ERROR": "%TYPE% error: %ERROR%"
"ERROR": "%TYPE% error: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "OpenPGP استيراد مفتاح",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Дешифрирай",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Валиден подпис за %USER%",
"ERROR": "%TYPE% грешка: %ERROR%"
"ERROR": "%TYPE% грешка: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Внасяне на OpenPGP ключ",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Dešifrovat",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Ověřený podpis od %USER%",
"ERROR": "%TYPE% chyba: %ERROR%"
"ERROR": "%TYPE% chyba: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Import OpenPGP klíče",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Dekrypter",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Accepteret signatur for %USER\"",
"ERROR": "%TYPE% fejl: %ERROR%"
"ERROR": "%TYPE% fejl: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importer OpenPGP nøgle",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Entschlüsseln",
"VERIFY": "Überprüfen",
"GOOD_SIGNATURE": "Gültige Unterschrift von %USER%",
"ERROR": "%TYPE%-Fehler: %ERROR%"
"ERROR": "%TYPE%-Fehler: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "OpenPGP-Schlüssel importieren",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Αποκρυπτογράφηση",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Good signature from %USER%",
"ERROR": "%TYPE% error: %ERROR%"
"ERROR": "%TYPE% error: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Εισαγωγή κλειδιού OpenPGP",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Decrypt",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Good signature from %USER%",
"ERROR": "%TYPE% error: %ERROR%"
"ERROR": "%TYPE% error: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Import OpenPGP key",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Decrypt",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Good signature from %USER%",
"ERROR": "%TYPE% error: %ERROR%"
"ERROR": "%TYPE% error: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Import OpenPGP key",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Descifrar",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Buena firma de %USER%",
"ERROR": "Error %TYPE%: %ERROR%"
"ERROR": "Error %TYPE%: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importar clave OpenPGP",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Dekrüpteeri",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Korralik signatuur kasutajalt %USER%",
"ERROR": "%TYPE% viga: %ERROR%"
"ERROR": "%TYPE% viga: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Impordi OpenPGP võti",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Deszifratu",
"VERIFY": "Egiaztatu",
"GOOD_SIGNATURE": "%USER%-en sinadura egokia",
"ERROR": "%TYPE% errorea: %ERROR%"
"ERROR": "%TYPE% errorea: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Inportatu OpenPGP gakoa",

View file

@ -280,7 +280,9 @@
"DECRYPT": "رمزگشایی",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "امضای صحیح از %USER%",
"ERROR": "خطای %TYPE%: %ERROR%"
"ERROR": "خطای %TYPE%: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "واردکردن کلید OpenPGP",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Pura",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Oikea allekirjoitus %USER% lle",
"ERROR": "%TYPE% virhe: %ERROR%"
"ERROR": "%TYPE% virhe: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Tuo OpenPGP avain",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Déchiffrer",
"VERIFY": "Vérifier",
"GOOD_SIGNATURE": "Signature valide pour %USER%",
"ERROR": "Erreur %TYPE%: %ERROR%"
"ERROR": "Erreur %TYPE%: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importer la clef OpenPGP",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Visszafejtés",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Jó aláírás tőle: %USER%",
"ERROR": "%TYPE% hiba: %ERROR%"
"ERROR": "%TYPE% hiba: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "OpenPGP kulcs importálás",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Deskripsi",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Tandatangan sah dari user %USER%",
"ERROR": "Kesalahan %TYPE%: %ERROR%"
"ERROR": "Kesalahan %TYPE%: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Impor kunci OpenPGP",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Afkóða",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Gild undirritun frá %USER%",
"ERROR": "%TYPE% villa: %ERROR%"
"ERROR": "%TYPE% villa: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Flytja inn OpenPGP-lykil",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Decriptazione",
"VERIFY": "Verifica",
"GOOD_SIGNATURE": "Firma valida da %USER%",
"ERROR": "Errore di %TYPE%: %ERROR%"
"ERROR": "Errore di %TYPE%: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importa chiave OpenPGP",

View file

@ -280,7 +280,9 @@
"DECRYPT": "復号化",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "%USER%からの正しい署名",
"ERROR": "%TYPE% エラー: %ERROR%"
"ERROR": "%TYPE% エラー: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "OpenPGPキーをインポート",

View file

@ -280,7 +280,9 @@
"DECRYPT": "복호화",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "%USER%(으)로부터 수신한 양호한 서명",
"ERROR": "%TYPE% 오류: %ERROR%"
"ERROR": "%TYPE% 오류: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "OpenPGP 키 가져오기",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Decrypt",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Tinkamas parašas nuo %USER%",
"ERROR": "%TYPE% klaida: %ERROR%"
"ERROR": "%TYPE% klaida: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importuoti OpenPGP raktą",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Decrypt",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Good signature from %USER%",
"ERROR": "%TYPE% error: %ERROR%"
"ERROR": "%TYPE% error: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Import OpenPGP key",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Dekrypter",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Gyldig signatur fra %USER%",
"ERROR": "%TYPE%-feil: %ERROR%"
"ERROR": "%TYPE%-feil: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importer OpenPGP-nøkkel",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Ontsleutelen",
"VERIFY": "Verifiëren",
"GOOD_SIGNATURE": "Juiste handtekening van %USER%",
"ERROR": "%TYPE% foutmelding: %ERROR%"
"ERROR": "%TYPE% foutmelding: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importeer OpenPGP sleutel",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Odszyfruj",
"VERIFY": "Weryfikuj",
"GOOD_SIGNATURE": "Poprawnie podpisana przez %USER%",
"ERROR": "Błąd %TYPE%: %ERROR%"
"ERROR": "Błąd %TYPE%: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importowanie klucza OpenPGP",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Decrypt",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Boa assinatura de %USER%",
"ERROR": "Erro %TYPE%: %ERROR%"
"ERROR": "Erro %TYPE%: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importar chave OpenPGP",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Desencriptar",
"VERIFY": "Validar",
"GOOD_SIGNATURE": "Boa assinatura de %USER%",
"ERROR": "Erro %TYPE%: %ERROR%"
"ERROR": "Erro %TYPE%: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importar chave OpenPGP",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Desencriptar",
"VERIFY": "Validar",
"GOOD_SIGNATURE": "Boa assinatura de %USER%",
"ERROR": "Erro %TYPE%: %ERROR%"
"ERROR": "Erro %TYPE%: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importar chave OpenPGP",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Decrypt",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Good signature from %USER%",
"ERROR": "%TYPE% error: %ERROR%"
"ERROR": "%TYPE% error: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Import OpenPGP key",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Расшифровать",
"VERIFY": "Проверить",
"GOOD_SIGNATURE": "Подтвержденная сигнатура для %USER%",
"ERROR": "%TYPE% ошибка: %ERROR%"
"ERROR": "%TYPE% ошибка: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Импорт OpenPGP ключа",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Decrypt",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Good signature from %USER%",
"ERROR": "%TYPE% error: %ERROR%"
"ERROR": "%TYPE% error: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Importovať kľúč OpenPGP",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Dešifriraj",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Dober podpis od %USER%",
"ERROR": "%TYPE% napaka: %ERROR%"
"ERROR": "%TYPE% napaka: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Uvoz OpenPGP ključa",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Avkryptera",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Godkänd signatur för %USER%",
"ERROR": "%TYPE%-fel: %ERROR%"
"ERROR": "%TYPE%-fel: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Import av OpenPGP-nyckel",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Decrypt",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Geçerli imza %USER%",
"ERROR": "%TYPE% hatası: %ERROR%"
"ERROR": "%TYPE% hatası: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "OpenPGP key'i içe aktar",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Дешифрувати",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "Підтверджена сигнатура для %USER%",
"ERROR": "%TYPE% помилка: %ERROR%"
"ERROR": "%TYPE% помилка: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Імпорт OpenPGP ключа",

View file

@ -280,7 +280,9 @@
"DECRYPT": "Gỡ mã hóa",
"VERIFY": "Xác minh",
"GOOD_SIGNATURE": "Chữ ký ổn từ %USER%",
"ERROR": "Lỗi %TYPE%: %ERROR%"
"ERROR": "Lỗi %TYPE%: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "Nhập mật mã OpenPGP",

View file

@ -280,7 +280,9 @@
"DECRYPT": "解密",
"VERIFY": "Verify",
"GOOD_SIGNATURE": "来自 %USER% 的可用签名",
"ERROR": "%TYPE% 错误: %ERROR%"
"ERROR": "%TYPE% 错误: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "导入 OpenPGP 密钥",

View file

@ -280,7 +280,9 @@
"DECRYPT": "解密",
"VERIFY": "驗證",
"GOOD_SIGNATURE": "來自「%USER%」的良好簽署",
"ERROR": "%TYPE% 錯誤: %ERROR%"
"ERROR": "%TYPE% 錯誤: %ERROR%",
"CREATE_SELF_SIGNED": "Create self-signed",
"VALID_UNTIL": "Valid until"
},
"OPENPGP": {
"POPUP_IMPORT_TITLE": "匯入 OpenPGP 金鑰",

View file

@ -98,7 +98,7 @@
</div>
<div class="control-group" data-bind="hidden:smimeKey">
<label></label>
<button type="button" data-bind="click: $root.createSelfSigned">Create self-signed</button>
<button type="button" data-bind="click: $root.createSelfSigned" data-i18n="CRYPTO/CREATE_SELF_SIGNED"></button>
</div>
</details>
</div>

View file

@ -126,16 +126,16 @@
<details>
<summary class="legend">S/MIME Certificates</summary>
<table class="table table-hover list-table">
<tbody data-bind="foreach: smimeCertificates">
<tbody data-bind="foreach: smimeCertificates, i18nUpdate: 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>
<br/>
<span data-i18n="CRYPTO/VALID_UNTIL"></span>:
<time data-time-format="FULL" data-bind="time:validTo_time_t"></time>
</td>
<!--
<td>