2018-01-10 Encrypted Gopher

Sure, we could do Gophers like HTTPS. Or... we could create a new item type.

How about e for encrypted? Like the w for write type, it depends on the client sending more information.

For example:

$ echo "Alex/menu" | cat - ~/.gnupg/key.asc | nc alexschroeder.ch 70
-----BEGIN PGP MESSAGE-----

hQQMAxHFg2RFKaRcAR//WbDO20XJPSTAyzTMGK26+krowPXYuWY0k0qfhedyMESK
cx+w37SzFPkJJVVQO021GHLMORT3ABG41QPY8SwEhkVG9uWTm70+zh4GJA56OjBA
huA97yRdlRuUQzSs3MsZyr3i5zRzecKUI99oqZLAMrx4sWiicD/ndUNIPHljUlZ6
tP0Kaw8SNMpbV6PEkJnNqNn0cEvcRwP+ZOq8wu0aSLLyJHbmGF1ceq7fsTfWCh7N
1kzTK8DJVFVKeHM7+X48eKu6GJXNH/vgpaiO33ivUhFTQ35uxzuU5KXZDvoHYEgM
8vDX5NNTV8gPeyALR27SVj2gl2RT8az7TRrC1gdv91ZnjRqdoIilikNnrRl5JDx9
1o5N7nE2vJwiZ4yL5kIdFuu/SmikRsj0Ec6OkE9QiQgENfbs4B00TLA6sWHAnfgY
STmxBd8VWCndiE794oD+ieBW5vIWuTKRteniRRQh38r+JWSTJttD6cQh7vdarGfj
NEwaIwpbCqAA1xhqAujJh5/VTGQW4fegshhRmwCszpyOy4dn0haSAe8t6zYn15Y2
Ot2Ppi73D2Jc2R9sLrb6e3Hvfj/dZliUp3l6DDA9Gv8jK4ACUQt6kJSx1vKmO4Oz
O7+hKQGq+DCV99QCq9lFls6YJU6aMmelgz+COTqoUSZAe4by+/VQ+ZtaXtXfb6ye
Q+FjTSHT21AInmy0w5rhaFi6Sl+b4r7eHzjPCLW7cEkX0FOv6V/Qx4hBkbix4/m4
RbgkwvWM0PEqfd6ayyNwU++hvpF76FVxMT1Kqz76bsJveO+/XWJy/2NMjlycElvg
nu21qpgISB1ZgTkxqzovZ86APopiS8872B4QvWxBumYGlRDQhZaNbcWTlF8MUpqA
WDx+rXqL3O5WCEk45049B0kkjrpTarSHtXUEIDdHIXhse6IiDdCnHpv+lfft+Sqq
bMUX2QBI2E24u1y330uwnbkOMuLTDi4xZOJUpmrSyFTzhwZ77e2pq2fwSIxOs779
R9T4zljS2Vt8LBdIr9IfcABKkEB/Yg4MnXZyhxbXPHOougQ3CEoygPrPrTx9sUc7
r+Z5pQv3QUduzzmLNiAzhCRIHG9mqXquaYsOejMwhmg3UvqzPrAVkzBMwu5ZqSEh
/5NOqCXOnYctbjuu3nSkeDvS9tX92/ijpDjztvl6fbYRLNcSinpYm+QJp+ubCOkU
SzCFZ7JKNHsD4CxE5kwzokP8801zpYjltzBGl6qG1DHt3uXfgdnvkE5cicIyE327
jfzdcAMEq9DYuT8dw61pUcEXWGYrl72Jmj86LQXBC5m8dlDn9LitU+hcOG0P4Ln5
v6mYiXExu1UFReVILqrj4XDeVLw6IjD/ifPzt5whqtJYAQkdixhbSzwRbHmSyzTF
MgLiUZgh87w9KtVgJ31Ig+BqzuAQHtb7RY/xLvZFPBftikxY8vi1eAwLQ6TVE+59
3RI2hjTQtb/21I2pNRGxx/ffIgnlB+VX/g==
=xfw+
-----END PGP MESSAGE-----

So... we wouldn’t keep the requests a secret, but we’d keep the data sent back a secret, encrypted for the individual making the request. And the server itself can have a public key. The response is both encrypted and signed, and possibly includes the public key, and so we “know” the identity of the server.

As the client, we need the following:

  1. we need access to gpg
  2. we need to import the public signature of the server when we get our first reponse
  3. we need to warn the user when the public key of the server changed between requests

Keeping our requests secret would require the server to not hang up, or it would require us to send the selector as part of the encrypted package. Doable, I guess? This needs more thought.

As I now have a Gopher server (for this wiki) and a Gopher client (for Emacs) to hack, I should make some experiments.

I guess here is how it would work:

We need to get the public key of the server, for example using this:

$ echo Site_GPG_Key \
  | nc alexschroeder.ch 70 \
  | gpg --import

Then we need a message containing our own public key and our request, encrypted for the server.

$ (gpg --export --armor DF9446EB7B7846387CCC018BC78CA29BACECFEAE; \
   echo Alex | gpg --encrypt --armor --recipient alexschroeder.ch; ) \
   > message.txt

The message now contains a PGP PUBLIC KEY BLOCK and a PGP MESSAGE.

This is what we send to the server, using a special selector to indicate That we have an encrypted payload.

$ echo do/gpg | cat - message.txt | nc alexschroeder.ch 70

On the server side, we need to import the key of the person making the request:

$ gpg --import < message.txt
gpg: key ACECFEAE: public key "Alex Schroeder <kensanata@keybase.io>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

We need to remember this key for later!

So how about extracting this from the message:

$ gpg --import < message.txt 2>&1 \
  | sed -n 's/.*key \([^:]*\).*/\1/p'
ACECFEAE
$ sed -n "/-----BEGIN PGP MESSAGE-----/,/-----END PGP MESSAGE-----/p" \
  < message.txt \
  | gpg --decrypt --passphrase-file passphrase.txt --output request.txt
Reading passphrase from file descriptor 3    

You need a passphrase to unlock the secret key for
user: "alexschroeder.ch"
2048-bit RSA key, ID B4E46A78, created 2018-01-12 (main key ID AC23889A)

gpg: encrypted with 2048-bit RSA key, ID B4E46A78, created 2018-01-12
      "alexschroeder.ch"

And now we have our request on the server side here:

$ cat request.txt
Alex

And for the reply:

$ gpg --encrypt --armor --sign --recipient ACECFEAE \
  --passphrase-file passphrase.txt --trust-model always \
  < haiku.txt
Reading passphrase from file descriptor 3

You need a passphrase to unlock the secret key for
user: "alexschroeder.ch"
2048-bit RSA key, ID AC23889A, created 2018-01-12

-----BEGIN PGP MESSAGE-----
Version: GnuPG v1

hQQMAxHFg2RFKaRcAR//exdg5fKlKWnbqO9yFnOUG+GZTRqVHWOesybP4AoDXzs1
jvisAaDpDhzbW8DXWXLQUFblckqtCFZyVMWO0VFNIV5cOBnIKn5/U6lJeeyXZ9hn
Z1Rbcr60bz2yN6nf3G/c7A10Rlg+FumMSzS8GhpodeYTJILl0oiGDAbxE//VLAVT
voc1rIKA6vIX2rwL8IOsiKt1TL/HusjPqB+hXhAjT03p++LgLM9dgY6nRYoCZ7O6
JWZqu9UI+vAIqKylZKg+1Q5CpqinufRDW9h3jQNdDtAzTggS8aJJGa+d9v98cAjH
HqSP2aUmO3uh5YYalXETJ1x0YBZphIuf/426/4dj6qWlhIduKwTRsXr1akZEGAYF
kN+uRio+Y7vWbv/xmrg+Cw2iripCEKcDhpQESt63Us+MHOepSgkICJN7sLwPwR1Q
h7jHFg6wzj3m9kbAB79CWuzxdvWecCGFwsedJgv3e2OZ4EVTGTttNrs+lwyKRNrw
ebBEH7qlK96D2f0+Z8Hp7GWZe6s1Zd14u17ulyokv9LkiEhk4uccoa0GsG9mmdZ2
WWTkF+IKXn/5nrK4FLUE0Rkl2Uf0u4GiKG08bIMuBLYQT5kRqmL9p8l0xwEnwaud
2o4eLOvFDXYeSN8TydQwcsEqrT+uInLOsLQxa6o6u/hHnvRmY/0wSaye1qigjo5R
yn5dTsZN65NXEKQOcFO3Zwf72YG5YLfad49BU17mWEYwwEInVRGg4meTurxkkgES
VW2dy7Fs8y9lJf1vFweWy4QoTRKcF6jByJWerUm6Tx2UoLEyv4YHChQOJbKm0wDa
GND4M8WxGApX6/K69PCS4YJQSH8znT2R0v0H7/nrnftx/YukkqXGqcrqKs1VUaTf
OZZvTNcB/E3+N+Q5m4fQX8EhH89f0MGLro6zM8z+DldJRrjBD0JuVbn6r55F11kC
rIQuup9S1BjnfGRqmNSmKRoqEAjKhTKk/BeBazHq0wnVmjXYs5haAbk6mn4lmR7x
BW1ffSzr+LuybgH4CSmFBdbPgGaOG/eO5x9pDzuW0Es6jbhUy4oNusoJqdJ+2gfq
tzM/Sr6+/dgysWgjNmzlMALdtxQ+IgKv0mn4S+zOAE2RBa+76IM1F1CNWdxIP98U
GnQjN4LhXI2jrc1KEeqo74uJQzVQhtlJRL3Ik9o5sZmyWFlpJRQ81/L1IE9puIc6
vFoTLy5mvu58eboIoIViFkPBwE6EThz7iPyaMt9ZvTvmIfce1bEeWGVYJlOIfc2f
WnihRB11O+BpDrr+ReZXG9xNYNmlV8DLvEAdVsWJLiq23Gs2PUzZFFz1JR+YziEk
Ti8OwHalvthRzMvxu+0J6L0/wNsbmuhhU7ogF2MJiNLA2QH9nRF44J8g5pAQqNSG
1uhEeLAYbzauSGU7CWwk38m8Y6m8jR5mjX/VT3LAoklgN6HRLzhVCxwcxO2BLM/1
BsowldsQvKlh9MMqY5tCMKdXqG4PgQTU+HwZuZ0qKqm4Xg42Nr60BS+xhjCOyp35
DvJUBI9JEjR0zqzmtgI8LKVG1UvNAAIClQBDhFgAW9wVrTuTQ3m7FEay9FeXBA1u
xpPSnuoPlYSiS04cTXlO5JNAsnrmubv+Qw21U+g/FMH/GFgKg5WAxyFdzrAKeWxN
KkfniJmy4gDj/AqlhdhWq3iSnR07gloQHBTySkakSs0UiiP+nqTTeOviBuCnKlRa
kHy6AE8dKjHR1YrcSKS2g0IBx6mGsBwC/Z0bJETGpx+8XkyNN4C0hNvVh0NjEqyN
QGNvg1+CnpdZueuYucOm3WMRHWpRh0UPh5rgHAoXjPMWbvmKHyZyE+zp03Y4FA1o
oJi4JoveScC0majYSx1EaYCZGDhhEThl/fcM5As66DZSBWMLYa/hV1+xxZR1GGic
4pzW1UnJV7d6zl0=
=pJzD
-----END PGP MESSAGE-----

This message gets sent back over the wire and I can decrypt it.

$ gpg --decrypt < response.txt
gpg: verschl"usselt mit 8192-Bit RSA Schl"ussel, ID 11C583644529A45C, erzeugt 2015-03-01
      "Alex Schroeder <kensanata@keybase.io>"

    old pond
    frog leaps in
    water's sound 
gpg: Signatur vom Fri Jan 12 15:54:53 2018 CET
gpg:                mittels RSA-Schl"ussel 9F8EE9F5AC23889A
gpg: Korrekte Signatur von "alexschroeder.ch" [unbekannt]
gpg: WARNUNG: Ein Schl"ussel ohne gesichertes Vertrauen wird benutzt!

I guess we want to delete the key on the server after sending the reply, right? The sad part is that ideally, the client would generate a new key every now and then, and these would be throwaway keys, of course. We don’t actually want to help prove which requests we sent to the server.

It might work.

It might be too much work.

Tags:

Comments

Maybe we should use TLS after all. I just noticed that there is a Perl 5 library called Protocol::TLS::Server. Then again, since I’m using Net::Server, I should probably take a closer look at Net::Server::HTTP which has support for SSL.

– Alex Schroeder 2018-01-15 08:34 UTC


Please make sure you contribute only your own work, or work licensed under the GNU Free Documentation License. See Info for text formatting rules. You can edit the comment page if you need to fix typos. You can subscribe to new comments by email without leaving a comment.

To save this page you must answer this question:

Please say HELLO.