summaryrefslogtreecommitdiff
path: root/lisp/net/gnutls.el
diff options
context:
space:
mode:
authorRobert Pluim <rpluim@gmail.com>2019-01-24 11:34:34 +0100
committerRobert Pluim <rpluim@gmail.com>2019-01-24 11:36:47 +0100
commitf3f9a3582ef2081e96d12fb92ac190ffe9c1c431 (patch)
tree1fe5526cbf926877ebca4dec14aa36e80a790e38 /lisp/net/gnutls.el
parent0744c35307d544d960c9d7628ea91ad722ff6217 (diff)
downloademacs-f3f9a3582ef2081e96d12fb92ac190ffe9c1c431.tar.gz
Check for client certificates when using GnuTLS
This fixes Bug#33780, and extends the documentation to describe how to enable use of client certificates. * lisp/net/network-stream.el (network-stream-certificate): Correct order of parameters to plist-get. (network-stream-open-tls): Pass all received parameters to open-gnutls-stream as plist, not just :nowait. * lisp/net/gnutls.el (open-gnutls-stream): Change optional nowait arg to be plist. Derive nowait and client certificate(s) and keys(s) from plist (maybe via auth-source) and pass to gnutls-boot-parameters and gnutls-negotiate. (network-stream-certificate): Add declare-function form for it. * doc/misc/auth.texi (Help for users): Describe format to use for client key/cert specification. * doc/misc/emacs-gnutls.texi (Help For Developers): Describe usage of optional plist argument. Add crossreference to description of .authinfo format for client key/cert specification. * etc/NEWS: Describe new client certificate functionality for 'open-network-stream'. * test/lisp/net/network-stream-tests.el: Add require of network-stream. (connect-to-tls-ipv4-nowait): Bind network-security-level to 'low in order to bypass nsm prompting. (connect-to-tls-ipv6-nowait): Likewise. (open-network-stream-tls-wait): New test. (open-network-stream-tls-nowait): New test. (open-network-stream-tls): New test. (open-network-stream-tls-nocert): New test. (open-gnutls-stream-new-api-default): New test. (open-gnutls-stream-new-api-wait): New test. (open-gnutls-stream-old-api-wait): New test. (open-gnutls-stream-new-api-nowait): New test. (open-gnutls-stream-old-api-nowait): New test. (open-gnutls-stream-new-api-errors): New test. The new tests exercise 'open-network-stream' and the old and new api of 'open-gnutls-stream'.
Diffstat (limited to 'lisp/net/gnutls.el')
-rw-r--r--lisp/net/gnutls.el50
1 files changed, 35 insertions, 15 deletions
diff --git a/lisp/net/gnutls.el b/lisp/net/gnutls.el
index 78ac3fe35b1..61480f35877 100644
--- a/lisp/net/gnutls.el
+++ b/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 @@ node `(emacs) Network Security'."
(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.
@@ -149,12 +152,15 @@ BUFFER is the buffer (or `buffer-name') to associate with the process.
a filter function to handle the output.
BUFFER may be also nil, meaning that this process is not associated
with any buffer
-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
+Third arg HOST is the name of the host to connect to, or its IP address.
+Fourth arg SERVICE is the 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 an optional list of keyword/value pairs.
+Only :client-certificate and :nowait keywords are recognized, and
+have the same meaning as for `open-network-stream'.
+For historical reasons PARAMETERS can also be a symbol, which is
+interpreted the same as passing a list containing :nowait and the
+value of that symbol.
Usage example:
@@ -168,19 +174,33 @@ This is a very simple wrapper around `gnutls-negotiate'. See its
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* ((parameters
+ (cond ((symbolp parameters)
+ (list :nowait parameters))
+ ((not (cl-evenp (length parameters)))
+ (error "Malformed keyword list"))
+ ((consp parameters)
+ parameters)
+ (t
+ (error "Unknown parameter type"))))
+ (cert (network-stream-certificate host service parameters))
+ (keylist (and cert (list cert)))
+ (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
+ :keylist keylist
+ :hostname (puny-encode-domain host)))))))
(if nowait
process
(gnutls-negotiate :process process
:type 'gnutls-x509pki
+ :keylist keylist
:hostname (puny-encode-domain host)))))
(define-error 'gnutls-error "GnuTLS error")