aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChong Yidong2011-10-27 16:07:28 +0800
committerChong Yidong2011-10-27 16:07:28 +0800
commit435c1d6793ce358f4d2c77c9e9c1ad81fd754651 (patch)
treec4a4bf709d74290d4c59f8b1a152190c8d89d9c6 /src
parent416a2c45b3068568e47076ed089db25830117ea8 (diff)
downloademacs-435c1d6793ce358f4d2c77c9e9c1ad81fd754651.tar.gz
emacs-435c1d6793ce358f4d2c77c9e9c1ad81fd754651.zip
More gnutls memory fixes.
* src/gnutls.c (emacs_gnutls_deinit): Deinit the gnutls_state if it is non-NULL, regardless of GNUTLS_INITSTAGE. (Fgnutls_boot): Cleanups. Call emacs_gnutls_deinit if we signal an error. Set process slots as soon as we allocate them. * src/gnutls.h (GNUTLS_LOG, GNUTLS_LOG2): Fix macros. * src/process.c (make_process): Set gnutls_state to NULL.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog11
-rw-r--r--src/gnutls.c240
-rw-r--r--src/gnutls.h4
-rw-r--r--src/process.c1
4 files changed, 110 insertions, 146 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 65995d0ac92..c3926f6024b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,16 @@
12011-10-27 Chong Yidong <cyd@gnu.org> 12011-10-27 Chong Yidong <cyd@gnu.org>
2 2
3 * process.c (make_process): Set gnutls_state to NULL.
4
5 * gnutls.c (emacs_gnutls_deinit): Deinit the gnutls_state if it is
6 non-NULL, regardless of GNUTLS_INITSTAGE.
7 (Fgnutls_boot): Cleanups. Call emacs_gnutls_deinit if we signal
8 an error. Set process slots as soon as we allocate them.
9
10 * gnutls.h (GNUTLS_LOG, GNUTLS_LOG2): Fix macros.
11
122011-10-27 Chong Yidong <cyd@gnu.org>
13
3 * gnutls.c (emacs_gnutls_deinit): New function. Deallocate 14 * gnutls.c (emacs_gnutls_deinit): New function. Deallocate
4 credentials structures as well as calling gnutls_deinit. 15 credentials structures as well as calling gnutls_deinit.
5 (Fgnutls_deinit, Fgnutls_boot): Use it. 16 (Fgnutls_deinit, Fgnutls_boot): Use it.
diff --git a/src/gnutls.c b/src/gnutls.c
index f836692198c..500f09432b1 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -490,10 +490,12 @@ emacs_gnutls_deinit (Lisp_Object proc)
490 XPROCESS (proc)->gnutls_anon_cred = NULL; 490 XPROCESS (proc)->gnutls_anon_cred = NULL;
491 } 491 }
492 492
493 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT) 493 if (XPROCESS (proc)->gnutls_state)
494 { 494 {
495 fn_gnutls_deinit (XPROCESS (proc)->gnutls_state); 495 fn_gnutls_deinit (XPROCESS (proc)->gnutls_state);
496 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1; 496 XPROCESS (proc)->gnutls_state = NULL;
497 if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT)
498 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1;
497 } 499 }
498 500
499 XPROCESS (proc)->gnutls_p = 0; 501 XPROCESS (proc)->gnutls_p = 0;
@@ -647,7 +649,7 @@ emacs_gnutls_global_deinit (void)
647 649
648DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 3, 0, 650DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 3, 0,
649 doc: /* Initialize GnuTLS client for process PROC with TYPE+PROPLIST. 651 doc: /* Initialize GnuTLS client for process PROC with TYPE+PROPLIST.
650Currently only client mode is supported. Returns a success/failure 652Currently only client mode is supported. Return a success/failure
651value you can check with `gnutls-errorp'. 653value you can check with `gnutls-errorp'.
652 654
653TYPE is a symbol, either `gnutls-anon' or `gnutls-x509pki'. 655TYPE is a symbol, either `gnutls-anon' or `gnutls-x509pki'.
@@ -698,23 +700,13 @@ one trustfile (usually a CA bundle). */)
698 (Lisp_Object proc, Lisp_Object type, Lisp_Object proplist) 700 (Lisp_Object proc, Lisp_Object type, Lisp_Object proplist)
699{ 701{
700 int ret = GNUTLS_E_SUCCESS; 702 int ret = GNUTLS_E_SUCCESS;
701
702 int max_log_level = 0; 703 int max_log_level = 0;
703 704
704 /* TODO: GNUTLS_X509_FMT_DER is also an option. */
705 int file_format = GNUTLS_X509_FMT_PEM;
706
707 unsigned int gnutls_verify_flags = GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
708 gnutls_x509_crt_t gnutls_verify_cert;
709 unsigned int gnutls_verify_cert_list_size;
710 const gnutls_datum_t *gnutls_verify_cert_list;
711
712 gnutls_session_t state; 705 gnutls_session_t state;
713 gnutls_certificate_credentials_t x509_cred; 706 gnutls_certificate_credentials_t x509_cred = NULL;
714 gnutls_anon_client_credentials_t anon_cred; 707 gnutls_anon_client_credentials_t anon_cred = NULL;
715 Lisp_Object global_init; 708 Lisp_Object global_init;
716 char const *priority_string_ptr = "NORMAL"; /* default priority string. */ 709 char const *priority_string_ptr = "NORMAL"; /* default priority string. */
717 Lisp_Object tail;
718 unsigned int peer_verification; 710 unsigned int peer_verification;
719 char* c_hostname; 711 char* c_hostname;
720 712
@@ -726,7 +718,6 @@ one trustfile (usually a CA bundle). */)
726 /* Lisp_Object callbacks; */ 718 /* Lisp_Object callbacks; */
727 Lisp_Object loglevel; 719 Lisp_Object loglevel;
728 Lisp_Object hostname; 720 Lisp_Object hostname;
729 Lisp_Object verify_flags;
730 /* Lisp_Object verify_error; */ 721 /* Lisp_Object verify_error; */
731 Lisp_Object verify_hostname_error; 722 Lisp_Object verify_hostname_error;
732 Lisp_Object prime_bits; 723 Lisp_Object prime_bits;
@@ -741,21 +732,23 @@ one trustfile (usually a CA bundle). */)
741 return gnutls_make_error (GNUTLS_EMACS_ERROR_NOT_LOADED); 732 return gnutls_make_error (GNUTLS_EMACS_ERROR_NOT_LOADED);
742 } 733 }
743 734
735 if (!EQ (type, Qgnutls_x509pki) && !EQ (type, Qgnutls_anon))
736 {
737 error ("Invalid GnuTLS credential type");
738 return gnutls_make_error (GNUTLS_EMACS_ERROR_INVALID_TYPE);
739 }
740
744 hostname = Fplist_get (proplist, QCgnutls_bootprop_hostname); 741 hostname = Fplist_get (proplist, QCgnutls_bootprop_hostname);
745 priority_string = Fplist_get (proplist, QCgnutls_bootprop_priority); 742 priority_string = Fplist_get (proplist, QCgnutls_bootprop_priority);
746 trustfiles = Fplist_get (proplist, QCgnutls_bootprop_trustfiles); 743 trustfiles = Fplist_get (proplist, QCgnutls_bootprop_trustfiles);
747 keylist = Fplist_get (proplist, QCgnutls_bootprop_keylist); 744 keylist = Fplist_get (proplist, QCgnutls_bootprop_keylist);
748 crlfiles = Fplist_get (proplist, QCgnutls_bootprop_crlfiles); 745 crlfiles = Fplist_get (proplist, QCgnutls_bootprop_crlfiles);
749 /* callbacks = Fplist_get (proplist, QCgnutls_bootprop_callbacks); */
750 loglevel = Fplist_get (proplist, QCgnutls_bootprop_loglevel); 746 loglevel = Fplist_get (proplist, QCgnutls_bootprop_loglevel);
751 verify_flags = Fplist_get (proplist, QCgnutls_bootprop_verify_flags);
752 /* verify_error = Fplist_get (proplist, QCgnutls_bootprop_verify_error); */
753 verify_hostname_error = Fplist_get (proplist, QCgnutls_bootprop_verify_hostname_error); 747 verify_hostname_error = Fplist_get (proplist, QCgnutls_bootprop_verify_hostname_error);
754 prime_bits = Fplist_get (proplist, QCgnutls_bootprop_min_prime_bits); 748 prime_bits = Fplist_get (proplist, QCgnutls_bootprop_min_prime_bits);
755 749
756 if (!STRINGP (hostname)) 750 if (!STRINGP (hostname))
757 error ("gnutls-boot: invalid :hostname parameter"); 751 error ("gnutls-boot: invalid :hostname parameter");
758
759 c_hostname = SSDATA (hostname); 752 c_hostname = SSDATA (hostname);
760 753
761 if (NUMBERP (loglevel)) 754 if (NUMBERP (loglevel))
@@ -777,53 +770,50 @@ one trustfile (usually a CA bundle). */)
777 770
778 /* Mark PROC as a GnuTLS process. */ 771 /* Mark PROC as a GnuTLS process. */
779 XPROCESS (proc)->gnutls_p = 1; 772 XPROCESS (proc)->gnutls_p = 1;
773 XPROCESS (proc)->gnutls_state = NULL;
780 XPROCESS (proc)->gnutls_x509_cred = NULL; 774 XPROCESS (proc)->gnutls_x509_cred = NULL;
781 XPROCESS (proc)->gnutls_anon_cred = NULL; 775 XPROCESS (proc)->gnutls_anon_cred = NULL;
776 XPROCESS (proc)->gnutls_cred_type = type;
782 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_EMPTY; 777 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_EMPTY;
783 778
784 GNUTLS_LOG (1, max_log_level, "allocating credentials"); 779 GNUTLS_LOG (1, max_log_level, "allocating credentials");
785 if (EQ (type, Qgnutls_x509pki)) 780 if (EQ (type, Qgnutls_x509pki))
786 { 781 {
782 Lisp_Object verify_flags;
783 unsigned int gnutls_verify_flags = GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
784
787 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials"); 785 GNUTLS_LOG (2, max_log_level, "allocating x509 credentials");
788 x509_cred = XPROCESS (proc)->gnutls_x509_cred;
789 fn_gnutls_certificate_allocate_credentials (&x509_cred); 786 fn_gnutls_certificate_allocate_credentials (&x509_cred);
787 XPROCESS (proc)->gnutls_x509_cred = x509_cred;
790 788
789 verify_flags = Fplist_get (proplist, QCgnutls_bootprop_verify_flags);
791 if (NUMBERP (verify_flags)) 790 if (NUMBERP (verify_flags))
792 { 791 {
793 gnutls_verify_flags = XINT (verify_flags); 792 gnutls_verify_flags = XINT (verify_flags);
794 GNUTLS_LOG (2, max_log_level, "setting verification flags"); 793 GNUTLS_LOG (2, max_log_level, "setting verification flags");
795 } 794 }
796 else if (NILP (verify_flags)) 795 else if (NILP (verify_flags))
797 { 796 GNUTLS_LOG (2, max_log_level, "using default verification flags");
798 /* The default is already GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT. */
799 GNUTLS_LOG (2, max_log_level, "using default verification flags");
800 }
801 else 797 else
802 { 798 GNUTLS_LOG (2, max_log_level, "ignoring invalid verify-flags");
803 /* The default is already GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT. */ 799
804 GNUTLS_LOG (2, max_log_level, "ignoring invalid verify-flags");
805 }
806 fn_gnutls_certificate_set_verify_flags (x509_cred, gnutls_verify_flags); 800 fn_gnutls_certificate_set_verify_flags (x509_cred, gnutls_verify_flags);
807 } 801 }
808 else if (EQ (type, Qgnutls_anon)) 802 else /* Qgnutls_anon: */
809 { 803 {
810 GNUTLS_LOG (2, max_log_level, "allocating anon credentials"); 804 GNUTLS_LOG (2, max_log_level, "allocating anon credentials");
811 anon_cred = XPROCESS (proc)->gnutls_anon_cred;
812 fn_gnutls_anon_allocate_client_credentials (&anon_cred); 805 fn_gnutls_anon_allocate_client_credentials (&anon_cred);
813 } 806 XPROCESS (proc)->gnutls_anon_cred = anon_cred;
814 else
815 {
816 error ("unknown credential type");
817 ret = GNUTLS_EMACS_ERROR_INVALID_TYPE;
818 } 807 }
819 808
820 if (ret < GNUTLS_E_SUCCESS)
821 return gnutls_make_error (ret);
822
823 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_ALLOC; 809 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_ALLOC;
824 810
825 if (EQ (type, Qgnutls_x509pki)) 811 if (EQ (type, Qgnutls_x509pki))
826 { 812 {
813 /* TODO: GNUTLS_X509_FMT_DER is also an option. */
814 int file_format = GNUTLS_X509_FMT_PEM;
815 Lisp_Object tail;
816
827 for (tail = trustfiles; !NILP (tail); tail = Fcdr (tail)) 817 for (tail = trustfiles; !NILP (tail); tail = Fcdr (tail))
828 { 818 {
829 Lisp_Object trustfile = Fcar (tail); 819 Lisp_Object trustfile = Fcar (tail);
@@ -841,8 +831,8 @@ one trustfile (usually a CA bundle). */)
841 } 831 }
842 else 832 else
843 { 833 {
844 error ("Sorry, GnuTLS can't use non-string trustfile %s", 834 emacs_gnutls_deinit (proc);
845 SDATA (trustfile)); 835 error ("Invalid trustfile");
846 } 836 }
847 } 837 }
848 838
@@ -854,17 +844,15 @@ one trustfile (usually a CA bundle). */)
854 GNUTLS_LOG2 (1, max_log_level, "setting the CRL file: ", 844 GNUTLS_LOG2 (1, max_log_level, "setting the CRL file: ",
855 SSDATA (crlfile)); 845 SSDATA (crlfile));
856 ret = fn_gnutls_certificate_set_x509_crl_file 846 ret = fn_gnutls_certificate_set_x509_crl_file
857 (x509_cred, 847 (x509_cred, SSDATA (crlfile), file_format);
858 SSDATA (crlfile),
859 file_format);
860 848
861 if (ret < GNUTLS_E_SUCCESS) 849 if (ret < GNUTLS_E_SUCCESS)
862 return gnutls_make_error (ret); 850 return gnutls_make_error (ret);
863 } 851 }
864 else 852 else
865 { 853 {
866 error ("Sorry, GnuTLS can't use non-string CRL file %s", 854 emacs_gnutls_deinit (proc);
867 SDATA (crlfile)); 855 error ("Invalid CRL file");
868 } 856 }
869 } 857 }
870 858
@@ -879,45 +867,31 @@ one trustfile (usually a CA bundle). */)
879 GNUTLS_LOG2 (1, max_log_level, "setting the client cert file: ", 867 GNUTLS_LOG2 (1, max_log_level, "setting the client cert file: ",
880 SSDATA (certfile)); 868 SSDATA (certfile));
881 ret = fn_gnutls_certificate_set_x509_key_file 869 ret = fn_gnutls_certificate_set_x509_key_file
882 (x509_cred, 870 (x509_cred, SSDATA (certfile), SSDATA (keyfile), file_format);
883 SSDATA (certfile),
884 SSDATA (keyfile),
885 file_format);
886 871
887 if (ret < GNUTLS_E_SUCCESS) 872 if (ret < GNUTLS_E_SUCCESS)
888 return gnutls_make_error (ret); 873 return gnutls_make_error (ret);
889 } 874 }
890 else 875 else
891 { 876 {
892 if (STRINGP (keyfile)) 877 emacs_gnutls_deinit (proc);
893 error ("Sorry, GnuTLS can't use non-string client cert file %s", 878 error (STRINGP (keyfile) ? "Invalid client cert file"
894 SDATA (certfile)); 879 : "Invalid client key file");
895 else
896 error ("Sorry, GnuTLS can't use non-string client key file %s",
897 SDATA (keyfile));
898 } 880 }
899 } 881 }
900 } 882 }
901 883
902 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_FILES; 884 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_FILES;
903
904 GNUTLS_LOG (1, max_log_level, "gnutls callbacks"); 885 GNUTLS_LOG (1, max_log_level, "gnutls callbacks");
905
906 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CALLBACKS; 886 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CALLBACKS;
907 887
908#ifdef HAVE_GNUTLS_CALLBACK_CERTIFICATE_VERIFY 888 /* Call gnutls_init here: */
909#else
910#endif
911 889
912 GNUTLS_LOG (1, max_log_level, "gnutls_init"); 890 GNUTLS_LOG (1, max_log_level, "gnutls_init");
913
914 ret = fn_gnutls_init (&state, GNUTLS_CLIENT); 891 ret = fn_gnutls_init (&state, GNUTLS_CLIENT);
915 892 XPROCESS (proc)->gnutls_state = state;
916 if (ret < GNUTLS_E_SUCCESS) 893 if (ret < GNUTLS_E_SUCCESS)
917 return gnutls_make_error (ret); 894 return gnutls_make_error (ret);
918
919 XPROCESS (proc)->gnutls_state = state;
920
921 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT; 895 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT;
922 896
923 if (STRINGP (priority_string)) 897 if (STRINGP (priority_string))
@@ -933,46 +907,25 @@ one trustfile (usually a CA bundle). */)
933 } 907 }
934 908
935 GNUTLS_LOG (1, max_log_level, "setting the priority string"); 909 GNUTLS_LOG (1, max_log_level, "setting the priority string");
936
937 ret = fn_gnutls_priority_set_direct (state, 910 ret = fn_gnutls_priority_set_direct (state,
938 priority_string_ptr, 911 priority_string_ptr,
939 NULL); 912 NULL);
940
941 if (ret < GNUTLS_E_SUCCESS) 913 if (ret < GNUTLS_E_SUCCESS)
942 return gnutls_make_error (ret); 914 return gnutls_make_error (ret);
943 915
944 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_PRIORITY; 916 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_PRIORITY;
945 917
946 if (!EQ (prime_bits, Qnil)) 918 if (INTEGERP (prime_bits))
947 { 919 fn_gnutls_dh_set_prime_bits (state, XUINT (prime_bits));
948 fn_gnutls_dh_set_prime_bits (state, XUINT (prime_bits));
949 }
950
951 if (EQ (type, Qgnutls_x509pki))
952 {
953 ret = fn_gnutls_credentials_set (state, GNUTLS_CRD_CERTIFICATE, x509_cred);
954 }
955 else if (EQ (type, Qgnutls_anon))
956 {
957 ret = fn_gnutls_credentials_set (state, GNUTLS_CRD_ANON, anon_cred);
958 }
959 else
960 {
961 error ("unknown credential type");
962 ret = GNUTLS_EMACS_ERROR_INVALID_TYPE;
963 }
964 920
921 ret = EQ (type, Qgnutls_x509pki)
922 ? fn_gnutls_credentials_set (state, GNUTLS_CRD_CERTIFICATE, x509_cred)
923 : fn_gnutls_credentials_set (state, GNUTLS_CRD_ANON, anon_cred);
965 if (ret < GNUTLS_E_SUCCESS) 924 if (ret < GNUTLS_E_SUCCESS)
966 return gnutls_make_error (ret); 925 return gnutls_make_error (ret);
967 926
968 XPROCESS (proc)->gnutls_anon_cred = anon_cred;
969 XPROCESS (proc)->gnutls_x509_cred = x509_cred;
970 XPROCESS (proc)->gnutls_cred_type = type;
971
972 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_SET; 927 GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_SET;
973
974 ret = emacs_gnutls_handshake (XPROCESS (proc)); 928 ret = emacs_gnutls_handshake (XPROCESS (proc));
975
976 if (ret < GNUTLS_E_SUCCESS) 929 if (ret < GNUTLS_E_SUCCESS)
977 return gnutls_make_error (ret); 930 return gnutls_make_error (ret);
978 931
@@ -983,69 +936,71 @@ one trustfile (usually a CA bundle). */)
983 gnutls_x509_crt_check_hostname() against :hostname. */ 936 gnutls_x509_crt_check_hostname() against :hostname. */
984 937
985 ret = fn_gnutls_certificate_verify_peers2 (state, &peer_verification); 938 ret = fn_gnutls_certificate_verify_peers2 (state, &peer_verification);
986
987 if (ret < GNUTLS_E_SUCCESS) 939 if (ret < GNUTLS_E_SUCCESS)
988 return gnutls_make_error (ret); 940 return gnutls_make_error (ret);
989 941
990 if (XINT (loglevel) > 0 && peer_verification & GNUTLS_CERT_INVALID) 942 if (XINT (loglevel) > 0 && peer_verification & GNUTLS_CERT_INVALID)
991 message ("%s certificate could not be verified.", 943 message ("%s certificate could not be verified.", c_hostname);
992 c_hostname); 944
993 945 if (peer_verification & GNUTLS_CERT_REVOKED)
994 if (peer_verification & GNUTLS_CERT_REVOKED) 946 GNUTLS_LOG2 (1, max_log_level, "certificate was revoked (CRL):",
995 GNUTLS_LOG2 (1, max_log_level, "certificate was revoked (CRL):", 947 c_hostname);
996 c_hostname); 948
997 949 if (peer_verification & GNUTLS_CERT_SIGNER_NOT_FOUND)
998 if (peer_verification & GNUTLS_CERT_SIGNER_NOT_FOUND) 950 GNUTLS_LOG2 (1, max_log_level, "certificate signer was not found:",
999 GNUTLS_LOG2 (1, max_log_level, "certificate signer was not found:", 951 c_hostname);
1000 c_hostname); 952
1001 953 if (peer_verification & GNUTLS_CERT_SIGNER_NOT_CA)
1002 if (peer_verification & GNUTLS_CERT_SIGNER_NOT_CA) 954 GNUTLS_LOG2 (1, max_log_level, "certificate signer is not a CA:",
1003 GNUTLS_LOG2 (1, max_log_level, "certificate signer is not a CA:", 955 c_hostname);
1004 c_hostname); 956
1005 957 if (peer_verification & GNUTLS_CERT_INSECURE_ALGORITHM)
1006 if (peer_verification & GNUTLS_CERT_INSECURE_ALGORITHM) 958 GNUTLS_LOG2 (1, max_log_level,
1007 GNUTLS_LOG2 (1, max_log_level, 959 "certificate was signed with an insecure algorithm:",
1008 "certificate was signed with an insecure algorithm:", 960 c_hostname);
1009 c_hostname); 961
1010 962 if (peer_verification & GNUTLS_CERT_NOT_ACTIVATED)
1011 if (peer_verification & GNUTLS_CERT_NOT_ACTIVATED) 963 GNUTLS_LOG2 (1, max_log_level, "certificate is not yet activated:",
1012 GNUTLS_LOG2 (1, max_log_level, "certificate is not yet activated:", 964 c_hostname);
1013 c_hostname); 965
1014 966 if (peer_verification & GNUTLS_CERT_EXPIRED)
1015 if (peer_verification & GNUTLS_CERT_EXPIRED) 967 GNUTLS_LOG2 (1, max_log_level, "certificate has expired:",
1016 GNUTLS_LOG2 (1, max_log_level, "certificate has expired:", 968 c_hostname);
1017 c_hostname); 969
1018 970 if (peer_verification != 0)
1019 if (peer_verification != 0) 971 {
1020 { 972 if (NILP (verify_hostname_error))
1021 if (NILP (verify_hostname_error)) 973 GNUTLS_LOG2 (1, max_log_level, "certificate validation failed:",
1022 { 974 c_hostname);
1023 GNUTLS_LOG2 (1, max_log_level, "certificate validation failed:", 975 else
1024 c_hostname); 976 {
1025 } 977 emacs_gnutls_deinit (proc);
1026 else 978 error ("Certificate validation failed %s, verification code %d",
1027 { 979 c_hostname, peer_verification);
1028 error ("Certificate validation failed %s, verification code %d", 980 }
1029 c_hostname, peer_verification); 981 }
1030 }
1031 }
1032 982
1033 /* Up to here the process is the same for X.509 certificates and 983 /* Up to here the process is the same for X.509 certificates and
1034 OpenPGP keys. From now on X.509 certificates are assumed. This 984 OpenPGP keys. From now on X.509 certificates are assumed. This
1035 can be easily extended to work with openpgp keys as well. */ 985 can be easily extended to work with openpgp keys as well. */
1036 if (fn_gnutls_certificate_type_get (state) == GNUTLS_CRT_X509) 986 if (fn_gnutls_certificate_type_get (state) == GNUTLS_CRT_X509)
1037 { 987 {
1038 ret = fn_gnutls_x509_crt_init (&gnutls_verify_cert); 988 gnutls_x509_crt_t gnutls_verify_cert;
989 const gnutls_datum_t *gnutls_verify_cert_list;
990 unsigned int gnutls_verify_cert_list_size;
1039 991
992 ret = fn_gnutls_x509_crt_init (&gnutls_verify_cert);
1040 if (ret < GNUTLS_E_SUCCESS) 993 if (ret < GNUTLS_E_SUCCESS)
1041 return gnutls_make_error (ret); 994 return gnutls_make_error (ret);
1042 995
1043 gnutls_verify_cert_list = 996 gnutls_verify_cert_list =
1044 fn_gnutls_certificate_get_peers (state, &gnutls_verify_cert_list_size); 997 fn_gnutls_certificate_get_peers (state, &gnutls_verify_cert_list_size);
1045 998
1046 if (NULL == gnutls_verify_cert_list) 999 if (gnutls_verify_cert_list == NULL)
1047 { 1000 {
1048 error ("No x509 certificate was found!\n"); 1001 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
1002 emacs_gnutls_deinit (proc);
1003 error ("No x509 certificate was found\n");
1049 } 1004 }
1050 1005
1051 /* We only check the first certificate in the given chain. */ 1006 /* We only check the first certificate in the given chain. */
@@ -1062,18 +1017,15 @@ one trustfile (usually a CA bundle). */)
1062 if (!fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname)) 1017 if (!fn_gnutls_x509_crt_check_hostname (gnutls_verify_cert, c_hostname))
1063 { 1018 {
1064 if (NILP (verify_hostname_error)) 1019 if (NILP (verify_hostname_error))
1065 { 1020 GNUTLS_LOG2 (1, max_log_level, "x509 certificate does not match:",
1066 GNUTLS_LOG2 (1, max_log_level, "x509 certificate does not match:", 1021 c_hostname);
1067 c_hostname);
1068 }
1069 else 1022 else
1070 { 1023 {
1071 fn_gnutls_x509_crt_deinit (gnutls_verify_cert); 1024 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
1072 error ("The x509 certificate does not match \"%s\"", 1025 emacs_gnutls_deinit (proc);
1073 c_hostname); 1026 error ("The x509 certificate does not match \"%s\"", c_hostname);
1074 } 1027 }
1075 } 1028 }
1076
1077 fn_gnutls_x509_crt_deinit (gnutls_verify_cert); 1029 fn_gnutls_x509_crt_deinit (gnutls_verify_cert);
1078 } 1030 }
1079 1031
diff --git a/src/gnutls.h b/src/gnutls.h
index 5ec6fb76c01..076e9fdba9c 100644
--- a/src/gnutls.h
+++ b/src/gnutls.h
@@ -49,9 +49,9 @@ typedef enum
49 49
50#define GNUTLS_PROCESS_USABLE(proc) (GNUTLS_INITSTAGE(proc) >= GNUTLS_STAGE_READY) 50#define GNUTLS_PROCESS_USABLE(proc) (GNUTLS_INITSTAGE(proc) >= GNUTLS_STAGE_READY)
51 51
52#define GNUTLS_LOG(level, max, string) if (level <= max) { gnutls_log_function (level, "(Emacs) " string); } 52#define GNUTLS_LOG(level, max, string) do { if (level <= max) { gnutls_log_function (level, "(Emacs) " string); } } while (0)
53 53
54#define GNUTLS_LOG2(level, max, string, extra) if (level <= max) { gnutls_log_function2 (level, "(Emacs) " string, extra); } 54#define GNUTLS_LOG2(level, max, string, extra) do { if (level <= max) { gnutls_log_function2 (level, "(Emacs) " string, extra); } } while (0)
55 55
56extern EMACS_INT 56extern EMACS_INT
57emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, EMACS_INT nbyte); 57emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, EMACS_INT nbyte);
diff --git a/src/process.c b/src/process.c
index 3daa55b259e..dc37ec5f961 100644
--- a/src/process.c
+++ b/src/process.c
@@ -642,6 +642,7 @@ make_process (Lisp_Object name)
642 p->gnutls_initstage = GNUTLS_STAGE_EMPTY; 642 p->gnutls_initstage = GNUTLS_STAGE_EMPTY;
643 p->gnutls_log_level = 0; 643 p->gnutls_log_level = 0;
644 p->gnutls_p = 0; 644 p->gnutls_p = 0;
645 p->gnutls_state = NULL;
645 p->gnutls_x509_cred = NULL; 646 p->gnutls_x509_cred = NULL;
646 p->gnutls_anon_cred = NULL; 647 p->gnutls_anon_cred = NULL;
647#endif 648#endif