gopher-tls.txt - gopher-tutorials - The gopher tutorials project. | |
git clone git://bitreich.org/gopher-tutorials/ git://enlrupgkhuxnvlhsf6lc3fziv5… | |
Log | |
Files | |
Refs | |
Tags | |
--- | |
gopher-tls.txt (3182B) | |
--- | |
1 Adding TLS to Gopher | |
2 ==================== | |
3 The changes are minimal, do not break compatibility, and the support | |
4 for clients like hurl, curl or servers like geomyidae is already there. | |
5 | |
6 Context and challenge | |
7 --------------------- | |
8 Traditionnal clients use port 70 without encryption, for which we want | |
9 compatibility. | |
10 | |
11 The gophermap syntax, with gopher links, write down only one port | |
12 (usually 70), so bringing Gopher+TLS on a different port would require | |
13 changing the gophermap standard for everyone, and breaking compatibility, | |
14 and also asking everyone to change their content. | |
15 | |
16 The best compromise would be using port 70 for both plaintext and | |
17 encrypted gopher to preserve gophermaps, with no change for the plaintext | |
18 version to keep compatibility. | |
19 | |
20 It happen to be possible and not difficult to implement using only | |
21 standard (POSIX.1) features. | |
22 | |
23 If the client use raw TCP, the server communicate in raw TCP. | |
24 | |
25 If the client uses TLS, the server communicates in TLS right away. | |
26 | |
27 Without TLS | |
28 ----------- | |
29 [ Client open TCP to Server on port :70 ] | |
30 C: /page\r\n | |
31 S: Hello world! | |
32 | |
33 The client sends usual selector directly over TCP, in which case the | |
34 content is served over plain TCP (non-encrypted). | |
35 | |
36 With TLS | |
37 -------- | |
38 [ Client opens TCP to Server on port :70 ] | |
39 [ Client negotiate TLS with server ] | |
40 C: /page\r\n | |
41 S: Hello world! | |
42 | |
43 The client open TLS on the port 70. The server notices that the | |
44 first byte is 0x16, as always in TLS, and pursue with negotiation. | |
45 | |
46 How to implement | |
47 ---------------- | |
48 The only thing needed for negotiation is reading the first byte and check | |
49 if it is 0x16. | |
50 | |
51 In order to read without messing up the data stream from the client, | |
52 POSIX provides at least two ways to peek at the data without shifting | |
53 the read position, such as pread(2) and recv(2). | |
54 | |
55 Using recv(2): | |
56 | |
57 if (recv(sockfd, buf, 1, MSG_PEEK) < 1) | |
58 err("could not peek at first byte"); | |
59 if (buf[0] == 0x16) | |
60 istls = 1; | |
61 | |
62 > The MSG_PEEK flag causes the receive operation to return data from the | |
63 > beginning of the receive queue without removing that data from the que… | |
64 > Thus, a subsequent receive call will return the same data. -- recv(2) | |
65 | |
66 [7|man page search:|/man.dcgi|perso.pw|70] | |
67 | |
68 Then we can pursue with plain TCP or with TLS right away without | |
69 negtciating anything nor breaking existing clients that only handle TCP. | |
70 Graceful fallback does not change anything for the client. | |
71 | |
72 Known implementations | |
73 --------------------- | |
74 Here are not listed generic tools that can add a layer of TLS encryption | |
75 which can also work for Gopher. | |
76 | |
77 ### Geomyidae (server) | |
78 | |
79 [1|project home page|/scm/geomyidae/files.gph|bitreich.org|70] | |
80 [1|commit 07240d76|/scm/geomyidae/commit/07240d76fd8e1d0a67c49bf7e123bb5… | |
81 | |
82 ### Hurl (client) | |
83 | |
84 Use gophers:// to explicitely use gopher on top of TLS. | |
85 | |
86 [1|project home page|/git/hurl/files.gph|git.codemadness.org|70] | |
87 [1|commit 9546c0f1|/git/hurl/commit/9546c0f17665658befbc25876245acaa9db4… | |
88 | |
89 ### Curl (client) | |
90 | |
91 Use gophers:// to explicitely use gopher on top of TLS. | |
92 | |
93 [h|project home page|URL:https://curl.haxx.se/||] | |
94 [h|commit a1f06f32|URL:https://github.com/curl/curl/commit/a1f06f32b8603… |