mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-07 00:17:03 +03:00
Optionally use existing private key to generate S/MIME certificate
This commit is contained in:
parent
97b65465e2
commit
182f884374
6 changed files with 41 additions and 14 deletions
|
|
@ -52,10 +52,13 @@ export class IdentityPopupView extends AbstractViewPopup {
|
||||||
if (oData.Result.x509) {
|
if (oData.Result.x509) {
|
||||||
identity.smimeKey(oData.Result.pkey);
|
identity.smimeKey(oData.Result.pkey);
|
||||||
identity.smimeCertificate(oData.Result.x509);
|
identity.smimeCertificate(oData.Result.x509);
|
||||||
|
} else {
|
||||||
|
this.submitError(oData.ErrorMessage);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
name: identity.name(),
|
name: identity.name(),
|
||||||
email: identity.email(),
|
email: identity.email(),
|
||||||
|
privateKey: identity.smimeKey(),
|
||||||
passphrase: pass.password
|
passphrase: pass.password
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -261,7 +261,11 @@ trait Accounts
|
||||||
if (!$oIdentity->FromJSON($this->GetActionParams(), true)) {
|
if (!$oIdentity->FromJSON($this->GetActionParams(), true)) {
|
||||||
throw new ClientException(Notifications::InvalidInputArgument);
|
throw new ClientException(Notifications::InvalidInputArgument);
|
||||||
}
|
}
|
||||||
|
/* // TODO: verify private key for certificate?
|
||||||
|
if ($oIdentity->smimeCertificate && $oIdentity->smimeKey) {
|
||||||
|
new \SnappyMail\SMime\Certificate($oIdentity->smimeCertificate, $oIdentity->smimeKey);
|
||||||
|
}
|
||||||
|
*/
|
||||||
$this->IdentitiesProvider()->UpdateIdentity($oAccount, $oIdentity);
|
$this->IdentitiesProvider()->UpdateIdentity($oAccount, $oIdentity);
|
||||||
return $this->TrueResponse();
|
return $this->TrueResponse();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,15 +59,13 @@ trait SMime
|
||||||
{
|
{
|
||||||
$oAccount = $this->getAccountFromToken();
|
$oAccount = $this->getAccountFromToken();
|
||||||
|
|
||||||
$sName = $this->GetActionParam('name', '') ?: $oAccount->Name();
|
|
||||||
$sEmail = $this->GetActionParam('email', '') ?: $oAccount->Email();
|
|
||||||
$sPassphrase = $this->GetActionParam('passphrase', '');
|
$sPassphrase = $this->GetActionParam('passphrase', '');
|
||||||
$this->logMask($sPassphrase);
|
$this->logMask($sPassphrase);
|
||||||
|
|
||||||
$cert = new Certificate();
|
$cert = new Certificate();
|
||||||
$cert->distinguishedName['commonName'] = $sName;
|
$cert->distinguishedName['commonName'] = $this->GetActionParam('name', '') ?: $oAccount->Name();
|
||||||
$cert->distinguishedName['emailAddress'] = $sEmail;
|
$cert->distinguishedName['emailAddress'] = $this->GetActionParam('email', '') ?: $oAccount->Email();
|
||||||
$result = $cert->createSelfSigned($sPassphrase);
|
$result = $cert->createSelfSigned($sPassphrase, $this->GetActionParam('privateKey', ''));
|
||||||
return $this->DefaultResponse($result ?: false);
|
return $this->DefaultResponse($result ?: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,16 @@ class Identity implements \JsonSerializable
|
||||||
$this->sEmail = $sEmail;
|
$this->sEmail = $sEmail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function __get(string $name)
|
||||||
|
{
|
||||||
|
if (!\property_exists($this, $name)) {
|
||||||
|
$name = \substr($name, 1);
|
||||||
|
}
|
||||||
|
if (\property_exists($this, $name)) {
|
||||||
|
return $this->$name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function toMime() : \MailSo\Mime\Email
|
function toMime() : \MailSo\Mime\Email
|
||||||
{
|
{
|
||||||
return new \MailSo\Mime\Email($this->sEmail, $this->sName);
|
return new \MailSo\Mime\Email($this->sEmail, $this->sName);
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,11 @@ class Certificate
|
||||||
return \openssl_get_cipher_methods($aliases);
|
return \openssl_get_cipher_methods($aliases);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createSelfSigned(string $passphrase = '') : array
|
public function createSelfSigned(
|
||||||
|
#[\SensitiveParameter]
|
||||||
|
string $passphrase = '',
|
||||||
|
?string $privateKey = null
|
||||||
|
) : array
|
||||||
{
|
{
|
||||||
$options = array(
|
$options = array(
|
||||||
'config' => __DIR__ . '/openssl.cnf',
|
'config' => __DIR__ . '/openssl.cnf',
|
||||||
|
|
@ -134,7 +138,13 @@ class Certificate
|
||||||
}
|
}
|
||||||
|
|
||||||
$pkey = null; // openssl_pkey_new($options);
|
$pkey = null; // openssl_pkey_new($options);
|
||||||
$csr = \openssl_csr_new($dn, $pkey, $options);
|
if ($privateKey) {
|
||||||
|
$pkey = \openssl_pkey_get_private($privateKey, $passphrase);
|
||||||
|
if (!$pkey) {
|
||||||
|
throw new \RuntimeException('OpenSSL pkey: ' . \openssl_error_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$csr = \openssl_csr_new($dn, $pkey, $options);
|
||||||
if ($csr) {
|
if ($csr) {
|
||||||
$this->x509 = \openssl_csr_sign(
|
$this->x509 = \openssl_csr_sign(
|
||||||
$csr,
|
$csr,
|
||||||
|
|
@ -145,13 +155,11 @@ class Certificate
|
||||||
);
|
);
|
||||||
if ($this->x509/* && $this->canSign() && $this->canEncrypt()*/) {
|
if ($this->x509/* && $this->canSign() && $this->canEncrypt()*/) {
|
||||||
$this->pkey = $pkey;
|
$this->pkey = $pkey;
|
||||||
$privatekey = '';
|
$privateKey || \openssl_pkey_export($pkey, $privateKey, $passphrase);
|
||||||
$certificate = '';
|
$certificate = '';
|
||||||
$csrStr = '';
|
|
||||||
\openssl_pkey_export($pkey, $privatekey, $passphrase);
|
|
||||||
\openssl_x509_export($this->x509, $certificate);
|
\openssl_x509_export($this->x509, $certificate);
|
||||||
return array(
|
return array(
|
||||||
'pkey' => $privatekey,
|
'pkey' => $privateKey,
|
||||||
'x509' => $certificate,
|
'x509' => $certificate,
|
||||||
// 'pkcs12' => $this->asPKCS12($pkey, $passphrase/*, array $args = array()*/)
|
// 'pkcs12' => $this->asPKCS12($pkey, $passphrase/*, array $args = array()*/)
|
||||||
// 'canSign' => $this->canSign(),
|
// 'canSign' => $this->canSign(),
|
||||||
|
|
@ -167,7 +175,11 @@ class Certificate
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns binary data
|
// returns binary data
|
||||||
public function asPKCS12(string $pass = '', array $args = array()) : string
|
public function asPKCS12(
|
||||||
|
#[\SensitiveParameter]
|
||||||
|
string $pass = '',
|
||||||
|
array $args = array()
|
||||||
|
) : string
|
||||||
{
|
{
|
||||||
$out = '';
|
$out = '';
|
||||||
\openssl_pkcs12_export($this->x509, $out, $this->pkey, $pass, $args);
|
\openssl_pkcs12_export($this->x509, $out, $this->pkey, $pass, $args);
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@
|
||||||
<label>Certificate</label>
|
<label>Certificate</label>
|
||||||
<textarea name="smimeCertificate" class="input-xxlarge" rows="14" autofocus="" autocomplete="off" data-bind="value: smimeCertificate"></textarea>
|
<textarea name="smimeCertificate" class="input-xxlarge" rows="14" autofocus="" autocomplete="off" data-bind="value: smimeCertificate"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group" data-bind="hidden:smimeKey">
|
<div class="control-group" data-bind="hidden:smimeCertificate">
|
||||||
<label></label>
|
<label></label>
|
||||||
<button type="button" data-bind="click: $root.createSelfSigned" data-i18n="CRYPTO/CREATE_SELF_SIGNED"></button>
|
<button type="button" data-bind="click: $root.createSelfSigned" data-i18n="CRYPTO/CREATE_SELF_SIGNED"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue