• Home
Name
Date
Size
#Lines
LOC

..--

plugins/ssp-h1url/12-May-2024-4123

protocols/12-May-2024-1,241775

system/12-May-2024-437277

README.mdD12-May-202413.6 KiB466311

policy.cD12-May-202423.6 KiB988752

private-lib-secure-streams.hD12-May-20249.6 KiB354201

secure-streams-client.cD12-May-202412.4 KiB575373

secure-streams-process.cD12-May-202412.8 KiB534315

secure-streams-serialize.cD12-May-202420.7 KiB927621

secure-streams.cD12-May-202413 KiB595386

README.md

1# Secure Streams
2
3Secure Streams is a client api that strictly separates payload from any metadata.
4That includes the endpoint address for the connection, the tls CA and even the
5protocol used to connect to the endpoint.
6
7The user api just receives and transmits payload, and receives advisory connection
8state information.
9
10The details about how the connections for different types of secure stream should
11be made are held in JSON "policy database" initially passed in to the context
12creation, but able to be updated from a remote copy.
13
14![overview](../doc-assets/ss-explain.png)
15
16## Convention for rx and tx callback return
17
18Function|Return|Meaning
19---|---|---
20tx|0|Send the amount of `buf` stored in `*len`
21tx|>0|Do not send anything
22tx|<0|Finished with stream
23rx|>=0|accepted
24rx|<0|Finished with stream
25
26
27# JSON Policy Database
28
29Example JSON policy... formatting is shown for clarity but whitespace can be
30omitted in the actual policy.
31
32Ordering is not critical in itself, but forward references are not allowed,
33things must be defined before they are allowed to be referenced later in the
34JSON.
35
36
37```
38{
39	"release": "01234567",
40	"product": "myproduct",
41	"schema-version": 1,
42	"retry": [{
43		"default": {
44			"backoff": [1000, 2000, 3000, 5000, 10000],
45			"conceal": 5,
46			"jitterpc": 20
47		}
48	}],
49	"certs": [{
50		"isrg_root_x1": "MIIFazCCA1OgAw...AnX5iItreGCc="
51	}, {
52		"LEX3_isrg_root_x1": "MIIFjTCCA3WgAwIB...WEsikxqEt"
53	}],
54	"trust_stores": [{
55		"le_via_isrg": ["isrg_root_x1", "LEX3_isrg_root_x1"]
56	}],
57	"s": [{
58		"mintest": {
59			"endpoint": "warmcat.com",
60			"port": 4443,
61			"protocol": "h1get",
62			"aux": "index.html",
63			"plugins": [],
64			"tls": true,
65			"opportunistic": true,
66			"retry": "default",
67			"tls_trust_store": "le_via_isrg"
68		}
69	}]
70}
71```
72
73### `Release`
74
75Identifies the policy version
76
77### `Product`
78
79Identifies the product the policy should apply to
80
81### `Schema-version`
82
83The minimum version of the policy parser required to parse this policy
84
85### `via-socks5`
86
87Optional redirect for Secure Streams client traffic through a socks5
88proxy given in the format `address:port`, eg, `127.0.0.1:12345`.
89
90### `retry`
91
92A list of backoff schemes referred to in the policy
93
94### `backoff`
95
96An array of ms delays for each retry in turn
97
98### `conceal`
99
100The number of retries to conceal from higher layers before giving errors.  If
101this is larger than the number of times in the backoff array, then the last time
102is used for the extra delays
103
104### `jitterpc`
105
106Percentage of the delay times mentioned in the backoff array that may be
107randomly added to the figure from the array.  For example with an array entry of
1081000ms, and jitterpc of 20%, actual delays will be chosen randomly from 1000ms
109through 1200ms.  This is to stop retry storms triggered by a single event like
110an outage becoming synchronized into a DoS.
111
112### `certs`
113
114Certificates needed for validation should be listed here each with a name.  The
115format is base64 DER, which is the same as the part of PEM that is inside the
116start and end lines.
117
118### `trust_stores`
119
120Chains of certificates given in the `certs` section may be named and described
121inside the `trust_stores` section.  Each entry in `trust_stores` is created as
122a vhost + tls context with the given name.  Stream types can later be associated
123with one of these to enforce validity checking of the remote server.
124
125Entries should be named using "name" and the stack array defined using "stack"
126
127### `s`
128
129These are an array of policies for the supported stream type names.
130
131### `endpoint`
132
133The DNS address the secure stream should connect to.
134
135This may contain string symbols which will be replaced with the
136corresponding streamtype metadata value at runtime.  Eg, if the
137streamtype lists a metadata name "region", it's then possible to
138define the endpoint as, eg, `${region}.mysite.com`, and before
139attempting the connection setting the stream's metadata item
140"region" to the desired value, eg, "uk".
141
142### `port`
143
144The port number as an integer on the endpoint to connect to
145
146### `protocol`
147
148The wire protocol to connect to the endpoint with.  Currently supported
149streamtypes are
150
151|Wire protocol|Description|
152|---|---|
153|h1|http/1|
154|h2|http/2|
155|ws|http/1 Websockets|
156|mqtt|mqtt 3.1.1|
157
158### `plugins`
159
160Array of plugin names to apply to the stream, if any
161
162### `tls`
163
164Set to `true` to enforce the stream travelling in a tls tunnel
165
166### `client cert`
167
168Set if the stream needs to authenticate itself using a tls client certificate.
169Set to the certificate index counting from 0+.  The certificates are managed
170using lws_sytstem blobs.
171
172### `opportunistic`
173
174Set to `true` if the connection may be left dropped except when in use
175
176### `nailed_up`
177
178Set to `true` to have lws retry if the connection carrying this stream should
179ever drop.
180
181### `retry`
182
183The name of the policy described in the `retry` section to apply to this
184connection for retry + backoff
185
186### `tls_trust_store`
187
188The name of the trust store described in the `trust_stores` section to apply
189to validate the remote server cert.
190
191## http transport
192
193### `http_method`
194
195HTTP method to use with http-related protocols, like GET or POST.
196Not required for ws.
197
198### `http_url`
199
200Url path to use with http-related protocols
201
202The URL path can include metatadata like this
203
204"/mypath?whatever=${metadataname}"
205
206${metadataname} will be replaced by the current value of the
207same metadata name.  The metadata names must be listed in the
208"metadata": [ ] section.
209
210### `http_auth_header`
211
212The name of the header that takes the auth token, with a trailing ':', eg
213
214```
215  "http_auth_header": "authorization:"
216```
217
218### `http_dsn_header`
219
220The name of the header that takes the dsn token, with a trailing ':', eg
221
222```
223  "http_dsn_header": "x-dsn:"
224```
225
226### `http_fwv_header`
227
228The name of the header that takes the firmware version token, with a trailing ':', eg
229
230```
231  "http_fwv_header": "x-fw-version:"
232```
233
234### `http_devtype_header`
235
236The name of the header that takes the device type token, with a trailing ':', eg
237
238```
239  "http_devtype_header": "x-device-type:"
240```
241
242### `http_auth_preamble`
243
244An optional string that precedes the auth token, eg
245
246```
247 "http_auth_preamble": "bearer "
248```
249
250### `auth_hexify`
251
252Convert the auth token to hex ('A' -> "41") before transporting.  Not necessary if the
253auth token is already in printable string format suitable for transport.  Needed if the
254auth token is a chunk of 8-bit binary.
255
256### `nghttp2_quirk_end_stream`
257
258Set this to `true` if the peer server has the quirk it won't send a response until we have
259sent an `END_STREAM`, even though we have sent headers with `END_HEADERS`.
260
261### `h2q_oflow_txcr`
262
263Set this to `true` if the peer server has the quirk it sends an maximum initial tx credit
264of 0x7fffffff and then later increments it illegally.
265
266### `http_multipart_name`
267
268Indicates this stream goes out using multipart mime, and provides the name part of the
269multipart header
270
271### `http_multipart_filename`
272
273Indicates this stream goes out using multipart mime, and provides the filename part of the
274multipart header
275
276### `http_multipart_content_type`
277
278The `content-type` to mark up the multipart mime section with if present
279
280### `http_www_form_urlencoded`
281
282Indicate the data is sent in `x-www-form-urlencoded` form
283
284### `rideshare`
285
286For special cases where one logically separate stream travels with another when using this
287protocol.  Eg, a single multipart mime transaction carries content from two or more streams.
288
289## ws transport
290
291### `ws_subprotocol`
292
293Name of the ws subprotocol to use.
294
295### `ws_binary`
296
297Use if the ws messages are binary
298
299## MQTT transport
300
301### `mqtt_topic`
302
303Set the topic this streamtype uses for writes
304
305### `mqtt_subscribe`
306
307Set the topic this streamtype subscribes to
308
309### `mqtt qos`
310
311Set the QOS level for this streamtype
312
313### `mqtt_keep_alive`
314
31516-bit number representing MQTT keep alive for the stream.
316
317This is applied at connection time... where different streams may bind to the
318same underlying MQTT connection, all the streams should have an identical
319setting for this.
320
321### `mqtt_clean_start`
322
323Set to true if the connection should use MQTT's "clean start" feature.
324
325This is applied at connection time... where different streams may bind to the
326same underlying MQTT connection, all the streams should have an identical
327setting for this.
328
329### `mqtt_will_topic`
330
331Set the topic of the connection's will message, if any (there is none by default).
332
333This is applied at connection time... where different streams may bind to the
334same underlying MQTT connection, all the streams should have an identical
335setting for this.
336
337### `mqtt_will_message`
338
339Set the content of the connect's will message, if any (there is none by default).
340
341This is applied at connection time... where different streams may bind to the
342same underlying MQTT connection, all the streams should have an identical
343setting for this.
344
345### `mqtt_will_qos`
346
347Set the QoS of the will message, if any (there is none by default).
348
349This is applied at connection time... where different streams may bind to the
350same underlying MQTT connection, all the streams should have an identical
351setting for this.
352
353### `mqtt_will_retain`
354
355Set to true if the connection should use MQTT's "will retain" feature, if there
356is a will message (there is none by default).
357
358This is applied at connection time... where different streams may bind to the
359same underlying MQTT connection, all the streams should have an identical
360setting for this.
361
362## Loading and using updated remote policy
363
364If the default, hardcoded policy includes a streamtype `fetch_policy`,
365during startup when lws_system reaches the POLICY state, lws will use
366a Secure Stream of type `fetch_policy` to download, parse and update
367the policy to use it.
368
369The secure-streams-proxy minimal example shows how this is done and
370fetches its real policy from warmcat.com at startup using the built-in
371one.
372
373## Stream serialization and proxying
374
375By default Secure Streams expects to make the outgoing connection described in
376the policy in the same process / thread, this suits the case where all the
377participating clients are in the same statically-linked image.
378
379In this case the `lws_ss_` apis are fulfilled locally by secure-streams.c and
380policy.c for policy lookups.
381
382However it also supports serialization, where the SS api can be streamed over
383another transport such as a Unix Domain Socket connection.  This suits the case
384where the clients are actually in different processes in, eg, Linux or Android.
385
386In those cases, you run a proxy process (minimal-secure-streams-proxy) that
387listens on a Unix Domain Socket and is connected to by one or more other
388processes that pass their SS API activity to the proxy for fulfilment (or
389onward proxying).
390
391In this case the proxy uses secure-streams.c and policy.c as before to fulfil
392the inbound proxy streams, but uses secure-streams-serialize.c to serialize and
393deserialize the proxied SS API activity.  The proxy clients define
394LWS_SS_USE_SSPC either very early in their sources before the includes, or on
395the compiler commandline... this causes the lws_ss_ apis to be replaced at
396preprocessor time with lws_sspc_ equivalents.  These serialize the api action
397and pass it to the proxy over a Unix Domain Socket for fulfilment, the results
398and state changes etc are streamed over the Unix Domain Socket and presented to
399the application exactly the same as if it was being fulfilled locally.
400
401To demonstrate this, some minimal examples, eg, minimal-secure-streams and
402mimimal-secure-streams-avs build themselves both ways, once with direct SS API
403fulfilment and once with Unix Domain Socket proxying and -client appended on the
404executable name.  To test the -client variants, run minimal-secure-streams-proxy
405on the same machine.
406
407## Complicated scenarios with secure streams proxy
408
409As mentioned above, Secure Streams has two modes, by default the application
410directly parses the policy and makes the outgoing connections itself.
411However when configured at cmake with
412
413```
414-DLWS_WITH_SOCKS5=1 -DLWS_WITH_SECURE_STREAMS=1 -DLWS_WITH_SECURE_STREAMS_PROXY_API=1 -DLWS_WITH_MINIMAL_EXAMPLES=1
415```
416
417and define `LWS_SS_USE_SSPC` when building the application, applications forward
418their network requests to a local or remote SS proxy for fulfilment... and only
419the SS proxy has the system policy.  By default, the SS proxy is on the local
420machine and is connected to via a Unix Domain Socket, but tcp links are also
421possible.  (Note the proxied traffic is not encrypyed by default.)
422
423Using the configuration above, the example SS applications are built two ways,
424once for direct connection fulfilment (eg, `./bin/lws-minimal-secure-streams`),
425and once with `LWS_SS_USE_SSPC` also defined so it connects via an SS proxy,
426(eg, `./bin/lws-minimal-secure-streams-client`).
427
428## Testing an example scenario with SS Proxy and socks5 proxy
429
430```
431 [ SS application ] --- tcp --- [ socks 5 proxy ] --- tcp --- [ SS proxy ] --- internet
432```
433
434In this scenario, everything is on localhost, the socks5 proxy listens on :1337 and
435the SS proxy listens on :1234.  The SS application connects to the socks5
436proxy to get to the SS proxy, which then goes out to the internet
437
438### 1 Start the SS proxy
439
440Tell it to listen on lo interface on port 1234
441
442```
443$ ./bin/lws-minimal-secure-streams-proxy -p 1234 -i lo
444```
445
446### 2 Start the SOCKS5 proxy
447
448```
449$ ssh -D 1337 -N -v localhost
450```
451
452The -v makes connections to the proxy visible in the terminal for testing
453
454### 3 Run the SS application
455
456The application is told to make all connections via the socks5 proxy at
457127.0.0.1:1337, and to fulfil its SS connections via an SS proxy, binding
458connections to 127.0.0.1 (ipv4 lo interface, -1), to 127.0.0.1:1234 (-a/-p).
459
460```
461socks_proxy=127.0.0.1:1337 ./bin/lws-minimal-secure-streams-client -p 1234 -i 127.0.0.1 -a 127.0.0.1
462```
463
464You can confirm this goes through the ssh socks5 proxy to get to the SS proxy
465and fulfil the connection.
466