Update code to openpgpjs 5 syntax

This commit is contained in:
Yarmo Mackenbach 2021-11-17 15:54:48 +01:00
parent e87c2bce60
commit 56daec3755
3 changed files with 64 additions and 49 deletions

View file

@ -16,6 +16,8 @@ limitations under the License.
const axios = require('axios') const axios = require('axios')
const validUrl = require('valid-url') const validUrl = require('valid-url')
const openpgp = require('openpgp') const openpgp = require('openpgp')
const HKP = require('@openpgp/hkp-client')
const WKD = require('@openpgp/wkd-client')
const Claim = require('./claim') const Claim = require('./claim')
/** /**
@ -28,7 +30,7 @@ const Claim = require('./claim')
* @function * @function
* @param {string} identifier - Fingerprint or email address * @param {string} identifier - Fingerprint or email address
* @param {string} [keyserverDomain=keys.openpgp.org] - Domain of the keyserver * @param {string} [keyserverDomain=keys.openpgp.org] - Domain of the keyserver
* @returns {openpgp.key.Key} * @returns {openpgp.PublicKey}
* @example * @example
* const key1 = doip.keys.fetchHKP('alice@domain.tld'); * const key1 = doip.keys.fetchHKP('alice@domain.tld');
* const key2 = doip.keys.fetchHKP('123abc123abc'); * const key2 = doip.keys.fetchHKP('123abc123abc');
@ -38,12 +40,14 @@ exports.fetchHKP = async (identifier, keyserverDomain) => {
? `https://${keyserverDomain}` ? `https://${keyserverDomain}`
: 'https://keys.openpgp.org' : 'https://keys.openpgp.org'
const hkp = new openpgp.HKP(keyserverBaseUrl) const hkp = new HKP(keyserverBaseUrl)
const lookupOpts = { const lookupOpts = {
query: identifier query: identifier
} }
const publicKey = await hkp.lookup(lookupOpts).catch((error) => { const publicKey = await hkp
.lookup(lookupOpts)
.catch((error) => {
throw new Error(`Key does not exist or could not be fetched (${error})`) throw new Error(`Key does not exist or could not be fetched (${error})`)
}) })
@ -51,13 +55,11 @@ exports.fetchHKP = async (identifier, keyserverDomain) => {
throw new Error('Key does not exist or could not be fetched') throw new Error('Key does not exist or could not be fetched')
} }
return await openpgp.key return await openpgp.readKey({
.readArmored(publicKey) armoredKey: publicKey
.then((result) => {
return result.keys[0]
}) })
.catch((error) => { .catch((error) => {
throw new Error(`Key does not exist or could not be fetched (${error})`) throw new Error(`Key could not be read (${error})`)
}) })
} }
@ -65,24 +67,32 @@ exports.fetchHKP = async (identifier, keyserverDomain) => {
* Fetch a public key using Web Key Directory * Fetch a public key using Web Key Directory
* @function * @function
* @param {string} identifier - Identifier of format 'username@domain.tld` * @param {string} identifier - Identifier of format 'username@domain.tld`
* @returns {openpgp.key.Key} * @returns {openpgp.PublicKey}
* @example * @example
* const key = doip.keys.fetchWKD('alice@domain.tld'); * const key = doip.keys.fetchWKD('alice@domain.tld');
*/ */
exports.fetchWKD = async (identifier) => { exports.fetchWKD = async (identifier) => {
const wkd = new openpgp.WKD() const wkd = new WKD()
const lookupOpts = { const lookupOpts = {
email: identifier email: identifier
} }
return await wkd const publicKey = await wkd
.lookup(lookupOpts) .lookup(lookupOpts)
.then((result) => {
return result.keys[0]
})
.catch((error) => { .catch((error) => {
throw new Error(`Key does not exist or could not be fetched (${error})`) throw new Error(`Key does not exist or could not be fetched (${error})`)
}) })
if (!publicKey) {
throw new Error('Key does not exist or could not be fetched')
}
return await openpgp.readKey({
binaryKey: publicKey
})
.catch((error) => {
throw new Error(`Key could not be read (${error})`)
})
} }
/** /**
@ -90,7 +100,7 @@ exports.fetchWKD = async (identifier) => {
* @function * @function
* @param {string} username - Keybase username * @param {string} username - Keybase username
* @param {string} fingerprint - Fingerprint of key * @param {string} fingerprint - Fingerprint of key
* @returns {openpgp.key.Key} * @returns {openpgp.PublicKey}
* @example * @example
* const key = doip.keys.fetchKeybase('alice', '123abc123abc'); * const key = doip.keys.fetchKeybase('alice', '123abc123abc');
*/ */
@ -114,10 +124,8 @@ exports.fetchKeybase = async (username, fingerprint) => {
throw new Error(`Error fetching Keybase key: ${e.message}`) throw new Error(`Error fetching Keybase key: ${e.message}`)
} }
return await openpgp.key return await openpgp.readKey({
.readArmored(rawKeyContent) armoredKey: rawKeyContent
.then((result) => {
return result.keys[0]
}) })
.catch((error) => { .catch((error) => {
throw new Error(`Key does not exist or could not be fetched (${error})`) throw new Error(`Key does not exist or could not be fetched (${error})`)
@ -128,7 +136,7 @@ exports.fetchKeybase = async (username, fingerprint) => {
* Get a public key from plaintext data * Get a public key from plaintext data
* @function * @function
* @param {string} rawKeyContent - Plaintext ASCII-formatted public key data * @param {string} rawKeyContent - Plaintext ASCII-formatted public key data
* @returns {openpgp.key.Key} * @returns {openpgp.PublicKey}
* @example * @example
* const plainkey = `-----BEGIN PGP PUBLIC KEY BLOCK----- * const plainkey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
* *
@ -139,7 +147,13 @@ exports.fetchKeybase = async (username, fingerprint) => {
* const key = doip.keys.fetchPlaintext(plainkey); * const key = doip.keys.fetchPlaintext(plainkey);
*/ */
exports.fetchPlaintext = async (rawKeyContent) => { exports.fetchPlaintext = async (rawKeyContent) => {
const publicKey = (await openpgp.key.readArmored(rawKeyContent)).keys[0] const publicKey = await openpgp.readKey({
armoredKey: rawKeyContent
})
.catch((error) => {
throw new Error(`Key could not be read (${error})`)
})
return publicKey return publicKey
} }
@ -147,7 +161,7 @@ exports.fetchPlaintext = async (rawKeyContent) => {
* Fetch a public key using an URI * Fetch a public key using an URI
* @function * @function
* @param {string} uri - URI that defines the location of the key * @param {string} uri - URI that defines the location of the key
* @returns {openpgp.key.Key} * @returns {openpgp.PublicKey}
* @example * @example
* const key1 = doip.keys.fetchURI('hkp:alice@domain.tld'); * const key1 = doip.keys.fetchURI('hkp:alice@domain.tld');
* const key2 = doip.keys.fetchURI('hkp:123abc123abc'); * const key2 = doip.keys.fetchURI('hkp:123abc123abc');
@ -186,7 +200,7 @@ exports.fetchURI = async (uri) => {
/** /**
* Process a public key to get user data and claims * Process a public key to get user data and claims
* @function * @function
* @param {openpgp.key.Key} publicKey - The public key to process * @param {openpgp.PublicKey} publicKey - The public key to process
* @returns {object} * @returns {object}
* @example * @example
* const key = doip.keys.fetchURI('hkp:alice@domain.tld'); * const key = doip.keys.fetchURI('hkp:alice@domain.tld');
@ -196,11 +210,11 @@ exports.fetchURI = async (uri) => {
* }); * });
*/ */
exports.process = async (publicKey) => { exports.process = async (publicKey) => {
if (!publicKey || !(publicKey instanceof openpgp.key.Key)) { if (!publicKey || !(publicKey instanceof openpgp.PublicKey)) {
throw new Error('Invalid public key') throw new Error('Invalid public key')
} }
const fingerprint = await publicKey.primaryKey.getFingerprint() const fingerprint = publicKey.getFingerprint()
const primaryUser = await publicKey.getPrimaryUser() const primaryUser = await publicKey.getPrimaryUser()
const users = publicKey.users const users = publicKey.users
const usersOutput = [] const usersOutput = []
@ -229,7 +243,7 @@ exports.process = async (publicKey) => {
) )
.map( .map(
({ value }) => ({ value }) =>
new Claim(openpgp.util.decode_utf8(value), fingerprint) new Claim(new TextDecoder().decode(value), fingerprint)
) )
usersOutput[i].userData.isRevoked = selfCertification.revoked usersOutput[i].userData.isRevoked = selfCertification.revoked

View file

@ -46,13 +46,14 @@ const process = async (signature) => {
} }
try { try {
sigData = await openpgp.cleartext.readArmored(signature) sigData = await openpgp.readCleartextMessage({
cleartextMessage: signature
})
} catch (error) { } catch (error) {
throw new Error('invalid_signature') throw new Error(`Signature could not be read (${error})`)
} }
const issuerKeyID = sigData.signature.packets[0].issuerKeyID.toHex()
const issuerKeyId = sigData.signature.packets[0].issuerKeyId.toHex() const signersUserID = sigData.signature.packets[0].signersUserID
const signersUserId = sigData.signature.packets[0].signersUserId
const preferredKeyServer = const preferredKeyServer =
sigData.signature.packets[0].preferredKeyServer || sigData.signature.packets[0].preferredKeyServer ||
'https://keys.openpgp.org/' 'https://keys.openpgp.org/'
@ -87,9 +88,9 @@ const process = async (signature) => {
} catch (e) {} } catch (e) {}
} }
// Try WKD // Try WKD
if (!result.key.data && signersUserId) { if (!result.key.data && signersUserID) {
try { try {
result.key.uri = `wkd:${signersUserId}` result.key.uri = `wkd:${signersUserID}`
result.key.data = await keys.fetchURI(result.key.uri) result.key.data = await keys.fetchURI(result.key.uri)
result.key.fetchMethod = 'wkd' result.key.fetchMethod = 'wkd'
} catch (e) {} } catch (e) {}
@ -98,7 +99,7 @@ const process = async (signature) => {
if (!result.key.data) { if (!result.key.data) {
try { try {
const match = preferredKeyServer.match(/^(.*:\/\/)?([^/]*)(?:\/)?$/i) const match = preferredKeyServer.match(/^(.*:\/\/)?([^/]*)(?:\/)?$/i)
result.key.uri = `hkp:${match[2]}:${issuerKeyId || signersUserId}` result.key.uri = `hkp:${match[2]}:${issuerKeyID || signersUserID}`
result.key.data = await keys.fetchURI(result.key.uri) result.key.data = await keys.fetchURI(result.key.uri)
result.key.fetchMethod = 'hkp' result.key.fetchMethod = 'hkp'
} catch (e) { } catch (e) {
@ -115,9 +116,9 @@ const process = async (signature) => {
const primaryUserData = await result.key.data.getPrimaryUser() const primaryUserData = await result.key.data.getPrimaryUser()
let userData let userData
if (signersUserId) { if (signersUserID) {
result.key.data.users.forEach((user) => { result.key.data.users.forEach((user) => {
if (user.userId.email === signersUserId) { if (user.userID.email === signersUserID) {
userData = user userData = user
} }
}) })
@ -127,11 +128,11 @@ const process = async (signature) => {
} }
result.users[0].userData = { result.users[0].userData = {
id: userData.userId ? userData.userId.userid : null, id: userData.userID ? userData.userID.userid : null,
name: userData.userId ? userData.userId.name : null, name: userData.userID ? userData.userID.name : null,
email: userData.userId ? userData.userId.email : null, email: userData.userID ? userData.userID.email : null,
comment: userData.userId ? userData.userId.comment : null, comment: userData.userID ? userData.userID.comment : null,
isPrimary: primaryUserData.user.userId.userid === userData.userId.userid isPrimary: primaryUserData.user.userID.userid === userData.userID.userid
} }
result.primaryUserIndex = result.users[0].userData.isPrimary ? 0 : null result.primaryUserIndex = result.users[0].userData.isPrimary ? 0 : null

View file

@ -99,7 +99,7 @@ describe('keys.fetchURI', () => {
it('should return a Key object when provided a hkp: uri', async () => { it('should return a Key object when provided a hkp: uri', async () => {
expect( expect(
await doipjs.keys.fetchURI(`hkp:${pubKeyFingerprint}`) await doipjs.keys.fetchURI(`hkp:${pubKeyFingerprint}`)
).to.be.instanceOf(openpgp.key.Key) ).to.be.instanceOf(openpgp.PublicKey)
}).timeout('12s') }).timeout('12s')
it('should reject when provided an invalid uri', () => { it('should reject when provided an invalid uri', () => {
return expect( return expect(
@ -115,12 +115,12 @@ describe('keys.fetchHKP', () => {
}) })
it('should return a Key object when provided a valid fingerprint', async () => { it('should return a Key object when provided a valid fingerprint', async () => {
expect(await doipjs.keys.fetchHKP(pubKeyFingerprint)).to.be.instanceOf( expect(await doipjs.keys.fetchHKP(pubKeyFingerprint)).to.be.instanceOf(
openpgp.key.Key openpgp.PublicKey
) )
}) })
it('should return a Key object when provided a valid email address', async () => { it('should return a Key object when provided a valid email address', async () => {
expect(await doipjs.keys.fetchHKP(pubKeyEmail)).to.be.instanceOf( expect(await doipjs.keys.fetchHKP(pubKeyEmail)).to.be.instanceOf(
openpgp.key.Key openpgp.PublicKey
) )
}) })
it('should reject when provided an invalid fingerprint', async () => { it('should reject when provided an invalid fingerprint', async () => {
@ -146,7 +146,7 @@ describe('keys.fetchPlaintext', () => {
}) })
it('should return a Key object', async () => { it('should return a Key object', async () => {
expect(await doipjs.keys.fetchPlaintext(pubKeyPlaintext)).to.be.instanceOf( expect(await doipjs.keys.fetchPlaintext(pubKeyPlaintext)).to.be.instanceOf(
openpgp.key.Key openpgp.PublicKey
) )
}) })
}) })