mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-07 08:27:03 +03:00
Added support to lookup public keys online #89
This commit is contained in:
parent
bac6c2d332
commit
6c01db395d
4 changed files with 47 additions and 9 deletions
|
|
@ -4,11 +4,16 @@ import { OpenPGPUserStore } from 'Stores/User/OpenPGP';
|
||||||
|
|
||||||
import { AbstractViewPopup } from 'Knoin/AbstractViews';
|
import { AbstractViewPopup } from 'Knoin/AbstractViews';
|
||||||
|
|
||||||
|
import Remote from 'Remote/User/Fetch';
|
||||||
|
import { i18n } from 'Common/Translator';
|
||||||
|
|
||||||
export class OpenPgpImportPopupView extends AbstractViewPopup {
|
export class OpenPgpImportPopupView extends AbstractViewPopup {
|
||||||
constructor() {
|
constructor() {
|
||||||
super('OpenPgpImport');
|
super('OpenPgpImport');
|
||||||
|
|
||||||
addObservablesTo(this, {
|
addObservablesTo(this, {
|
||||||
|
search: '',
|
||||||
|
|
||||||
key: '',
|
key: '',
|
||||||
keyError: false,
|
keyError: false,
|
||||||
keyErrorMessage: '',
|
keyErrorMessage: '',
|
||||||
|
|
@ -25,6 +30,21 @@ export class OpenPgpImportPopupView extends AbstractViewPopup {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
searchPGP() {
|
||||||
|
this.key(i18n('SUGGESTIONS/SEARCHING_DESC'));
|
||||||
|
Remote.request('SearchPGPKey',
|
||||||
|
(iError, oData) => {
|
||||||
|
if (iError) {
|
||||||
|
this.key(oData.ErrorMessage);
|
||||||
|
} else {
|
||||||
|
this.key(oData.Result);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
query: this.search()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
submitForm() {
|
submitForm() {
|
||||||
let keyTrimmed = this.key().trim();
|
let keyTrimmed = this.key().trim();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,14 @@ trait Pgp
|
||||||
* Also see trait Messages::DoMessagePgpVerify
|
* Also see trait Messages::DoMessagePgpVerify
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
public function DoSearchPGPKey() : array
|
||||||
|
{
|
||||||
|
$result = \SnappyMail\PGP\Keyservers::get(
|
||||||
|
$this->GetActionParam('query', '')
|
||||||
|
);
|
||||||
|
return $this->DefaultResponse($result ?: false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \MailSo\RuntimeException
|
* @throws \MailSo\RuntimeException
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,10 @@
|
||||||
* https://datatracker.ietf.org/doc/html/rfc4387
|
* https://datatracker.ietf.org/doc/html/rfc4387
|
||||||
* https://datatracker.ietf.org/doc/html/rfc7929
|
* https://datatracker.ietf.org/doc/html/rfc7929
|
||||||
* https://datatracker.ietf.org/doc/html/draft-koch-openpgp-webkey-service-13
|
* https://datatracker.ietf.org/doc/html/draft-koch-openpgp-webkey-service-13
|
||||||
|
*
|
||||||
|
* GET https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=security@snappymail.eu
|
||||||
|
* GET https://keys.openpgp.org/vks/v1/by-fingerprint/445D265124E6072671E64D0733F868A7E35E8277
|
||||||
|
* GET https://openpgpkey.example.org/.well-known/openpgpkey/example.org/hu/ihyath4noz8dsckzjbuyqnh4kbup6h4i?l=john.doe
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace SnappyMail\PGP;
|
namespace SnappyMail\PGP;
|
||||||
|
|
@ -15,18 +19,16 @@ namespace SnappyMail\PGP;
|
||||||
abstract class Keyservers
|
abstract class Keyservers
|
||||||
{
|
{
|
||||||
public static $hosts = [
|
public static $hosts = [
|
||||||
|
'https://keys.openpgp.org'
|
||||||
/*
|
/*
|
||||||
'https://keys.openpgp.org',
|
|
||||||
'https://pgp.mit.edu',
|
'https://pgp.mit.edu',
|
||||||
'https://keyring.debian.org',
|
'https://keyring.debian.org',
|
||||||
'https://attester.flowcrypt.com',
|
'https://attester.flowcrypt.com',
|
||||||
'https://zimmermann.mayfirst.org',
|
'https://zimmermann.mayfirst.org',
|
||||||
'https://pool.sks-keyservers.net',
|
'https://pool.sks-keyservers.net',
|
||||||
'https://keys.mailvelope.com',
|
'https://keys.mailvelope.com',
|
||||||
*/
|
|
||||||
'https://keyserver.ubuntu.com',
|
'https://keyserver.ubuntu.com',
|
||||||
'https://keys.fedoraproject.org',
|
*/
|
||||||
'https://keys.openpgp.org'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
private static function fetch(string $host, string $op, string $search, bool $fingerprint = false, bool $exact = false) : ?\SnappyMail\HTTP\Response
|
private static function fetch(string $host, string $op, string $search, bool $fingerprint = false, bool $exact = false) : ?\SnappyMail\HTTP\Response
|
||||||
|
|
@ -36,7 +38,9 @@ abstract class Keyservers
|
||||||
$search = \urlencode($search);
|
$search = \urlencode($search);
|
||||||
$fingerprint = $fingerprint ? '&fingerprint=on' : '';
|
$fingerprint = $fingerprint ? '&fingerprint=on' : '';
|
||||||
$exact = $exact ? '&exact=on' : '';
|
$exact = $exact ? '&exact=on' : '';
|
||||||
return static::HTTP()->doRequest('GET', "{$host}/pks/lookup?op={$op}&options=mr{$fingerprint}&search={$search}");
|
$url = "{$host}/pks/lookup?op={$op}&options=mr{$fingerprint}&search={$search}";
|
||||||
|
\SnappyMail\Log::debug('PGP', $url);
|
||||||
|
return static::HTTP()->doRequest('GET', $url);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static $HTTP;
|
private static $HTTP;
|
||||||
|
|
@ -56,11 +60,12 @@ abstract class Keyservers
|
||||||
*/
|
*/
|
||||||
public static function get(string $keyId) : string
|
public static function get(string $keyId) : string
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
// add the 0x prefix if absent
|
// add the 0x prefix if absent
|
||||||
if ('0x' !== \substr($keyId, 0, 2)) {
|
if ('0x' !== \substr($keyId, 0, 2)) {
|
||||||
$keyId = '0x' . $keyId;
|
$keyId = '0x' . $keyId;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
foreach (static::$hosts as $host) {
|
foreach (static::$hosts as $host) {
|
||||||
$oResponse = static::fetch($host, 'get', $keyId);
|
$oResponse = static::fetch($host, 'get', $keyId);
|
||||||
if (!$oResponse) {
|
if (!$oResponse) {
|
||||||
|
|
@ -68,14 +73,14 @@ abstract class Keyservers
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (200 !== $oResponse->status) {
|
if (200 !== $oResponse->status) {
|
||||||
\SnappyMail\Log::info('PGP', "{$oResponse->status} for key {$keyId} on {$host}");
|
\SnappyMail\Log::debug('PGP', "{$oResponse->status} for key {$keyId} on {$host}");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $oResponse->body;
|
return $oResponse->body;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new \Exception('Could not obtain public key from the keyserver.');
|
throw new \Exception('Could not obtain public key from the keyservers.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -97,7 +102,7 @@ abstract class Keyservers
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (200 !== $oResponse->status) {
|
if (200 !== $oResponse->status) {
|
||||||
\SnappyMail\Log::info('PGP', "{$oResponse->status} for search `{$search}` on {$host}");
|
\SnappyMail\Log::debug('PGP', "{$oResponse->status} for search `{$search}` on {$host}");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,11 @@
|
||||||
</header>
|
</header>
|
||||||
<form id="openpgp-import" class="modal-body" autocomplete="off" data-bind="submit: submitForm">
|
<form id="openpgp-import" class="modal-body" autocomplete="off" data-bind="submit: submitForm">
|
||||||
<div class="alert" data-bind="visible: keyError() && keyErrorMessage(), text: keyErrorMessage"></div>
|
<div class="alert" data-bind="visible: keyError() && keyErrorMessage(), text: keyErrorMessage"></div>
|
||||||
|
<div class="control-group">
|
||||||
|
<!-- could be email or fingerprint -->
|
||||||
|
<input type="text" data-bind="textInput: search"/>
|
||||||
|
<button class="btn" type="button" data-bind="enable: search, click: searchPGP" data-i18n="GLOBAL/SEARCH"></button>
|
||||||
|
</div>
|
||||||
<div class="control-group" data-bind="css: {'error': keyError}">
|
<div class="control-group" data-bind="css: {'error': keyError}">
|
||||||
<textarea class="input-xxlarge" rows="14" autofocus="" autocomplete="off" data-bind="value: key" required=""></textarea>
|
<textarea class="input-xxlarge" rows="14" autofocus="" autocomplete="off" data-bind="value: key" required=""></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue