Added: DoGnupgGenerateKey() which generates new private keys

This commit is contained in:
the-djmaze 2022-01-24 17:05:11 +01:00
parent 8635771537
commit 998a1c6cc8
3 changed files with 126 additions and 10 deletions

View file

@ -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', '');

View file

@ -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;
}
}
}
}

View file

@ -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');