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

Add legacy v2-signed keys #131

Merged
merged 13 commits into from
Feb 2, 2024
Merged

Add legacy v2-signed keys #131

merged 13 commits into from
Feb 2, 2024

Conversation

richardhuaaa
Copy link
Contributor

@richardhuaaa richardhuaaa commented Jan 16, 2024

  • Add LegacyCreateIdentityAssociation
  • Split out GrantMessagingAccessAssociation and RevokeMessagingAccessAssociation from Eip191Association - not all EIP191 associations will have the same data, and this allows for stronger type-checking
  • Change time format from ISO8601 string to nanoseconds since epoch - this creates consistency with the old SignedPublicKey type. The ISO8601 string can be constructed at the time of generating the signature text.

Will land xmtp/libxmtp#425 immediately after this PR lands

@richardhuaaa richardhuaaa marked this pull request as ready for review January 19, 2024 02:26
@richardhuaaa richardhuaaa requested a review from a team as a code owner January 19, 2024 02:26
Copy link
Collaborator

@neekolas neekolas left a comment

Choose a reason for hiding this comment

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

This LGTM

bytes installation_public_key = 1;
oneof public_key {
bytes installation_key = 1;
bytes unsigned_legacy_create_identity_key = 2;
Copy link
Collaborator

Choose a reason for hiding this comment

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

What do we mean by unsigned here?

Copy link
Contributor Author

@richardhuaaa richardhuaaa Feb 2, 2024

Choose a reason for hiding this comment

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

This is referring to the key_bytes field on the legacy SignedPublicKey, rather than a serialization of the whole SignedPublicKey. We need to do this because proto serialization is not always consistent, so comparing the bytes of the proto may not always match.

Can see why this might be confusing, open to suggestions!

Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we care about serialization consistency here? If we've included the exact bytes that were signed, can't we just verify that it deserializes into the right proto. Or are we re-serializing it somewhere?

It seems like it would be helpful to have the wallet signature on the proto, since then you can verify that the wallet doing the revoking matches the wallet that signed the key.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Totally possible I'm misunderstanding something

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we've included the exact bytes that were signed, can't we just verify that it deserializes into the right proto

There's two reasons why we might want to attach the unsigned bytes rather than the signed bytes:

  1. The client can just do == on the unsigned bytes, whereas the alternative is that the client must deserialize the signed bytes, and then do == on the unsigned bytes anyway. With the latter, the added complexity means clients might screw this up (e.g., do == on the signed bytes)
  2. Attaching the unsigned bytes results in a smaller payload that only contains what is needed

It seems like it would be helpful to have the wallet signature on the proto, since then you can verify that the wallet doing the revoking matches the wallet that signed the key.

I don't think that's the important thing to verify here. Note that a malicious user could sign an existing installation key from someone else using their own wallet, and then revoke it using their own wallet, and then the revocation payload will be internally consistent. I think the important thing to verify here is that within the context of a conversation, the account address on the credential in the conversation matches the account address on the revocation signature.

We're simply saying that this key cannot perform actions on behalf of this account, regardless of how the key was originally registered.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I do think maybe there's an issue with this field being ambiguous or confusing. I can add an explanatory comment for what it's referring to, or use a different name if you have any thoughts there?

Copy link
Collaborator

Choose a reason for hiding this comment

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

OK. That sounds reasonable. You've convinced me.

@richardhuaaa richardhuaaa merged commit 1304edd into main Feb 2, 2024
8 checks passed
@richardhuaaa richardhuaaa deleted the rich/legacy-keys-2 branch February 2, 2024 23:17
Copy link

github-actions bot commented Feb 2, 2024

🎉 This PR is included in version 3.41.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

richardhuaaa added a commit to xmtp/libxmtp that referenced this pull request Feb 2, 2024
This adds the legacy credential type. Support for generating these credentials will be added in the next PR.

- Apply the changes from xmtp/proto#131
- Add ValidatedLegacySignedPublicKey type and tests
- Add LegacyCreateIdentityAssociation - cannot add tests until I have support for serializing into proto, will add in next PR
- Significant refactoring. We use separate classes in separate files for different associations. The strong typing ensures we can't mix them up (for example confusing grant messaging access with revoke messaging access).

Because the protos have changed, some steps are required to avoid errors for those who already have libxmtp running:
- Run `./dev/down && ./dev/up` from `libxmtp`. This rebuilds the validation service, and clears out any data stored on the server.
- Remove any existing databases, for example from the CLI and Android/iOS/flutter/RN
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants