7

After reading this post I decided to harder the security of Emacs. However, after setting everything and doing the test, Emacs is still ill-configured. Everything is done in a GNU/Linux distribution.

Installing certifi

As said the in the blog post above, we install certifi

pip3 install -U --user certifi

I check that the module have been installed correctly

python3 -m certifi

Which it was!

/home/jorge/.local/lib/python3.5/site-packages/certifi/cacert.pem

Configuring Emacs

I little modified version of the elisp snippet from the blog post above.

(let ((trustfile
       (replace-regexp-in-string
        "\\\\" "/"
        (replace-regexp-in-string
         "\n" ""
         (shell-command-to-string "python3 -m certifi")))))
  (setf tls-program
        (list
         (format "gnutls-cli%s --x509cafile %s -p %%p %%h"
                 (if (eq window-system 'w32) ".exe" "") trustfile)))
  (setf tls-checktrust t)
  (setf gnutls-verify-error t)
  (setf gnutls-trustfiles (list trustfile)))

Testing the configuration

Again, another snippet of elisp slightly modified by me.

(let ((bad-hosts
       (loop for bad
             in `("https://wrong.host.badssl.com/"
                  "https://self-signed.badssl.com/")
             if (condition-case e
                    (url-retrieve
                     bad (lambda (retrieved) t))
                  (error nil))
             collect bad)))
  (if bad-hosts
      (print (format "tls misconfigured; retrieved %s ok"
                     bad-hosts))
    (url-retrieve "https://badssl.com"
                  (lambda (retrieved) t))))

After running that snippet, I get this output:

"tls misconfigured; retrieved (https://self-signed.badssl.com/) ok"

What am I doing wrong?


Edit

Setting gnutls-log-level to 2 output this:

Evaluate this emacs-lisp code block on your system? (y or n) y
executing Emacs-Lisp code block...
Contacting host: wrong.host.badssl.com:443
gnutls.c: [1] (Emacs) allocating credentials
gnutls.c: [2] (Emacs) allocating x509 credentials
gnutls.c: [2] (Emacs) using default verification flags
gnutls.c: [1] (Emacs) setting the trustfile:  /home/jorge/.local/lib/python3.5/site-packages/certifi/cacert.pem
gnutls.c: [1] (Emacs) gnutls callbacks
gnutls.c: [1] (Emacs) gnutls_init
gnutls.c: [1] (Emacs) got non-default priority string: NORMAL
gnutls.c: [1] (Emacs) setting the priority string
gnutls.c: [audit] Note that the security level of the Diffie-Hellman key exchange has been lowered to 256 bits and this may allow decryption of the session data

gnutls.c: [1] (Emacs) non-fatal error: Resource temporarily unavailable, try again. [4822 times]
Contacting host: self-signed.badssl.com:443
gnutls.c: [1] (Emacs) allocating credentials
gnutls.c: [2] (Emacs) allocating x509 credentials
gnutls.c: [2] (Emacs) using default verification flags
gnutls.c: [1] (Emacs) setting the trustfile:  /home/jorge/.local/lib/python3.5/site-packages/certifi/cacert.pem
gnutls.c: [1] (Emacs) gnutls callbacks
gnutls.c: [1] (Emacs) gnutls_init
gnutls.c: [1] (Emacs) got non-default priority string: NORMAL
gnutls.c: [1] (Emacs) setting the priority string
gnutls.c: [audit] Note that the security level of the Diffie-Hellman key exchange has been lowered to 256 bits and this may allow decryption of the session data

gnutls.c: [1] (Emacs) non-fatal error: Resource temporarily unavailable, try again. [3737 times]
Code block evaluation complete.

EDIT 2

I decided to try fetching another website, a website which such SSL certificate bothers Firefox/Iceweasel:

(url-retrieve "https://parabola.nu/" (lambda (retrieved) t))

Then, I got this sweet error:

Debugger entered--Lisp error: (error "Certificate validation failed parabola.nu, verification code 66")
gnutls-boot(#<process parabola.nu> gnutls-x509pki (:priority "NORMAL" :hostname "parabola.nu" :loglevel 0 :min-prime-bits 256 :trustfiles ("/home/jorge/.local/lib/python3.5/site-packages/certifi/cacert.pem") :crlfiles nil :keylist nil :verify-flags nil :verify-error t :callbacks nil))
gnutls-negotiate(:process #<process parabola.nu> :type gnutls-x509pki :hostname "parabola.nu")
open-gnutls-stream("parabola.nu" #<buffer  *url-http-temp*> "parabola.nu" 443)
network-stream-open-tls("parabola.nu" #<buffer  *url-http-temp*> "parabola.nu" 443 (:type tls :nowait t))
open-network-stream("parabola.nu" #<buffer  *url-http-temp*> "parabola.nu" 443 :type tls :nowait t)
byte-code("\306\211\n\307>\203$\n\310=\203\311\312\f
\313\n\314\315\316\317\"&\202Y\n\320=\2034\321\f
$\202Y\n\322=\203D\323\f
$\202Y\n\324=\203T\325\f
$\202Y\326\327\"*\306\207" [coding-system-for-write coding-system-for-read gw-method name buffer host binary (tls ssl native) native plain open-network-stream :type :nowait featurep make-network-process (:nowait t) socks socks-open-network-stream telnet url-open-telnet rlogin url-open-rlogin error "Bad setting of url-gateway-method: %s" service url-gateway-method conn] 11)
url-open-stream("parabola.nu" #<buffer  *url-http-temp*> "parabola.nu" 443)
url-http-find-free-connection("parabola.nu" 443)
url-http([cl-struct-url "https" nil nil "parabola.nu" nil "/" nil nil t nil t] (lambda (retrieved) t) (nil))
url-https([cl-struct-url "https" nil nil "parabola.nu" nil "/" nil nil t nil t] (lambda (retrieved) t) (nil))
url-retrieve-internal("https://parabola.nu/" (lambda (retrieved) t) (nil) nil nil)
url-retrieve("https://parabola.nu/" (lambda (retrieved) t))
eval((url-retrieve "https://parabola.nu/" (function (lambda (retrieved) t))) nil)
eval-last-sexp-1(nil)
eval-last-sexp(nil)
call-interactively(eval-last-sexp nil nil)
command-execute(eval-last-sexp)

So, so far I can say the changes made to my Emacs configuration are working.

Kirill
  • 1,019
  • 7
  • 19
shackra
  • 2,702
  • 18
  • 47
  • 1
    It'd help if you did not shadow the original error in your last snippet. Please get rid of the `condition-case`, try the script again, and show the _actual_ error that you receive. Also, please set `gnutls-verify-error` to `nil`. That makes Emacs show a popup with certificate information if verification fails. –  Nov 13 '15 at 22:53
  • 1
    Can you set gnutls-log-level to 2 or higher to see in more detail what gnutls is doing? That may help identify why it accepts a self-signed certificate. – Kirill Nov 13 '15 at 23:05
  • @Kirill I have updated the question with more information – shackra Nov 14 '15 at 03:36
  • One possibility is that the instructions in that blog post are somehow incorrect or incomplete. So (a) why is `tls-program` needed if the `gnutls` functionality will be used? (b) why is `gnutls-trustfiles` being set to something other than the default files with trusted root certificates - I think it should work on linux with the default value? (c) did you accept or reject the certificate yourself for self-signed.badssl.com when prompted by gnutls? – Kirill Nov 16 '15 at 20:03
  • @Kirill A/c: Emacs never asked me what to do for self-signed.badssl.com, thus I never have rejected nor accepted the certificate. – shackra Nov 16 '15 at 21:16
  • 1
    Another thing that bothers me is that `url-retrieve` is *asynchronous*, so its return value will likely be a (empty) buffer (http://www.gnu.org/software/emacs/manual/html_node/url/Retrieving-URLs.html), and the error will not necessarily be caught by the condition-case. Maybe try `url-retrieve-synchronously` instead? – Kirill Nov 16 '15 at 21:35
  • @Kirill Nothing is different, Emacs don't pop up an error message or anything with the same URLs :( – shackra Nov 24 '15 at 05:41
  • 1
    Check [this](https://www.reddit.com/r/emacs/comments/3sjdyi/your_text_editor_is_malware/cxfol83) reddit comment. It states that the problem is the emacs built-in TLS isn't working. Adding those two lines of code worked for me. – Choma Dec 03 '15 at 15:33
  • @Choma please make your reply an answer as it fixed my issue with Emacs and TLS :) – shackra Dec 03 '15 at 20:49

1 Answers1

4

I found this reddit comment, which states that the problem is Emacs built-in TLS doesn't reject bad certificates. It proposes using external TLS like this:

(if (fboundp 'gnutls-available-p)
    (fmakunbound 'gnutls-available-p))

NOTE: if you still have issues trying to connect to marmalde repo, it seems to be a different problem. See this github issue.

Choma
  • 156
  • 1
  • 6
  • 1
    Doing this may trigger [Emacs bug#15905](http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15905) though. – npostavs Dec 04 '15 at 16:22