Move WKD client to openpgpjs/wkd-client
This commit is contained in:
parent
43f0724aeb
commit
7203e6afb6
9
openpgp.d.ts
vendored
9
openpgp.d.ts
vendored
|
@ -908,13 +908,4 @@ declare namespace util {
|
||||||
function hexToStr(hex: string): string;
|
function hexToStr(hex: string): string;
|
||||||
|
|
||||||
function normalizeDate(date: Date | null): Date | null;
|
function normalizeDate(date: Date | null): Date | null;
|
||||||
|
|
||||||
/**
|
|
||||||
* Encode input buffer using Z-Base32 encoding.
|
|
||||||
* See: https://tools.ietf.org/html/rfc6189#section-5.1.6
|
|
||||||
*
|
|
||||||
* @param {Uint8Array} data - The binary data to encode
|
|
||||||
* @returns {String} Binary data encoded using Z-Base32.
|
|
||||||
*/
|
|
||||||
function encodeZBase32(data: Uint8Array): string;
|
|
||||||
}
|
}
|
||||||
|
|
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -3534,11 +3534,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node-fetch": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz",
|
|
||||||
"integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U="
|
|
||||||
},
|
|
||||||
"node-localstorage": {
|
"node-localstorage": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-localstorage/-/node-localstorage-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-localstorage/-/node-localstorage-1.3.0.tgz",
|
||||||
|
|
|
@ -89,7 +89,6 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"asn1.js": "^5.0.0",
|
"asn1.js": "^5.0.0",
|
||||||
"node-fetch": "^2.1.2",
|
|
||||||
"node-localstorage": "~1.3.0"
|
"node-localstorage": "~1.3.0"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
|
@ -30,5 +30,3 @@ export { default as enums } from './enums';
|
||||||
export { default as config } from './config/config';
|
export { default as config } from './config/config';
|
||||||
|
|
||||||
export { default as Keyring } from './keyring';
|
export { default as Keyring } from './keyring';
|
||||||
|
|
||||||
export { default as WKD } from './wkd';
|
|
||||||
|
|
36
src/util.js
36
src/util.js
|
@ -650,42 +650,6 @@ const util = {
|
||||||
}).join('\n');
|
}).join('\n');
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Encode input buffer using Z-Base32 encoding.
|
|
||||||
* See: https://tools.ietf.org/html/rfc6189#section-5.1.6
|
|
||||||
*
|
|
||||||
* @param {Uint8Array} data - The binary data to encode
|
|
||||||
* @returns {String} Binary data encoded using Z-Base32.
|
|
||||||
*/
|
|
||||||
encodeZBase32: function(data) {
|
|
||||||
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;
|
|
||||||
},
|
|
||||||
|
|
||||||
wrapError: function(message, error) {
|
wrapError: function(message, error) {
|
||||||
if (!error) {
|
if (!error) {
|
||||||
return new Error(message);
|
return new Error(message);
|
||||||
|
|
83
src/wkd.js
83
src/wkd.js
|
@ -1,83 +0,0 @@
|
||||||
// OpenPGP.js - An OpenPGP implementation in javascript
|
|
||||||
// Copyright (C) 2018 Wiktor Kwapisiewicz
|
|
||||||
//
|
|
||||||
// This library is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
|
||||||
// License as published by the Free Software Foundation; either
|
|
||||||
// version 3.0 of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
|
||||||
// License along with this library; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
import util from './util';
|
|
||||||
import crypto from './crypto';
|
|
||||||
import { readKeys } from './key';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class implements a client for the Web Key Directory (WKD) protocol
|
|
||||||
* in order to lookup keys on designated servers.
|
|
||||||
* @see https://datatracker.ietf.org/doc/draft-koch-openpgp-webkey-service/
|
|
||||||
*/
|
|
||||||
class WKD {
|
|
||||||
/**
|
|
||||||
* Initialize the WKD client
|
|
||||||
*/
|
|
||||||
constructor() {
|
|
||||||
this._fetch = typeof globalThis.fetch === 'function' ? globalThis.fetch : require('node-fetch');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search for a public key using Web Key Directory protocol.
|
|
||||||
* @param {String} options.email User's email.
|
|
||||||
* @param {Boolean} options.rawBytes Returns Uint8Array instead of parsed key.
|
|
||||||
* @returns {Promise<Uint8Array|
|
|
||||||
* {keys: Array<Key>,
|
|
||||||
* err: (Array<Error>|null)}>} The public key.
|
|
||||||
* @async
|
|
||||||
*/
|
|
||||||
async lookup(options) {
|
|
||||||
const fetch = this._fetch;
|
|
||||||
|
|
||||||
if (!options.email) {
|
|
||||||
throw new Error('You must provide an email parameter!');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!util.isEmailAddress(options.email)) {
|
|
||||||
throw new Error('Invalid e-mail address.');
|
|
||||||
}
|
|
||||||
|
|
||||||
const [, localPart, domain] = /(.*)@(.*)/.exec(options.email);
|
|
||||||
const localEncoded = util.encodeZBase32(await crypto.hash.sha1(util.strToUint8Array(localPart.toLowerCase())));
|
|
||||||
|
|
||||||
const urlAdvanced = `https://openpgpkey.${domain}/.well-known/openpgpkey/${domain}/hu/${localEncoded}`;
|
|
||||||
const urlDirect = `https://${domain}/.well-known/openpgpkey/hu/${localEncoded}`;
|
|
||||||
|
|
||||||
let response;
|
|
||||||
try {
|
|
||||||
response = await fetch(urlAdvanced);
|
|
||||||
if (response.status !== 200) {
|
|
||||||
throw new Error('Advanced WKD lookup failed: ' + response.statusText);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
util.printDebugError(err);
|
|
||||||
response = await fetch(urlDirect);
|
|
||||||
if (response.status !== 200) {
|
|
||||||
throw new Error('Direct WKD lookup failed: ' + response.statusText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const rawBytes = new Uint8Array(await response.arrayBuffer());
|
|
||||||
if (options.rawBytes) {
|
|
||||||
return rawBytes;
|
|
||||||
}
|
|
||||||
return readKeys({ binaryKeys: rawBytes });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default WKD;
|
|
|
@ -8,7 +8,6 @@ module.exports = () => describe('General', function () {
|
||||||
require('./key.js')();
|
require('./key.js')();
|
||||||
require('./openpgp.js')();
|
require('./openpgp.js')();
|
||||||
require('./config.js')();
|
require('./config.js')();
|
||||||
require('./wkd.js')();
|
|
||||||
require('./oid.js')();
|
require('./oid.js')();
|
||||||
require('./ecc_nist.js')();
|
require('./ecc_nist.js')();
|
||||||
require('./ecc_secp256k1.js')();
|
require('./ecc_secp256k1.js')();
|
||||||
|
|
|
@ -150,11 +150,4 @@ module.exports = () => describe('Util unit tests', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Zbase32", function() {
|
|
||||||
it('util.encodeZBase32 encodes correctly', function() {
|
|
||||||
const encoded = util.encodeZBase32(util.strToUint8Array('test-wkd'));
|
|
||||||
expect(encoded).to.equal('qt1zg7bpq7ise');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..');
|
|
||||||
|
|
||||||
const chai = require('chai');
|
|
||||||
|
|
||||||
const { expect } = chai;
|
|
||||||
|
|
||||||
/* eslint-disable no-invalid-this */
|
|
||||||
module.exports = () => describe.skip('WKD unit tests', function() {
|
|
||||||
this.timeout(60000);
|
|
||||||
|
|
||||||
let wkd;
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
wkd = new openpgp.WKD();
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(function() {});
|
|
||||||
|
|
||||||
describe('lookup', function() {
|
|
||||||
it('by email address should work', function() {
|
|
||||||
return wkd.lookup({
|
|
||||||
email: 'test-wkd@metacode.biz',
|
|
||||||
rawBytes: true
|
|
||||||
}).then(function(keys) {
|
|
||||||
expect(keys).to.exist;
|
|
||||||
expect(keys).to.be.an.instanceof(Uint8Array);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('by email address should work', function() {
|
|
||||||
return wkd.lookup({
|
|
||||||
email: 'test-wkd@metacode.biz'
|
|
||||||
}).then(function(keys) {
|
|
||||||
expect(keys).to.exist;
|
|
||||||
expect(keys).to.have.length(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('by email address should not find a key', function() {
|
|
||||||
return wkd.lookup({
|
|
||||||
email: 'test-wkd-does-not-exist@metacode.biz'
|
|
||||||
}).then(function(keys) {
|
|
||||||
expect(keys).to.be.undefined;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
Loading…
Reference in New Issue
Block a user