From 7e4a3e9f537085eb8b2409391e8c96725eb7ff81 Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Mon, 19 Apr 2021 11:06:29 +0200 Subject: [PATCH] Make process functions uniform --- src/keys.js | 38 ++++++----------- src/signatures.js | 105 +++++++++++++++++++++++++--------------------- 2 files changed, 71 insertions(+), 72 deletions(-) diff --git a/src/keys.js b/src/keys.js index babca69..00c8cc8 100644 --- a/src/keys.js +++ b/src/keys.js @@ -17,6 +17,7 @@ const bent = require('bent') const req = bent('GET') const validUrl = require('valid-url') const openpgp = require('openpgp') +const Claim = require('./claim') const fetchHKP = (identifier, keyserverBaseUrl) => { return new Promise(async (resolve, reject) => { @@ -164,14 +165,14 @@ const fetchURI = (uri) => { const process = (publicKey) => { return new Promise(async (resolve, reject) => { - if (!publicKey) { + if (!publicKey || !(publicKey instanceof openpgp.key.Key)) { reject('Invalid public key') } + const fingerprint = await publicKey.primaryKey.getFingerprint() const primaryUser = await publicKey.getPrimaryUser() const users = publicKey.users - let primaryUserIndex, - usersOutput = [] + let usersOutput = [] users.forEach((user, i) => { usersOutput[i] = { @@ -182,19 +183,19 @@ const process = (publicKey) => { comment: user.userId ? user.userId.comment : null, isPrimary: primaryUser.index === i, }, + claims: [], } if ('selfCertifications' in user && user.selfCertifications.length > 0) { const notations = user.selfCertifications[0].rawNotations - usersOutput[i].notations = notations.map( + usersOutput[i].claims = notations.map( ({ name, value, humanReadable }) => { if (humanReadable && name === 'proof@metacode.biz') { - return openpgp.util.decode_utf8(value) + const notation = openpgp.util.decode_utf8(value) + return new Claim(notation, fingerprint) } } ) - } else { - usersOutput[i].notations = [] } }) @@ -202,26 +203,15 @@ const process = (publicKey) => { fingerprint: fingerprint, users: usersOutput, primaryUserIndex: primaryUser.index, + key: { + data: publicKey, + fetchMethod: null, + uri: null + } }) }) } -const getUserData = (publicKey) => { - return new Promise(async (resolve, reject) => { - const keyData = await process(publicKey) - - resolve(keyData.users) - }) -} - -const getFingerprint = (publicKey) => { - return new Promise(async (resolve, reject) => { - const keyData = await process(publicKey) - - resolve(keyData.fingerprint) - }) -} - exports.fetch = { uri: fetchURI, hkp: fetchHKP, @@ -231,5 +221,3 @@ exports.fetch = { signature: fetchSignature, } exports.process = process -exports.getUserData = getUserData -exports.getFingerprint = getFingerprint diff --git a/src/signatures.js b/src/signatures.js index ddfccc8..49cbe7b 100644 --- a/src/signatures.js +++ b/src/signatures.js @@ -14,20 +14,30 @@ See the License for the specific language governing permissions and limitations under the License. */ const openpgp = require('openpgp') -const mergeOptions = require('merge-options') -const claims = require('./claims') +const Claim = require('./claim') const keys = require('./keys') -const verify = (signature, opts) => { +const process = (signature) => { return new Promise(async (resolve, reject) => { - let errors = [], - sigData + let sigData, + result = { + fingerprint: null, + users: [{ + userData: {}, + claims: [], + }], + primaryUserIndex: null, + key: { + data: null, + fetchMethod: null, + uri: null, + }, + } try { sigData = await openpgp.cleartext.readArmored(signature) } catch (error) { - errors.push('invalid_signature') - reject({ errors: errors }) + reject('invalid_signature') return } @@ -38,7 +48,6 @@ const verify = (signature, opts) => { 'https://keys.openpgp.org/' const text = sigData.getText() let sigKeys = [] - let sigClaims = [] text.split('\n').forEach((line, i) => { const match = line.match(/^([a-zA-Z0-9]*)\=(.*)$/i) @@ -51,7 +60,7 @@ const verify = (signature, opts) => { break case 'proof': - sigClaims.push(match[2]) + result.users[0].claims.push(new Claim(match[2])) break default: @@ -59,65 +68,67 @@ const verify = (signature, opts) => { } }) - let keyData, keyUri - // Try overruling key if (sigKeys.length > 0) { try { - keyUri = sigKeys[0] - keyData = await keys.fetch.uri(keyUri) + result.key.uri = sigKeys[0] + result.key.data = await keys.fetch.uri(result.key.uri) + result.key.fetchMethod = result.key.uri.split(':')[0] } catch (e) {} } // Try WKD - if (!keyData && signersUserId) { + if (!result.key.data && signersUserId) { try { - keyUri = `wkd:${signersUserId}` - keyData = await keys.fetch.uri(keyUri) + result.key.uri = `wkd:${signersUserId}` + result.key.data = await keys.fetch.uri(result.key.uri) + result.key.fetchMethod = 'wkd' } catch (e) {} } // Try HKP - if (!keyData) { + if (!result.key.data) { try { const match = preferredKeyServer.match(/^(.*\:\/\/)?([^/]*)(?:\/)?$/i) - keyUri = `hkp:${match[2]}:${issuerKeyId ? issuerKeyId : signersUserId}` - keyData = await keys.fetch.uri(keyUri) + result.key.uri = `hkp:${match[2]}:${issuerKeyId ? issuerKeyId : signersUserId}` + result.key.data = await keys.fetch.uri(result.key.uri) + result.key.fetchMethod = 'hkp' } catch (e) { - errors.push('key_not_found') - reject({ errors: errors }) + reject('key_not_found') return } } - const fingerprint = keyData.keyPacket.getFingerprint() + result.fingerprint = result.key.data.keyPacket.getFingerprint() - try { - const sigVerification = await sigData.verify([keyData]) - await sigVerification[0].verified - } catch (e) { - errors.push('invalid_signature_verification') - reject({ errors: errors }) - return + result.users[0].claims.forEach(claim => { + claim.fingerprint = result.fingerprint + }) + + const primaryUserData = await result.key.data.getPrimaryUser() + let userData + + if (signersUserId) { + result.key.data.users.forEach(user => { + if (user.userId.email == signersUserId) { + userData = user + } + }) + } + if (!userData) { + userData = primaryUserData.user } - const claimVerifications = await claims.verify(sigClaims, fingerprint, opts) + result.users[0].userData = { + id: userData.userId ? userData.userId.userid : null, + name: userData.userId ? userData.userId.name : null, + email: userData.userId ? userData.userId.email : null, + comment: userData.userId ? userData.userId.comment : null, + isPrimary: primaryUserData.user.userId.userid === userData.userId.userid, + } - resolve({ - errors: errors, - signature: { - data: sigData.signature, - issuerKeyId: issuerKeyId, - signersUserId: signersUserId, - preferredKeyServer: preferredKeyServer, - }, - publicKey: { - data: keyData, - uri: keyUri, - fingerprint: fingerprint, - }, - text: text, - claims: claimVerifications, - }) + result.primaryUserIndex = result.users[0].userData.isPrimary ? 0 : null + + resolve(result) }) } -exports.verify = verify +exports.process = process