lokinet/docs/wire-protocol.txt

167 lines
3.2 KiB
Plaintext
Raw Normal View History

2019-01-05 13:45:05 +00:00
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].
2019-01-05 13:45:05 +00:00
LLARP supports by default an authenticated message transport over a
datagram based network layer.
2019-01-05 13:45:05 +00:00
outer message format:
2019-01-05 13:45:05 +00:00
{
A: command,
B: <16 bytes flow id>,
C: <optional 32 bytes cookie>,
X: <N bytes payload>
}
2019-01-05 13:45:05 +00:00
comamnds:
2019-01-05 13:45:05 +00:00
A - get handshake cookie
2019-01-05 13:45:05 +00:00
obtain a handshake cookie
2019-01-05 13:45:05 +00:00
B is randomized
X MUST contain the user agent string of the requester.
2019-01-05 13:45:05 +00:00
the if the network id differs from the current network's id a reject message is
sent:
2019-01-05 13:45:05 +00:00
{
A: R,
B: msg.B,
X: "<reply line>"
}
2019-01-05 13:45:05 +00:00
MUST be replied to with a message rejected or a give handshake cookie
2019-01-05 13:45:05 +00:00
C - give handshake cookie
2019-01-05 13:45:05 +00:00
give a handshake cookie to a remote endpoint that asks for one
2019-01-05 13:45:05 +00:00
B is the B value from the get handshake cookie message
X is a 32 byte handshake cookie, calcuated via:
2019-01-05 13:45:05 +00:00
r = RAND(32)
a = "<ascii representation of ip>" + " " + "<port number>"
X = HS(a + B + r)
2019-01-05 13:45:05 +00:00
R - message rejected
2019-01-05 13:45:05 +00:00
B is the flow id from the recipiant
X is a reply line
2019-01-05 13:45:05 +00:00
reject a message with flow id B
2019-01-05 13:45:05 +00:00
S - session negotiation
2019-01-05 13:45:05 +00:00
negotiate encrypted session
2019-01-05 13:45:05 +00:00
B is the flow id from the recipiant
C is the handshake cookie
X is encrypted session negotiation data
2019-01-05 13:45:05 +00:00
D - encrypted data transmission
2019-01-05 13:45:05 +00:00
transmit encrypted data on session
2019-01-05 13:45:05 +00:00
B is the flow id from the recipiant
X is authenticated and encrypted data
2019-01-05 13:45:05 +00:00
BNF:
2019-01-05 13:45:05 +00:00
<reply-line> ::= <status-code> <space> <method> <space> <message>
2019-01-05 13:45:05 +00:00
<status-code> ::= <integer> <digit> <digit>
2019-01-05 13:45:05 +00:00
<word> ::= <letter>+
2019-01-05 13:45:05 +00:00
<message> ::= <word> <space> <word>* | <word>
2019-01-05 13:45:05 +00:00
<method> ::= "COOKIE" | "HANDSHAKE"
2019-01-05 13:45:05 +00:00
<user-agent> ::= <net-id> <space> <protocol-version> <space> <agent-version>
2019-01-05 13:45:05 +00:00
<net-id> ::= "lokinet" | "testnet"
2019-01-05 13:45:05 +00:00
<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>