aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Magne Ingebrigtsen2014-11-23 14:52:04 +0100
committerLars Magne Ingebrigtsen2014-11-23 14:52:04 +0100
commita85950469e6fc045de6157f9ad739e28f30ecd8d (patch)
tree99d4c9b37dd5b23db0112eaafe27f0f8ea1c89e1 /src
parent0b1d7cd596b9784584812d1bde8aa2d376891cdb (diff)
downloademacs-a85950469e6fc045de6157f9ad739e28f30ecd8d.tar.gz
emacs-a85950469e6fc045de6157f9ad739e28f30ecd8d.zip
Add functions to gnutls.c for exporting certificate details
* gnutls.c (gnutls_hex_string, gnutls_certificate_details) (Fgnutls_peer_status): New functions to export TLS certificate details to Emacs Lisp. * process.h: Added more fields to Lisp_Process to track certificate details. * gnutls.c (Fgnutls_boot): Save certificate for later inspection.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog11
-rw-r--r--src/gnutls.c351
-rw-r--r--src/process.h3
3 files changed, 364 insertions, 1 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index b75b2f7f659..10ef4fab1c0 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
12014-11-23 Lars Magne Ingebrigtsen <larsi@gnus.org>
2
3 * gnutls.c (Fgnutls_boot): Save certificate for later inspection.
4
5 * process.h: Added more fields to Lisp_Process to track
6 certificate details.
7
8 * gnutls.c (gnutls_hex_string, gnutls_certificate_details)
9 (Fgnutls_peer_status): New functions to export TLS certificate
10 details to Emacs Lisp.
11
12014-11-23 Jan Djärv <jan.h.d@swipnet.se> 122014-11-23 Jan Djärv <jan.h.d@swipnet.se>
2 13
3 * gtkutil.c (gtk_adjustment_configure): Define for Gtk+ < 2.14. 14 * gtkutil.c (gtk_adjustment_configure): Define for Gtk+ < 2.14.
diff --git a/src/gnutls.c b/src/gnutls.c
index 5d48f78a6d4..37d797a4b43 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -18,6 +18,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
18 18
19#include <config.h> 19#include <config.h>
20#include <errno.h> 20#include <errno.h>
21#include <stdio.h>
21 22
22#include "lisp.h" 23#include "lisp.h"
23#include "process.h" 24#include "process.h"
@@ -61,6 +62,11 @@ static void gnutls_log_function2 (int, const char *, const char *);
61static void gnutls_audit_log_function (gnutls_session_t, const char *); 62static void gnutls_audit_log_function (gnutls_session_t, const char *);
62#endif 63#endif
63 64
65static enum
66 {
67 CERTIFICATE_NOT_MATCHING = 2,
68 } extra_peer_verification_t;
69
64 70
65#ifdef WINDOWSNT 71#ifdef WINDOWSNT
66 72
@@ -146,6 +152,40 @@ DEF_GNUTLS_FN (int, gnutls_x509_crt_import,
146 (gnutls_x509_crt_t, const gnutls_datum_t *, 152 (gnutls_x509_crt_t, const gnutls_datum_t *,
147 gnutls_x509_crt_fmt_t)); 153 gnutls_x509_crt_fmt_t));
148DEF_GNUTLS_FN (int, gnutls_x509_crt_init, (gnutls_x509_crt_t *)); 154DEF_GNUTLS_FN (int, gnutls_x509_crt_init, (gnutls_x509_crt_t *));
155DEF_GNUTLS_FN (int, gnutls_x509_crt_get_fingerprint,
156 (gnutls_digest_algorithm_t,
157 const gnutls_datum_t*, void *, size_t *));
158DEF_GNUTLS_FN (int, gnutls_x509_crt_get_version,
159 (gnutls_x509_crt_t));
160DEF_GNUTLS_FN (int, gnutls_x509_crt_get_serial,
161 (gnutls_x509_crt_t, void *, size_t *));
162DEF_GNUTLS_FN (int, gnutls_x509_crt_get_issuer_dn,
163 (gnutls_x509_crt_t, char *, size_t *));
164DEF_GNUTLS_FN (time_t, gnutls_x509_crt_get_activation_time,
165 (gnutls_x509_crt_t));
166DEF_GNUTLS_FN (time_t, gnutls_x509_crt_get_expiration_time,
167 (gnutls_x509_crt_t));
168DEF_GNUTLS_FN (int, gnutls_x509_crt_get_dn,
169 (gnutls_x509_crt_t, char *, size_t *));
170DEF_GNUTLS_FN (int, gnutls_x509_crt_get_pk_algorithm,
171 (gnutls_x509_crt_t, unsigned int *));
172DEF_GNUTLS_FN (int, gnutls_pk_algorithm_get_name, (gnutls_pk_algorithm_t));
173DEF_GNUTLS_FN (int, gnutls_pk_bits_to_sec_param,
174 (gnutls_pk_algorithm_t, unsigned int));
175DEF_GNUTLS_FN (int, gnutls_x509_crt_get_issuer_unique_id,
176 (gnutls_x509_crt_t, char *, size_t *));
177DEF_GNUTLS_FN (int, gnutls_x509_crt_get_subject_unique_id,
178 (gnutls_x509_crt_t, char *, size_t *));
179DEF_GNUTLS_FN (int, gnutls_x509_crt_get_signature_algorithm,
180 (gnutls_x509_crt_t));
181DEF_GNUTLS_FN (int, gnutls_x509_crt_get_signature,
182 (gnutls_x509_crt_t, char *, size_t *));
183DEF_GNUTLS_FN (int, gnutls_x509_crt_get_key_id,
184 (gnutls_x509_crt_t, unsigned int,
185 unsigned char *, size_t *_size));
186DEF_GNUTLS_FN (const char*, gnutls_sec_param_get_name, (gnutls_sec_param_t));
187DEF_GNUTLS_FN (const char*, gnutls_sign_algorithm_get_name,
188 (gnutls_sign_algorithm_t));
149 189
150static bool 190static bool
151init_gnutls_functions (void) 191init_gnutls_functions (void)
@@ -205,6 +245,23 @@ init_gnutls_functions (void)
205 LOAD_GNUTLS_FN (library, gnutls_x509_crt_deinit); 245 LOAD_GNUTLS_FN (library, gnutls_x509_crt_deinit);
206 LOAD_GNUTLS_FN (library, gnutls_x509_crt_import); 246 LOAD_GNUTLS_FN (library, gnutls_x509_crt_import);
207 LOAD_GNUTLS_FN (library, gnutls_x509_crt_init); 247 LOAD_GNUTLS_FN (library, gnutls_x509_crt_init);
248 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_fingerprint);
249 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_version);
250 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_serial);
251 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_issuer_dn);
252 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_activation_time);
253 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_expiration_time);
254 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_dn);
255 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_pk_algorithm);
256 LOAD_GNUTLS_FN (library, gnutls_pk_algorithm_get_name);
257 LOAD_GNUTLS_FN (library, gnutls_pk_bits_to_sec_param);
258 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_issuer_unique_id);
259 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_subject_unique_id);
260 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_signature_algorithm);
261 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_signature);
262 LOAD_GNUTLS_FN (library, gnutls_x509_crt_get_key_id);
263 LOAD_GNUTLS_FN (library, gnutls_sec_param_get_name);
264 LOAD_GNUTLS_FN (library, gnutls_sign_algorithm_get_name);
208 265
209 max_log_level = global_gnutls_log_level; 266 max_log_level = global_gnutls_log_level;
210 267
@@ -260,6 +317,23 @@ init_gnutls_functions (void)
260#define fn_gnutls_x509_crt_deinit gnutls_x509_crt_deinit 317#define fn_gnutls_x509_crt_deinit gnutls_x509_crt_deinit
261#define fn_gnutls_x509_crt_import gnutls_x509_crt_import 318#define fn_gnutls_x509_crt_import gnutls_x509_crt_import
262#define fn_gnutls_x509_crt_init gnutls_x509_crt_init 319#define fn_gnutls_x509_crt_init gnutls_x509_crt_init
320#define fn_gnutls_x509_crt_get_fingerprint gnutls_x509_crt_get_fingerprint
321#define fn_gnutls_x509_crt_get_version gnutls_x509_crt_get_version
322#define fn_gnutls_x509_crt_get_serial gnutls_x509_crt_get_serial
323#define fn_gnutls_x509_crt_get_issuer_dn gnutls_x509_crt_get_issuer_dn
324#define fn_gnutls_x509_crt_get_activation_time gnutls_x509_crt_get_activation_time
325#define fn_gnutls_x509_crt_get_expiration_time gnutls_x509_crt_get_expiration_time
326#define fn_gnutls_x509_crt_get_dn gnutls_x509_crt_get_dn
327#define fn_gnutls_x509_crt_get_pk_algorithm gnutls_x509_crt_get_pk_algorithm
328#define fn_gnutls_pk_algorithm_get_name gnutls_pk_algorithm_get_name
329#define fn_gnutls_pk_bits_to_sec_param gnutls_pk_bits_to_sec_param
330#define fn_gnutls_x509_crt_get_issuer_unique_id gnutls_x509_crt_get_issuer_unique_id
331#define fn_gnutls_x509_crt_get_subject_unique_id gnutls_x509_crt_get_subject_unique_id
332#define fn_gnutls_x509_crt_get_signature_algorithm gnutls_x509_crt_get_signature_algorithm
333#define fn_gnutls_x509_crt_get_signature gnutls_x509_crt_get_signature
334#define fn_gnutls_x509_crt_get_key_id gnutls_x509_crt_get_key_id
335#define fn_gnutls_sec_param_get_name gnutls_sec_param_get_name
336#define fn_gnutls_sign_algorithm_get_name gnutls_sign_algorithm_get_name
263 337
264#endif /* !WINDOWSNT */ 338#endif /* !WINDOWSNT */
265 339
@@ -693,6 +767,273 @@ DEFUN ("gnutls-available-p", Fgnutls_available_p, Sgnutls_available_p, 0, 0, 0,
693#endif 767#endif
694} 768}
695 769
770Lisp_Object
771gnutls_hex_string (char *buf, size_t buf_size, char *prefix) {
772 size_t prefix_length = strlen (prefix);
773 char *string = malloc (buf_size * 3 + prefix_length);
774 Lisp_Object ret;
775
776 strcpy (string, prefix);
777
778 for (int i = 0; i < buf_size; i++)
779 sprintf (string + i * 3 + prefix_length,
780 i == buf_size - 1? "%02x": "%02x:",
781 ((unsigned char*)buf)[i]);
782
783 ret = build_string (string);
784 free (string);
785 return ret;
786}
787
788Lisp_Object
789gnutls_certificate_details (gnutls_x509_crt_t cert)
790{
791 Lisp_Object res = Qnil;
792 int err;
793
794 /* Version. */
795 {
796 int version = fn_gnutls_x509_crt_get_version (cert);
797 if (version >= GNUTLS_E_SUCCESS)
798 res = nconc2 (res, list2 (intern (":version"),
799 make_number (version)));
800 }
801
802 /* Serial. */
803 {
804 size_t serial_size = 0;
805
806 err = fn_gnutls_x509_crt_get_serial (cert, NULL, &serial_size);
807 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) {
808 char *serial = malloc (serial_size);
809 err = fn_gnutls_x509_crt_get_serial (cert, serial, &serial_size);
810 if (err >= GNUTLS_E_SUCCESS) {
811 res = nconc2 (res, list2 (intern (":serial-number"),
812 gnutls_hex_string (serial, serial_size, "")));
813 }
814 free (serial);
815 }
816 }
817
818 /* Issuer. */
819 {
820 size_t dn_size = 0;
821
822 err = fn_gnutls_x509_crt_get_issuer_dn (cert, NULL, &dn_size);
823 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) {
824 char *dn = malloc (dn_size);
825 err = fn_gnutls_x509_crt_get_issuer_dn (cert, dn, &dn_size);
826 if (err >= GNUTLS_E_SUCCESS)
827 res = nconc2 (res, list2 (intern (":issuer"),
828 make_string (dn, dn_size)));
829 free (dn);
830 }
831 }
832
833 /* Validity. */
834 {
835 char buf[11];
836 size_t buf_size = sizeof (buf);
837 struct tm t;
838 time_t tim = fn_gnutls_x509_crt_get_activation_time (cert);
839
840 if (gmtime_r (&tim, &t) != NULL &&
841 strftime (buf, buf_size, "%Y-%m-%d", &t) != 0)
842 res = nconc2 (res, list2 (intern (":valid-from"), build_string (buf)));
843
844 tim = fn_gnutls_x509_crt_get_expiration_time (cert);
845 if (gmtime_r (&tim, &t) != NULL &&
846 strftime (buf, buf_size, "%Y-%m-%d", &t) != 0)
847 res = nconc2 (res, list2 (intern (":valid-to"), build_string (buf)));
848 }
849
850 /* Subject. */
851 {
852 size_t dn_size = 0;
853
854 err = fn_gnutls_x509_crt_get_dn (cert, NULL, &dn_size);
855 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) {
856 char *dn = malloc (dn_size);
857 err = fn_gnutls_x509_crt_get_dn (cert, dn, &dn_size);
858 if (err >= GNUTLS_E_SUCCESS)
859 res = nconc2 (res, list2 (intern (":subject"),
860 make_string (dn, dn_size)));
861 free (dn);
862 }
863 }
864
865 /* SubjectPublicKeyInfo. */
866 {
867 unsigned int bits;
868
869 err = fn_gnutls_x509_crt_get_pk_algorithm (cert, &bits);
870 if (err >= GNUTLS_E_SUCCESS) {
871 const char *name = fn_gnutls_pk_algorithm_get_name (err);
872 if (name)
873 res = nconc2 (res, list2 (intern (":public-key-algorithm"),
874 build_string (name)));
875
876 name = fn_gnutls_sec_param_get_name (fn_gnutls_pk_bits_to_sec_param
877 (err, bits));
878 res = nconc2 (res, list2 (intern (":certificate-security-level"),
879 build_string (name)));
880 }
881 }
882
883 /* Unique IDs. */
884 {
885 size_t buf_size = 0;
886
887 err = fn_gnutls_x509_crt_get_issuer_unique_id (cert, NULL, &buf_size);
888 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) {
889 char *buf = malloc (buf_size);
890 err = fn_gnutls_x509_crt_get_issuer_unique_id (cert, buf, &buf_size);
891 if (err >= GNUTLS_E_SUCCESS)
892 res = nconc2 (res, list2 (intern (":issuer-unique-id"),
893 make_string (buf, buf_size)));
894 free (buf);
895 }
896
897 buf_size = 0;
898 err = fn_gnutls_x509_crt_get_subject_unique_id (cert, NULL, &buf_size);
899 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) {
900 char *buf = malloc (buf_size);
901 err = fn_gnutls_x509_crt_get_subject_unique_id (cert, buf, &buf_size);
902 if (err >= GNUTLS_E_SUCCESS)
903 res = nconc2 (res, list2 (intern (":subject-unique-id"),
904 make_string (buf, buf_size)));
905 free (buf);
906 }
907 }
908
909 /* Signature. */
910 {
911 size_t buf_size = 0;
912
913 err = fn_gnutls_x509_crt_get_signature_algorithm (cert);
914 if (err >= GNUTLS_E_SUCCESS) {
915 const char *name = fn_gnutls_sign_algorithm_get_name (err);
916 if (name)
917 res = nconc2 (res, list2 (intern (":signature-algorithm"),
918 build_string (name)));
919
920 err = fn_gnutls_x509_crt_get_signature (cert, NULL, &buf_size);
921 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) {
922 char *buf = malloc (buf_size);
923 err = fn_gnutls_x509_crt_get_signature (cert, buf, &buf_size);
924 if (err >= GNUTLS_E_SUCCESS) {
925 res = nconc2 (res, list2 (intern (":signature"),
926 gnutls_hex_string (buf, buf_size, "")));
927 }
928 free (buf);
929 }
930 }
931 }
932
933 /* Public key ID. */
934 {
935 size_t buf_size = 0;
936
937 err = fn_gnutls_x509_crt_get_key_id (cert, 0, NULL, &buf_size);
938 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) {
939 unsigned char *buf = malloc (buf_size);
940 err = fn_gnutls_x509_crt_get_key_id (cert, 0, buf, &buf_size);
941 if (err >= GNUTLS_E_SUCCESS)
942 res = nconc2 (res, list2 (intern (":public-key-id"),
943 gnutls_hex_string ((char *)buf,
944 buf_size, "sha1:")));
945 free (buf);
946 }
947 }
948
949 /* Certificate fingerprint. */
950 {
951 size_t buf_size = 0;
952
953 err = fn_gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1,
954 NULL, &buf_size);
955 if (err == GNUTLS_E_SHORT_MEMORY_BUFFER) {
956 unsigned char *buf = malloc (buf_size);
957 err = fn_gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1,
958 buf, &buf_size);
959 if (err >= GNUTLS_E_SUCCESS)
960 res = nconc2 (res, list2 (intern (":certificate-id"),
961 gnutls_hex_string ((char *)buf,
962 buf_size, "sha1:")));
963 free (buf);
964 }
965 }
966
967 return res;
968}
969
970DEFUN ("gnutls-peer-status", Fgnutls_peer_status, Sgnutls_peer_status, 1, 1, 0,
971 doc: /* Return the status of the gnutls PROC peer certificate.
972The return value is a property list. */)
973 (Lisp_Object proc)
974{
975 Lisp_Object warnings = Qnil, result = Qnil;
976 unsigned int verification;
977
978 CHECK_PROCESS (proc);
979
980 if (XPROCESS (proc)->gnutls_p == 0)
981 return Qnil;
982
983 /* Then collect any warnings already computed by the handshake. */
984 verification = XPROCESS (proc)->gnutls_peer_verification;
985
986 if (verification & GNUTLS_CERT_INVALID)
987 warnings = Fcons (list2 (intern (":invalid"),
988 build_string("certificate could not be verified")),
989 warnings);
990
991 if (verification & GNUTLS_CERT_REVOKED)
992 warnings = Fcons (list2 (intern (":revoked"),
993 build_string("certificate was revoked (CRL)")),
994 warnings);
995
996 if (verification & GNUTLS_CERT_SIGNER_NOT_FOUND)
997 warnings = Fcons (list2 (intern (":self-signed"),
998 build_string("certificate signer was not found (self-signed)")),
999 warnings);
1000
1001 if (verification & GNUTLS_CERT_SIGNER_NOT_CA)
1002 warnings = Fcons (list2 (intern (":not-ca"),
1003 build_string("certificate signer is not a CA")),
1004 warnings);
1005
1006 if (verification & GNUTLS_CERT_INSECURE_ALGORITHM)
1007 warnings = Fcons (list2 (intern (":insecure"),
1008 build_string("certificate was signed with an insecure algorithm")),
1009 warnings);
1010
1011 if (verification & GNUTLS_CERT_NOT_ACTIVATED)
1012 warnings = Fcons (list2 (intern (":not-activated"),
1013 build_string("certificate is not yet activated")),
1014 warnings);
1015
1016 if (verification & GNUTLS_CERT_EXPIRED)
1017 warnings = Fcons (list2 (intern (":expired"),
1018 build_string("certificate has expired")),
1019 warnings);
1020
1021 if (XPROCESS (proc)->gnutls_extra_peer_verification &
1022 CERTIFICATE_NOT_MATCHING)
1023 warnings = Fcons (list2 (intern (":no-host-match"),
1024 build_string("certificate host does not match hostname")),
1025 warnings);
1026
1027 if (!NILP (warnings))
1028 result = list2 (intern (":warnings"), warnings);
1029
1030 result = nconc2 (result, list2
1031 (intern (":certificate"),
1032 gnutls_certificate_details(XPROCESS (proc)->gnutls_certificate)));
1033
1034 return result;
1035}
1036
696 1037
697/* Initializes global GnuTLS state to defaults. 1038/* Initializes global GnuTLS state to defaults.
698Call `gnutls-global-deinit' when GnuTLS usage is no longer needed. 1039Call `gnutls-global-deinit' when GnuTLS usage is no longer needed.
@@ -1048,6 +1389,8 @@ one trustfile (usually a CA bundle). */)
1048 if (ret < GNUTLS_E_SUCCESS) 1389 if (ret < GNUTLS_E_SUCCESS)
1049 return gnutls_make_error (ret); 1390 return gnutls_make_error (ret);
1050 1391
1392 XPROCESS (proc)->gnutls_peer_verification = peer_verification;
1393
1051 if (XINT (loglevel) > 0 && peer_verification & GNUTLS_CERT_INVALID) 1394 if (XINT (loglevel) > 0 && peer_verification & GNUTLS_CERT_INVALID)
1052 message ("%s certificate could not be verified.", c_hostname); 1395 message ("%s certificate could not be verified.", c_hostname);
1053 1396
@@ -1126,8 +1469,12 @@ one trustfile (usually a CA bundle). */)
1126 return gnutls_make_error (ret); 1469 return gnutls_make_error (ret);
1127 } 1470 }
1128 1471
1472 XPROCESS (proc)->gnutls_certificate = gnutls_verify_cert;
1473
1129 if (!fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname)) 1474 if (!fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname))
1130 { 1475 {
1476 XPROCESS (proc)->gnutls_extra_peer_verification |=
1477 CERTIFICATE_NOT_MATCHING;
1131 if (verify_error_all 1478 if (verify_error_all
1132 || !NILP (Fmember (QCgnutls_bootprop_hostname, verify_error))) 1479 || !NILP (Fmember (QCgnutls_bootprop_hostname, verify_error)))
1133 { 1480 {
@@ -1141,7 +1488,6 @@ one trustfile (usually a CA bundle). */)
1141 c_hostname); 1488 c_hostname);
1142 } 1489 }
1143 } 1490 }
1144 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
1145 } 1491 }
1146 1492
1147 /* Set this flag only if the whole initialization succeeded. */ 1493 /* Set this flag only if the whole initialization succeeded. */
@@ -1173,6 +1519,8 @@ This function may also return `gnutls-e-again', or
1173 1519
1174 state = XPROCESS (proc)->gnutls_state; 1520 state = XPROCESS (proc)->gnutls_state;
1175 1521
1522 fn_gnutls_x509_crt_deinit (XPROCESS (proc)->gnutls_certificate);
1523
1176 ret = fn_gnutls_bye (state, 1524 ret = fn_gnutls_bye (state,
1177 NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR); 1525 NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR);
1178 1526
@@ -1224,6 +1572,7 @@ syms_of_gnutls (void)
1224 defsubr (&Sgnutls_deinit); 1572 defsubr (&Sgnutls_deinit);
1225 defsubr (&Sgnutls_bye); 1573 defsubr (&Sgnutls_bye);
1226 defsubr (&Sgnutls_available_p); 1574 defsubr (&Sgnutls_available_p);
1575 defsubr (&Sgnutls_peer_status);
1227 1576
1228 DEFVAR_INT ("gnutls-log-level", global_gnutls_log_level, 1577 DEFVAR_INT ("gnutls-log-level", global_gnutls_log_level,
1229 doc: /* Logging level used by the GnuTLS functions. 1578 doc: /* Logging level used by the GnuTLS functions.
diff --git a/src/process.h b/src/process.h
index 273ad9267d6..56c0f6d6302 100644
--- a/src/process.h
+++ b/src/process.h
@@ -162,6 +162,9 @@ struct Lisp_Process
162 gnutls_session_t gnutls_state; 162 gnutls_session_t gnutls_state;
163 gnutls_certificate_client_credentials gnutls_x509_cred; 163 gnutls_certificate_client_credentials gnutls_x509_cred;
164 gnutls_anon_client_credentials_t gnutls_anon_cred; 164 gnutls_anon_client_credentials_t gnutls_anon_cred;
165 gnutls_x509_crt_t gnutls_certificate;
166 unsigned int gnutls_peer_verification;
167 unsigned int gnutls_extra_peer_verification;
165 int gnutls_log_level; 168 int gnutls_log_level;
166 int gnutls_handshakes_tried; 169 int gnutls_handshakes_tried;
167 bool_bf gnutls_p : 1; 170 bool_bf gnutls_p : 1;