You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lokinet/docs/wire-protocol.txt

167 lines
3.2 KiB
Plaintext

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