From 32b8d58bd6632430131be7e16c8c166422ce26ba Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Mon, 29 Jun 2020 20:58:34 +0200 Subject: [PATCH] Add WKD Local Part utility --- assets/scripts.js | 57 ++++++++++++++++++++++++++++++++++++++++++++- index.php | 8 ++++++- pages/util/wkd.html | 50 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 pages/util/wkd.html diff --git a/assets/scripts.js b/assets/scripts.js index ee9bf9f..a4b7477 100644 --- a/assets/scripts.js +++ b/assets/scripts.js @@ -504,12 +504,50 @@ async function fetchKeys(opts) { return output; } +function encodeZBase32(data) { + // Source: https://github.com/openpgpjs/openpgpjs/blob/master/src/util.js + if (data.length === 0) { + return ""; + } + const ALPHABET = "ybndrfg8ejkmcpqxot1uwisza345h769"; + const SHIFT = 5; + const MASK = 31; + let buffer = data[0]; + let index = 1; + let bitsLeft = 8; + let result = ''; + while (bitsLeft > 0 || index < data.length) { + if (bitsLeft < SHIFT) { + if (index < data.length) { + buffer <<= 8; + buffer |= data[index++] & 0xff; + bitsLeft += 8; + } else { + const pad = SHIFT - bitsLeft; + buffer <<= pad; + bitsLeft += pad; + } + } + bitsLeft -= SHIFT; + result += ALPHABET[MASK & (buffer >> bitsLeft)]; + } + return result; +} + +async function computeWKDLocalPart(message) { + const encoder = new TextEncoder(); + const data = encoder.encode(message); + const hash = await crypto.subtle.digest('SHA-1', data); + return encodeZBase32(new Uint8Array(hash)); +} + // General purpose let elFormVerify = document.body.querySelector("#form-verify"), elFormEncrypt = document.body.querySelector("#form-encrypt"), elFormProofs = document.body.querySelector("#form-proofs"), elProfileUid = document.body.querySelector("#profileUid"), - elProfileMode = document.body.querySelector("#profileMode"); + elProfileMode = document.body.querySelector("#profileMode"), + elUtilWKD = document.body.querySelector("#form-util-wkd"); if (elFormVerify) { elFormVerify.onsubmit = function (evt) { @@ -628,3 +666,20 @@ if (elProfileUid) { } displayProfile(opts); } + +if (elUtilWKD) { + elUtilWKD.onsubmit = function (evt) { + evt.preventDefault(); + } + + const elInput = document.body.querySelector("#input"); + const elOutput = document.body.querySelector("#output"); + + elInput.addEventListener("input", async function(evt) { + if (evt.target.value) { + elOutput.value = await computeWKDLocalPart(evt.target.value); + } else { + elOutput.value = ""; + } + }); +} diff --git a/index.php b/index.php index ec8317d..1b23e7c 100644 --- a/index.php +++ b/index.php @@ -26,6 +26,7 @@ $router->map('GET', '/encrypt/[:uid]', function() {}, 'encryptUid'); $router->map('GET', '/proofs/[:uid]', function() {}, 'proofsUid'); $router->map('GET', '/hkp/[**:uid]', function() {}, 'profileHKP'); $router->map('GET', '/wkd/[**:uid]', function() {}, 'profileWKD'); +$router->map('GET', '/util/[:id]', function() {}, 'util'); $router->map('GET', '/[**:uid]', function() {}, 'profile'); // Router matching @@ -132,8 +133,13 @@ if(is_array($match) && is_callable($match['target'])) { echo($content); break; + case 'util': + $id = $match['params']['id']; + readfile("pages/util/$id.html"); + break; + case 'faq': - readfile('pages/faq.html'); + readfile("pages/faq.html"); break; } } else { diff --git a/pages/util/wkd.html b/pages/util/wkd.html new file mode 100644 index 0000000..ef8cf89 --- /dev/null +++ b/pages/util/wkd.html @@ -0,0 +1,50 @@ + + + + + + + WKD utilities - Keyoxide + + + +
+
+ Keyoxide +
+ +
+
+ +
+

WKD Local Part

+
+
+

Name

+ +

Result

+ +
+
+ + +
+ + + + +