July 30, 2013

How GPG works: Encrypt

Posted in Software at 22:02 by graham

Here’s what happens when you encrypt a message with GPG / GnuPG (and probably other OpenPGP implementations):

  1. Generate session key

    When you encrypt a file to someone (-r person on the command line), GPG generates a session key, which is a large random number. You can see it when you decrypt a message:

    gpg --show-session-key myfile.gpg
  2. Choose a symmetric cipher

    GPG then looks at the recipients public key to find their preferred symmetric cipher. If you have my key on your ring (get it by doing gpg --recv-keys 0x127CFCD9B3B929D2) you can see my preferred symmetric cipher by typing:

    gpg -r graham -e --verbose test.txt

    It should be AES256.

  3. Encrypt using chosen cipher and generated session key

    Next it compresses then encrypts the file using the session key and the preferred cipher. So until now we’re still all symmetric encryption.

  4. Encrypt session key with public key

    Finally it encrypts that session key using the recipients public key (using RSA), and prepends the result to the front of the message. If there are several recipients, this step is repeated once for each person.

The passphrase GPG asks for when decrypting or signing a message, has nothing to do with message encryption. It is only used to symmetric encrypt your private key (default is CAST5 cipher). That’s in case someone steals your private key file. In terms of how GPG works, you can ignore the passphrase. If you just encrypt a message (without signing it) you won’t need to enter your passphrase at all (but in practice your should always sign your messages).

July 21, 2013

Online upgrades in Go

Posted in Software at 05:40 by graham

tl;dr Send your socket fd over a UNIX domain socket: syscall/passfd_test.go.

When your server holds long running connections (WebSocket, long-running HTTP, IRC, XMPP, etc) you often want to be able to upgrade the server without dropping the connections (zero downtime upgrade). In UNIX there are at least two ways to do this:

  1. Inherit the file descriptor
  2. Send the file descriptor over a domain socket

The first one is straightforward, because a UNIX process automatically inherits the file descriptors of it’s parent, except if they have the close-on-exec flag set. Go complicates things a bit by always setting that flag on it’s sockets (in net/sock_cloexec.go). For a child process to inherit it’s parent’s file descriptors, you have to manually add them to ExtraFiles in os/exec/Cmd. There’s an example in TestExtraFiles in os/exec/exec_test.go.

Usually you need to send more that just the connections to the child process. There will be some state, and probably a communication where the child tells the parents it’s ready to take over (after priming it’s cache, for example). Hence the second approach, unix domain sockets, is more interesting.

Read the rest of this entry »