gopher-tls.txt - gopher-tutorials - The gopher tutorials project. HTML git clone git://bitreich.org/gopher-tutorials/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/gopher-tutorials/ DIR Log DIR Files DIR Refs DIR 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 queue. 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/07240d76fd8e1d0a67c49bf7e123bb508613e691.gph|server|port] 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/9546c0f17665658befbc25876245acaa9db4b08f.gph|git.codemadness.org|70] 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/a1f06f32b8603427535fc21183a84ce92a9b96f7||]