did-jwt
Version:
Library for Signing and Verifying JWTs that use DIDs as issuers and JWEs that use DIDs as recipients
119 lines • 5.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyProof = verifyProof;
const Errors_js_1 = require("./Errors.js");
const JWT_js_1 = require("./JWT.js");
const CONDITIONAL_PROOF_2022 = 'ConditionalProof2022';
async function verifyProof(jwt, { header, payload, signature, data }, authenticator, options) {
if (authenticator.type === CONDITIONAL_PROOF_2022) {
return verifyConditionalProof(jwt, { payload, header, signature, data }, authenticator, options);
}
else {
return (0, JWT_js_1.verifyJWTDecoded)({ header, payload, data, signature }, [authenticator]);
}
}
async function verifyConditionalProof(jwt, { header, payload, signature, data }, authenticator, options) {
// Validate the condition according to its condition property
if (authenticator.conditionWeightedThreshold) {
return verifyConditionWeightedThreshold(jwt, { header, payload, data, signature }, authenticator, options);
}
else if (authenticator.conditionDelegated) {
return verifyConditionDelegated(jwt, { header, payload, data, signature }, authenticator, options);
}
// TODO other conditions
throw new Error(`${Errors_js_1.JWT_ERROR.INVALID_JWT}: conditional proof type did not find condition for authenticator ${authenticator.id}.`);
}
async function verifyConditionWeightedThreshold(jwt, { header, payload, data, signature }, authenticator, options) {
if (!authenticator.conditionWeightedThreshold || !authenticator.threshold) {
throw new Error('Expected conditionWeightedThreshold and threshold');
}
const issuers = [];
const threshold = authenticator.threshold;
let weightCount = 0;
for (const weightedCondition of authenticator.conditionWeightedThreshold) {
const currentCondition = weightedCondition.condition;
let foundSigner;
try {
if (currentCondition.type === CONDITIONAL_PROOF_2022) {
if (!options.didAuthenticator) {
throw new Error('Expected didAuthenticator');
}
const newOptions = {
...options,
didAuthenticator: {
didResolutionResult: options.didAuthenticator?.didResolutionResult,
authenticators: [currentCondition],
issuer: currentCondition.id,
},
};
const { verified } = await (0, JWT_js_1.verifyJWT)(jwt, newOptions);
if (verified) {
foundSigner = currentCondition;
}
}
else {
foundSigner = await (0, JWT_js_1.verifyJWTDecoded)({ header, payload, data, signature }, currentCondition);
}
}
catch (e) {
if (!e.message.startsWith(Errors_js_1.JWT_ERROR.INVALID_SIGNATURE))
throw e;
}
if (foundSigner && !issuers.includes(foundSigner.id)) {
issuers.push(foundSigner.id);
weightCount += weightedCondition.weight;
if (weightCount >= threshold) {
return authenticator;
}
}
}
throw new Error(`${Errors_js_1.JWT_ERROR.INVALID_SIGNATURE}: condition for authenticator ${authenticator.id} is not met.`);
}
async function verifyConditionDelegated(jwt, { header, payload, data, signature }, authenticator, options) {
if (!authenticator.conditionDelegated) {
throw new Error('Expected conditionDelegated');
}
if (!options.resolver) {
throw new Error('Expected resolver');
}
let foundSigner;
const issuer = authenticator.conditionDelegated;
const didAuthenticator = await (0, JWT_js_1.resolveAuthenticator)(options.resolver, header.alg, issuer, options.proofPurpose);
const didResolutionResult = didAuthenticator.didResolutionResult;
if (!didResolutionResult?.didDocument) {
throw new Error(`${Errors_js_1.JWT_ERROR.RESOLVER_ERROR}: Could not resolve delegated DID ${issuer}.`);
}
const delegatedAuthenticator = didAuthenticator.authenticators.find((authenticator) => authenticator.id === issuer);
if (!delegatedAuthenticator) {
throw new Error(`${Errors_js_1.JWT_ERROR.NO_SUITABLE_KEYS}: Could not find delegated authenticator ${issuer} in it's DID Document`);
}
if (delegatedAuthenticator.type === CONDITIONAL_PROOF_2022) {
const { verified } = await (0, JWT_js_1.verifyJWT)(jwt, {
...options,
...{
didAuthenticator: {
didResolutionResult,
authenticators: [delegatedAuthenticator],
issuer: delegatedAuthenticator.id,
},
},
});
if (verified) {
foundSigner = delegatedAuthenticator;
}
}
else {
try {
foundSigner = (0, JWT_js_1.verifyJWTDecoded)({ header, payload, data, signature }, delegatedAuthenticator);
}
catch (e) {
if (!e.message.startsWith('invalid_signature:'))
throw e;
}
}
if (foundSigner) {
return authenticator;
}
throw new Error(`${Errors_js_1.JWT_ERROR.INVALID_SIGNATURE}: condition for authenticator ${authenticator.id} is not met.`);
}
//# sourceMappingURL=ConditionalAlgorithm.js.map