|
13 | 13 | :information_source: _Please carefully read the [Security](#security) section before using `tlspyo` anywhere other than your own secure private network._ |
14 | 14 |
|
15 | 15 |
|
| 16 | +## Quick links |
| 17 | + |
| 18 | +- [Principle](#principle) |
| 19 | +- [Example usage](#example-usage) |
| 20 | +- [Getting started](#getting-started) |
| 21 | + - [Installation](#installation) |
| 22 | + - [TLS setup](#tls-setup) |
| 23 | + - [Producer-consumer example](#a-simple-producer-consumer-example) |
| 24 | +- [Security](#security) |
| 25 | +- [Custom serialization](#custom-serialization) |
| 26 | + |
| 27 | + |
16 | 28 | ## Principle |
17 | 29 |
|
18 | 30 | `tlspyo` provides two classes: `Relay` and `Endpoint`. |
@@ -338,6 +350,73 @@ If they successfully posed as your `Endpoint` they could send malicious pickled |
338 | 350 |
|
339 | 351 | In a nutshell, you want your password to be as strong as possible, and your TLS secret key to be kept... well, secret :lock: |
340 | 352 |
|
| 353 | +## Custom serialization |
| 354 | + |
| 355 | +By default, `tlspyo` uses `pickle` for serialization and relies on TLS to prevent attacks. |
| 356 | + |
| 357 | +In advanced application, you may want to use another serialization protocol instead. |
| 358 | +For instance, you may want to transfer non-picklable objects, or further optimize the security of your application. |
| 359 | + |
| 360 | +**In particular, in `connection="TCP"` mode (i.e., with TLS disabled) over a public network, using your own secure serialization protocol is critical.** |
| 361 | + |
| 362 | +`tlspyo` makes this easy. |
| 363 | +All you need to do is code your own serialization protocol following the `pickle.dumps`/`pickle.loads` signature, and pass it to the `serializer`/`deserializer` arguments of both your `Relay` and `Endpoints`. |
| 364 | + |
| 365 | +For instance: |
| 366 | +```python |
| 367 | +import pickle as pkl |
| 368 | +from tlspyo import Relay, Endpoint |
| 369 | + |
| 370 | +# We define a custom serialization protocol based on pickle for simplicity. |
| 371 | +# Of course, this is only for illustration. |
| 372 | +# You probably do not want to use pickle in practice here. |
| 373 | + |
| 374 | + |
| 375 | +def my_custom_serializer(obj): |
| 376 | + """ |
| 377 | + Takes a python object as input and outputs a bytestring |
| 378 | + """ |
| 379 | + return b"header" + pkl.dumps(["TEST", pkl.dumps(obj)]) |
| 380 | + |
| 381 | + |
| 382 | +def my_custom_deserializer(bytestring): |
| 383 | + """ |
| 384 | + Takes a bytestring as input and outputs a python object |
| 385 | + """ |
| 386 | + assert len(bytestring) > len(b"header") |
| 387 | + assert bytestring[:len(b"header")] == b"header" |
| 388 | + bytestring = bytestring[len(b"header"):] |
| 389 | + tmp = pkl.loads(bytestring) |
| 390 | + assert isinstance(tmp, list) |
| 391 | + assert len(tmp) == 2 |
| 392 | + assert tmp[0] == "TEST" |
| 393 | + obj = pkl.loads(tmp[1]) |
| 394 | + return obj |
| 395 | + |
| 396 | + |
| 397 | +if __name__ == '__main__': |
| 398 | + |
| 399 | + re = Relay( |
| 400 | + port=3000, |
| 401 | + password="VerySecurePassword", |
| 402 | + local_com_port=3001, |
| 403 | + connection="TLS", |
| 404 | + serializer=my_custom_serializer, |
| 405 | + deserializer=my_custom_deserializer |
| 406 | + ) |
| 407 | + |
| 408 | + ep = Endpoint( |
| 409 | + ip_server='127.0.0.1', |
| 410 | + port=3000, |
| 411 | + password="VerySecurePassword", |
| 412 | + groups="group1", |
| 413 | + local_com_port=3002, |
| 414 | + connection="TLS", |
| 415 | + serializer=my_custom_serializer, |
| 416 | + deserializer=my_custom_deserializer |
| 417 | +) |
| 418 | +``` |
| 419 | + |
341 | 420 | ## External links |
342 | 421 |
|
343 | 422 | `tlspyo` is an open-source project hosted at [Polytechnique Montreal - MISTlab](https://mistlab.ca). |
|
0 commit comments