From e3e55778f1d4b442c7a8b67fe295f5707f5a5a1e Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Sun, 5 Jul 2020 15:04:12 +0200 Subject: [PATCH] Add support for keys hosted on keybase --- assets/scripts.js | 105 ++++++++++++++++++++++++++++++++++------------ index.php | 23 ++++++++-- views/encrypt.php | 5 +++ views/verify.php | 5 +++ 4 files changed, 107 insertions(+), 31 deletions(-) diff --git a/assets/scripts.js b/assets/scripts.js index c5b0ed9..32a09f4 100644 --- a/assets/scripts.js +++ b/assets/scripts.js @@ -205,37 +205,45 @@ async function displayProfile(opts) { let userData = keyData.user.user.userId; // Determine WKD or HKP link - if (opts.mode == "wkd") { - const [, localPart, domain] = /(.*)@(.*)/.exec(opts.input); - const localEncoded = await computeWKDLocalPart(localPart.toLowerCase()); - const urlAdvanced = `https://openpgpkey.${domain}/.well-known/openpgpkey/${domain}/hu/${localEncoded}`; - const urlDirect = `https://${domain}/.well-known/openpgpkey/hu/${localEncoded}`; + switch (opts.mode) { + case "wkd": + const [, localPart, domain] = /(.*)@(.*)/.exec(opts.input); + const localEncoded = await computeWKDLocalPart(localPart.toLowerCase()); + const urlAdvanced = `https://openpgpkey.${domain}/.well-known/openpgpkey/${domain}/hu/${localEncoded}`; + const urlDirect = `https://${domain}/.well-known/openpgpkey/hu/${localEncoded}`; - try { - keyLink = await fetch(urlAdvanced).then(function(response) { - if (response.status === 200) { - return urlAdvanced; - } - }); - } catch (e) { - console.warn(e); - } - if (!keyLink) { try { - keyLink = await fetch(urlDirect).then(function(response) { + keyLink = await fetch(urlAdvanced).then(function(response) { if (response.status === 200) { - return urlDirect; + return urlAdvanced; } }); } catch (e) { console.warn(e); } - } - if (!keyLink) { + if (!keyLink) { + try { + keyLink = await fetch(urlDirect).then(function(response) { + if (response.status === 200) { + return urlDirect; + } + }); + } catch (e) { + console.warn(e); + } + } + if (!keyLink) { + keyLink = `https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x${keyData.fingerprint}`; + } + break; + + case "hkp": keyLink = `https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x${keyData.fingerprint}`; - } - } else { - keyLink = `https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x${keyData.fingerprint}`; + break; + + case "keybase": + keyLink = opts.keyLink; + break; } // Fill in various data @@ -261,10 +269,13 @@ async function displayProfile(opts) { feedback += `
fingerprint
`; feedback += `
${keyData.fingerprint}
`; feedback += ``; - feedback += `
`; - feedback += `
qrcode
`; - feedback += ``; - feedback += `
`; + + if (opts.mode == "hkp") { + feedback += `
`; + feedback += `
qrcode
`; + feedback += ``; + feedback += `
`; + } if (keyData.notations.length > 0) { feedback += `
`; @@ -589,6 +600,27 @@ async function fetchKeys(opts) { } break; + case "keybase": + opts.keyLink = `https://keybase.io/${opts.username}/pgp_keys.asc?fingerprint=${opts.fingerprint}`; + opts.input = `${opts.username}/${opts.fingerprint}`; + try { + opts.plaintext = await fetch(opts.keyLink).then(function(response) { + if (response.status === 200) { + return response; + } + }) + .then(response => response.blob()) + .then(response => response.text()); + } catch (e) { + throw("Error: No public keys could be fetched from the Keybase account."); + } + output.publicKey = (await openpgp.key.readArmored(opts.plaintext)).keys[0]; + + if (!output.publicKey) { + throw("Error: No public keys could be read from the Keybase account."); + } + break; + case "signature": sig = (await openpgp.signature.readArmored(opts.signature)); if ('compressed' in sig.packets[0]) { @@ -738,10 +770,15 @@ if (elFormVerify) { case "plaintext": opts.input = document.body.querySelector("#plaintext_input").value; break; + + case "keybase": + opts.username = document.body.querySelector("#keybase_username").value; + opts.fingerprint = document.body.querySelector("#keybase_fingerprint").value; + break; } // If no input was detect - if (!opts.input) { + if (!opts.input && !opts.username) { opts.mode = "signature"; } @@ -781,6 +818,11 @@ if (elFormEncrypt) { case "plaintext": opts.input = document.body.querySelector("#plaintext_input").value; break; + + case "keybase": + opts.username = document.body.querySelector("#keybase_username").value; + opts.fingerprint = document.body.querySelector("#keybase_fingerprint").value; + break; } encryptMessage(opts); @@ -850,6 +892,15 @@ if (elProfileUid) { mode: elProfileMode.innerHTML } break; + + case "keybase": + let match = profileUid.match(/(.*)\/(.*)/); + opts = { + username: match[1], + fingerprint: match[2], + mode: elProfileMode.innerHTML + } + break; } displayProfile(opts); } diff --git a/index.php b/index.php index f196d91..4a85573 100644 --- a/index.php +++ b/index.php @@ -21,16 +21,19 @@ $router->map('GET', '/verify', function() {}, 'verify'); $router->map('GET', '/encrypt', function() {}, 'encrypt'); $router->map('GET', '/proofs', function() {}, 'proofs'); $router->map('GET', '/verify/hkp/[**:uid]', function() {}, 'verifyHKP'); -$router->map('GET', '/encrypt/hkp/[**:uid]', function() {}, 'encryptHKP'); -$router->map('GET', '/proofs/hkp/[**:uid]', function() {}, 'proofsHKP'); $router->map('GET', '/verify/wkd/[**:uid]', function() {}, 'verifyWKD'); -$router->map('GET', '/encrypt/wkd/[**:uid]', function() {}, 'encryptWKD'); -$router->map('GET', '/proofs/wkd/[**:uid]', function() {}, 'proofsWKD'); +$router->map('GET', '/verify/keybase/[:uid]/[:fp]', function() {}, 'verifyKeybase'); $router->map('GET', '/verify/[**:uid]', function() {}, 'verifyAUTO'); +$router->map('GET', '/encrypt/hkp/[**:uid]', function() {}, 'encryptHKP'); +$router->map('GET', '/encrypt/wkd/[**:uid]', function() {}, 'encryptWKD'); +$router->map('GET', '/encrypt/keybase/[:uid]/[:fp]', function() {}, 'encryptKeybase'); $router->map('GET', '/encrypt/[**:uid]', function() {}, 'encryptAUTO'); +$router->map('GET', '/proofs/hkp/[**:uid]', function() {}, 'proofsHKP'); +$router->map('GET', '/proofs/wkd/[**:uid]', function() {}, 'proofsWKD'); $router->map('GET', '/proofs/[**:uid]', function() {}, 'proofsAUTO'); $router->map('GET', '/hkp/[**:uid]', function() {}, 'profileHKP'); $router->map('GET', '/wkd/[**:uid]', function() {}, 'profileWKD'); +$router->map('GET', '/keybase/[:uid]/[:fp]', function() {}, 'profileKeybase'); $router->map('GET', '/[**:uid]', function() {}, 'profile'); // Router matching @@ -59,6 +62,10 @@ if(is_array($match) && is_callable($match['target'])) { echo $templates->render('verify', ['title' => 'Verify — ', 'mode' => 'wkd', 'wkd_input' => $match['params']['uid']]); break; + case 'verifyKeybase': + echo $templates->render('verify', ['title' => 'Verify — ', 'mode' => 'keybase', 'keybase_username' => htmlspecialchars($match['params']['uid']), 'keybase_fingerprint' => htmlspecialchars($match['params']['fp'])]); + break; + case 'encrypt': echo $templates->render('encrypt', ['title' => 'Encrypt — ', 'mode' => 'auto']); break; @@ -75,6 +82,10 @@ if(is_array($match) && is_callable($match['target'])) { echo $templates->render('encrypt', ['title' => 'Encrypt — ', 'mode' => 'wkd', 'wkd_input' => $match['params']['uid']]); break; + case 'encryptKeybase': + echo $templates->render('encrypt', ['title' => 'Encrypt — ', 'mode' => 'keybase', 'keybase_username' => htmlspecialchars($match['params']['uid']), 'keybase_fingerprint' => htmlspecialchars($match['params']['fp'])]); + break; + case 'proofs': echo $templates->render('proofs', ['title' => 'Proofs — ', 'mode' => 'auto']); break; @@ -103,6 +114,10 @@ if(is_array($match) && is_callable($match['target'])) { echo $templates->render('profile', ['mode' => 'wkd', 'uid' => htmlspecialchars($match['params']['uid'])]); break; + case 'profileKeybase': + echo $templates->render('profile', ['mode' => 'keybase', 'uid' => htmlspecialchars($match['params']['uid']).'/'.htmlspecialchars($match['params']['fp'])]); + break; + case 'guides': echo $templates->render('guides'); break; diff --git a/views/encrypt.php b/views/encrypt.php index 809300e..a31624e 100644 --- a/views/encrypt.php +++ b/views/encrypt.php @@ -10,6 +10,7 @@ +
@@ -25,6 +26,10 @@
+
+ + +

Message

diff --git a/views/verify.php b/views/verify.php index f208f94..40204dd 100644 --- a/views/verify.php +++ b/views/verify.php @@ -10,6 +10,7 @@ +
@@ -25,6 +26,10 @@
+
+ + +

Signature