You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: rfcs/2025-03-16-smp-queues.md
+27-24
Original file line number
Diff line number
Diff line change
@@ -62,29 +62,21 @@ data QueueIdsKeys = QIK
62
62
63
63
ProposedNEW command replaces SenderCanSecure with QueueMode, adds link data, and combines NKEY command:
64
64
65
-
The problem: at a point of preparing immutable data we donot yet have sender_id for the primary queue (the only queue at the moment), and we cannot simply use ID returned from the server inLINK response, as it would not mitigate server changing it.Which was the original reason to supply sender_id.So it seems that the only option is to either accept that the sender_id existence can be checked (by creating the queue with passed ID) or that the link data will be passed in a separate command, requiring additional roundtrip.
66
-
67
-
For contact addresses we could user-generate sender_id, but for 1-time invitations it is a bad trade-off - sending the additional command is better.It also simplifies the protocol, as adding link data at the point of creating the queue does not need to be supported.
68
-
69
-
Is server changing the IDin the response a risk?Does the queue recipient even need to know sender_id?Potentially the server could return sender_id inLINK response, and the queue recipient would include some placeholder in the address that the queue sender would replace with ID from LINK response.This would avoid both the extra roundtrip to save queue dataand the possibility of checking for queue existense (by creating the queue using sender-defined ID).
70
-
71
-
So, possibly, for contact addresses user will provide both sender_id and link_id, as it's possible to check address existense anyway, without creating the queue, and for 1-time invitations it may be ok to use placeholder ID for primary queue in the address.It may be "cleaner" from protocol design point of view to have the extra roundtrip though.
72
-
73
65
```haskell
74
66
NEW::NewQueueRequest->CommandRecipient
75
67
76
-
dataNewQueueRequest=NewQueueRequest
68
+
dataNewQueueReq=NewQueueReq
77
69
{rcvAuthKey::RcvPublicAuthKey,
78
70
rcvDhKey::RcvPublicDhKey,
79
-
basicAuth::MaybeBasicAuth,
71
+
auth_::MaybeBasicAuth,
80
72
subMode::SubscriptionMode,
81
-
ntfRequest::MaybeNtfRequest,
82
-
queueLink::MaybeQueueLink-- it is Maybe to allow testing and staged roll-out
73
+
queueData::MaybeQueueModeData,
74
+
ntfCreds::MaybeNewNtfCreds
83
75
}
84
76
85
77
-- To allow updating the existing contact addresses without changing them.
86
-
-- This command would fail on queues that support sndSecure and also on new queues created with QLMessaging.
87
-
-- RecipientId is entity ID.
78
+
-- This command would fail on queues that support sndSecure and also on new queues created with QDMessaging.
-- Further changes would move NotifierId generation to the client, and including a signed and encrypted command to be forwarded by SMP server to notification server.
--QLMessaging implies that sender can secure the queue.
97
-
-- LinkId is not used with QLMessaging, to prevent the possibility of checking when connection is established by re-using the same link ID when creating another queue – the creating would have to fail if it is used.
98
-
-- LinkId is required with QLContact, to have shorter link - it will be derived from the link_uri. And in this case we do not need to prevent checks that this queue exists.
--QDMessaging implies that sender can secure the queue.
89
+
-- LinkId is not used with QDMessaging, to prevent the possibility of checking when connection is established by re-using the same link ID when creating another queue – the creating would have to fail if it is used.
90
+
-- LinkId is required with QDContact, to have shorter link - it will be derived from the link_uri. And in this case we do not need to prevent checks that this queue exists.
-- Sender's key provided on the first request prevents observers from undetectably accessing 1-time link data.
145
-
-- If queue mode is QLContact (and queue does NOT allow sndSecure) the command will fail, same as SKEY.
139
+
-- If queue mode is QDContact (and queue does NOT allow sndSecure) the command will fail, same as SKEY.
146
140
-- Once queue is secured, the key must be the same in subsequent requests - to allow retries in case of network failures, and to prevent passive attacks.
147
141
-- The difference with securing queues is that queues allow sending unsecured messages to queues that allow sndSecure (for backwards compatibility), and 1-time links will NOT allow retrieving link data without securing the queue at the same time, preventing undetected access by observers.
148
142
-- Entity ID is LinkId here
149
143
LKEY::SndPublicAuthKey->CommandSender
150
144
151
-
-- If queue mode is QLMessaging the command will fail.
145
+
-- If queue mode is QDMessaging the command will fail.
152
146
-- Entity ID is LinkId here
153
147
LGET::CommandSender
154
148
@@ -157,6 +151,15 @@ LGET :: Command Sender
157
151
LINK::SenderId->QueueLinkData->BrokerMsg
158
152
```
159
153
154
+
To both include sender_id into the full link before the server response, and to prevent "oracle attack" when a failure to create the queue with the supplied `sender_id` can be used as a proof of queue existense, it is proposed that `sender_id` is computed client-side as `sha3-256(correlation_id)` and validated server-side, where `corelation_id` is the transmission correlation ID.
155
+
156
+
To allow retries and to avoid regenerating all queue data, NEW command must be idempotent, and `correlation_id` must be preserved in command for queue creation, so that the same `correlation_id` and all other data is used in retries. `correlation_id` should be removed after queue creation success.
157
+
158
+
Alternative solutions considered and rejected:
159
+
- additional request to save queue data, after `sender_id` is returned by the server.
160
+
- include empty sender_id in the immutable data and have it replaced by the accepting party with `sender_id` received in `LINK` response - both a weird design, and might create possibility for some attacks via server, especially for contact addresses.
161
+
- use random `correlation_id` and new `sender_id` in retries. While it would remove the need for `NEW` command to be idempotent, it would increase the cost of retries and would require regenerating the whole immutable data of the queue on each retry.
162
+
160
163
## Algorithm to prepare and to interpret queue link data.
161
164
162
165
For contact addresses this approach follows the design proposed in [Short links](./2024-06-21-short-links.md) RFC - when link id is derived from the same random binary as key. For 1-time invitations link ID is independent and server-generated, to prevent existense checks.
While using content hash as encryption key is unconventional, it is not completely unheard of - e.g., it is used in convergent encryption (although in our case using random nonce makes it not convergent, but it means that it preserves encryption security). It is particularly acceptable for our use case, as `immutable_data` contains mostly random keys.
214
+
While using content hash as encryption key is unconventional, it is not completely unheard of - e.g., it is used in convergent encryption (although in our case using random nonce makes it not convergent, but other use cases suggest that this approach preserves encryption security). It is particularly acceptable for our use case, as `immutable_data` contains mostly random keys.
0 commit comments