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

Change the app link signature encoding to hex #636

Closed
RiccardoM opened this issue Sep 30, 2021 · 9 comments · Fixed by #652
Closed

Change the app link signature encoding to hex #636

RiccardoM opened this issue Sep 30, 2021 · 9 comments · Fixed by #652
Assignees
Labels
kind/enhancement Enhance an already existing feature; no "New feature" to add x/profiles Module that allows to create and manage decentralized social profiles
Milestone

Comments

@RiccardoM
Copy link
Contributor

Feature description

Currently when we verify an application link result, we assume that the plain text value has been encoded using UTF-8 (see here). Unfortunately, this currently makes it impossible to sign something using the Ledger or any common wallet due to the fact that they do not allow to sign arbitrary strings.

Implementation proposal

In order to fix this issue, I think we should adopt the same strategy that we currently use for the chain links: require that the plain text is encoded using the hex format (see here). This would make it easier for developers to use any arbitrary value as the plain text, even a full transaction that is then signed using the Ledger.

Note that this change requires a change to all data sources as well to make sure they decode the plain text as a HEX instead of UTF-8 before verifying the signature.

Please @bragaz @dadamu let me know what you think about this before we can make an ADR.

@RiccardoM RiccardoM added kind/enhancement Enhance an already existing feature; no "New feature" to add x/profiles Module that allows to create and manage decentralized social profiles labels Sep 30, 2021
@RiccardoM RiccardoM added this to the v2.1.0 milestone Sep 30, 2021
@dadamu
Copy link
Contributor

dadamu commented Sep 30, 2021

@RiccardoM
The chain link's plain text to sign is also UTF-8 encoded string of address as default, it can be changed to other custom string without UTF-8 encoded so it has same problem in chain link. I think chain link plain text should be also changed to hex-encoded if following this issue.

However, I think it is better to remain UTF-8 encoded. Is it able to force to convert the plain text to UTF-8 string before signing?

@RiccardoM
Copy link
Contributor Author

@RiccardoM The chain link's plain text to sign is also UTF-8 encoded string of address as default, it can be changed to other custom string without UTF-8 encoded so it has same problem in chain link. I think chain link plain text should be also changed to hex-encoded if following this issue.

You're right, I just checked here and it assumes the plain text is UTF-8 encoded

However, I think it is better to remain UTF-8 encoded. Is it able to force to convert the plain text to UTF-8 string before signing?

Unfortunately this issue is not about encoding only, but also about the signature verification process. To better understand this, let's assume we keep the UTF-8 encoding as it is right now, and that we want to create an app/chain link using the Ledger as a signer.

As per design, the Ledger can sign only Cosmos transactions. You give to it a transaction as a byte array and it signs it. It doesn't allow the signature of arbitrary data. So to build an app/chain link we need to provide it with a Cosmos transaction as a byte array. What would happen is:

  1. I give the Ledger a Cosmos transaction as a byte array
  2. I encode the signed bytes as UTF-8 and the signature as hex

To be honest, I don't think that encoding the transaction to a UTF-8 string would always work. We might have some problems here due to the fact that UTF-8 does not support all characters. Reading here we get that:

ISO Latin-1, a subset of UNICODE, is not a subset of UTF-8.

Which means that if the transaction contains a particular memo field with ISO Latin-1 characters, it will not get converted to a UTF-8 byte array properly.

For this reason, I think we should convert both app and chain links to require HEX-encoded plain texts instead in order to support even Ledger signers

@dadamu
Copy link
Contributor

dadamu commented Sep 30, 2021

@RiccardoM
Thanks for explaining. I am clear now. I agree with changing plain text to hex encoded before signing.

@leobragaz
Copy link
Contributor

@RiccardoM @dadamu From what I've read, this problem extend also to chain-link plain-text right?
If so, I guess we should open an ADR for both and standardise the behaviour of the two in order to accept only hex-encoded plain text. Make sense?

@RiccardoM
Copy link
Contributor Author

@bragaz I think a single ADR for both of them is great instead of having two different ADRs. Whoever wishes can go on

@dadamu
Copy link
Contributor

dadamu commented Oct 5, 2021

@RiccardoM I can draft it later.

@leobragaz
Copy link
Contributor

leobragaz commented Oct 5, 2021

@bragaz I think a single ADR for both of them is great instead of having two different ADRs. Whoever wishes can go on

@RiccardoM Yes I meant one 👍

@dadamu
Copy link
Contributor

dadamu commented Oct 6, 2021

@RiccardoM @bragaz Deeply re-thinking about it when writing the ADR. If we change the plain text of the old links which is UTF-8 encoded to hex before verifying the signature, the old links are all invalid since their signatures are simply signed with UTF-8 string bytes. So, all of old links must be re-created to sign the signature in hex bytes.

How about we force the plain text to be hex-encoded string to the new link, then remain the old links used the old proof since they have already passed the verification.
For instance, the signing process of chain link in CLI tool will be like:

// generateChainLinkJSON returns build a new ChainLinkJSON intance using the provided mnemonic and chain configuration
func generateChainLinkJSON(mnemonic string, chain chainlinktypes.Chain) (profilescliutils.ChainLinkJSON, error) {
	
       ...

        // force to change the value to hex-encoded string as plain text automatically
	plainText := hex.EncodeToString([]byte(value))
	sig, pubkey, err := keyBase.Sign(keyName, []byte(plainText))
	if err != nil {
		return profilescliutils.ChainLinkJSON{}, err
	}

	return profilescliutils.NewChainLinkJSON(
		profilestypes.NewBech32Address(addr, chain.Prefix),
		profilestypes.NewProof(pubkey, hex.EncodeToString(sig), plainText),
		profilestypes.NewChainConfig(chain.Name),
	), nil
}

What do you think @RiccardoM, @bragaz

@RiccardoM
Copy link
Contributor Author

@dadamu Changing from UTF-8 to HEX for new links shouldn't be a problem to old links. Once a link is created, the signature is checked only during the creation process and never after that. If we want to keep things consistent on-chain, then we can write a migration script that takes all the currently stored links and transforms them into HEX-encoded values. This can be done as follow:

  1. Iterate over all the chain and application links
  2. Convert the plain text by doing link.PlainText = hex.EncodeToString([]byte(link.PlainText))

This will make all the links backward compatible as well.

@dadamu dadamu self-assigned this Oct 7, 2021
mergify bot pushed a commit that referenced this issue Oct 14, 2021
)

## Description

<!-- Add a description of the changes that this PR introduces and the files that
are the most critical to review. -->

This PR introduces the draft of the 8th ADR related to Change the plain text encoding of links to hex in #636.

---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [ ] targeted the correct branch (see [PR Targeting](https://github.com/desmos-labs/desmos/blob/master/CONTRIBUTING.md#pr-targeting))
- [ ] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://docs.cosmos.network/v0.44/building-modules/intro.html)
- [ ] included the necessary unit and integration [tests](https://github.com/desmos-labs/desmos/blob/master/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [ ] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
@mergify mergify bot closed this as completed in #652 Oct 15, 2021
mergify bot pushed a commit that referenced this issue Oct 15, 2021
## Description

This PR implements what's described inside [ADR-008](#642).
Closes: #636

<!-- Add a description of the changes that this PR introduces and the files that
are the most critical to review. -->

---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [x] targeted the correct branch (see [PR Targeting](https://github.com/desmos-labs/desmos/blob/master/CONTRIBUTING.md#pr-targeting))
- [ ] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://docs.cosmos.network/v0.44/building-modules/intro.html)
- [ ] included the necessary unit and integration [tests](https://github.com/desmos-labs/desmos/blob/master/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [ ] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
@RiccardoM RiccardoM reopened this Oct 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement Enhance an already existing feature; no "New feature" to add x/profiles Module that allows to create and manage decentralized social profiles
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants