Merge from emacs-23; up to 2010-06-12T08:59:37Z!albinus@detlef.
[bpt/emacs.git] / lisp / net / gnutls.el
1 ;;; gnutls.el --- Support SSL/TLS connections through GnuTLS
2
3 ;; Copyright (C) 2010-2011 Free Software Foundation, Inc.
4
5 ;; Author: Ted Zlatanov <tzz@lifelogs.com>
6 ;; Keywords: comm, tls, ssl, encryption
7 ;; Originally-By: Simon Josefsson (See http://josefsson.org/emacs-security/)
8 ;; Thanks-To: Lars Magne Ingebrigtsen <larsi@gnus.org>
9
10 ;; This file is part of GNU Emacs.
11
12 ;; GNU Emacs is free software: you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation, either version 3 of the License, or
15 ;; (at your option) any later version.
16
17 ;; GNU Emacs is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
24
25 ;;; Commentary:
26
27 ;; This package provides language bindings for the GnuTLS library
28 ;; using the corresponding core functions in gnutls.c. It should NOT
29 ;; be used directly, only through open-protocol-stream.
30
31 ;; Simple test:
32 ;;
33 ;; (open-gnutls-stream "tls" "tls-buffer" "yourserver.com" "https")
34 ;; (open-gnutls-stream "tls" "tls-buffer" "imap.gmail.com" "imaps")
35
36 ;;; Code:
37
38 (eval-when-compile (require 'cl))
39
40 (defgroup gnutls nil
41 "Emacs interface to the GnuTLS library."
42 :prefix "gnutls-"
43 :group 'net-utils)
44
45 (defcustom gnutls-log-level 0
46 "Logging level to be used by `starttls-negotiate' and GnuTLS."
47 :type 'integer
48 :group 'gnutls)
49
50 (defun open-gnutls-stream (name buffer host service)
51 "Open a SSL/TLS connection for a service to a host.
52 Returns a subprocess-object to represent the connection.
53 Input and output work as for subprocesses; `delete-process' closes it.
54 Args are NAME BUFFER HOST SERVICE.
55 NAME is name for process. It is modified if necessary to make it unique.
56 BUFFER is the buffer (or `buffer-name') to associate with the process.
57 Process output goes at end of that buffer, unless you specify
58 an output stream or filter function to handle the output.
59 BUFFER may be also nil, meaning that this process is not associated
60 with any buffer
61 Third arg is name of the host to connect to, or its IP address.
62 Fourth arg SERVICE is name of the service desired, or an integer
63 specifying a port number to connect to.
64
65 Usage example:
66
67 \(with-temp-buffer
68 \(open-gnutls-stream \"tls\"
69 \(current-buffer)
70 \"your server goes here\"
71 \"imaps\"))
72
73 This is a very simple wrapper around `gnutls-negotiate'. See its
74 documentation for the specific parameters you can use to open a
75 GnuTLS connection, including specifying the credential type,
76 trust and key files, and priority string."
77 (gnutls-negotiate :process (open-network-stream name buffer host service)
78 :type 'gnutls-x509pki
79 :hostname host))
80
81 (put 'gnutls-error
82 'error-conditions
83 '(error gnutls-error))
84 (put 'gnutls-error
85 'error-message "GnuTLS error")
86
87 (declare-function gnutls-boot "gnutls.c" (proc type proplist))
88 (declare-function gnutls-errorp "gnutls.c" (error))
89
90 (defun* gnutls-negotiate
91 (&rest spec
92 &key process type hostname priority-string
93 trustfiles crlfiles keylist verify-flags
94 verify-error verify-hostname-error
95 &allow-other-keys)
96 "Negotiate a SSL/TLS connection. Returns proc. Signals gnutls-error.
97
98 Note arguments are passed CL style, :type TYPE instead of just TYPE.
99
100 TYPE is `gnutls-x509pki' (default) or `gnutls-anon'. Use nil for the default.
101 PROCESS is a process returned by `open-network-stream'.
102 HOSTNAME is the remote hostname. It must be a valid string.
103 PRIORITY-STRING is as per the GnuTLS docs, default is \"NORMAL\".
104 TRUSTFILES is a list of CA bundles.
105 CRLFILES is a list of CRL files.
106 KEYLIST is an alist of (client key file, client cert file) pairs.
107
108 When VERIFY-HOSTNAME-ERROR is not nil, an error will be raised
109 when the hostname does not match the presented certificate's host
110 name. The exact verification algorithm is a basic implementation
111 of the matching described in RFC2818 (HTTPS), which takes into
112 account wildcards, and the DNSName/IPAddress subject alternative
113 name PKIX extension. See GnuTLS' gnutls_x509_crt_check_hostname
114 for details. When VERIFY-HOSTNAME-ERROR is nil, only a warning
115 will be issued.
116
117 When VERIFY-ERROR is not nil, an error will be raised when the
118 peer certificate verification fails as per GnuTLS'
119 gnutls_certificate_verify_peers2. Otherwise, only warnings will
120 be shown about the verification failure.
121
122 VERIFY-FLAGS is a numeric OR of verification flags only for
123 `gnutls-x509pki' connections. See GnuTLS' x509.h for details;
124 here's a recent version of the list.
125
126 GNUTLS_VERIFY_DISABLE_CA_SIGN = 1,
127 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT = 2,
128 GNUTLS_VERIFY_DO_NOT_ALLOW_SAME = 4,
129 GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT = 8,
130 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2 = 16,
131 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5 = 32,
132 GNUTLS_VERIFY_DISABLE_TIME_CHECKS = 64,
133 GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS = 128,
134 GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT = 256
135
136 It must be omitted, a number, or nil; if omitted or nil it
137 defaults to GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT."
138 (let* ((type (or type 'gnutls-x509pki))
139 (default-trustfile "/etc/ssl/certs/ca-certificates.crt")
140 (trustfiles (or trustfiles
141 (when (file-exists-p default-trustfile)
142 (list default-trustfile))))
143 (priority-string (or priority-string
144 (cond
145 ((eq type 'gnutls-anon)
146 "NORMAL:+ANON-DH:!ARCFOUR-128")
147 ((eq type 'gnutls-x509pki)
148 "NORMAL"))))
149 (params `(:priority ,priority-string
150 :hostname ,hostname
151 :loglevel ,gnutls-log-level
152 :trustfiles ,trustfiles
153 :crlfiles ,crlfiles
154 :keylist ,keylist
155 :verify-flags ,verify-flags
156 :verify-error ,verify-error
157 :verify-hostname-error ,verify-hostname-error
158 :callbacks nil))
159 ret)
160
161 (gnutls-message-maybe
162 (setq ret (gnutls-boot process type params))
163 "boot: %s" params)
164
165 (when (gnutls-errorp ret)
166 ;; This is a error from the underlying C code.
167 (signal 'gnutls-error (list process ret)))
168
169 process))
170
171 (declare-function gnutls-error-string "gnutls.c" (error))
172
173 (defun gnutls-message-maybe (doit format &rest params)
174 "When DOIT, message with the caller name followed by FORMAT on PARAMS."
175 ;; (apply 'debug format (or params '(nil)))
176 (when (gnutls-errorp doit)
177 (message "%s: (err=[%s] %s) %s"
178 "gnutls.el"
179 doit (gnutls-error-string doit)
180 (apply 'format format (or params '(nil))))))
181
182 (provide 'gnutls)
183
184 ;;; gnutls.el ends here