mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-07 08:27:03 +03:00
Added: DoGnupgGenerateKey() which generates new private keys
This commit is contained in:
parent
8635771537
commit
998a1c6cc8
3 changed files with 126 additions and 10 deletions
|
|
@ -54,6 +54,23 @@ trait Pgp
|
||||||
: $this->FalseResponse(__FUNCTION__);
|
: $this->FalseResponse(__FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function DoGnupgGenerateKey() : array
|
||||||
|
{
|
||||||
|
$fingerprint = false;
|
||||||
|
$GPG = $this->GnuPG();
|
||||||
|
if ($GPG) {
|
||||||
|
$sName = $this->GetActionParam('Name', '');
|
||||||
|
$sEmail = $this->GetActionParam('Email', '');
|
||||||
|
$fingerprint = $GPG->generateKey(
|
||||||
|
$sName ? "{$sName} <{$sEmail}>" : $sEmail,
|
||||||
|
$this->GetActionParam('Passphrase', '')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return $fingerprint
|
||||||
|
? $this->DefaultResponse(__FUNCTION__, $fingerprint)
|
||||||
|
: $this->FalseResponse(__FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
public function DoGnupgImportKey() : array
|
public function DoGnupgImportKey() : array
|
||||||
{
|
{
|
||||||
$sKey = $this->GetActionParam('Key', '');
|
$sKey = $this->GetActionParam('Key', '');
|
||||||
|
|
|
||||||
|
|
@ -401,6 +401,20 @@ class GnuPG
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a key
|
||||||
|
*/
|
||||||
|
public function generateKey(string $uid, string $passphrase) /*: string|false*/
|
||||||
|
{
|
||||||
|
if (!$this->GPG) {
|
||||||
|
if (!\SnappyMail\PGP\GPG::isSupported()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$this->GPG = new \SnappyMail\PGP\GPG($homedir);
|
||||||
|
}
|
||||||
|
return $this->GPG->generateKey($uid, $passphrase);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Imports a key
|
* Imports a key
|
||||||
*/
|
*/
|
||||||
|
|
@ -446,12 +460,6 @@ class GnuPG
|
||||||
// Public
|
// Public
|
||||||
foreach ($GPG->keyinfo($pattern) as $info) {
|
foreach ($GPG->keyinfo($pattern) as $info) {
|
||||||
if (!$info['disabled'] && !$info['expired'] && !$info['revoked']) {
|
if (!$info['disabled'] && !$info['expired'] && !$info['revoked']) {
|
||||||
/*
|
|
||||||
$hasPrivateKey = false;
|
|
||||||
foreach ($info['subkeys'] as $key) {
|
|
||||||
$hasPrivateKey |= \is_file("{$this->homedir}/private-keys-v1.d/{$key['keygrip']}.key");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
foreach ($info['uids'] as $uid) {
|
foreach ($info['uids'] as $uid) {
|
||||||
$id = $uid['email'];
|
$id = $uid['email'];
|
||||||
if (isset($keys[$id])) {
|
if (isset($keys[$id])) {
|
||||||
|
|
@ -466,9 +474,15 @@ class GnuPG
|
||||||
'can_encrypt' => $info['can_encrypt'],
|
'can_encrypt' => $info['can_encrypt'],
|
||||||
// Private Key tasks
|
// Private Key tasks
|
||||||
'can_sign' => false,
|
'can_sign' => false,
|
||||||
'can_decrypt' => false
|
'can_decrypt' => false,
|
||||||
|
// The keys
|
||||||
|
'publicKeys' => [],
|
||||||
|
'privateKeys' => []
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
foreach ($info['subkeys'] as $key) {
|
||||||
|
$keys[$id]['publicKeys'][$key['fingerprint']] = $key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -489,9 +503,15 @@ class GnuPG
|
||||||
'can_encrypt' => false,
|
'can_encrypt' => false,
|
||||||
// Private Key tasks
|
// Private Key tasks
|
||||||
'can_sign' => $info['can_sign'],
|
'can_sign' => $info['can_sign'],
|
||||||
'can_decrypt' => $info['can_encrypt']
|
'can_decrypt' => $info['can_encrypt'],
|
||||||
|
// The keys
|
||||||
|
'publicKeys' => [],
|
||||||
|
'privateKeys' => []
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
foreach ($info['subkeys'] as $key) {
|
||||||
|
$keys[$id]['privateKeys'][$key['fingerprint']] = $key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,10 +53,10 @@ class GPG
|
||||||
|
|
||||||
private
|
private
|
||||||
$binary,
|
$binary,
|
||||||
$version = '1.0',
|
$version = '2.0',
|
||||||
$cipher_algorithms = ['IDEA', '3DES', 'CAST5', 'BLOWFISH', 'AES', 'AES192', 'AES256', 'TWOFISH', 'CAMELLIA128', 'CAMELLIA192', 'CAMELLIA256'],
|
$cipher_algorithms = ['IDEA', '3DES', 'CAST5', 'BLOWFISH', 'AES', 'AES192', 'AES256', 'TWOFISH', 'CAMELLIA128', 'CAMELLIA192', 'CAMELLIA256'],
|
||||||
$hash_algorithms = ['SHA1', 'RIPEMD160', 'SHA256', 'SHA384', 'SHA512', 'SHA224'],
|
$hash_algorithms = ['SHA1', 'RIPEMD160', 'SHA256', 'SHA384', 'SHA512', 'SHA224'],
|
||||||
$pubkey_algorithms = ['RSA', 'DSA'],
|
$pubkey_algorithms = ['RSA', 'ELG', 'DSA', 'ECDH', 'ECDSA', 'EDDSA'],
|
||||||
$compression = ['Uncompressed', 'ZIP', 'ZLIB'],
|
$compression = ['Uncompressed', 'ZIP', 'ZLIB'],
|
||||||
|
|
||||||
$proc_resource,
|
$proc_resource,
|
||||||
|
|
@ -303,6 +303,85 @@ class GPG
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a key
|
||||||
|
* Also saves revocation certificate in {homedir}/openpgp-revocs.d/
|
||||||
|
*/
|
||||||
|
public function generateKey(string $uid, string $passphrase) /*: string|false*/
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* https://www.gnupg.org/documentation/manuals/gnupg/Unattended-GPG-key-generation.html
|
||||||
|
* But it can't generate multiple subkeys
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
$this->_input = "Key-Type: ECDSA
|
||||||
|
Key-Curve: nistp256
|
||||||
|
Key-Usage: sign
|
||||||
|
Subkey-Type: ecdh
|
||||||
|
Subkey-Curve: Curve25519
|
||||||
|
Subkey-Usage: sign
|
||||||
|
Name-Real: John
|
||||||
|
Name-Comment: comment
|
||||||
|
Name-Email: john.doe@example.com
|
||||||
|
Expire-Date: 0
|
||||||
|
Passphrase: {$passphrase}
|
||||||
|
%commit";
|
||||||
|
|
||||||
|
// gpg --full-generate-key
|
||||||
|
// gpg --quick-gen-key
|
||||||
|
$result = $this->exec(array(
|
||||||
|
'--batch',
|
||||||
|
'--yes',
|
||||||
|
'--full-gen-key' // '--gen-key'
|
||||||
|
));
|
||||||
|
*/
|
||||||
|
$arguments = array(
|
||||||
|
'--batch',
|
||||||
|
'--yes',
|
||||||
|
'--passphrase', \escapeshellarg($passphrase)
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = $this->exec(\array_merge($arguments, array(
|
||||||
|
'--quick-generate-key',
|
||||||
|
\escapeshellarg(\rawurlencode($uid)),
|
||||||
|
'ed25519',
|
||||||
|
'cert',
|
||||||
|
'0'
|
||||||
|
)));
|
||||||
|
$fingerprint = '';
|
||||||
|
foreach ($result['status'] as $line) {
|
||||||
|
$tokens = \explode(' ', $line);
|
||||||
|
if ('KEY_CREATED' === $tokens[0]/* && 'P' === $tokens[1]*/) {
|
||||||
|
$fingerprint = $tokens[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$fingerprint) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$arguments[] = '--quick-add-key';
|
||||||
|
$arguments[] = $fingerprint;
|
||||||
|
$this->exec(\array_merge($arguments, array(
|
||||||
|
'ed25519',
|
||||||
|
'sign',
|
||||||
|
'0'
|
||||||
|
)));
|
||||||
|
$this->exec(\array_merge($arguments, array(
|
||||||
|
'cv25519',
|
||||||
|
'encrypt',
|
||||||
|
'0'
|
||||||
|
)));
|
||||||
|
/*
|
||||||
|
[status][0] => KEY_NOT_CREATED
|
||||||
|
[errors][0] => gpg: -:3: specified Key-Usage not allowed for algo 22
|
||||||
|
[errors][0] => gpg: key generation failed: Unknown elliptic curve
|
||||||
|
|
||||||
|
[status][0] => KEY_CONSIDERED B2FD2BCADCC6A9E4B2C90DBBE776CADFF94D327F 0
|
||||||
|
[status][1] => KEY_CREATED P B2FD2BCADCC6A9E4B2C90DBBE776CADFF94D327F
|
||||||
|
*/
|
||||||
|
return $fingerprint;
|
||||||
|
}
|
||||||
|
|
||||||
protected function _importKey($input) /*: array|false*/
|
protected function _importKey($input) /*: array|false*/
|
||||||
{
|
{
|
||||||
$arguments = array('--import');
|
$arguments = array('--import');
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue