More ideas and EC-DSA signatures
diff --git a/intermud/doc/intermud-v25.rst b/intermud/doc/intermud-v25.rst
index 4388317..75bda22 100644
--- a/intermud/doc/intermud-v25.rst
+++ b/intermud/doc/intermud-v25.rst
@@ -80,7 +80,7 @@
names **SHOULD** consist of ASCII characters.
Each packet sent consists of a string as follows:
- M:xxx|V:nnn|F:nnn|header1:body1|headerN:bodyN|DATA:body-data
+ S:xxx|V:nnn|F:nnn|header1:body1|headerN:bodyN|DATA:body-data
In other words, a header name, followed by a : and then the data
associated with this header. Each field, consisting of a header/body pair, is
@@ -94,15 +94,20 @@
field. This means it can contain special characters without error and
it is used to carry the main body or data of all packets.
+The fields S (packet signature), V (version) and F (flags) **MUST** be in this
+order at the start of the packet before any other fields. This 3 fields are
+also referred to as the 'packet header'. The general layout of packets is:
+
+ [fragmentation header]|packet header|packet payload/data
+
+The packet header **MUST NOT** be larger than 512 bytes.
+
By convention, predefined system fields will use capital letters for
field headers and custom headers used by specific applications will
use lowercase names to avoid clashes.
A header name **MUST** be unique in a packet.
-The fields M (hash based message authentication code), V (version) and F
-(flags) **MUST** be in this order at the start of the packet before any other
-fields.
Fragmented packets
------------------
@@ -113,7 +118,7 @@
These fragmentation headers are of the format:
- PKT:peername:packet-id:packet-number/total-packets|M:xxx|rest-of-packet
+ PKT:peername:packet-id:packet-number/total-packets|S:xxx|rest-of-packet
In this case, the mudname and packet-id combine to form a unique id
for the packet. The packet-number and total-packets information is
@@ -129,7 +134,7 @@
Any peer **MUST** support at least 100 fragments per packet.
-Each fragment **MUST** contain its own valid HMAC in the field M.
+Each fragment **MUST** contain its own valid signature in the field S.
The sender **SHOULD** send the fragments in the correct order. However, the
receiver **MUST** assume the fragments arrive in any order.
@@ -149,41 +154,34 @@
Strings **MUST** be prefixed with the character $. If the first character of a
string is the $ character, it is escaped by prepending another $ character.
-Message authentication codes
-----------------------------
+Packet signatures
+-----------------
For packet validation and to prevent tampering on the wire and spoofing of
-peers, each packet sent **MUST** contain a field M containing a hash-based
-message authentication code.
+peers, each packet sent **MUST** contain a field S containing the EC-DSA
+signature of the packet.
-The first byte of the MAC field specifies the HMAC algorithm used. In intermud
+The first byte of the MAC field specifies the method and curve used. In intermud
v2.5 the following algorithms **MUST** be supported:
-* TLS_HASH_SHA1: 1
-* TLS_HASH_SHA256: 2
-* TLS_HASH_SHA512: 3
+*
+*
+*
-The recommended method is SHA1.
+The recommended method is ...
-The transferred data is the complete packet string **without** the field M.
-After the packet (or fragment) is encoded (without the field M), the HMAC is
-calculated and then inserted into the packet string either at the beginning of
-the packet or (for fragments) at the end of the fragmentation
-header.
-
-The secret must be known to both communicating peers and must be exchanged
-between the operators of two communicating peers. If an intermud peer does not
-use an indivdual secret, it **SHOULD** use its own name. If a receiving peer
-does not know the secret of the sending peer, it SHOULD try to use the
-sending peer's name. Of course, this makes the HMAC just a measure to prevent
-transmission errors.
+The transferred data is the complete packet string **without** the field S.
+After the packet (or fragment) is encoded (without the field S), the signature
+is calculated using the private EC key and then inserted into the packet
+string either at the beginning of the packet or (for fragments) at the end of
+the fragmentation header.
Packet validation
-----------------
Upon receiving a fragment or packet, the receiver **MUST** first try to
-validate the HMAC in the field M. The receiver extracts the whole field from
-the received string and re-calculates the HMAC using the known secret or the
-default secret as fallback. If the calculated and received HMACs do not
-match, the receiver **MUST** discard the fragment or packet.
+validate the signature in the field S, if a public key for the sending peer is
+known. The receiver extracts the whole field from the received string and
+verifies the signature. If signature can't be verified, the receiver **MUST**
+discard the fragment or packet.
Fragments are then stored until the packet is completed or the timeout is
exceeded.
@@ -201,7 +199,7 @@
and will then be treated as a string.
Any other strings will be converted to integers.
-The fields M, V and F **SHOULD** be stripped from the packet data that is
+The fields S, V and F **SHOULD** be stripped from the packet data that is
transferred from the inetd implementation to the application.
Legacy mode packets and encoding
@@ -211,7 +209,7 @@
format that is sent by older intermud peers. Unless in strict mode, the following
deviations are acceptable when receiving:
-* The M, V and F fields are missing or are not the first three fields.
+* The packet header (S, V and F fields) is missing.
* A string **MAY** be prefixed with the character $, but does not have to, unless
there ambiguity as to wether they should be decoded as a string or an
integer. If a string is losslessly convertable to an integer and back to a
@@ -222,12 +220,12 @@
However, a packet **MUST NOT** be parsed as legacy mode packet, if one of the
following conditions are met:
-* the packet contains the field M
+* the packet contains the field S
* the packet contains a version field F with a version of at least 2500
* the receiving peer operates in strict mode
After a packet conforming to protocol version >= 2.5 (>=2500) was received
-from a peer (this implies the succesful validation of the HMAC), legacy mode
+from a peer (this implies the succesful validation of the signature), legacy mode
packets from that peer **MUST NOT** be accepted without manual intervention of
an operator or expiration of the peer from the peer list.
@@ -237,13 +235,10 @@
Strict mode
-----------
To prevent spoofing of other muds, an operator MAY decide to operate in strict
-mode. In this mode, the peer accepts intermud v2.5 packets with a valid M
-field only and discards all other packets. Additionally, the default secrets
-are not used.
-In other words, it disables the compatibility with peers older than v2.5.
-
-Determination of the MTU
-------------------------
+mode. In this mode, the peer accepts intermud v2.5 packets with a valid S
+field only and discards all other packets.
+In other words, it disables the compatibility with peers older than v2.5 and
+does not communicate with unknown peers.
Request bookkeeping
-------------------
@@ -261,25 +256,81 @@
A peer **MUST** store the following data about other known peers:
* peer name (unique)
+* public key (unique), if available
* peer address
* peer port (receiving)
* time of last contact
+* time of first contact
+* reputation (trust) of that peer
A peer **SHOULD** store the following data about other known peers:
-* time of first contact
* list of supported services
* last seen intermud version
-* secret for calculating the HMAC
-* trust score of that peer
+* expiration time
* MTU of the peer
-A peer should expire peers from its host list some after the last contact. The
+A peers public key would be the best unique identifier. However, in the
+intermud a peer needs a unique symbolic name to address it. So a peers name
+and its public key should both be used as unique and long-lived identifier.
+
+But a peer MAY change its name by either announcing it or by just using a new
+name. If the public key remains the same, the entry in the peer list should
+be updated accordingly.
+
+If a peer claims to have a name that already exists, but its public key does
+not match the known public key of the existing peer entry, the new peer **MUST
+NOT** be entered in the peer list. Instead, any packets from that peer
+**SHOULD** be discarded. An implementation MAY notify the operator about this.
+
+Reputation
+----------
+The reputation is a score that symbolizes how trustworthy a peer is. It may be
+used for a number of decisions. By default, the reputation score is used as a
+scaling factor when exchanging peer information (see below) and it influences
+how quickly a peer is expired once it can't be reached.
+
+By default, a new peer starts with a score of 0 (which basically means, the
+information it offers, is not trusted). After a peer has been known for some
+time, its score gets increased:
+
+========== ==============
+time known score increase
+========== ==============
+7 days +1
+3 months +1
+1 year +1
+========== ==============
+
+A reputation of more than 3 can only be assigned by an operator.
+
+Peer expiration
+---------------
+A peer should expire peers from its host list some time after the last contact. The
expiration time may be chosen by the operator.
-However, peers **MUST NOT** be expired before 48h or a time this peer
-announced earlier (see module... TODO) passed without contact.
+
+However, to prevent rogue peers impersonating other peers, peers **MUST NOT**
+be expired before 48h or a time this peer announced earlier (see module...
+TODO) passed without contact.
+
+========== ===============
+reputation expiration time
+========== ===============
+0 48h
+1 7 days
+2 3 months
+3 6 months
+4+ 12 months
+========== ===============
+
If a peer announces it wants to be remembered for longer than 48h without
-contact, this wish MAY be respected.
+contact, this wish MAY be respected and the decision MAY be based on its
+reputation.
+
+An implementation **MAY** may move offline peers to a separate list for
+bookkeeping after some time and stop trying to contact it anymore. This keeps
+the active peer list short and efficient. However the 'long offline' peers
+should still be remembered to keep the binding of public key and name.
Before expiring a peer, a ping **SHOULD** be sent to check for reachability.
@@ -296,26 +347,19 @@
However, this carries the risk of rogue peers successfully impersonating
another peer for an extended time.
-Update of the secret
---------------------
-There are two ways to perform an update of the secret without operator
-intervention. In both cases, the new secret **MUST** be received in a v2.5
-packet with valid HMAC
+An inetd **SHOULD** contact the known peers at least once per 24h to check if
+it is still online and reachable (ping or helo).
-# Query: a peer may be asked for its secret with a Query request. However, any
- peer **MAY** decide freely if it honors such a request (e.g. because the
- requesting peer is known and trustworthy).
-# Push: a peer may inform other peers about an update of its HMAC secret by
- sending a - TODO fill in module - to trustworthy known peers. Such an
+Update of the public key
+------------------------
+There ist a way to perform an update of the public key without operator
+intervention. The new public key **MUST** be received in a v2.5 packet with
+valid signature.
+
+A peer may inform other peers about an update of its public key by
+ sending a push notification - TODO fill in module - Such an
update **SHOULD** be honored.
-Combined with the default HMAC secret the second possibility enables peers to
-upgrade from the default secret to a specific one at any time.
-
-Which peers to inform about the secret, depends on the operator preferences.
-It may depend on a trust score the operator assigns or it may be sent to peers
-that are around for a certain time.
-
Defined system headers / fields
===============================
@@ -390,6 +434,10 @@
RECIPIENT field. It should also include an appropriate string
in the DATA field, eg. "Mud-Name is alive.\n"
+helo
+^^^^
+Used to exchange information like the public key.
+
query
^^^^^
This module expects the type of query requested to appear in the
@@ -397,6 +445,7 @@
the original ID in the ID field, the SENDER in it's RECIPIENT
field, and the query type in a QUERY field. The DATA field should
contain the information requested.
+TODO: include asking for peer list in JSON format.
Optional requests / modules