lokinet/docs/wire-protocol.txt
2019-01-05 08:45:05 -05:00

167 lines
3.2 KiB
Plaintext

Wire Protocol (version 1)
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in RFC 2119 [RFC2119].
LLARP supports by default an authenticated message transport over a
datagram based network layer.
outer message format:
{
A: command,
B: <16 bytes flow id>,
C: <optional 32 bytes cookie>,
X: <N bytes payload>
}
comamnds:
A - get handshake cookie
obtain a handshake cookie
B is randomized
X MUST contain the user agent string of the requester.
the if the network id differs from the current network's id a reject message is
sent:
{
A: R,
B: msg.B,
X: "<reply line>"
}
MUST be replied to with a message rejected or a give handshake cookie
C - give handshake cookie
give a handshake cookie to a remote endpoint that asks for one
B is the B value from the get handshake cookie message
X is a 32 byte handshake cookie, calcuated via:
r = RAND(32)
a = "<ascii representation of ip>" + " " + "<port number>"
X = HS(a + B + r)
R - message rejected
B is the flow id from the recipiant
X is a reply line
reject a message with flow id B
S - session negotiation
negotiate encrypted session
B is the flow id from the recipiant
C is the handshake cookie
X is encrypted session negotiation data
D - encrypted data transmission
transmit encrypted data on session
B is the flow id from the recipiant
X is authenticated and encrypted data
BNF:
<reply-line> ::= <status-code> <space> <method> <space> <message>
<status-code> ::= <integer> <digit> <digit>
<word> ::= <letter>+
<message> ::= <word> <space> <word>* | <word>
<method> ::= "COOKIE" | "HANDSHAKE"
<user-agent> ::= <net-id> <space> <protocol-version> <space> <agent-version>
<net-id> ::= "lokinet" | "testnet"
<space> ::= " "
<zero> ::= "0"
<integer> ::= "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<digit> ::= <zero> | <integer>
<number> ::= <zero> | <integer> <digit>*
<agent-version> ::= <number> "." <number> "." <number>
<protocol-version> ::= <number>
session negotiation:
The session starts out with each side having 2 session keys rx_K and tx_K for
decrypting inbound messages and encrypting outbound messages respectively.
The initiator (alice) and the recipiant (bob) start out with static session keys
k_a = HS(a.k)
k_b = HS(b.k)
a.rx_K = k_a
b.rx_K = k_b
a.tx_K = k_b
b.tx_K = k_a
inner message format:
<32 bytes blake2s keyed hash of following data>
<24 bytes nounce>
<remaining bytes encrypted payload>
decryption is done via:
SD(remaining, rx_K, nounce)
encrypted payload is bencoded LIM (see proto_v0.txt)
the initiator starts out by sending a LIM a_LIM to the recipiant.
the recipiant replies with a LIM b_LIM to the initiator.
when the initiator gets a valid LIM from the recipiant the session keys for data
transmission are set to:
k_a = TKE(a.k, b.k, a.sk, a_LIM.n)
k_b = TKE(b.k, a.k, b.sk, b_LIM.n)
a.rx_K = k_a
b.rx_K = k_b
a.tx_K = k_b
b.tx_K = k_a
afterwards data transmission may happen
data tranmission:
message format:
<10 byte header>
<remaining data payload>
header format:
<1 byte proto version>
<1 byte command>
<1 byte flags>
<1 byte fragno>
<2 bytes fraglen>
<4 bytes seqno>