Internet-Draft | The GNUnet communicators | August 2023 |
Schanzenbach & Grothoff | Expires 5 February 2024 | [Page] |
This document contains the GNUnet communicator specification.¶
This document defines the normative wire format of communicator protocols, cryptographic routines and security considerations for use by implementers.¶
This specification was developed outside the IETF and does not have IETF consensus. It is published here to inform readers about the function of GNUnet communicators, guide future communicator implementations, and ensure interoperability among implementations including with the pre-existing GNUnet implementation.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 5 February 2024.¶
Copyright (c) 2023 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
FIXME This document defines the normative wire format of resource records, resolution processes, cryptographic routines and security considerations for use by implementers.¶
This specification was developed outside the IETF and does not have IETF consensus. It is published here to guide implementers of GNS and to ensure interoperability among implementations.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
Each communicator must specify its (global) communication characteristics, which for now only say whether the communication is reliable (e.g. TCP, HTTPS) or unreliable (e.g. UDP, WLAN). Each communicator must specify a unique address prex, or NULL if the communicator cannot establish outgoing connections (for example because it is only acting as a TCP server). A communicator must tell TRANSPORT which addresses it is reachable under. Addresses may be added or removed at any time. A communicator may have zero addresses (transmission only). Addresses do not have to match the address prefix.¶
TRANSPORT may ask a communicator to try to connect to another address. TRANSPORT will only ask for connections where the address matches the communicator’s address prefix that was provided when the connection was established. Communicators should then attempt to establish a connection. No response is provided to TRANSPORT service on failure. The TRANSPORT service has to ask the communicator explicitly to retry.¶
If a communicator succeeds in establishing an outgoing connection for transmission, or if a communicator receives an incoming bi-directional connection, the communicator must inform the TRANSPORT service that a message queue (MQ) for transmission is now available. For that MQ, the communicator must provide the peer identity claimed by the other end. It must also provide a human-readable address (for debugging) and a maximum transfer unit (MTU). A MTU of zero means sending is not supported, SIZE_MAX should be used for no MTU. The communicator should also tell TRANSPORT what network type is used for the queue. The communicator may tell TRANSPORT anytime that the queue was deleted and is no longer available.¶
The communicator API also provides for flow control. First, communicators exhibit back-pressure on TRANSPORT: the number of messages TRANSPORT may add to a queue for transmission will be limited. So by not draining the transmission queue, back-pressure is provided to TRANSPORT. In the other direction, communicators may allow TRANSPORT to give back-pressure towards the communicator by providing a non-NULL GNUNET_TRANSPORT_MessageCompletedCallback (FIXME generic API) argument to the GNUNET_TRANSPORT_communicator_receive (FIXME generic API) function. In this case, TRANSPORT will only invoke this function once it has processed the message and is ready to receive more. Communicators should then limit how much traffic they receive based on this backpressure. Note that communicators do not have to provide a GNUNET_TRANSPORT_MessageCompletedCallback (FIXME generic API); for example, UDP cannot support back-pressure due to the nature of the UDP protocol. In this case, TRANSPORT will implement its own TRANSPORT-to-TRANSPORT flow control to reduce the sender’s data rate to acceptable levels.¶
TRANSPORT may notify a communicator about backchannel messages TRANSPORT received from other peers for this communicator. Similarly, communicators can ask TRANSPORT to try to send a backchannel message to other communicators of other peers. The semantics of the backchannel message are up to the communicators which use them. TRANSPORT may fail transmitting backchannel messages, and TRANSPORT will not attempt to retransmit them.¶
The UDP communicator implements a basic encryption layer to protect from metadata leakage. The layer tries to establish a shared secret using an Elliptic-Curve Diffie-Hellman key exchange in which the initiator of a packet creates an ephemeral key pair to encrypt a message for the target peer identity. The communicator always offers this kind of transmission queue to a (reachable) peer in which messages are encrypted with dedicated keys. The performance of this queue is not suitable for high volume data transfer.¶
If the UDP connection is bi-directional, or the TRANSPORT is able to offer a backchannel connection, the resulting key can be re-used if the recieving peer is able to ACK the reception. This will cause the communicator to offer a new queue (with a higher priority than the default queue) to TRANSPORT with a limited capacity. The capacity is increased whenever the communicator receives an ACK for a transmission. This queue is suitable for high-volume data transfer and TRANSPORT will likely prioritize this queue (if available).¶
Communicators that try to establish a connection to a target peer authenticate their peer ID (public key) in the first packets by signing a monotonic time stamp, its peer ID, and the target peerID and send this data as well as the signature in one of the first packets. Receivers should keep track (persist) of the monotonic time stamps for each peer ID to reject possible replay attacks.¶
Until a shared secret has been established, messages sent from the sender peer to the receiver peer are always encrypted and a key exchange metadata header is prepended. The wire format can be found in Figure 1. This method of sending messages to a peer can be used indefinitely, but is ineffienct since for every message, a new symmetric key must be established.¶
Once a shared secret MSK is established through the Diffie-Hellman KEM, symmetric keys are derived according to a key schedule from a 32-bit sequence number seq (in network byte order).¶
The KID derivation uses a hash-based key derivation function (HKDF) as defined in [RFC5869], using SHA-512 [RFC6234] for the extraction phase and SHA-256 [RFC6234] for the expansion phase. PRK_h is key material retrieved using an HKDF using the byte string seq as salt and k as initial keying material. key and initialization vector are the 256 + 96-bit HKDF expansion result. The expansion information input is the string "UDP-IV-KEY":¶
SetupCipher(MSK,SEQ): PRK_h := HKDF-Extract (SEQ, MSK) K,IV := HKDF-Expand (PRK_h, "UDP-IV-KEY", (256 + 96) / 8) return K,IV¶
With SetupCipher, a 256-bit AES key as well as a 96-bit IV for use in AES-GCM are derived from the MSK and SEQ.¶
Each derived key is uniquely identified using a separately derived 256-bit key ID (KID) derived in a similar fashion:¶
DeriveKID(MSK,SEQ): PRK_h := HKDF-Extract (SEQ, MSK) KID := HKDF-Expand (PRK_h, "UDP-KID", 256 / 8) return KID¶
The sequence number SEQ for any shared secret is initially 0 and incremented with each successive encryption (sent/received message).¶
All metadata for headers is chosen such that they are indistinguishable from random. For the use of (ephemeral) ECC public key material, this probably requires the use of additional randomization techniques such as Elligator (TODO). There are three distinct message types that are sent and received by UDP communciators: KX, BOX, BROADCAST. In any case, the common header is 32 + 16 bytes in length.¶
0 8 16 24 +-----+-----+-----+-----+-----+-----+-----+-----+ | EPHEMERAL PUBLIC KEY | | | | | | | | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | GCM TAG | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ / ENCRYPTED DATA / +-----+-----+-----+-----+-----+-----+-----+-----+
In order to prevent replay attacks for KX messages, the plaintext resulting from decryption of the ENCRYPTED DATA in the KX message starts with a session-specific confirmation header:¶
0 8 16 24 32 40 48 56 +-----+-----+-----+-----+-----+-----+-----+-----+ | | | SENDER PEER ID | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | | | SIGNATURE | | | | | | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | MONOTONIC TIMESTAMP | | | | | | | | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ / PAYLOAD / +-----+-----+-----+-----+-----+-----+-----+-----+
0 8 16 24 32 40 48 56 +-----+-----+-----+-----+-----+-----+-----+-----+ | SIZE | PURPOSE (0x0X) | +-----+-----+-----+-----+-----+-----+-----+-----+ | SENDER PEER ID | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | RECEIVER PEER ID | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | EPHEMERAL PUBLIC KEY | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | MONOTONIC TIMESTAMP | | | | | | | | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | NONCE | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+
Once a KX message is received and validated, the peer SHOULD try to acknowledge (ACK) the established shared secret.¶
TODO UDPAck payload. TODO UDPRekey payload.¶
0 8 16 24 +-----+-----+-----+-----+-----+-----+-----+-----+ | KEY ID | | | | | | | | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | GCM TAG | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ / ENCRYPTED DATA / +-----+-----+-----+-----+-----+-----+-----+-----+
Notice how a receiver should have precalculated all derived keys and corresponding KIDs for which it has already sent ACKs. Consequently, for valid sequence numbers below the current ACK limit, KID should match one of the precalculated keys in the key cache and the encrypted data can be decrypted. Otherwise, the message MUST be rejected.¶
FIXME: UDPAck, Broadcast¶
0 16 +-----+-----+-----+-----+-----+-----+-----+-----+ | SIZE | TYPE (0x0X) | +-----+-----+-----+-----+-----+-----+-----+-----+ | SEQ ACK | +-----+-----+-----+-----+-----+-----+-----+-----+ | MSK HASH (fromerly CMAC) | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+
0 16 +-----+-----+-----+-----+-----+-----+-----+-----+ | SIZE | TYPE (0x0X) | +-----+-----+-----+-----+-----+-----+-----+-----+ | EPHEMERAL PUBLIC KEY | | | | | | | | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+
The first data from a communicator that is trying to establish a connection is always an ephemeral public key. This key is used to derive an initial symmetric key which is used to decrypt the following data. Let MSK be the symmetric key decapsulated from the ephemeral public key with the receiving peer's private key.¶
SetupCipher(MSK): PRK_k := HKDF-Extract ("TCP-key", MSK) K := HKDF-Expand (PRK_k, PEERID, 256 / 8) PRK_i := HKDF-Extract ("TCP-ctr", MSK) IV := HKDF-Expand (PRK_i, PEERID, 128 / 8) PRK_h := HKDF-Extract ("TCP-hmac", MSK) H := HKDF-Expand (PRK_i, PEERID, 512 / 8) return K,IV,H¶
The above K and IV are used to decrypt the following 136 bytes of data which are expected to consist of a TCP handshake message as defined in Section 5.1 below.¶
0 8 16 24 32 40 48 56 +-----+-----+-----+-----+-----+-----+-----+-----+ | SENDER PEER ID | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | SIGNATURE | | | | | | | | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | MONOTONIC TIMESTAMP | +-----+-----+-----+-----+-----+-----+-----+-----+ | NONCE | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+
0 8 16 24 32 40 48 56 +-----+-----+-----+-----+-----+-----+-----+-----+ | SIZE | PURPOSE (0x0X) | +-----+-----+-----+-----+-----+-----+-----+-----+ | SENDER PEER ID | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | RECEIVER PEER ID | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | EPHEMERAL PUBLIC KEY | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | MONOTONIC TIMESTAMP | | | | | | | | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | NONCE | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+
If the handshake data is invalid, the connection is dropped. (FIXME define invalid, signature invalid OR sender invalid etc). Otherwise, we send our own TCP handshake to establish a shared secret for outgoing messages and reply with a TCP handshake acknowledgment message. The TCP handshake acknowledgement message is defined in Figure 9 and is encrypted with the¶
0 8 16 24 +-----+-----+-----+-----+-----+-----+-----+-----+ | SIZE | TYPE (0x0X) | +-----+-----+-----+-----+-----+-----+-----+-----+ | SENDER PEER ID | | | | | | | | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | RECEIVER PEER ID | | | | | | | | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | MONOTONIC TIMESTAMP | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | NONCE | | | / / / / | | +-----+-----+-----+-----+-----+-----+-----+-----+
One outgoing and incoming shared secrets are established, actual payload can be exchanged bi-directionally using TCP Box messages. FIXME hmac, MtE discussion, padding-oracle, etc¶
The QUIC [RFC9000] communicator uses TLS-over-QUIC for a baseline layer of metadata protection. Peers use self-signed certificates and corresponding public-private key pairs when establishing a TLS channel. No trust anchors are used to verify the trustworthiness and authenticity of the identities in the TLS certificates. However, QUIC communicators MUST provide a signature using the peer private key over the certificate used in the TLS key exchange.¶
0 8 16 24 32 40 48 56 +-----+-----+-----+-----+-----+-----+-----+-----+ | | | PEER ID | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+ | | | SIGNATURE | | | | | | | | | | | | | +-----+-----+-----+-----+-----+-----+-----+-----+
0 8 16 24 32 40 48 56 +-----+-----+-----+-----+-----+-----+-----+-----+ | SIZE | PURPOSE (0x0TODO)| +-----+-----+-----+-----+-----+-----+-----+-----+ | DER-encoded public key certificate | / / / / +-----+-----+-----+-----+-----+-----+-----+-----+
This document makes no requests for IANA action. This section may be removed on publication as an RFC.¶
FIXME¶
FIXME¶