Emacs 24 introduced the possibility to open TLS network connections using the GnuTLS library directly, instead of using a command line tool as a wrapper. This is especially interesting for those who are stuck using Emacs on Windows, as the command line tools can be rather brittle on that platform.

However, there are some steps that need to be performed in order to get native GnuTLS to work. This page attempts to describe them.

Get a GnuTLS-enabled Emacs

The Windows binaries available for download from the GNU site are compiled against GnuTLS, but if you compile your own Emacs, see the file nt/INSTALL in the Emacs source distribution for instructions.

Find the GnuTLS DLLs

The first google hit for "emacs gnutls windows" is this page. It says:

There's one way to find out if GnuTLS is available, by calling gnutls-available-p. This is a little bit trickier on the W32 (Windows) platform, but if you have the GnuTLS DLLs (available from http://sourceforge.net/projects/ezwinports/files/ thanks to Eli Zaretskii) in the same directory as Emacs, you should be OK.

On that page, I found:

gnutls-3.0.9-w32-bin.zip    2012-01-02  7.2 MB

Extract the GnuTLS DLLs

I first naïvely tried opening the zip file in Explorer and copying the files from there, but that does nothing—it neither copies the files nor displays any error message. You need to extract the zip file, and then copy all DLL files to the bin directory where your Emacs is installed, probably somewhere like C:\Program Files (x86)\emacs-24.3\bin.

Restart Emacs and try it

At this point, if you restart Emacs and type:

M-: (gnutls-available-p) RET

you should see t in the echo area, which means that Emacs can find the GnuTLS libraries.

Configure trust files

However, if you try to open a TLS connection, it will fail complaining that certificate validation failed. This happens because GnuTLS needs to have a set of CA certificates to verify the certificates of the servers it connects to. It looks for CA certificates in the locations specified in the variable gnutls-trustfiles, but none of the default values work out of the box on Windows.

I'm not aware of any way to make GnuTLS use any certificates that come with the Windows system, so you need to get a certificate bundle from elsewhere. The cURL project provides such a bundle that you can download. Download the cacert.pem file to a suitable location, and point gnutls-trustfiles to it with customize-option. Note that the file name is passed unexpanded to GnuTLS, so you cannot use ~ as a shorthand for your home directory; use the full absolute file name instead.

See if it works

Paste the following piece of code into the *scratch* buffer:

(condition-case e
    (delete-process
     (gnutls-negotiate
      :process (open-network-stream "test" nil "www.google.com" 443)
      :hostname "www.google.com"
      :verify-error t))
  (error e))

Then put point at the end and hit C-j. If nil gets inserted into the buffer, then the certificate could be verified, and your setup appears to be working.

Otherwise, you'll see an error like:

(error "Certificate validation failed www.google.com, verification code 66")

If so, a good place to start debugging is setting the variable gnutls-log-level to a value greater than 0.

Emacs 24 introduced the possibility to open TLS network connections using the GnuTLS library directly, instead of using a command line tool as a wrapper. This is especially interesting for those who are stuck using Emacs on Windows, as the command line tools can be rather brittle on that platform. However, there are some steps that need to be performed in order to get native GnuTLS to work. This page attempts to describe them.