Skip to content

Commit 1d7b0b0

Browse files
committed
Generate and store wkd hash in the database
Thanks to wkd-client npm module, Akshay S Dinesh and Ananthu CV
1 parent 60da5dc commit 1d7b0b0

2 files changed

Lines changed: 62 additions & 0 deletions

File tree

src/lib/util.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
/**
22
* Copyright (C) 2020 Mailvelope GmbH
33
* Licensed under the GNU Affero General Public License version 3
4+
*
5+
* genWKDHash and encodeZBase32 are based on wkd-client node module,
6+
* which is WKD client implementation in javascript
7+
* Copyright (C) 2018 Wiktor Kwapisiewicz
8+
*
9+
* This library is free software; you can redistribute it and/or
10+
* modify it under the terms of the GNU Lesser General Public
11+
* License as published by the Free Software Foundation; either
12+
* version 3.0 of the License, or (at your option) any later version.
13+
*
14+
* This library is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+
* Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public
20+
* License along with this library; if not, write to the Free Software
21+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
22+
* USA
423
*/
524

625
'use strict';
@@ -87,6 +106,47 @@ exports.normalizeEmail = function(email) {
87106
return email;
88107
};
89108

109+
exports.genWKDHash = function(email) {
110+
return new Promise((resolve, reject) => {
111+
const [localPart, domain] = email.split('@');
112+
const localPartHashed = crypto.createHash('sha1')
113+
.update(localPart.toLowerCase())
114+
.digest();
115+
const localPartBase32 = encodeZBase32(localPartHashed);
116+
const wkdhash = localPartBase32 + '@' + domain;
117+
resolve(wkdhash);
118+
});
119+
}
120+
121+
function encodeZBase32(data) {
122+
if (data.length === 0) {
123+
return "";
124+
}
125+
const ALPHABET = "ybndrfg8ejkmcpqxot1uwisza345h769";
126+
const SHIFT = 5;
127+
const MASK = 31;
128+
let buffer = data[0];
129+
let index = 1;
130+
let bitsLeft = 8;
131+
let result = '';
132+
while (bitsLeft > 0 || index < data.length) {
133+
if (bitsLeft < SHIFT) {
134+
if (index < data.length) {
135+
buffer <<= 8;
136+
buffer |= data[index++] & 0xff;
137+
bitsLeft += 8;
138+
} else {
139+
const pad = SHIFT - bitsLeft;
140+
buffer <<= pad;
141+
bitsLeft += pad;
142+
}
143+
}
144+
bitsLeft -= SHIFT;
145+
result += ALPHABET[MASK & (buffer >> bitsLeft)];
146+
}
147+
return result;
148+
}
149+
90150
/**
91151
* Generate a cryptographically secure random hex string. If no length is
92152
* provided a 32 char hex string will be generated by default.

src/modules/public-key.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ class PublicKey {
162162
if (userId.notify === true) {
163163
// generate nonce for verification
164164
userId.nonce = util.random();
165+
// generate wkd hash
166+
userId.wkdhash = await util.genWKDHash(userId.email);
165167
await this._email.send({template: tpl.verifyKey, userId, keyId, origin, publicKeyArmored: userId.publicKeyArmored, i18n});
166168
}
167169
}

0 commit comments

Comments
 (0)