mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-10-28 16:13:32 +03:00
Added Base32 for handling GnuPG WKD key finder
This commit is contained in:
parent
6d0b2121b8
commit
b792fd461d
3 changed files with 102 additions and 4 deletions
84
snappymail/v/0.0.0/app/libraries/snappymail/base32.php
Normal file
84
snappymail/v/0.0.0/app/libraries/snappymail/base32.php
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
namespace SnappyMail;
|
||||
|
||||
class Base32
|
||||
{
|
||||
private string $chars;
|
||||
|
||||
function __construct(string $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
|
||||
{
|
||||
$this->chars = $chars;
|
||||
}
|
||||
|
||||
public function random(int $length): string
|
||||
{
|
||||
$secret = '';
|
||||
while (0 < $length--) {
|
||||
$secret .= $this->chars[\random_int(0,31)];
|
||||
}
|
||||
return $secret;
|
||||
}
|
||||
|
||||
public function encode(string $data, bool $padding = false, int $chunklen = 0, string $end = "\r\n"): string
|
||||
{
|
||||
$sl = \is_string($data) ? \strlen($data) : 0;
|
||||
|
||||
$base32 = '';
|
||||
$remainder = 0;
|
||||
$remainderSize = 0;
|
||||
|
||||
for ($i = 0; $i < $sl; ++$i) {
|
||||
$remainder = ($remainder << 8) | \ord($data[$i]);
|
||||
$remainderSize += 8;
|
||||
while ($remainderSize > 4) {
|
||||
$remainderSize -= 5;
|
||||
$base32 .= $this->chars[($remainder & (31 << $remainderSize)) >> $remainderSize];
|
||||
}
|
||||
}
|
||||
|
||||
if ($remainderSize > 0) {
|
||||
// remainderSize < 5:
|
||||
$base32 .= $this->chars[($remainder << (5 - $remainderSize)) & 31];
|
||||
}
|
||||
|
||||
if ($padding) {
|
||||
$base32 .= \str_repeat('=', (8 - \ceil(($sl % 5) * 8 / 5)) % 8);
|
||||
}
|
||||
|
||||
return 0 < $chunklen
|
||||
? \chunk_split($base32, $chunklen, $end)
|
||||
: $base32;
|
||||
}
|
||||
|
||||
public function decode(string $data, bool $strict = false): ?string
|
||||
{
|
||||
$data = \strtoupper(\rtrim($data, "=\x20\t\n\r\0\x0B"));
|
||||
$dataSize = \strlen($data);
|
||||
$buf = 0;
|
||||
$bufSize = 0;
|
||||
$res = '';
|
||||
$charMap = \array_flip(\str_split($this->chars));
|
||||
for ($i = 0; $i < $dataSize; ++$i) {
|
||||
$c = $data[$i];
|
||||
if (isset($charMap[$c])) {
|
||||
$buf = ($buf << 5) | $charMap[$c];
|
||||
$bufSize += 5;
|
||||
if ($bufSize > 7) {
|
||||
$bufSize -= 8;
|
||||
$res .= \chr(($buf & (0xff << $bufSize)) >> $bufSize);
|
||||
}
|
||||
} else if ($strict && false === \strpos(" \r\n\t", $c)) {
|
||||
\trigger_error('Base32 string contains unexpected char #'.\ord($c)." at offset {$i}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function verify(string $data): bool
|
||||
{
|
||||
return (bool) \preg_match('/^['.\preg_quote($this->chars).' \\r\\n\\t]+=*$/D', $data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -398,6 +398,11 @@ class PGP extends Base implements \SnappyMail\PGP\PGPInterface
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Import remote key from WKD
|
||||
gpg --auto-key-locate clear,wkd --locate-keys releases@snappymail.eu
|
||||
*/
|
||||
|
||||
public function deleteKey(string $keyId, bool $private): bool
|
||||
{
|
||||
$key = $this->keyInfo($keyId, $private);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ abstract class Keyservers
|
|||
'https://pool.sks-keyservers.net',
|
||||
'https://keys.mailvelope.com',
|
||||
'https://keyserver.ubuntu.com',
|
||||
'hkps://openpgpkeyserver.com',
|
||||
*/
|
||||
];
|
||||
|
||||
|
|
@ -196,10 +197,18 @@ abstract class Keyservers
|
|||
*/
|
||||
}
|
||||
|
||||
/** https://wiki.gnupg.org/WKD */
|
||||
public static function wkd(string $host, string $keyid)
|
||||
/**
|
||||
* https://wiki.gnupg.org/WKD
|
||||
* gpg --with-wkd-hash --fingerprint releases@snappymail.eu
|
||||
* gpg --no-armor --export releases@snappymail.eu > i4cdqgcarfjdjnba6y4jnf498asg8c6p
|
||||
*/
|
||||
public static function wkd(string $host, string $emailAddress)
|
||||
{
|
||||
/*
|
||||
$localPart = \explode('@', $emailAddress)[0];
|
||||
$b32 = new \SnappyMail\Base32('ybndrfg8ejkmcpqxot1uwisza345h769');
|
||||
$keyid = $b32->encode(\sha1($localPart, true));
|
||||
|
||||
"https://{$host}/.well-known/openpgpkey/hu/{$keyid}";
|
||||
/** https://wiki.gnupg.org/WKD
|
||||
DNS:
|
||||
|
|
@ -208,8 +217,8 @@ abstract class Keyservers
|
|||
https://openpgpkey.example.com/.well-known/openpgpkey/example.com/hu/
|
||||
else https://example.com/.well-known/openpgpkey/hu/
|
||||
|
||||
An example: https://example.com/.well-known/openpgpkey/hu/it5sewh54rxz33fwmr8u6dy4bbz8itz4
|
||||
is the direct method URL for "bernhard.reiter@example.com"
|
||||
An example: https://snappymail.eu/.well-known/openpgpkey/hu/i4cdqgcarfjdjnba6y4jnf498asg8c6p
|
||||
is the direct method URL for "releases@snappymail.eu"
|
||||
*/
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue