nuances of implicit signing format
looking at ssb-validate because of this formats discussion with @aljoscha I'm looking at the details of the signing format, to see if there are wobbly bits we can shore up (and lay ground work towards a better format)
field order (and signature position)
currently, field order of the top level object is not specified. I did a test:
{ 'previous,author,sequence,timestamp,hash,content,signature': 480644,
'previous,sequence,author,timestamp,hash,content,signature': 49692 }
that's nearly 50k messages with sequence before author.
But, signature
is always last!
This is important, because if you inserted signature some place else, it would have a different hash but the signature would be the same! That would mean someone could send a message for someone with the signature moved, and it would seem valid, but the hash would not be the correct previous hash on the next message, so you would drop any future messages on that feed.
This would be a DoS, that we could fix by checking that the signature field is always last. Instead of deleting the signature, we should have signed were the signature would go, or require that it's last. Requiring that it's last is the thing we can do now.
I propose at the very least, rejecting messages that do not have the signature last
optional fields
Every current message has a hash
field, but it's not checked. that means the current implementation would still accept messages missing the hash field.
We should make this required. But, prehaps we can take advantage of this opportunity to add a version
field?
hash
was included to enable upgrading the hash.
utf8 & hashes
this is the most embarassing one. before node@6 (iirc) the default encoding for crypto.createHash('sha256').update(string)
is "binary"
which is an alias for "latin1"
(defined in https://tools.ietf.org/html/rfc1345) if only ascii characters are used, this makes no difference. but if ascii characters are used, only the first byte of each character is used in the hash. however, since the signature uses new Buffer(string, 'utf-8')
they are included in the signature. Thankfully, this means the signature is not mutable, but the hash is.
As it is, this is ugly but not a problem.
We could fix it by using a hash: utf8-sha256
in the hash field. We'd have to add code for handling that, then a few months later, make that the default way to make messages. (this might be good practice for upgrading formats)