[Standards] Re: [jdev] XEP-0115: Entity Capabilities

Dave Cridland dave at cridland.net
Fri Jun 29 04:40:09 CDT 2007


On Thu Jun 28 23:12:25 2007, Joe Hildebrand wrote:
> The current spec could absolutely be used for this.  The hardest 
> part  is spec'ing how to generate a string that has all of the  
> capabilities, so that you can run the hash.  Canonical XML is 
> massive  overkill, but, for example, if we just said:
> 
> - For all sorting, use the Unicode Collation Algorithm (http:// 
> www.unicode.org/unicode/reports/tr10/)

Feh. UTF-8 encode then i;octet - much faster, just as stable, and a 
heck of a lot simpler to implement, especially given that namespaces 
will be us-ascii anyway (hence UTF-8). RFC4790 defines this. (i;basic 
uses TR10, but ISTR it's not yet ready).


> - Initialize an empty string E
> - sort the identities by category, then type
> - for each identity, append the category, then the type (if it  
> exists) to E (note: any information inside an identity will be 
> ignored)

I'd propose something mildly more structured here, really such that 
it's simpler to view by eye to ensure the formatting and ordering is 
correct. This has no security impact, it's just easier to implement. 
Something like:

For each identity, append the following production:

cat-line = cat-tag SP category [SP type] CRLF
	;; Note that type MUST be present if it exists.
cat-tag = %43 %41 %54
	;; "CAT", case insensitively.


> - sort the features by URI
> - for each feature, append the URI to E  (note: any information  
> inside a feature will be ignored)

Similarly:

feat-line = feat-tag SP feat-uri CRLF
feat-tag = %46 %45 %41 %54
	;; "FEAT" case insensitively.


> - calculate the MD5 sum for E

MD5 has a bad reputation, but note that the stricter the input 
formatting, the less likely it is to be forged (ie, the less likely 
it is that someone could find a colliding input that makes semantic 
sense.)

For better security, we could use HMAC, and/or a different hash 
function. One option would be that, if H is the result of the 
hash/hmac function, then V, the version string, is formed by 
prepending its algorithm and a $, something like:

E = *(cat-line) *(feat-line)
H = <hash/hmac of E>
V = hash-func-name "$" H
hash-func-name = hash-name / "HMAC-" hash-name
hash-name = "MD5" / "SHA1" / "SHA-256"

We mandate that HMAC-MD5 is used, but a future specification MAY 
change this requirement. MD5 does have the minor advantage of being 
smaller.


> - use this for the version number or extension name
> 
> 
(Given my suggestion above, we'd use V, rather than Hash(E)).


> Example (adapted from XEP-115, example 2):
> 
> <presence from='romeo at montague.net/home'>
>   <c xmlns='http://jabber.org/protocol/caps'
>      node='http://exodus.jabberstudio.org/caps'
>      ver='730c80b442e150dd5e19a31f8edfa8b1'
>      ext='d6224a352df544cfde1fbce177301c67  
> d0ef9e8327acf5873d16fe083b4d3f3f'/>
> </presence>
> 
> 
This example would have the same form, roughly:

ver='HMAC-MD5$[...]'
ext='HMAC-MD5$[...] HMAC-MD5$[...]'


> The receiving client SHOULD check the hashes, after doing the 
> IQ/gets:
> 
> md5(clientpchttp://jabber.org/protocol/disco#infohttp://jabber.org/ 
> protocol/disco#itemshttp://jabber.org/protocol/feature-neghttp:// 
> jabber.org/protocol/muc) = 730c80b442e150dd5e19a31f8edfa8b1

This one becomes (using literal whitespace for clarification, not 
syntax):

Hash("
CAT client pc\r\n
FEAT http://jabber.org/protocol/disco#info\r\n
FEAT http://jabber.org/protocol/disco#items\r\n
FEAT http://jabber.org/protocol/feature-neg\r\n
FEAT http://jabber.org/protocol/muc\r\n
")

I'll skip the remaining examples, but presumably you get the notion.

> If the receiving client detects an inconsistency, it MUST NOT use 
> the  information it received, and SHOULD show an error of some kind.
> 
> For backwards-compatibility, any version number that is not 32 
> octets  long consisting only of [0-9a-f] MUST be treated as if it 
> does not  implement MD5 checking.
> 
> 
We've got slightly better error checking if we explicitly tag the 
data with the prefix defined by the V ABNF production above.


> Analysis:
> - Existing entities, both sending and receiving, should work fine
> - Over time, we can phase in entities that send md5 versions and 
> ext's
> - Receiving clients that care about security can start checking MD5 
>  hashes of the features to check for poisoning.
> - Downside: more bytes in presence than today.

We send these out, currently, with every presence update, correct? Is 
it worth looking at an alternate mechanism, or a generalized 
presence-delta? (After all, I'm pretty sure that this data won't 
change as often as my status).

I have to admit, I have an odd feeling that combining all extensions 
together might generate a better result, too, but that's nothing more 
than a gut feeling.


> - Assertion: anything else we do will be at least this bad if not 
> worse.
> 
> If we add these bits to -115, will everyone agree to never bring up 
>  changing caps again, and to all agree on that the next time a n00b 
>  comes around?

I hate to say never, but I can't see how we can get much better than 
this.

Dave.
-- 
Dave Cridland - mailto:dave at cridland.net - xmpp:dwd at jabber.org
  - acap://acap.dave.cridland.net/byowner/user/dwd/bookmarks/
  - http://dave.cridland.net/
Infotrope Polymer - ACAP, IMAP, ESMTP, and Lemonade


More information about the Standards mailing list