all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Robert Pluim <rpluim@gmail.com>
To: Vinothan Shankar <darael@dracon.is>
Cc: larsi@gnus.org, 33780@debbugs.gnu.org
Subject: bug#33780: network-stream.el: network-stream-certificate always returns nil
Date: Wed, 19 Dec 2018 18:19:53 +0100	[thread overview]
Message-ID: <m2va3pa0xy.fsf@gmail.com> (raw)
In-Reply-To: <36f7918ec93135504092dc856a4490c846f6e947.camel@dracon.is>

Vinothan Shankar <darael@dracon.is> writes:

> network-stream-certificate will *always* return nil, regardless of
> whether there actually is a client-certificate value-pair specified,
> because (plist-get :client-certificate parameters) is always nil.  This
> is because plist-get takes the plist as the first argument, and the key
> as the second; trying to find a list in a token is always going to be
> nil.
>
> This makes it impossible to use client certificates with Emacs's built-
> in network-stream support, at least without overriding functions.
>
> The error is in net/network-stream.el.  It has been there since the
> function was first written in 2011, according to git blame.

Yes. Lars?

> I surmise that this, in combination with there being no support for
> client certificates in network-stream-tls (though it's available in
> network-stream-starttls) is part of the reason there are so many
> conflicting guides on, for example, using client-certificate SASL with 
> ERC.

Could you apply the following patch, and test something like

(open-network-stream
 "*tls*" (current-buffer) "server.example.com"
 "443"
 :type 'tls
 :warn-unless-encrypted t
 :return-list t
 :client-certificate t)

with the appropriate entries in your .authinfo (replace the servername
and port number as needed)? It works in my limited testing, and
doesnʼt appear to have broken Gnus (but none of my TLS connections
require client certificates).

It could be argued that this should all be transparent, i.e. we should
assume ":client-certificate t" unless itʼs explicitly nil, which would
avoid having to fix all the packages that just call
`open-network-stream', but that we can revisit once things actually
work.

diff --git i/lisp/gnus/nnimap.el w/lisp/gnus/nnimap.el
index 1a3b05ddb3..956c7144cb 100644
--- i/lisp/gnus/nnimap.el
+++ w/lisp/gnus/nnimap.el
@@ -456,6 +456,7 @@ nnimap-open-connection-1
                :always-query-capabilities t
 	       :end-of-command "\r\n"
 	       :success " OK "
+               :client-certificate t
 	       :starttls-function
 	       (lambda (capabilities)
 		 (when (string-match-p "STARTTLS" capabilities)
diff --git i/lisp/gnus/nntp.el w/lisp/gnus/nntp.el
index be9e495510..efb4912a8f 100644
--- i/lisp/gnus/nntp.el
+++ w/lisp/gnus/nntp.el
@@ -1266,6 +1266,7 @@ nntp-open-connection
 		     :end-of-command "^\\([2345]\\|[.]\\).*\n"
 		     :capability-command "HELP\r\n"
 		     :success "^3"
+                     :client-certificate t
 		     :starttls-function
 		     (lambda (capabilities)
 		       (if (not (string-match "STARTTLS" capabilities))
diff --git i/lisp/net/gnutls.el w/lisp/net/gnutls.el
index 315932b7e6..625f11caa5 100644
--- i/lisp/net/gnutls.el
+++ w/lisp/net/gnutls.el
@@ -38,6 +38,9 @@
 (require 'cl-lib)
 (require 'puny)
 
+(declare-function network-stream-certificate "network-stream"
+                  (host service parameters))
+
 (defgroup gnutls nil
   "Emacs interface to the GnuTLS library."
   :version "24.1"
@@ -138,7 +141,7 @@ gnutls-min-prime-bits
                  (integer :tag "Number of bits" 512))
   :group 'gnutls)
 
-(defun open-gnutls-stream (name buffer host service &optional nowait)
+(defun open-gnutls-stream (name buffer host service &optional parameters)
   "Open a SSL/TLS connection for a service to a host.
 Returns a subprocess-object to represent the connection.
 Input and output work as for subprocesses; `delete-process' closes it.
@@ -152,9 +155,14 @@ open-gnutls-stream
 Third arg is name of the host to connect to, or its IP address.
 Fourth arg SERVICE is name of the service desired, or an integer
 specifying a port number to connect to.
-Fifth arg NOWAIT (which is optional) means that the socket should
-be opened asynchronously.  The connection process will be
-returned to the caller before TLS negotiation has happened.
+Fifth arg PARAMETERS is a property list.  It is currently checked for:
+
+    :nowait which means that the socket should be opened
+    asynchronously.  The connection process will be returned to
+    the caller before TLS negotiation has happened.
+
+    :client-certificate which allows the specification of
+    client certificates and keys to use to set up the connection.
 
 Usage example:
 
@@ -168,19 +176,22 @@ open-gnutls-stream
 documentation for the specific parameters you can use to open a
 GnuTLS connection, including specifying the credential type,
 trust and key files, and priority string."
-  (let ((process (open-network-stream
-                  name buffer host service
-                  :nowait nowait
-                  :tls-parameters
-                  (and nowait
-                       (cons 'gnutls-x509pki
-                             (gnutls-boot-parameters
-                              :type 'gnutls-x509pki
-                              :hostname (puny-encode-domain host)))))))
+  (let* ((cert (network-stream-certificate host service parameters))
+         (nowait (plist-get parameters :nowait))
+         (process (open-network-stream
+                   name buffer host service
+                   :nowait nowait
+                   :tls-parameters
+                   (and nowait
+                        (cons 'gnutls-x509pki
+                              (gnutls-boot-parameters
+                               :type 'gnutls-x509pki
+                               :hostname (puny-encode-domain host)))))))
     (if nowait
         process
       (gnutls-negotiate :process process
                         :type 'gnutls-x509pki
+                        :keylist (and cert (list cert))
                         :hostname (puny-encode-domain host)))))
 
 (define-error 'gnutls-error "GnuTLS error")
diff --git i/lisp/net/network-stream.el w/lisp/net/network-stream.el
index a0589e25a4..8b813eef2c 100644
--- i/lisp/net/network-stream.el
+++ w/lisp/net/network-stream.el
@@ -196,7 +196,7 @@ open-network-stream
 	  (car result))))))
 
 (defun network-stream-certificate (host service parameters)
-  (let ((spec (plist-get :client-certificate parameters)))
+  (let ((spec (plist-get parameters :client-certificate)))
     (cond
      ((listp spec)
       ;; Either nil or a list with a key/certificate pair.
@@ -389,7 +389,7 @@ network-stream-open-tls
 	   (stream
             (if (gnutls-available-p)
                 (open-gnutls-stream name buffer host service
-                                    (plist-get parameters :nowait))
+                                    parameters)
               (require 'tls)
               (open-tls-stream name buffer host service)))
 	   (eoc (plist-get parameters :end-of-command)))





  reply	other threads:[~2018-12-19 17:19 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-17 19:02 bug#33780: network-stream.el: network-stream-certificate always returns nil Vinothan Shankar
2018-12-19 17:19 ` Robert Pluim [this message]
2018-12-20 11:24   ` Vinothan Shankar
2018-12-20 18:45     ` Robert Pluim
2018-12-21 13:16       ` Robert Pluim
2019-01-09 10:48         ` Robert Pluim
2019-01-12 11:13           ` Eli Zaretskii
2019-01-14 13:27             ` Robert Pluim
2019-01-14 16:00               ` Eli Zaretskii
2019-01-14 16:25                 ` Robert Pluim
2019-01-14 16:45                   ` Eli Zaretskii
2019-01-14 17:40                     ` Robert Pluim
2019-01-14 18:51                       ` Eli Zaretskii
2019-01-15 20:31                         ` Robert Pluim
2019-01-24 10:40                           ` Robert Pluim

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m2va3pa0xy.fsf@gmail.com \
    --to=rpluim@gmail.com \
    --cc=33780@debbugs.gnu.org \
    --cc=darael@dracon.is \
    --cc=larsi@gnus.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.