373 lines
10 KiB
Plaintext
373 lines
10 KiB
Plaintext
ZERO BYTE (the byte at zero offset of the datagram):
|
|
|
|
|
|
00--BF: first byte of an encrypted message within an established connection
|
|
(that is, the first byte of the obfuscated nonce)
|
|
C0--DF: means that the actual encrypted message starts with a byte
|
|
C0..FF, hence the message begins at the next byte
|
|
E0--FF: a message outside of an established connection
|
|
|
|
Please note the particular value for C0..DF or E0..FF must be randomly
|
|
generated for each individual datagram.
|
|
|
|
|
|
|
|
MESSAGES OUTSIDE OF ENCRYPTED CONNECTIONS
|
|
|
|
The least significant half-byte of the Zero Byte is duplicated to form a
|
|
byte (e.g., 0xE8 becomes 0x88); the second byte is XOR'ed with this value.
|
|
The result of the XOR is the command:
|
|
|
|
|
|
14 ("Introduce Yourself") request for the peer's credentials
|
|
2 1 0 (in future, this might change)
|
|
3..363 361 random padding
|
|
|
|
|
|
1A ("I Am") self-introduction
|
|
2..33 32 master_pub
|
|
34..65 32 master_hash
|
|
66..129 64 master_hash_sign
|
|
130 1 point id
|
|
131 1 "signed-by" code (0x00 or 0xff)
|
|
132..183 52 zero point cert (for signed-by==0x00 only)
|
|
184..247 64 signature for zp cert (... -- // -- ...)
|
|
248..299 52 this point cert
|
|
300..363 64 signature for this point cert
|
|
|
|
|
|
57 ("STub") senseless datagram to raise "response credit"
|
|
2..127 126 random padding
|
|
|
|
|
|
7E ("TEst") I'm willing to test my NAT (and here's my public key)
|
|
2..33 32 the public key
|
|
34..127 94 random padding
|
|
|
|
|
|
7F reply on 7E
|
|
2..33 32 the kex public key of the responder
|
|
(the rest is a cryptobox)
|
|
34..41 8 nonce
|
|
42..57 16 MAC
|
|
(the rest is encrypted)
|
|
58..63 6 your (visible) addr/port, MSBF
|
|
64 1 your current stub credit
|
|
65 1 reserved (zero)
|
|
66..125 60 up to 10 ip/port pairs of the friendly peers
|
|
126..127 2 random padding
|
|
|
|
|
|
# 9A ("please ask") please ask to contact me (unassoc. peers)
|
|
# 2..7 6 addr/port to ask, MSBF
|
|
# 8..127 120 random padding
|
|
#
|
|
#
|
|
# 9C ("please contact") please contact the given address (unassoc. peers)
|
|
# SENSELESS! One can't "ask" a restricted cone
|
|
# peer unless it's associated, and there's no
|
|
# point in asking a fullcone/nonNAT peer for
|
|
# anything
|
|
# 2..7 6 addr/port to contact, MSBF
|
|
# 8..127 120 random padding
|
|
|
|
|
|
A5 ("ASsociate") here's my public key for Diffie-Hellman, I know yours
|
|
(you perhaps know mine, as well, but you could forget it)
|
|
2..33 32 the kex public key
|
|
(the rest is a cryptobox)
|
|
34..41 8 nonce
|
|
42..57 16 MAC
|
|
(the rest is encrypted)
|
|
58..67 (0) 10 node id
|
|
68 (10) 1 point id
|
|
69 (11) 1 "signed-by" code (0x00 or 0xff)
|
|
70..121 (12) 52 zero point cert (for signed-by==0x00 only)
|
|
122..185 (64) 64 signature for zp cert (... -- // -- ...)
|
|
186..237 (128) 52 this point cert
|
|
238..301 (180) 64 signature for this point cert
|
|
302..305 (244) 4 timemark (minutes since Epoch)
|
|
306..313 (248) 8 nonce2
|
|
314..377 (256) 64 signature for: kex_pubkey+timemark+nonce2
|
|
(320)
|
|
|
|
|
|
C4 ("Change keY") your encrypted dgram looks strange, here's the actual key
|
|
2..33 32 the kex public key
|
|
34..41 8 nonce from the err. packet, obfuscated
|
|
42..45 4 timemark (minutes)
|
|
46..53 8 nonce2 (from our counter)
|
|
54..117 64 signature for all the previous
|
|
118..127 10 random padding
|
|
|
|
|
|
E8 ("error") You sent me something strange or unsupported
|
|
2 1 error code
|
|
3..127 125 random padding
|
|
|
|
|
|
EC ("echo") echo request
|
|
2..33 32 the public key
|
|
34..37 4 timemark (minutes)
|
|
38..45 8 nonce
|
|
46..127 82 random padding
|
|
|
|
ED ("echoeD") echo reply
|
|
2..33 32 the kex public key of the responder
|
|
(the rest is a cryptobox)
|
|
34..41 8 nonce
|
|
42..57 16 MAC
|
|
(the rest is encrypted)
|
|
58..63 (0) 6 your (visible) addr/port, MSBF
|
|
64..67 (6) 4 timemark (minutes) FROM THE REQ.
|
|
68..75 (10) 8 echo request's nonce
|
|
76..85 (18) 10 node_id (our)
|
|
86 (28) 1 point (our)
|
|
87 (29) 1 minpref (our)
|
|
88..95 (30) 8 nonce2 (from our counter)
|
|
96..159 (38) 64 signature for the kex key
|
|
|
|
for the echo reply, the kex public key from the request is always
|
|
used, even when we have an established association with the peer
|
|
and its key differs; this is because the peer could have restarted
|
|
thus loosing (changing) its kex credentials, and now tries to
|
|
reestablish the association with us
|
|
|
|
|
|
F0 ("forward") Not used in the present version of the protocol;
|
|
intended for (encrypted) messages that should be
|
|
forwarded to another node without decrypting
|
|
|
|
|
|
|
|
ENCRYPTED MESSAGE STRUCTURE
|
|
|
|
|
|
[-16..-1] (not in the message, only in the buffer) the part of the
|
|
nonce to be zeroed; the byte at [-1] may become a part of
|
|
the datagram in case the first byte of the nonce is >= 0xC0
|
|
0..7 8 nonce (last 8 bytes, obfuscated; the first 16 are 0s)
|
|
8..23 16 MAC
|
|
(the rest is ciphertext)
|
|
24 1 message type
|
|
25..end ? payload
|
|
|
|
|
|
|
|
ENCRYPTED MESSAGE TYPES
|
|
|
|
03 keep alive
|
|
25..127 103 random padding
|
|
|
|
0A please ask to contact me // not implemented yet
|
|
25 1 zero
|
|
26..31 6 ip/port to ask
|
|
32..127 96 random padding
|
|
|
|
0C please contact
|
|
25 1 zero
|
|
26..31 6 ip/port to contact
|
|
32..127 96 random padding
|
|
|
|
0E error
|
|
25 1 error code
|
|
26..127 102 random padding
|
|
|
|
|
|
|
|
|
|
8x "respond me" -- messages to be responded,
|
|
resent in case there's no response
|
|
25 1 zero
|
|
26..29 4 random cookie
|
|
30..507 478 (max) the payload
|
|
|
|
|
|
8C do you know this node?
|
|
25 1 zero
|
|
26..29 4 random cookie
|
|
30..39 10 node id
|
|
40..237 198 random padding
|
|
|
|
|
|
|
|
9x "so I respond" -- responses for the respective 9x
|
|
25 1 zero
|
|
26..29 4 the cookie from the request
|
|
30..507 478 (max) the payload
|
|
|
|
|
|
9C I do/don't know the node
|
|
25 1 zero
|
|
26..29 4 the cookie from the request
|
|
30..39 10 node id
|
|
40 1 status: 0:dunno 1:yes (possibly more in future)
|
|
41 1 rank: if 'yes', the rank for the node in q.
|
|
if 'no', the responder's min. rank to
|
|
be stored in the database
|
|
42..73 32 public key (or zeroes for 'no')
|
|
74..105 32 hash (or zeroes for 'no')
|
|
106..169 64 hsign (or zeroes for 'no')
|
|
170..173 4 timestamp (or zeroes for 'no')
|
|
174..237 64 sender's signature for 41..173 (or zeroes)
|
|
|
|
|
|
B0 Proxy Outbound (packet from proxyuser to proxy server)
|
|
25..30 6 ip/port to forward to
|
|
31..507 477 (max) the forwarded datagram
|
|
|
|
B1 Proxy Inbound (packet from proxy server to proxy user)
|
|
25..30 6 ip/port of the original source
|
|
31..507 477 (max) the forwarded datagram
|
|
|
|
|
|
|
|
Dx data (carries an encapsulated IPv6 packet)
|
|
24 1 0xD0 | ((part_cnt-1) << 2) | part_num
|
|
25..27 3 peer-local sequential number (wraps)
|
|
28..475 448 (max) the payload
|
|
|
|
The max. payload size is choosen keeping in mind that
|
|
we should remain to be able to enclose our packets
|
|
(full enclrypted dgrams) into other packets and still
|
|
not overcome the 508 bytes limit. The 448 bytes limit
|
|
for the payload (476 for the whole dgram) leaves 32
|
|
bytes for the encapsulating dgram. Okay, 8 bytes of
|
|
nonce, 16 bytes of MAC, 1 byte msg type, 4 bytes to
|
|
identify the forwarging stream somehow, and remember
|
|
that one byte to escape in case the obfuscated nonce
|
|
starts with 0xC0..0xFF... well, still 2 bytes are left
|
|
until The Limit. 4+2 may also be the ip:port, but in
|
|
this case we'll have no reserve.
|
|
|
|
Besides that, we keep in mind that one day we may implement
|
|
the MTU path discovery as it should be, and after that we'll
|
|
use dgrams of greater size, such as 1500 bytes. So we implement
|
|
reassembling of dgrams without imposing any size limits. Only
|
|
the sending procedures are affected with the limits.
|
|
|
|
|
|
|
|
MESSAGE EXCHANGE
|
|
|
|
|
|
|
|
***************
|
|
* Establishing crypto association
|
|
|
|
Client Server
|
|
|
|
echo request (EC) --->
|
|
|
|
<--- echo reply (ED)
|
|
|
|
(*if* client doesn't know the server's node)
|
|
|
|
[failure] (XXX to be changed)
|
|
|
|
(*if* client has the server's node, but not the server's point)
|
|
|
|
please introduce (14) --->
|
|
|
|
<--- i am (1A)
|
|
|
|
(*if* the client has the server's point cert, initially or after 1A)
|
|
|
|
associate (A5) --->
|
|
|
|
(*if* the servers knows at least the node of the client)
|
|
|
|
<--- keep alive (enc.03)
|
|
|
|
[ok]
|
|
|
|
(*if* the server doesn't know the client's node)
|
|
|
|
[failure] (XXX to be changed)
|
|
|
|
|
|
|
|
***************
|
|
* Checking NAT
|
|
|
|
Client Server Sibling(s)
|
|
|
|
stub (57) ---> *
|
|
stub (57) ---> *
|
|
stub (57) ---> *
|
|
stub (57) ---> *
|
|
stub (57) ---> *
|
|
|
|
test (7E) ---> *
|
|
|
|
* <--- test R (7F)
|
|
|
|
plz cnt (enc.0C) ---> *
|
|
|
|
* <---------------------------- stub (57)
|
|
|
|
(*if* client received all expected dgrams)
|
|
|
|
[done]
|
|
|
|
(*if* client's waiting timed out, only got the server's reply)
|
|
("second stage")
|
|
|
|
echo rq (EC) ----------------------------> *
|
|
|
|
* <---------------------------- echo rpl (ED)
|
|
|
|
[done]
|
|
|
|
|
|
|
|
***************
|
|
* Generic messages
|
|
|
|
Messages of the types "error" (E8) and "change key" (C4) are sent whenever
|
|
it is appropriate, which effectively means something went wrong.
|
|
|
|
The C4 type is used in situations when an incoming _encrypted_ datagram can
|
|
not be decrypted. It is used as indication for the error, but, unlike the
|
|
E8 type, it contains the actual KEX public key of the party which detected
|
|
the error, and the key is signed by the point's key together with the
|
|
current timemark. In (a very common) case when the error was caused by
|
|
restarting of the fedaserv instance, this makes it possible for the partner
|
|
to recover the cryptographic association with a single datagram of the A5
|
|
type ("associate"):
|
|
|
|
Alice Bob
|
|
|
|
(any encrypted dgram) --->
|
|
|
|
<--- change key (C4)
|
|
|
|
associate (A5) --->
|
|
|
|
<--- keep alive (enc.03)
|
|
|
|
[ok]
|
|
|
|
|
|
Unlike the C4 type, a datagram of the E8 type ("error") contains no
|
|
authentication info, so it can not be used for automated recovery of any
|
|
kind: otherwise, it would be possible for anyone on the Internet to spoof
|
|
such a datagram and fool random fedaserv instances into believing something
|
|
goes wrong and there's a need for recovery, thus effectively breaking
|
|
existing and normally functioning associations. Hence, E8 type dgrams can
|
|
only serve as a source of information for human operators, and they are
|
|
only sent in situations the software has no recovery procedure for the
|
|
error in question (as of now this means all errors except the inability to
|
|
decrypt an encrypted dgram). The only thing the receiving party does upon
|
|
receiving them is logging a message.
|
|
|
|
|
|
|
|
***************
|
|
* Established crypto association
|
|
|
|
There are no exchange procedures for the case of an established
|
|
cryptographic association; each type of the encrypted datagrams is used in
|
|
the respective situation and is expected to be reacted upon accordingly.
|
|
|