mirror of
https://github.com/the-djmaze/snappymail.git
synced 2025-09-13 08:34:36 +08: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__);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
$sKey = $this->GetActionParam('Key', '');
|
||||
|
|
|
@ -401,6 +401,20 @@ class GnuPG
|
|||
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
|
||||
*/
|
||||
|
@ -446,12 +460,6 @@ class GnuPG
|
|||
// Public
|
||||
foreach ($GPG->keyinfo($pattern) as $info) {
|
||||
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) {
|
||||
$id = $uid['email'];
|
||||
if (isset($keys[$id])) {
|
||||
|
@ -466,9 +474,15 @@ class GnuPG
|
|||
'can_encrypt' => $info['can_encrypt'],
|
||||
// Private Key tasks
|
||||
'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,
|
||||
// Private Key tasks
|
||||
'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
|
||||
$binary,
|
||||
$version = '1.0',
|
||||
$version = '2.0',
|
||||
$cipher_algorithms = ['IDEA', '3DES', 'CAST5', 'BLOWFISH', 'AES', 'AES192', 'AES256', 'TWOFISH', 'CAMELLIA128', 'CAMELLIA192', 'CAMELLIA256'],
|
||||
$hash_algorithms = ['SHA1', 'RIPEMD160', 'SHA256', 'SHA384', 'SHA512', 'SHA224'],
|
||||
$pubkey_algorithms = ['RSA', 'DSA'],
|
||||
$pubkey_algorithms = ['RSA', 'ELG', 'DSA', 'ECDH', 'ECDSA', 'EDDSA'],
|
||||
$compression = ['Uncompressed', 'ZIP', 'ZLIB'],
|
||||
|
||||
$proc_resource,
|
||||
|
@ -303,6 +303,85 @@ class GPG
|
|||
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*/
|
||||
{
|
||||
$arguments = array('--import');
|
||||
|
|
Loading…
Add table
Reference in a new issue