bitpay/copay — pull request #881 by ryanxcharles (2014-07-09 06:32:28+00:00)
Title: Add nonce to network protocol

A nonce (an iterated number added to messages) is a way to eliminate replay attacks. The nonce must be bigger with every message, or the message will be rejected. There is one tricky part with nonces in Copay, which is that we want to be able to restore old wallets, so a copayer may forget what nonce they are on.

The solution to this is to use a really big 8 byte big endian nonce that is created in two parts.

The first four bytes of the number are the current time in seconds. The second four bytes are a subnonce that is iterated through. If a copayer ever restores their old wallet and the subnonce goes back to zero, it is not a problem, because more than one second of time will have ellapsed since then, so the nonce will be bigger. Only if a copayer wishes to restore an old wallet within one second of having sent their last message will they have a problem (or if their system clock is grossly inaccurate).

The new network protocol sends messages that look like this:

(version1)(version2)(nonce)(payload)

Version 1 is changed for backwards-incompatible changes, like this one. I have increased version1 from 0 to 1. I have also added version2, which allows for backwards-compatible changes. Old clients will not reject messages with a different version2. Both versions are one byte. The nonce is the 8 byte big endian number. And the payload is a JSON string. The whole thing is encrypted and signed.

Note that this PR is not backwards-compatible. All copayers must upgrade simultaneously when upgrading to this new protocol or they will not be able to connect.

Like the last network PR where I added authentication, this change is not intended to solve every conceivable network attack. It is a short term fix for a specific vulnerability - replay attacks. Long-term, we need to convert to well-studied secure protocol like TLS. Or, hopefully, WebRTC, if we can figure out how to handle authentication correctly with that.

Please thoroughly review and test this before pulling it in. It may break stuff (although all tests do pass, and of course I added more tests).