#include "lisp.h"
#include "process.h"
+#include "coding.h"
#ifdef HAVE_GNUTLS
#include <gnutls/gnutls.h>
static Lisp_Object QCgnutls_bootprop_hostname;
static Lisp_Object QCgnutls_bootprop_min_prime_bits;
static Lisp_Object QCgnutls_bootprop_verify_flags;
-static Lisp_Object QCgnutls_bootprop_verify_hostname_error;
+static Lisp_Object QCgnutls_bootprop_verify_error;
/* Callback keys for `gnutls-boot'. Unused currently. */
static Lisp_Object QCgnutls_bootprop_callbacks_verify;
return ret;
}
-int
+ptrdiff_t
emacs_gnutls_record_check_pending (gnutls_session_t state)
{
return fn_gnutls_record_check_pending (state);
:verify-flags is a bitset as per GnuTLS'
gnutls_certificate_set_verify_flags.
-:verify-hostname-error, if non-nil, makes a hostname mismatch an
-error. Otherwise it will be just a warning.
+:verify-hostname-error is ignored. Pass :hostname in :verify-error
+instead.
+
+:verify-error is a list of symbols to express verification checks or
+`t' to do all checks. Currently it can contain `:trustfiles' and
+`:hostname' to verify the certificate or the hostname respectively.
:min-prime-bits is the minimum accepted number of bits the client will
accept in Diffie-Hellman key exchange.
/* Lisp_Object callbacks; */
Lisp_Object loglevel;
Lisp_Object hostname;
- /* Lisp_Object verify_error; */
- Lisp_Object verify_hostname_error;
+ Lisp_Object verify_error;
Lisp_Object prime_bits;
CHECK_PROCESS (proc);
keylist = Fplist_get (proplist, QCgnutls_bootprop_keylist);
crlfiles = Fplist_get (proplist, QCgnutls_bootprop_crlfiles);
loglevel = Fplist_get (proplist, QCgnutls_bootprop_loglevel);
- verify_hostname_error = Fplist_get (proplist, QCgnutls_bootprop_verify_hostname_error);
+ verify_error = Fplist_get (proplist, QCgnutls_bootprop_verify_error);
prime_bits = Fplist_get (proplist, QCgnutls_bootprop_min_prime_bits);
+ if (NILP (Flistp (verify_error)))
+ error ("gnutls-boot: invalid :verify_error parameter (not a list)");
+
if (!STRINGP (hostname))
- error ("gnutls-boot: invalid :hostname parameter");
+ error ("gnutls-boot: invalid :hostname parameter (not a string)");
c_hostname = SSDATA (hostname);
state = XPROCESS (proc)->gnutls_state;
{
GNUTLS_LOG2 (1, max_log_level, "setting the trustfile: ",
SSDATA (trustfile));
+ trustfile = ENCODE_FILE (trustfile);
+#ifdef WINDOWSNT
+ /* Since GnuTLS doesn't support UTF-8 or UTF-16 encoded
+ file names on Windows, we need to re-encode the file
+ name using the current ANSI codepage. */
+ trustfile = ansi_encode_filename (trustfile);
+#endif
ret = fn_gnutls_certificate_set_x509_trust_file
(x509_cred,
SSDATA (trustfile),
{
GNUTLS_LOG2 (1, max_log_level, "setting the CRL file: ",
SSDATA (crlfile));
+ crlfile = ENCODE_FILE (crlfile);
+#ifdef WINDOWSNT
+ crlfile = ansi_encode_filename (crlfile);
+#endif
ret = fn_gnutls_certificate_set_x509_crl_file
(x509_cred, SSDATA (crlfile), file_format);
SSDATA (keyfile));
GNUTLS_LOG2 (1, max_log_level, "setting the client cert file: ",
SSDATA (certfile));
+ keyfile = ENCODE_FILE (keyfile);
+ certfile = ENCODE_FILE (certfile);
+#ifdef WINDOWSNT
+ keyfile = ansi_encode_filename (keyfile);
+ certfile = ansi_encode_filename (certfile);
+#endif
ret = fn_gnutls_certificate_set_x509_key_file
(x509_cred, SSDATA (certfile), SSDATA (keyfile), file_format);
if (peer_verification != 0)
{
- if (NILP (verify_hostname_error))
- GNUTLS_LOG2 (1, max_log_level, "certificate validation failed:",
- c_hostname);
- else
- {
+ if (!NILP (Fmember (QCgnutls_bootprop_trustfiles, verify_error)))
+ {
emacs_gnutls_deinit (proc);
error ("Certificate validation failed %s, verification code %d",
c_hostname, peer_verification);
+ }
+ else
+ {
+ GNUTLS_LOG2 (1, max_log_level, "certificate validation failed:",
+ c_hostname);
}
}
if (!fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname))
{
- if (NILP (verify_hostname_error))
- GNUTLS_LOG2 (1, max_log_level, "x509 certificate does not match:",
- c_hostname);
- else
- {
+ if (!NILP (Fmember (QCgnutls_bootprop_hostname, verify_error)))
+ {
fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
emacs_gnutls_deinit (proc);
error ("The x509 certificate does not match \"%s\"", c_hostname);
+ }
+ else
+ {
+ GNUTLS_LOG2 (1, max_log_level, "x509 certificate does not match:",
+ c_hostname);
}
}
fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
DEFSYM (QCgnutls_bootprop_min_prime_bits, ":min-prime-bits");
DEFSYM (QCgnutls_bootprop_loglevel, ":loglevel");
DEFSYM (QCgnutls_bootprop_verify_flags, ":verify-flags");
- DEFSYM (QCgnutls_bootprop_verify_hostname_error, ":verify-hostname-error");
+ DEFSYM (QCgnutls_bootprop_verify_error, ":verify-error");
DEFSYM (Qgnutls_e_interrupted, "gnutls-e-interrupted");
Fput (Qgnutls_e_interrupted, Qgnutls_code,