aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Zlatanov2013-12-14 13:04:09 -0500
committerTed Zlatanov2013-12-14 13:04:09 -0500
commit31b4827ea9ba8d22deb17c0593f0f555a33e1fa4 (patch)
treedbfcb55f9fa3edc10623b34d5cf964a9a1167f7d
parentf93cc74f04312c1b27bfcc870c1782083525fc61 (diff)
downloademacs-31b4827ea9ba8d22deb17c0593f0f555a33e1fa4.tar.gz
emacs-31b4827ea9ba8d22deb17c0593f0f555a33e1fa4.zip
New verify-error GnuTLS interface for certificate validation
* net/gnutls.el (gnutls-verify-error): New defcustom to control the behavior when a certificate fails validation. Defaults to old behavior: never abort, just warn. (gnutls-negotiate): Use it. * gnutls.c: Replace `:verify_hostname_error' with `:verify_error', now a list of certificate validation checks that will abort a connection with an error. (Fgnutls_boot): Document it and use it.
-rw-r--r--lisp/ChangeLog7
-rw-r--r--lisp/net/gnutls.el67
-rw-r--r--src/ChangeLog7
-rw-r--r--src/gnutls.c48
4 files changed, 96 insertions, 33 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index f1f1f45df91..246b7ae5b5f 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,10 @@
12013-12-14 Teodor Zlatanov <tzz@lifelogs.com>
2
3 * net/gnutls.el (gnutls-verify-error): New defcustom to control
4 the behavior when a certificate fails validation. Defaults to
5 old behavior: never abort, just warn.
6 (gnutls-negotiate): Use it.
7
12013-12-14 Martin Rudalics <rudalics@gmx.at> 82013-12-14 Martin Rudalics <rudalics@gmx.at>
2 9
3 * window.el (display-buffer-below-selected): Never split window 10 * window.el (display-buffer-below-selected): Never split window
diff --git a/lisp/net/gnutls.el b/lisp/net/gnutls.el
index 923b108c708..5bf9adc2b53 100644
--- a/lisp/net/gnutls.el
+++ b/lisp/net/gnutls.el
@@ -51,6 +51,19 @@ set this variable to \"normal:-dhe-rsa\"."
51 :type '(choice (const nil) 51 :type '(choice (const nil)
52 string)) 52 string))
53 53
54(defcustom gnutls-verify-error nil
55 "If non-nil, this should be a list of checks per hostname regex or t."
56 :group 'gnutls
57 :type '(choice
58 (const t)
59 (repeat :tag "List of hostname regexps with flags for each"
60 (list
61 (choice :tag "Hostname"
62 (const ".*" :tag "Any hostname")
63 regexp)
64 (set (const :trustfiles)
65 (const :hostname))))))
66
54(defcustom gnutls-trustfiles 67(defcustom gnutls-trustfiles
55 '( 68 '(
56 "/etc/ssl/certs/ca-certificates.crt" ; Debian, Ubuntu, Gentoo and Arch Linux 69 "/etc/ssl/certs/ca-certificates.crt" ; Debian, Ubuntu, Gentoo and Arch Linux
@@ -138,19 +151,25 @@ MIN-PRIME-BITS is the minimum acceptable size of Diffie-Hellman keys
138\(see `gnutls-min-prime-bits' for more information). Use nil for the 151\(see `gnutls-min-prime-bits' for more information). Use nil for the
139default. 152default.
140 153
141When VERIFY-HOSTNAME-ERROR is not nil, an error will be raised 154VERIFY-HOSTNAME-ERROR is a backwards compatibility option for
142when the hostname does not match the presented certificate's host 155putting `:hostname' in VERIFY-ERROR.
143name. The exact verification algorithm is a basic implementation 156
144of the matching described in RFC2818 (HTTPS), which takes into 157When VERIFY-ERROR is t or a list containing `:trustfiles', an
145account wildcards, and the DNSName/IPAddress subject alternative 158error will be raised when the peer certificate verification fails
146name PKIX extension. See GnuTLS' gnutls_x509_crt_check_hostname 159as per GnuTLS' gnutls_certificate_verify_peers2. Otherwise, only
147for details. When VERIFY-HOSTNAME-ERROR is nil, only a warning 160warnings will be shown about the verification failure.
148will be issued.
149 161
150When VERIFY-ERROR is not nil, an error will be raised when the 162When VERIFY-ERROR is t or a list containing `:hostname', an error
151peer certificate verification fails as per GnuTLS' 163will be raised when the hostname does not match the presented
152gnutls_certificate_verify_peers2. Otherwise, only warnings will 164certificate's host name. The exact verification algorithm is a
153be shown about the verification failure. 165basic implementation of the matching described in
166RFC2818 (HTTPS), which takes into account wildcards, and the
167DNSName/IPAddress subject alternative name PKIX extension. See
168GnuTLS' gnutls_x509_crt_check_hostname for details. Otherwise,
169only a warning will be issued.
170
171Note that the list in `gnutls-verify-error', matched against the
172HOSTNAME, is the default VERIFY-ERROR.
154 173
155VERIFY-FLAGS is a numeric OR of verification flags only for 174VERIFY-FLAGS is a numeric OR of verification flags only for
156`gnutls-x509pki' connections. See GnuTLS' x509.h for details; 175`gnutls-x509pki' connections. See GnuTLS' x509.h for details;
@@ -183,8 +202,28 @@ defaults to GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT."
183 (if gnutls-algorithm-priority 202 (if gnutls-algorithm-priority
184 (upcase gnutls-algorithm-priority) 203 (upcase gnutls-algorithm-priority)
185 "NORMAL"))))) 204 "NORMAL")))))
205 (verify-error (or verify-error
206 ;; this uses the value of `gnutls-verify-error'
207 (cond
208 ;; if t, pass it on
209 ((eq gnutls-verify-error t)
210 t)
211 ;; if a list, look for hostname matches
212 ((listp gnutls-verify-error)
213 (mapcan
214 (lambda (check)
215 (when (string-match (car check) hostname)
216 (cdr check)))
217 gnutls-verify-error))
218 ;; else it's nil
219 (t nil))))
186 (min-prime-bits (or min-prime-bits gnutls-min-prime-bits)) 220 (min-prime-bits (or min-prime-bits gnutls-min-prime-bits))
187 (params `(:priority ,priority-string 221 params ret)
222
223 (when verify-hostname-error
224 (push :hostname verify-error))
225
226 (setq params `(:priority ,priority-string
188 :hostname ,hostname 227 :hostname ,hostname
189 :loglevel ,gnutls-log-level 228 :loglevel ,gnutls-log-level
190 :min-prime-bits ,min-prime-bits 229 :min-prime-bits ,min-prime-bits
@@ -193,9 +232,7 @@ defaults to GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT."
193 :keylist ,keylist 232 :keylist ,keylist
194 :verify-flags ,verify-flags 233 :verify-flags ,verify-flags
195 :verify-error ,verify-error 234 :verify-error ,verify-error
196 :verify-hostname-error ,verify-hostname-error
197 :callbacks nil)) 235 :callbacks nil))
198 ret)
199 236
200 (gnutls-message-maybe 237 (gnutls-message-maybe
201 (setq ret (gnutls-boot process type params)) 238 (setq ret (gnutls-boot process type params))
diff --git a/src/ChangeLog b/src/ChangeLog
index 80367c81166..081a6b8631c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
12013-12-14 Teodor Zlatanov <tzz@lifelogs.com>
2
3 * gnutls.c: Replace `:verify_hostname_error' with `:verify_error',
4 now a list of certificate validation checks that will abort a
5 connection with an error.
6 (Fgnutls_boot): Document it and use it.
7
12013-12-14 Martin Rudalics <rudalics@gmx.at> 82013-12-14 Martin Rudalics <rudalics@gmx.at>
2 9
3 * w32term.c (w32_enable_frame_resize_hack): New variable. 10 * w32term.c (w32_enable_frame_resize_hack): New variable.
diff --git a/src/gnutls.c b/src/gnutls.c
index 105e5071ed7..a14d3ef31c5 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -50,7 +50,7 @@ static Lisp_Object QCgnutls_bootprop_loglevel;
50static Lisp_Object QCgnutls_bootprop_hostname; 50static Lisp_Object QCgnutls_bootprop_hostname;
51static Lisp_Object QCgnutls_bootprop_min_prime_bits; 51static Lisp_Object QCgnutls_bootprop_min_prime_bits;
52static Lisp_Object QCgnutls_bootprop_verify_flags; 52static Lisp_Object QCgnutls_bootprop_verify_flags;
53static Lisp_Object QCgnutls_bootprop_verify_hostname_error; 53static Lisp_Object QCgnutls_bootprop_verify_error;
54 54
55/* Callback keys for `gnutls-boot'. Unused currently. */ 55/* Callback keys for `gnutls-boot'. Unused currently. */
56static Lisp_Object QCgnutls_bootprop_callbacks_verify; 56static Lisp_Object QCgnutls_bootprop_callbacks_verify;
@@ -754,8 +754,12 @@ certificates for `gnutls-x509pki'.
754:verify-flags is a bitset as per GnuTLS' 754:verify-flags is a bitset as per GnuTLS'
755gnutls_certificate_set_verify_flags. 755gnutls_certificate_set_verify_flags.
756 756
757:verify-hostname-error, if non-nil, makes a hostname mismatch an 757:verify-hostname-error is ignored. Pass :hostname in :verify-error
758error. Otherwise it will be just a warning. 758instead.
759
760:verify-error is a list of symbols to express verification checks or
761`t' to do all checks. Currently it can contain `:trustfiles' and
762`:hostname' to verify the certificate or the hostname respectively.
759 763
760:min-prime-bits is the minimum accepted number of bits the client will 764:min-prime-bits is the minimum accepted number of bits the client will
761accept in Diffie-Hellman key exchange. 765accept in Diffie-Hellman key exchange.
@@ -799,8 +803,7 @@ one trustfile (usually a CA bundle). */)
799 /* Lisp_Object callbacks; */ 803 /* Lisp_Object callbacks; */
800 Lisp_Object loglevel; 804 Lisp_Object loglevel;
801 Lisp_Object hostname; 805 Lisp_Object hostname;
802 /* Lisp_Object verify_error; */ 806 Lisp_Object verify_error;
803 Lisp_Object verify_hostname_error;
804 Lisp_Object prime_bits; 807 Lisp_Object prime_bits;
805 808
806 CHECK_PROCESS (proc); 809 CHECK_PROCESS (proc);
@@ -819,11 +822,14 @@ one trustfile (usually a CA bundle). */)
819 keylist = Fplist_get (proplist, QCgnutls_bootprop_keylist); 822 keylist = Fplist_get (proplist, QCgnutls_bootprop_keylist);
820 crlfiles = Fplist_get (proplist, QCgnutls_bootprop_crlfiles); 823 crlfiles = Fplist_get (proplist, QCgnutls_bootprop_crlfiles);
821 loglevel = Fplist_get (proplist, QCgnutls_bootprop_loglevel); 824 loglevel = Fplist_get (proplist, QCgnutls_bootprop_loglevel);
822 verify_hostname_error = Fplist_get (proplist, QCgnutls_bootprop_verify_hostname_error); 825 verify_error = Fplist_get (proplist, QCgnutls_bootprop_verify_error);
823 prime_bits = Fplist_get (proplist, QCgnutls_bootprop_min_prime_bits); 826 prime_bits = Fplist_get (proplist, QCgnutls_bootprop_min_prime_bits);
824 827
828 if (!Flistp (verify_error))
829 error ("gnutls-boot: invalid :verify_error parameter (not a list)");
830
825 if (!STRINGP (hostname)) 831 if (!STRINGP (hostname))
826 error ("gnutls-boot: invalid :hostname parameter"); 832 error ("gnutls-boot: invalid :hostname parameter (not a string)");
827 c_hostname = SSDATA (hostname); 833 c_hostname = SSDATA (hostname);
828 834
829 state = XPROCESS (proc)->gnutls_state; 835 state = XPROCESS (proc)->gnutls_state;
@@ -1065,14 +1071,17 @@ one trustfile (usually a CA bundle). */)
1065 1071
1066 if (peer_verification != 0) 1072 if (peer_verification != 0)
1067 { 1073 {
1068 if (NILP (verify_hostname_error)) 1074 if (EQ (verify_error, Qt)
1069 GNUTLS_LOG2 (1, max_log_level, "certificate validation failed:", 1075 || !NILP (Fmember (QCgnutls_bootprop_trustfiles, verify_error)))
1070 c_hostname); 1076 {
1071 else
1072 {
1073 emacs_gnutls_deinit (proc); 1077 emacs_gnutls_deinit (proc);
1074 error ("Certificate validation failed %s, verification code %d", 1078 error ("Certificate validation failed %s, verification code %d",
1075 c_hostname, peer_verification); 1079 c_hostname, peer_verification);
1080 }
1081 else
1082 {
1083 GNUTLS_LOG2 (1, max_log_level, "certificate validation failed:",
1084 c_hostname);
1076 } 1085 }
1077 } 1086 }
1078 1087
@@ -1112,14 +1121,17 @@ one trustfile (usually a CA bundle). */)
1112 1121
1113 if (!fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname)) 1122 if (!fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname))
1114 { 1123 {
1115 if (NILP (verify_hostname_error)) 1124 if (EQ (verify_error, Qt)
1116 GNUTLS_LOG2 (1, max_log_level, "x509 certificate does not match:", 1125 || !NILP (Fmember (QCgnutls_bootprop_hostname, verify_error)))
1117 c_hostname); 1126 {
1118 else
1119 {
1120 fn_gnutls_x509_crt_deinit (gnutls_verify_cert); 1127 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
1121 emacs_gnutls_deinit (proc); 1128 emacs_gnutls_deinit (proc);
1122 error ("The x509 certificate does not match \"%s\"", c_hostname); 1129 error ("The x509 certificate does not match \"%s\"", c_hostname);
1130 }
1131 else
1132 {
1133 GNUTLS_LOG2 (1, max_log_level, "x509 certificate does not match:",
1134 c_hostname);
1123 } 1135 }
1124 } 1136 }
1125 fn_gnutls_x509_crt_deinit (gnutls_verify_cert); 1137 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
@@ -1179,7 +1191,7 @@ syms_of_gnutls (void)
1179 DEFSYM (QCgnutls_bootprop_min_prime_bits, ":min-prime-bits"); 1191 DEFSYM (QCgnutls_bootprop_min_prime_bits, ":min-prime-bits");
1180 DEFSYM (QCgnutls_bootprop_loglevel, ":loglevel"); 1192 DEFSYM (QCgnutls_bootprop_loglevel, ":loglevel");
1181 DEFSYM (QCgnutls_bootprop_verify_flags, ":verify-flags"); 1193 DEFSYM (QCgnutls_bootprop_verify_flags, ":verify-flags");
1182 DEFSYM (QCgnutls_bootprop_verify_hostname_error, ":verify-hostname-error"); 1194 DEFSYM (QCgnutls_bootprop_verify_error, ":verify-error");
1183 1195
1184 DEFSYM (Qgnutls_e_interrupted, "gnutls-e-interrupted"); 1196 DEFSYM (Qgnutls_e_interrupted, "gnutls-e-interrupted");
1185 Fput (Qgnutls_e_interrupted, Qgnutls_code, 1197 Fput (Qgnutls_e_interrupted, Qgnutls_code,