Fix Public Key Message validation and use it

This commit is contained in:
Franck Royer 2021-07-02 11:29:04 +10:00
parent 2f2f89cf65
commit e9a1d88512
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
2 changed files with 29 additions and 13 deletions

View File

@ -127,12 +127,14 @@ function handlePublicKeyMessage(
if (ethDmPublicKey === myPublicKey) return;
const res = validatePublicKeyMessage(publicKeyMsg);
console.log(`Public Key Message Received, valid: ${res}`, publicKeyMsg);
console.log('Is Public Key Message valid?', res);
setter((prevPks: Map<string, string>) => {
prevPks.set(bytesToHexStr(publicKeyMsg.ethAddress), ethDmPublicKey);
return new Map(prevPks);
});
if (res) {
setter((prevPks: Map<string, string>) => {
prevPks.set(bytesToHexStr(publicKeyMsg.ethAddress), ethDmPublicKey);
return new Map(prevPks);
});
}
}
async function handleDirectMessage(

View File

@ -33,11 +33,14 @@ export async function createPublicKeyMessage(
ethDmPublicKey: string
): Promise<PublicKeyMessage> {
const ethAddress = await web3Signer.getAddress();
const bytesEthDmPublicKey = Buffer.from(
ethDmPublicKey.replace(/0x/, ''),
'hex'
);
const signature = await web3Signer.signMessage(
formatPublicKeyForSignature(ethDmPublicKey)
formatPublicKeyForSignature(bytesEthDmPublicKey)
);
const bytesEthDmPublicKey = Buffer.from(ethDmPublicKey, 'hex');
const bytesEthAddress = Buffer.from(ethAddress.replace(/0x/, ''), 'hex');
const bytesSignature = Buffer.from(signature.replace(/0x/, ''), 'hex');
@ -52,13 +55,24 @@ export async function createPublicKeyMessage(
* Validate that the EthDm Public Key was signed by the holder of the given Ethereum address.
*/
export function validatePublicKeyMessage(msg: PublicKeyMessage): boolean {
const formatedMsg = formatPublicKeyForSignature(msg.ethDmPublicKey);
try {
const sigAddress = ethers.utils.verifyMessage(
formatPublicKeyForSignature(bytesToHexStr(msg.ethDmPublicKey)),
msg.signature
const sigAddress = ethers.utils.verifyMessage(formatedMsg, msg.signature);
const sigAddressBytes = Buffer.from(sigAddress.replace(/0x/, ''), 'hex');
// Compare the actual byte arrays instead of strings that may differ in casing or prefixing.
const cmp = sigAddressBytes.compare(new Buffer(msg.ethAddress));
console.log(
`Buffer comparison result: ${cmp} for (signature address, message address)`,
sigAddressBytes,
msg.ethAddress
);
return sigAddress === bytesToHexStr(msg.ethAddress);
return cmp === 0;
} catch (e) {
console.log(
'Failed to verify signature for Public Key Message',
formatedMsg,
msg
);
return false;
}
}
@ -70,9 +84,9 @@ export function validatePublicKeyMessage(msg: PublicKeyMessage): boolean {
* The usage of the object helps ensure the signature is only used in an Eth-DM
* context.
*/
function formatPublicKeyForSignature(ethDmPublicKey: string): string {
function formatPublicKeyForSignature(ethDmPublicKey: Uint8Array): string {
return JSON.stringify({
ethDmPublicKey,
ethDmPublicKey: bytesToHexStr(ethDmPublicKey),
});
}