[Standards] serious bugs in XEP-0220 (Server Dialback)

Philipp Hancke fippo at goodadvice.pages.de
Fri Apr 22 13:27:42 UTC 2011


I think the bug is less serious than you think ...

> There are two basic problems:
>
> 1. In all of the examples of XEP-0220, the dialback key should be the
> same key -- but the key varies across examples.

The XEP shows _two_ dialback sessions on two TCP connections.
If you re-read it with that POV things should make more sense.

> 2. The 'id' of the <db:verify/> element should always be the StreamID of
> the response stream header sent from the Receiving Server to the
> Originating Server -- but sometimes the 'id' is the StreamID of the
> response stream header sent from the Authoritative Server to the
> Receiving Server.

Yes and I think that is correct. The roles 
originating/receiving/authoritative server change between 
2.1.1/2.1.2 and 2.2.1/2.2.2 respectively.

> Let's roll the video tape...
>
> ### SECTION 2.1.1 ###
>
> Example 1. Originating Server Sends Dialback Key (step 1)
>
> send: <db:result
>          from='sender.tld'
>          to='target.tld'>
> ==>     1e701f120f66824b57303384e83b51feba858024fd2221d39f7acc52dcf767a9
>      </db:result>
>
> The key sent is generated as described in Dialback Key Generation and
> Validation [6]:
>
> key = HMAC-SHA256(
>        SHA256('s3cr3tf0rd14lb4ck'),
>          { 'target.tld', ' ', 'sender.tld', ' ', 'D60000229F' }
>      )
>
> [Philipp, can you verify that the key in Example 1 is correct based on
> the inputs?]

correct, using a slightly updated version of the script from
http://wiki.xmpp.org/web/Dialback_Key_Generation_and_Validation_%28XEP-0185%29

> ### SECTION 2.1.2 ###
>
> Example 5. Receiving Server Sends Verification Request to Authoritative
> Server (step 2)
>
> send: <db:verify
>          from='target.tld'
> ==>       id='417GAF25'
>          to='sender.tld'>
> ==>    38b501ec606752318f72ad53de17ac6d15f86257485b0d8f5d54e1f619e6b869
>     </db:verify>

This one seems not to be generated with that input and either of the two 
secrets...

> ### SECTION 2.2.1 ###
>
> Example 9. Receiving Server Receives Dialback Key from Originating
> Server (step 1)
>
> recv: <db:result
>          from='sender.tld'
>          to='target.tld'>
> ==>    1e701f120f66824b57303384e83b51feba858024fd2221d39f7acc52dcf767a9
>     </db:result>

ok, this is the key from example 1.

> ### SECTION 2.2.2 ###
>
> Example 13. Authoritative Server Receives Verification Request from
> Receiving Server (step 2)
>
> recv: <db:verify
>          from='target.tld'
> ==>       id='417GAF25'
>          to='sender.tld'>
> ==>    fed84f34d39682fd80bd04e01894f98c4149cf9df47575b134eeb6d2c7fe9fee
>     </db:verify>

This key should be identical to example 5 obviously...

> [...]
>
> Upon receiving this <db:verify/> element, the Authoritative Server
> determines the validity of the dialback key provided in the XML
> character data of the element. This can be achieved for example by
> comparing the character data with the output of applying the same key
> generation mechanism that was (presumably) used for the generation of
> the key, using as input the values of the 'from', 'to', and 'id'
> attributes contained in the verification request and the secret known
> only to the Sender Domain:
>
> key = HMAC-SHA256(
>        SHA256('d14lb4ck43v3r'),
>          { 'sender.tld', ' ', 'target.tld', ' ', '417GAF25' }
>      )
>    = fed84f34d39682fd80bd04e01894f98c4149cf9df47575b134eeb6d2c7fe9fee
> 
> ###
>
> What the heck is going on here?!?

target.tld is originating/auth server and therefore using dialback4ever as
secret. Since target.tld reuses the stream originally opened for
verification of the other key, the id is correct, too.

I think the from/to are swapped incorrectly in sections 2.1.2 and 2.2.2.

> (And yes, I'm to blame because I am the primary author of this spec.)

Probably not, since IIRC I generated those examples. svn blame? :-)

> Look at that last text snippet. It shows the Authoritative Server
> checking a dialback key that is generated using the secret key of the
> *Target Domain* ("d14lb4ck43v3r") instead of the secret key of the
> *Sender Domain* ("s3cr3tf0rd14lb4ck"), and using the StreamID of the
> response stream header from the Authoritative Server to the Receiving
> Server ("417GAF25") instead of the StreamID of the response stream
> header from the Receiving Server to the Originating Server
> ("D60000229F"). This is utter nonsense!

No, the roles of originating and receiving server have changed, 
which makes dialback so hard to implement and debug :-/

> Also nonsensical are Examples 5 and 13, which show the Receiving Server
> sending a dialback key different from the dialback key that the
> Originating Server sent in Example 1. But the Receiving Server does not

No, see above.

[...]

> But wait, there's more! These errors about the dialback key and StreamID
> needlessly stray from RFC 3920, which has the following...

I am not sure what you mean. AFAICS, RFC 3920 is correct.

> This mess is fairly easy to clean up, but the bugs are so fundamental
> that I'd like a sanity check from folks on this list to ensure that I'm
> not way off base here!

I think this is really limited to one incorrect key and some swapped 
from/to attributes. I'll re-review a print version next week.

philipp



More information about the Standards mailing list