Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: make SIWE default to EIP55 #193

Merged
merged 1 commit into from
Jul 15, 2024
Merged

fix: make SIWE default to EIP55 #193

merged 1 commit into from
Jul 15, 2024

Conversation

oed
Copy link
Member

@oed oed commented Jul 12, 2024

A while back we updated the @didtools/cacao package to be able to verify SIWE messages with both eip55 encoded ethereum addresses as well as lower case ones. This is because the SIWE spec requires the address to be eip55. We needed to roll this change out to @ceramicnetwork/* packages before we could change the default behavior to sign eip55 messages from the pkh-ethereum package. This PR makes this change.

@oed oed requested review from ukstv and dbcfd July 12, 2024 19:53
@oed oed self-assigned this Jul 12, 2024
@oed oed requested a review from dav1do July 12, 2024 19:58
@oed oed merged commit dd9bc1b into main Jul 15, 2024
9 checks passed
@oed oed deleted the fix/siwe-default-eip55 branch July 15, 2024 06:37
@@ -78,7 +78,7 @@ async function createCACAO(
resources: opts.resources,
})
const signature = await safeSend(ethProvider, 'personal_sign', [
encodeHexStr(siweMessage.signMessage()),
encodeHexStr(siweMessage.signMessage({ eip55: true })),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought line https://github.com/ceramicnetwork/js-did/pull/193/files#diff-d2c60f04e1dcb4772ca82cf036d7f3826d992a107c54b8ff1e844128fb091189R99 was the issue with the casing of the address?

What you are signing might be modified to be eip55 but the message itself doesn't seem to have the casing.

Or am I mistaken?

Copy link

@derekpierre derekpierre Jul 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also this -

const normAccount = normalizeAccountId(account)
...?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this get's a bit complicated because Ceramic needs the DID in lowercase format for the controller of any given stream.

The .signMessage is badly named. It really just returns the messaged to be sent to the wallet and signed. You can see the implementation accepts the eip55 parameter here:

signMessage({ eip55 }: { eip55?: boolean } = {}): string {
// TODO - switch to eip55 by default when the verification change has been roled out
let message: string
switch (this.type) {
case SignatureType.PERSONAL_SIGNATURE: {
message = eip55 ? this.toMessageEip55() : this.toMessage()
break
}
default: {
message = eip55 ? this.toMessageEip55() : this.toMessage()
break
}
}
return message
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. So I would use toMessageEip55() to get the string with the correct casing.

The signature associated with the SiweMessage object used for the session, did that use lower case for the address when signing the string, or does it use the EIP-55 format?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and toMessageEip55() in turn uses checksumAddress from the viem package.

The string that gets sent to the wallet for signing should be a valid SIWE message, i.e. use eip55 encoding for the address.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I switched to using toMessageEip55() but now there is a signature mismatch with the signature on the SIWE message object.

Here is the code I use to get the information from the DID session:

const session = await DIDSession.fromSession(sessionStr);
const message = SiweMessage.fromCacao(session.cacao);
const messageStr = message.toMessageEip55();
const signature = message.signature;

Later on when validating the signature with the message, the validation fails:

error:  SiweError
expected: "0xf9B4Fbf41C540ba28491a5B9EFD9BbcaBaaa95d3"
received: "Resolved address to be 0x2d1F436Ce1A7Ca3959f23D90981B2e65f46629e6"
type: "Signature does not match address of the message."

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@derekpierre Why are you calling .toMessageEip55() separately? Maybe if you want to share more of your code I can help to see what's going wrong?

Copy link

@derekpierre derekpierre Jul 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, it was an old dependency. It works now!

I call .toMessageEip55() because I'm trying to reuse the same SIWE message string and signature that Ceramic stores in the DIDSession. This message/signature combination is passed to TACo nodes as proof of ownership of a wallet - so instead of generating a separate one, we just reuse Ceramic's as a single sign-on type of functionality.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, glad you got it working. Let us know if you run into any other issues!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants