@microsoft/useragent-sdk
Version:
SDK for building decentralized identity wallets and enterprise agents.
58 lines (52 loc) • 2.65 kB
text/typescript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import Identifier from '../Identifier';
import UserAgentError from '../UserAgentError';
import JwsToken from '../crypto/protocols/jose/jws/JwsToken';
import IdentifierDocument from '../IdentifierDocument';
export default class VerifyHelper {
/**
* Verify that Jwstoken was signed by the entity that
* owns the Identifier Document referenced by the senderId.
* @param sender the Identifier of the entity whose signature we are verifying.
* @param token the token that is being verified.
*/
public static async verify(sender: Identifier, token: JwsToken) {
const senderDocument = await sender.getDocument();
const matchingPublicKeys = this.findMatchingPublicKeys(token, senderDocument);
return token.verify(matchingPublicKeys);
}
/**
* Find Public Keys in an Identifier Document that
* match the ones specified in header/protected header of a signed token.
* @param token JWSToken whose signature needs to be matched
* @param document Identifer Document containing public keys
*/
private static findMatchingPublicKeys(token: JwsToken, document: IdentifierDocument) {
if (token.signatures.length < 0) {
throw new UserAgentError('No signature included');
}
let keyMatches: RegExpMatchArray | null = null;
const keyIdRegex = /([^#]*)#?(.+$)/;
if (token.signatures[0].protected && (token.signatures[0].protected).has('kid')) {
const keyIdentifier: string = (token.signatures[0].protected).get('kid');
keyMatches = keyIdentifier.match(keyIdRegex);
} else if (token.signatures[0].header && (token.signatures[0].header).has('kid')) {
const keyIdentifier: string = (token.signatures[0].header).get('kid');
keyMatches = keyIdentifier.match(keyIdRegex);
}
if (keyMatches === null) {
throw new UserAgentError('Cannot locate keyID');
}
if (keyMatches[1].length > 0 && keyMatches[1] !== document.id) {
throw new UserAgentError('Issuer signer does not match issuer');
}
const keyId = keyMatches[2];
const publicKeysFromDocument = document.getPublicKeysFromDocument();
return publicKeysFromDocument.filter((publicKey) => {
return publicKey.kid && publicKey.kid.endsWith(keyId);
});
}
}