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

Support subdomain update validation #1088

Open
kantai opened this issue Feb 28, 2022 · 1 comment
Open

Support subdomain update validation #1088

kantai opened this issue Feb 28, 2022 · 1 comment
Assignees
Labels

Comments

@kantai
Copy link

kantai commented Feb 28, 2022

The subdomain protocol supports updating subdomains (changing the zonefile or transferring the subdomain), through a signature field in the batched update. The API, which implements the subdomain processing, needs to validate these signatures before applying them. The protocol isn't well documented (or I can't find the old documentation), but I could find the old code:

https://github.com/stacks-network/stacks-blockchain/blob/253cf826d8230accc74b7d63b7e4160df6237bb1/blockstack/lib/subdomains.py#L199

Simplifying it down a little bit, the verification protocol looks something like:

def textToSign(subdomain, oldInfo, independentOfDomain):
  output = []
  assert subdomain.sequence_number - 1 == oldInfo.sequence_number
  if independentOfDomain:
    output.append(subdomain.fully_qualified_name)
  else:
    output.append(subdomain.subdomain_name)
  output.append("owner=%s" % subdomain.address)
  output.append("seqn=%s" % subdomain.sequence_number)

  # break the subdomain zonefile data up
  encoded_zf = b64encode(subdomain.zonefile_str)
  n_pieces = (len(encoded_zf) / 250) + 1
  if len(encoded_zf) % 250 == 0:
    n_pieces -= 1
  
  output.append("parts=%s" % n_pieces)

  for i in range(n_pieces):
    start = i * 250
    piece_len = min(250, len(encoded_zf[start:]))
    assert piece_len != 0
    piece = encoded_zf[start:(start+piece_len)]

    # next piece
    output.append("zf%d=%s" % (i, piece))

  return ",".join(output)

def verify(new_sub, old_sub, independentOfDomain, signature):
  script_data = b64decode(signature)
  expected_hash = sha256(textToSign(new_sub, old_sub, independentOfDomain))

  btc_sign_verify(old_sub.address, expected_hash, script_data)
@kantai kantai added the BNS label Feb 28, 2022
@rafaelcr rafaelcr moved this to Recent issues in API Board Mar 8, 2022
@rafaelcr rafaelcr moved this from Recent issues to Backlog in API Board Mar 8, 2022
@kantai
Copy link
Author

kantai commented Jul 11, 2022

Note @janniks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: 📋 Backlog
Development

No branches or pull requests

4 participants