[Solved] Gaia Hub Whitelisting Issues


#1

Solved: Had to add the ability to do association tokens in the extension, and serve a compressed public key because Gaia doesn’t know the difference =)


I’ve made my own GaiaHub but am running into an issue with whitelisting.

In the configuration, I added the entry:

{
  ...
  "whitelist": ["<my_id>"]
  ...
}

Which does work for limiting user authentication, but it also makes it so I cannot authenticate within any app, until I add the user-app bucket address to the whitelist as well, i.e.

// whitelist: [ my_id =============================== app_id ]
"whitelist": ["1JcnqiSpoWTE1ZDJ4ScdN19kDC2puGo3Hn", "1H3PREECTB84w8SjbaZwdwfwnvWAUGyMP"]

Is there a fix for this within the config file or otherwise? Has it been fixed and it’s my extension that is out of date with the gaia hub authentication? (I implemented it over the summer/fall of last year).

Thanks


#2

It’s been fixed in the Browser – the authResponse it generates contains an associationToken, which is a JWT embedded within the Gaia auth token that tells the Gaia hub that your app address was signed off on by your ID address. This way, you’d only need to whitelist your ID addresses, and they can dynamically whitelist your app addresses. However, your extension needs to generate the associationToken. Details: https://github.com/blockstack/gaia#association-tokens


#3

I’m checking the browser, and the master branch has nothing for association tokens as far as I see. In addition, blockstack.js only echoes what is given by the apps themselves, re:

(this is found in both the master and the develop branch)

Do I need to manually create these signatures? Or will they eventually become part of the makeAuthResponse code?

How much of this depends on the app? When authenticating with Graphite*, for example, no association token is given to me so blockstack.js does nothing with it, but it ultimately fails because it can’t store anything.


#4

The browser currently does not generate them – I opened an issue against it back in November (https://github.com/blockstack/blockstack-browser/issues/1733).

The CLI does this, however. You can find the relevant code here: https://github.com/blockstack/cli-blockstack/blob/master/src/auth.js#L127


#5

After looking through your code, duplicating it, trying to get it to work with GaiaHub, I’m deciding to wait until it gets put into the browser/blockstack.js and tested by you guys because it keeps failing for a multitude of reasons.


This was my process:

Here, the iss field should be the public key of a whitelisted address. The childtoAssociate should be equal to the iss field of the authentication JWT.

This is quite ambiguous, but I finally figured it to mean the iss is the publicKey of the whitelisted account address in hex. The childToAssociate field should be the publicKey of the app, in hex.

Compare this to the auth reply from the browser to the app, which has the public key in in compressed form, not hex, and is also delivered as did:btc-addr:<address> instead for some odd reason.

Once all this was sorted, I properly gave the association token with the right fields and a randomly generated salt, with the app’s public key in hex (and properly tested to be able to return back to it’s address form for double checking), however Gaia still didn’t want it throwing this error:

Which, if I did double check correctly, the GaiaHub has a bug here that was never actually tested, making this entire day a mess to begin with.

(this was my testing code:)

import { payments } from 'bitcoinjs-lib';
import { hexStringToECPair } from 'blockstack';
// ...
// this worked because the ECPair has a `.publicKey` field.
function getAddress(node: bip32, network?: any) {
  return payments.p2pkh({ pubkey: node.publicKey }).address;
}
// ...
const appPublicKey = hexStringToECPair(appPrivateKey).publicKey.toString('hex');
// v- showed the correct public (compressed) address
console.warn('DEBUG\n' + getAddress(ECPair.fromPublicKey(Buffer.from(appPublicKey, 'hex'))));

I do hope we can get these issues ironed out and a proper implementation so that users can start using their own gaiahubs soon.


#6

Sorry to hear you’re having trouble. I tried this out with a private Gaia hub to investigate, and it worked as expected. Can you confirm that you’re using the latest stable version of blockstack.js (i.e. 18.2.1)? Can you confirm that localStorage.getItem("blockstack-gaia-auth-config") gives you back a JSON string whose token field contains a v1:-prefixed JWT that defines an associationToken in its claim? If you have it handy, can you post your Gaia hub’s log output?

Regarding the blockstack-gaia-auth-config, here’s an example:

"{"url_prefix":"https://blockstack-server-profiles.s3.amazonaws.com/","address":"1JdL4rdNXKi2hU1sXeBs4uXbgeZkvz7u17","token":"v1:eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJnYWlhQ2hhbGxlbmdlIjoiW1wiZ2FpYWh1YlwiLFwiMFwiLFwibG9jYWxob3N0XCIsXCJibG9ja3N0YWNrX3N0b3JhZ2VfcGxlYXNlX3NpZ25cIl0iLCJodWJVcmwiOiJodHRwOi8vbG9jYWxob3N0OjQwMDEiLCJpc3MiOiIwM2Y0NzI3MGI0OTc0NWRlOTQwYWFmOTIwM2E3MjRmOWEyNzZiMGMwNWM2ODlmZmU1YmZkNmFkNDZhZDA5MDhiMTQiLCJzYWx0IjoiNjE1MjdkYWIzODhlNjk3NDU0NmQ5YmU1ZmMwZTM0YmYiLCJhc3NvY2lhdGlvblRva2VuIjoiZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKRlV6STFOa3NpZlEuZXlKamFHbHNaRlJ2UVhOemIyTnBZWFJsSWpvaU1ETm1ORGN5TnpCaU5EazNORFZrWlRrME1HRmhaamt5TUROaE56STBaamxoTWpjMllqQmpNRFZqTmpnNVptWmxOV0ptWkRaaFpEUTJZV1F3T1RBNFlqRTBJaXdpYVhOeklqb2lNRE5sWTJNeE5UUTVNREkxTURWak5HVXhObU14WlRVNVpEQXpaRGxpTm1SalltVTBZelJrWlRFMk5tRmlNamsyWVdZeU5XSmxNRGM0Tnpaa01tWmpOVEE0SWl3aVpYaHdJam94TlRZd01UZzBOVGswTGpNNU9Td2ljMkZzZENJNkltVTJOR1kzTlRFeE5XUTBZalU0TkdWbE5XUTRObU5oTURWbE9ETXpaalk1SW4wLi1MeXU2TFliazQ1T2NsOVVsZWVXWU1hTnQ0TVZBaExsSy02aGNiSndZYXlObE1DcThuN3o2UHd3TmNoeXo3U2U0U3JhVjU4WVN3ZVBNNERON3hjRUxRIn0.jxhgk61AxmEVqfMlBzrqHUo5tYsA-1pgSBW1XOLPftm-atXRTo1MRMcKOs3wMWc2-QXcts0P4PH-cyWsiS17EA","server":"http://localhost:4001"}"


#7

I found the issue, which is quite interesting.

I am sending the app a specific public key in hex form, which is this:

02895347687887fc50e2fb714f6c50f4dd70c48cb2327151efb9879a81c6db1ffa

Using this tool it gives me the following responses:

The input key is a uncompressed public key .

Compressed Address: 12DkXN89JvCSkMivS4CeX1UEW6GFCNbyMk

^ this is what the gaia hub is comparing it against

Uncompressed Address: 18mjzk3uwDAqr8PSM3hTq5aAkjYYj7zJJC

^ this is what the gaia hub is computing it as


I know this because I modified the file to give me the computed childAddress in the error field, which is this:

Association token child address 18mjzk3uwDAqr8PSM3hTq5aAkjYYj7zJJC [child address from public key] does not match 12DkXN89JvCSkMivS4CeX1UEW6GFCNbyMk [bearer address]

Thus I assume the app is giving it’s compressed address in the bearer token (which it should iirc), but the gaia hub is generating an uncompressed address to compare it against.

Is this a bug? Or should I be delivering a compressed public key in hex form?

edit: I served the keys as compressed, but I would argue Gaia should know it’s way around the keys to be able to convert it if it’s necessary.


#8

The childToAssociate and iss fields in the association token need to be compressed public keys. However, the pubkeyHexToECPair() method does not compress the given key – it just returns the key’s address. It looks like that’s the source of the trouble.