Make process functions uniform

This commit is contained in:
Yarmo Mackenbach 2021-04-19 11:06:29 +02:00
parent 4aaf25b705
commit 7e4a3e9f53
No known key found for this signature in database
GPG key ID: 37367F4AF4087AD1
2 changed files with 71 additions and 72 deletions

View file

@ -17,6 +17,7 @@ const bent = require('bent')
const req = bent('GET') const req = bent('GET')
const validUrl = require('valid-url') const validUrl = require('valid-url')
const openpgp = require('openpgp') const openpgp = require('openpgp')
const Claim = require('./claim')
const fetchHKP = (identifier, keyserverBaseUrl) => { const fetchHKP = (identifier, keyserverBaseUrl) => {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
@ -164,14 +165,14 @@ const fetchURI = (uri) => {
const process = (publicKey) => { const process = (publicKey) => {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
if (!publicKey) { if (!publicKey || !(publicKey instanceof openpgp.key.Key)) {
reject('Invalid public key') reject('Invalid public key')
} }
const fingerprint = await publicKey.primaryKey.getFingerprint() const fingerprint = await publicKey.primaryKey.getFingerprint()
const primaryUser = await publicKey.getPrimaryUser() const primaryUser = await publicKey.getPrimaryUser()
const users = publicKey.users const users = publicKey.users
let primaryUserIndex, let usersOutput = []
usersOutput = []
users.forEach((user, i) => { users.forEach((user, i) => {
usersOutput[i] = { usersOutput[i] = {
@ -182,19 +183,19 @@ const process = (publicKey) => {
comment: user.userId ? user.userId.comment : null, comment: user.userId ? user.userId.comment : null,
isPrimary: primaryUser.index === i, isPrimary: primaryUser.index === i,
}, },
claims: [],
} }
if ('selfCertifications' in user && user.selfCertifications.length > 0) { if ('selfCertifications' in user && user.selfCertifications.length > 0) {
const notations = user.selfCertifications[0].rawNotations const notations = user.selfCertifications[0].rawNotations
usersOutput[i].notations = notations.map( usersOutput[i].claims = notations.map(
({ name, value, humanReadable }) => { ({ name, value, humanReadable }) => {
if (humanReadable && name === 'proof@metacode.biz') { 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,23 +203,12 @@ const process = (publicKey) => {
fingerprint: fingerprint, fingerprint: fingerprint,
users: usersOutput, users: usersOutput,
primaryUserIndex: primaryUser.index, 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)
}) })
} }
@ -231,5 +221,3 @@ exports.fetch = {
signature: fetchSignature, signature: fetchSignature,
} }
exports.process = process exports.process = process
exports.getUserData = getUserData
exports.getFingerprint = getFingerprint

View file

@ -14,20 +14,30 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
const openpgp = require('openpgp') const openpgp = require('openpgp')
const mergeOptions = require('merge-options') const Claim = require('./claim')
const claims = require('./claims')
const keys = require('./keys') const keys = require('./keys')
const verify = (signature, opts) => { const process = (signature) => {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
let errors = [], let sigData,
sigData result = {
fingerprint: null,
users: [{
userData: {},
claims: [],
}],
primaryUserIndex: null,
key: {
data: null,
fetchMethod: null,
uri: null,
},
}
try { try {
sigData = await openpgp.cleartext.readArmored(signature) sigData = await openpgp.cleartext.readArmored(signature)
} catch (error) { } catch (error) {
errors.push('invalid_signature') reject('invalid_signature')
reject({ errors: errors })
return return
} }
@ -38,7 +48,6 @@ const verify = (signature, opts) => {
'https://keys.openpgp.org/' 'https://keys.openpgp.org/'
const text = sigData.getText() const text = sigData.getText()
let sigKeys = [] let sigKeys = []
let sigClaims = []
text.split('\n').forEach((line, i) => { text.split('\n').forEach((line, i) => {
const match = line.match(/^([a-zA-Z0-9]*)\=(.*)$/i) const match = line.match(/^([a-zA-Z0-9]*)\=(.*)$/i)
@ -51,7 +60,7 @@ const verify = (signature, opts) => {
break break
case 'proof': case 'proof':
sigClaims.push(match[2]) result.users[0].claims.push(new Claim(match[2]))
break break
default: default:
@ -59,65 +68,67 @@ const verify = (signature, opts) => {
} }
}) })
let keyData, keyUri
// Try overruling key // Try overruling key
if (sigKeys.length > 0) { if (sigKeys.length > 0) {
try { try {
keyUri = sigKeys[0] result.key.uri = sigKeys[0]
keyData = await keys.fetch.uri(keyUri) result.key.data = await keys.fetch.uri(result.key.uri)
result.key.fetchMethod = result.key.uri.split(':')[0]
} catch (e) {} } catch (e) {}
} }
// Try WKD // Try WKD
if (!keyData && signersUserId) { if (!result.key.data && signersUserId) {
try { try {
keyUri = `wkd:${signersUserId}` result.key.uri = `wkd:${signersUserId}`
keyData = await keys.fetch.uri(keyUri) result.key.data = await keys.fetch.uri(result.key.uri)
result.key.fetchMethod = 'wkd'
} catch (e) {} } catch (e) {}
} }
// Try HKP // Try HKP
if (!keyData) { if (!result.key.data) {
try { try {
const match = preferredKeyServer.match(/^(.*\:\/\/)?([^/]*)(?:\/)?$/i) const match = preferredKeyServer.match(/^(.*\:\/\/)?([^/]*)(?:\/)?$/i)
keyUri = `hkp:${match[2]}:${issuerKeyId ? issuerKeyId : signersUserId}` result.key.uri = `hkp:${match[2]}:${issuerKeyId ? issuerKeyId : signersUserId}`
keyData = await keys.fetch.uri(keyUri) result.key.data = await keys.fetch.uri(result.key.uri)
result.key.fetchMethod = 'hkp'
} catch (e) { } catch (e) {
errors.push('key_not_found') reject('key_not_found')
reject({ errors: errors })
return return
} }
} }
const fingerprint = keyData.keyPacket.getFingerprint() result.fingerprint = result.key.data.keyPacket.getFingerprint()
try { result.users[0].claims.forEach(claim => {
const sigVerification = await sigData.verify([keyData]) claim.fingerprint = result.fingerprint
await sigVerification[0].verified })
} catch (e) {
errors.push('invalid_signature_verification') const primaryUserData = await result.key.data.getPrimaryUser()
reject({ errors: errors }) let userData
return
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({ result.primaryUserIndex = result.users[0].userData.isPrimary ? 0 : null
errors: errors,
signature: { resolve(result)
data: sigData.signature,
issuerKeyId: issuerKeyId,
signersUserId: signersUserId,
preferredKeyServer: preferredKeyServer,
},
publicKey: {
data: keyData,
uri: keyUri,
fingerprint: fingerprint,
},
text: text,
claims: claimVerifications,
})
}) })
} }
exports.verify = verify exports.process = process