aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--proposals/340-packed-and-fragmented.md61
-rw-r--r--rend-spec-v3.txt106
-rw-r--r--tor-spec.txt4
3 files changed, 105 insertions, 66 deletions
diff --git a/proposals/340-packed-and-fragmented.md b/proposals/340-packed-and-fragmented.md
index e7f08f4..6fb1ca5 100644
--- a/proposals/340-packed-and-fragmented.md
+++ b/proposals/340-packed-and-fragmented.md
@@ -33,6 +33,9 @@ This proposal combines ideas from
[ntor v3](./332-ntor-v3-with-extra-data.md) and prepares for
[next-generation relay cryptography](./308-counter-galois-onion).
+Additionally, this proposal has been revised to incorporate another
+protocol change, and remove StreamId from the relay cell header.
+
## A preliminary change: Relay encryption, version 1.5
We are fairly sure that, whatever we do for our next batch of relay
@@ -66,12 +69,15 @@ Relay _messages_ now follow the following format:
Header
command u8
length u16
- stream_id u16
Body
data u8[length]
We require that "command" is never 0.
+One big change from the current tor protocol is something that is _not_
+here: we have moved `stream_id` into the body of the relay message of
+those commands that need it.
+
Messages can be split across relay cells; multiple messages can occur in
a single relay cell. We enforce the following rules:
@@ -92,7 +98,7 @@ Receivers MUST validate that headers are well-formed and have valid
lengths while handling the cell in which the header is encoded. If the
header is invalid, the receiver must destroy the circuit.
-### Some examples
+
## Negotiation
@@ -109,6 +115,42 @@ The `version` field is the `Relay` subprotocol version that the client
wants to use. The relay must send back the same extension in its ntor3
handshake to acknowledge support.
+
+## Specifying the message format with moved stream ID.
+
+Here, we'll specify how to adjust tor-spec to describe the `stream_id`
+move correctly.
+
+Below, suppose that `Relay=V` denotes whatever version of the relay
+message subprotocol denotes support for this proposal.
+
+For all relay message types that include a stream ID, we insert
+the following at the beginning of their fields:
+
+>```
+> STREAM_ID [2 bytes] (Present when Relay protocol version >= V).
+>```
+
+We add a note saying:
+
+> STREAM_ID is part of many message types, when using Relay protocol
+> version V or later. Earlier versions of the Relay protocol put
+> STREAM_ID in the RELAY header. In those versions, the field is
+> STREAM_ID omitted from the message.
+>
+> Except when noted, STREAM_ID may not be zero.
+
+The following message types take required stream IDs: `BEGIN`, `DATA`, `END`,
+`CONNECTED`, `RESOLVE`, `RESOLVED`, and `BEGIN_DIR`, `XON`, `XOFF`.
+
+The following message type takes an *optional* stream ID: `SENDME`.
+(*Stream-level sendmes are not a thing anymore with proposal 324, but I
+want to give implementations the freedom to implement prop324 and this
+proposal in either order.*)
+
+The following message types from proposal 339 (UDP) take required stream
+IDs: `CONNECT_UDP`, `CONNECTED_UDP` and `DATAGRAM`.
+
## Migration
We add a consensus parameter, "streamed-relay-messages", with default
@@ -191,8 +233,8 @@ cell. Here it is a BEGIN message.
message header:
command BEGIN [1 byte]
length 23 [2 bytes]
- stream_id (...) [2 bytes]
message body
+ stream_id (...) [2 bytes]
"www.torproject.org:443\0" [23 bytes]
end-of-messages marker
0 [1 byte]
@@ -215,8 +257,8 @@ across two relay cells.
message header:
command EXTEND [1 byte]
length 800 [2 bytes]
- stream_id 0 [2 bytes]
message body
+ stream_id 0 [2 bytes]
(extend body, part 1) [488 bytes]
Cell 2:
@@ -249,14 +291,13 @@ message in the same cell.
message header:
command BEGIN_DIR [1 byte]
length 0 [2 bytes]
- stream_id 32 [2 bytes]
message body:
- (empty) --- [0 bytes]
+ stream_id 32 [2 bytes]
message header:
command DATA [1 byte]
length 25 [2 bytes]
- stream_id 32 [2 bytes]
message body:
+ stream_id 32 [2 bytes]
"HTTP/1.0 GET /tor/foo\r\n\r\n" [25 bytes]
end-of-messages marker
0 [1 byte]
@@ -281,8 +322,8 @@ above; this is only an example of what parties need to accept.)
message header:
command DATAGRAM [1 byte]
length 1200 [2 bytes]
- stream_id 99 [2 bytes]
message body
+ stream_id 99 [2 bytes]
(datagram body, part 1) [488 bytes]
Cell 2:
@@ -307,16 +348,16 @@ above; this is only an example of what parties need to accept.)
message header:
command SENDME [1 byte]
length 23 [2 bytes]
- stream_id 0 [2 bytes]
message body:
+ stream_id 0 [2 bytes]
version 1 [1 byte]
datalen 20 [2 bytes]
data (digest to ack) [20 bytes]
message header:
command XON [1 byte]
length 1 [2 bytes]
- stream_id 50 [2 bytes]
message body:
+ stream_id 50 [2 bytes]
version 1 [1 byte]
end-of-messages marker
0 [1 byte]
diff --git a/rend-spec-v3.txt b/rend-spec-v3.txt
index fb570b4..13eb758 100644
--- a/rend-spec-v3.txt
+++ b/rend-spec-v3.txt
@@ -592,7 +592,7 @@ Table of contents:
the public blinded identity key for a service. This key is used
as an index in the DHT-like structure of the directory system
(see [SUBCRED]).
- KP_blind_id, KS_blind_id.
+ KP_hs_blind_id, KS_hs_blind_id.
Descriptor signing key -- A key used to sign hidden service
descriptors. This is signed by blinded signing keys. Unlike
@@ -603,33 +603,38 @@ Table of contents:
KP_hs_desc_sign, KS_hs_desc_sign.
Introduction point authentication key -- A short-term signing
- keypair used to identify a hidden service to a given
- introduction point. A fresh keypair is made for each
+ keypair used to identify a hidden service's session at a given
+ introduction point. The service makes a fresh keypair for each
introduction point; these are used to sign the request that a
hidden service host makes when establishing an introduction
point, so that clients who know the public component of this key
can get their introduction requests sent to the right
service. No keypair is ever used with more than one introduction
point. (previously called a "service key" in rend-spec.txt)
- KP_hs_intro_tid, KS_hs_intro_tid
- ("hidden service introduction point temporary id").
+ KP_hs_ipt_sid, KS_hs_ipt_sid
+ ("hidden service introduction point session id").
Introduction point encryption key -- A short-term encryption
keypair used when establishing connections via an introduction
- point. Plays a role analogous to Tor nodes' onion keys. A fresh
- keypair is made for each introduction point.
- KP_hs_intro_ntor, KS_hs_intro_ntor.
+ point. Plays a role analogous to Tor nodes' onion keys. The service
+ makes a fresh keypair is made for each introduction point.
+ KP_hss_ntor, KS_hss_ntor.
- Symmetric keys defined in this document:
+ Ephemeral descriptor encryption key -- A short-lived encryption
+ keypair made by the service, and used to encrypt the inner layer
+ of hidden service descriptors when client authentication is in
+ use.
+ KP_hss_desc_enc, KS_hss_desc_enc
- Descriptor encryption keys -- A symmetric encryption key used to
- encrypt the body of hidden service descriptors. Derived from the
- current period and the hidden service credential.
- K_desc_enc.
+ Nonces defined in this document:
+
+ N_hs_desc_enc -- a nonce used to derive keys to decrypt the inner
+ encryption layer of hidden service descriptors. This is
+ sometimes also called a "descriptor cookie".
Public/private keypairs defined elsewhere:
- Onion key -- Short-term encryption keypair (KS_onion_ntor, KP_onion_ntor).
+ Onion key -- Short-term encryption keypair (KS_ntor, KP_ntor).
(Node) identity key (KP_relayid).
@@ -651,7 +656,8 @@ Table of contents:
Specifically, each authorized client possesses:
- An x25519 keypair used to compute decryption keys that allow the client to
- decrypt the hidden service descriptor. See [HS-DESC-ENC].
+ decrypt the hidden service descriptor. See [HS-DESC-ENC]. This is
+ the client's counterpart to KP_hss_desc_enc.
KP_hsc_desc_enc, KS_hsd_desc_enc.
- An ed25519 keypair which allows the client to compute signatures which
@@ -811,7 +817,7 @@ Table of contents:
derived, the uploading or downloading party calculates:
for replicanum in 1...hsdir_n_replicas:
- hs_index(replicanum) = H("store-at-idx" |
+ hs_service_index(replicanum) = H("store-at-idx" |
blinded_public_key |
INT_8(replicanum) |
INT_8(period_length) |
@@ -825,7 +831,7 @@ Table of contents:
Then, for each node listed in the current consensus with the HSDir flag,
we compute a directory index for that node as:
- hsdir_index(node) = H("node-idx" | node_identity |
+ hs_relay_index(node) = H("node-idx" | node_identity |
shared_random_value |
INT_8(period_num) |
INT_8(period_length) )
@@ -836,7 +842,7 @@ Table of contents:
Finally, for replicanum in 1...hsdir_n_replicas, the hidden service
host uploads descriptors to the first hsdir_spread_store nodes whose
- indices immediately follow hs_index(replicanum). If any of those
+ indices immediately follow hs_service_index(replicanum). If any of those
nodes have already been selected for a lower-numbered replica of the
service, any nodes already chosen are disregarded (i.e. skipped over)
when choosing a replica's hsdir_spread_store nodes.
@@ -1187,10 +1193,11 @@ Table of contents:
"encrypted" field.
If client auth is enabled, the hidden service generates a fresh
- descriptor_cookie key (32 random bytes) and encrypts it using each
- authorized client's identity x25519 key. Authorized clients can use the
- descriptor cookie to decrypt the second layer of encryption. Our encryption
- scheme requires the hidden service to also generate an ephemeral x25519
+ descriptor_cookie key (`N_hs_desc_enc`, 32 random bytes) and encrypts
+ it using each authorized client's identity x25519 key. Authorized
+ clients can use the descriptor cookie (`N_hs_desc_enc`) to decrypt
+ the second (inner) layer of encryption. Our encryption scheme
+ requires the hidden service to also generate an ephemeral x25519
keypair for each new descriptor.
If client auth is disabled, fake data is placed in each of the fields below
@@ -1208,13 +1215,13 @@ Table of contents:
If client authorization is disabled, the value here should be "x25519".
- "desc-auth-ephemeral-key" SP key NL
+ "desc-auth-ephemeral-key" SP KP_hs_desc_ephem NL
[Exactly once]
- This field contains an ephemeral x25519 public key generated by the
- hidden service and encoded in base64. The key is used by the encryption
- scheme below.
+ This field contains `KP_hss_desc_enc`, an ephemeral x25519 public
+ key generated by the hidden service and encoded in base64. The key
+ is used by the encryption scheme below.
If client authorization is disabled, the value here should be a fresh
x25519 pubkey that will remain unused.
@@ -1229,23 +1236,16 @@ Table of contents:
data of the right size (that's 8 bytes for 'client-id', 16 bytes for 'iv'
and 16 bytes for 'encrypted-cookie' all encoded with base64).
- When client authorization is enabled, each "auth-client" line contains
- the descriptor cookie encrypted to each individual client. We assume that
- each authorized client possesses a pre-shared x25519 keypair which is
- used to decrypt the descriptor cookie.
-
- We now describe the descriptor cookie encryption scheme. Here are the
- relevant keys:
-
- client_x = private x25519 key of authorized client
- client_X = public x25519 key of authorized client
- hs_y = private key of ephemeral x25519 keypair of hidden service
- hs_Y = public key of ephemeral x25519 keypair of hidden service
- descriptor_cookie = descriptor cookie used to encrypt the descriptor
+ When client authorization is enabled, each "auth-client" line
+ contains the descriptor cookie `N_hs_desc_enc` encrypted to each
+ individual client. We assume that each authorized client possesses
+ a pre-shared x25519 keypair (`KP_hsc_desc_enc`) which is used to
+ decrypt the descriptor cookie.
- And here is what the hidden service computes:
+ We now describe the descriptor cookie encryption scheme. Here is what
+ the hidden service computes:
- SECRET_SEED = x25519(hs_y, client_X)
+ SECRET_SEED = x25519(KS_hs_desc_ephem, KP_hsc_desc_enc)
KEYS = KDF(N_hs_subcred | SECRET_SEED, 40)
CLIENT-ID = fist 8 bytes of KEYS
COOKIE-KEY = last 32 bytes of KEYS
@@ -1258,7 +1258,7 @@ Table of contents:
- The "encrypted-cookie" field contains the descriptor cookie ciphertext
as follows and is encoded in base64:
- encrypted-cookie = STREAM(iv, COOKIE-KEY) XOR descriptor_cookie
+ encrypted-cookie = STREAM(iv, COOKIE-KEY) XOR N_hs_desc_enc.
See section [FIRST-LAYER-CLIENT-BEHAVIOR] for the client-side logic of
how to decrypt the descriptor cookie.
@@ -1348,10 +1348,10 @@ Table of contents:
[Exactly once]
- A space-separated list of integers denoting CREATE2 cell format numbers
- that the server recognizes. Must include at least ntor as described in
- tor-spec.txt. See tor-spec section 5.1 for a list of recognized
- handshake types.
+ A space-separated list of integers denoting CREATE2 cell HTYPEs
+ (handshake types) that the server recognizes. Must include at least
+ ntor as described in tor-spec.txt. See tor-spec section 5.1 for a list
+ of recognized handshake types.
"intro-auth-required" SP types NL
@@ -1360,7 +1360,7 @@ Table of contents:
A space-separated list of introduction-layer authentication types; see
section [INTRO-AUTH] for more info. A client that does not support at
least one of these authentication types will not be able to contact the
- host. Defined types are: 'password' and 'ed25519'.
+ host. Recognized types are: 'ed25519'.
"single-onion-service"
@@ -1419,7 +1419,7 @@ Table of contents:
The certificate is a proposal 220 certificate wrapped in
"-----BEGIN ED25519 CERT-----". It contains the introduction
- point authentication key (`KP_hs_intro_tid`), signed by
+ point authentication key (`KP_hs_ipt_sid`), signed by
the descriptor signing key (`KP_hs_desc_sign`). The
certificate type must be [09], and the signing key extension
is mandatory.
@@ -1438,7 +1438,7 @@ Table of contents:
[Exactly once per introduction point]
The key is a base64 encoded curve25519 public key used to encrypt
- the introduction request to service. (`KP_hs_intro_ntor`)
+ the introduction request to service. (`KP_hss_ntor`)
"enc-key" SP KeyType SP key.. NL
@@ -1458,7 +1458,7 @@ Table of contents:
For "ntor" keys, certificate is a proposal 220 certificate
wrapped in "-----BEGIN ED25519 CERT-----" armor. The subject
key is the the ed25519 equivalent of a curve25519 public
- encryption key (`KP_hs_intro_ntor`), with the ed25519 key
+ encryption key (`KP_hss_ntor`), with the ed25519 key
derived using the process in proposal 228 appendix A. The
signing key is the descriptor signing key (`KP_hs_desc_sign`).
The certificate type must be [0B], and the signing-key
@@ -1468,7 +1468,7 @@ Table of contents:
constructed the other way around. However, for compatibility
with C tor, implementations need to construct it this way. It
serves even less point than "auth-key", however, since the
- encryption key `KP_hs_intro_ntor` is already available from
+ encryption key `KP_hss_ntor` is already available from
the `enc-key` entry.
"legacy-key" NL key NL
@@ -2071,10 +2071,8 @@ Table of contents:
One mechanism to do so is the credential mechanism, where only users who
know the credential for a hidden service may connect at all.
- There are two defined authentication types, `ed25519` and `password`.
+ There is one defined authentication type: `ed25519`.
- However, the `password` authentication type is not documented
- and ??? ??? ???.
3.4.1. Ed25519-based authentication `ed25519`.
diff --git a/tor-spec.txt b/tor-spec.txt
index e522135..69ed12e 100644
--- a/tor-spec.txt
+++ b/tor-spec.txt
@@ -252,7 +252,7 @@ see tor-design.pdf.
longer advertised. Because of this, relays MUST retain old keys for a
while after they're rotated. (See "onion key lifetime parameters" in
dir-spec.txt.)
- KP_onion_ntor, KS_onion_ntor.
+ KP_ntor, KS_ntor.
These are Ed25519 keys:
@@ -1022,7 +1022,7 @@ see tor-design.pdf.
HLEN (Server Handshake Data Len) [2 bytes]
HDATA (Server Handshake Data) [HLEN bytes]
- Recognized handshake types are:
+ Recognized HTYPEs (handshake types) are:
0x0000 TAP -- the original Tor handshake; see 5.1.3
0x0001 reserved