aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac16
-rw-r--r--src/gns/Makefile.am3
-rw-r--r--src/gns/gnunet-gns-proxy.c121
3 files changed, 122 insertions, 18 deletions
diff --git a/configure.ac b/configure.ac
index c68978d20..374f00cab 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1032,7 +1032,14 @@ AC_ARG_WITH(gnutls,
1032 AC_CHECK_LIB([gnutls], [gnutls_priority_set], 1032 AC_CHECK_LIB([gnutls], [gnutls_priority_set],
1033 gnutls=true))]) 1033 gnutls=true))])
1034AM_CONDITIONAL(HAVE_GNUTLS, test x$gnutls = xtrue) 1034AM_CONDITIONAL(HAVE_GNUTLS, test x$gnutls = xtrue)
1035AC_DEFINE_UNQUOTED([HAVE_GNUTLS], $gnutls, [We have gnutls]) 1035AC_DEFINE_UNQUOTED([HAVE_GNUTLS], $gnutls, [We have GnuTLS])
1036
1037gnutls_dane=0
1038AC_CHECK_HEADERS([gnutls/dane.h],
1039 AC_CHECK_LIB([gnutls-dane], [dane_verify_crt_raw],
1040 gnutls_dane=true))
1041AM_CONDITIONAL(HAVE_GNUTLS_DANE, test x$gnutls_dane = xtrue)
1042AC_DEFINE_UNQUOTED([HAVE_GNUTLS_DANE], $gnutls_dane, [We have GnuTLS with DANE support])
1036 1043
1037 1044
1038# Test if we are building for superMUC 1045# Test if we are building for superMUC
@@ -1470,7 +1477,12 @@ fi
1470#gnutls 1477#gnutls
1471if test x$gnutls != xtrue 1478if test x$gnutls != xtrue
1472then 1479then
1473 AC_MSG_NOTICE([NOTICE: gnutls not found, gnunet-gns-proxy will not be built]) 1480 AC_MSG_NOTICE([NOTICE: GnuTLS not found, gnunet-gns-proxy will not be built])
1481else
1482if test x$gnutls_dane != xtrue
1483then
1484 AC_MSG_NOTICE([NOTICE: GnuTLS has no DANE support, DANE validation will not be possible])
1485fi
1474fi 1486fi
1475 1487
1476# java ports 1488# java ports
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am
index f36af6e64..d97a4b48c 100644
--- a/src/gns/Makefile.am
+++ b/src/gns/Makefile.am
@@ -124,6 +124,9 @@ gnunet_gns_proxy_LDADD = -lmicrohttpd -lcurl -lgnutls \
124 $(top_builddir)/src/identity/libgnunetidentity.la \ 124 $(top_builddir)/src/identity/libgnunetidentity.la \
125 $(top_builddir)/src/util/libgnunetutil.la \ 125 $(top_builddir)/src/util/libgnunetutil.la \
126 $(GN_LIBINTL) 126 $(GN_LIBINTL)
127if HAVE_GNUTLS_DANE
128gnunet_gns_proxy_LDADD += -lgnutls-dane
129endif
127gnunet_gns_proxy_DEPENDENCIES = \ 130gnunet_gns_proxy_DEPENDENCIES = \
128 $(top_builddir)/src/identity/libgnunetidentity.la \ 131 $(top_builddir)/src/identity/libgnunetidentity.la \
129 $(top_builddir)/src/util/libgnunetutil.la \ 132 $(top_builddir)/src/util/libgnunetutil.la \
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c
index 4452e5e67..968470bd9 100644
--- a/src/gns/gnunet-gns-proxy.c
+++ b/src/gns/gnunet-gns-proxy.c
@@ -35,6 +35,9 @@
35#include <gnutls/x509.h> 35#include <gnutls/x509.h>
36#include <gnutls/abstract.h> 36#include <gnutls/abstract.h>
37#include <gnutls/crypto.h> 37#include <gnutls/crypto.h>
38#if HAVE_GNUTLS_DANE
39#include <gnutls/dane.h>
40#endif
38#include <regex.h> 41#include <regex.h>
39#include "gnunet_util_lib.h" 42#include "gnunet_util_lib.h"
40#include "gnunet_gns_service.h" 43#include "gnunet_gns_service.h"
@@ -502,6 +505,11 @@ struct Socks5Request
502 char *leho; 505 char *leho;
503 506
504 /** 507 /**
508 * Payload of the (last) DANE record encountered.
509 */
510 char *dane_data;
511
512 /**
505 * The URL to fetch 513 * The URL to fetch
506 */ 514 */
507 char *url; 515 char *url;
@@ -522,6 +530,11 @@ struct Socks5Request
522 unsigned int response_code; 530 unsigned int response_code;
523 531
524 /** 532 /**
533 * Number of bytes in @e dane_data.
534 */
535 size_t dane_data_len;
536
537 /**
525 * Number of bytes already in read buffer 538 * Number of bytes already in read buffer
526 */ 539 */
527 size_t rbuf_len; 540 size_t rbuf_len;
@@ -725,6 +738,7 @@ cleanup_s5r (struct Socks5Request *s5r)
725 GNUNET_free_non_null (s5r->domain); 738 GNUNET_free_non_null (s5r->domain);
726 GNUNET_free_non_null (s5r->leho); 739 GNUNET_free_non_null (s5r->leho);
727 GNUNET_free_non_null (s5r->url); 740 GNUNET_free_non_null (s5r->url);
741 GNUNET_free_non_null (s5r->dane_data);
728 GNUNET_free (s5r); 742 GNUNET_free (s5r);
729} 743}
730 744
@@ -809,7 +823,7 @@ check_ssl_certificate (struct Socks5Request *s5r)
809 } gptr; 823 } gptr;
810 char certdn[GNUNET_DNSPARSER_MAX_NAME_LENGTH + 3]; 824 char certdn[GNUNET_DNSPARSER_MAX_NAME_LENGTH + 3];
811 size_t size; 825 size_t size;
812 gnutls_x509_crt x509_cert; 826 gnutls_x509_crt_t x509_cert;
813 int rc; 827 int rc;
814 const char *name; 828 const char *name;
815 829
@@ -846,34 +860,101 @@ check_ssl_certificate (struct Socks5Request *s5r)
846 &size))) 860 &size)))
847 { 861 {
848 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 862 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
849 "Failed to fetch CN from cert: %s\n", 863 _("Failed to fetch CN from cert: %s\n"),
850 gnutls_strerror(rc)); 864 gnutls_strerror(rc));
851 gnutls_x509_crt_deinit (x509_cert); 865 gnutls_x509_crt_deinit (x509_cert);
852 return GNUNET_SYSERR; 866 return GNUNET_SYSERR;
853 } 867 }
854 /* FIXME: here we should check for TLSA/DANE records */ 868 /* check for TLSA/DANE records */
855 869#if HAVE_GNUTLS_DANE
856 name = s5r->domain; 870 if (NULL != s5r->dane_data)
857 if (NULL != s5r->leho)
858 name = s5r->leho;
859 if (NULL != name)
860 { 871 {
861 if (0 == (rc = gnutls_x509_crt_check_hostname (x509_cert, 872 char *dd[] = { s5r->dane_data, NULL };
862 name))) 873 int dlen[] = { s5r->dane_data_len, 0};
874 dane_state_t dane_state;
875 dane_query_t dane_query;
876 unsigned int verify;
877
878 /* FIXME: add flags to gnutls to NOT read UNBOUND_ROOT_KEY_FILE here! */
879 if (0 != (rc = dane_state_init (&dane_state,
880 DANE_F_IGNORE_LOCAL_RESOLVER)))
881 {
882 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
883 _("Failed to initialize DANE: %s\n"),
884 dane_strerror(rc));
885 gnutls_x509_crt_deinit (x509_cert);
886 return GNUNET_SYSERR;
887 }
888 if (0 != (rc = dane_raw_tlsa (dane_state,
889 &dane_query,
890 dd,
891 dlen,
892 GNUNET_YES,
893 GNUNET_NO)))
894 {
895 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
896 _("Failed to parse DANE record: %s\n"),
897 dane_strerror(rc));
898 dane_state_deinit (dane_state);
899 gnutls_x509_crt_deinit (x509_cert);
900 return GNUNET_SYSERR;
901 }
902 if (0 != (rc = dane_verify_crt_raw (dane_state,
903 chainp,
904 cert_list_size,
905 gnutls_certificate_type_get (tlsinfo.internals),
906 dane_query,
907 0, 0,
908 &verify)))
863 { 909 {
864 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 910 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
865 _("SSL certificate subject name (%s) does not match `%s'\n"), 911 _("Failed to verify TLS connection using DANE: %s\n"),
866 certdn, 912 dane_strerror(rc));
867 name); 913 dane_query_deinit (dane_query);
914 dane_state_deinit (dane_state);
868 gnutls_x509_crt_deinit (x509_cert); 915 gnutls_x509_crt_deinit (x509_cert);
869 return GNUNET_SYSERR; 916 return GNUNET_SYSERR;
870 } 917 }
918 if (0 != verify)
919 {
920 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
921 _("Failed DANE verification failed with GnuTLS verify status code: %u\n"),
922 verify);
923 dane_query_deinit (dane_query);
924 dane_state_deinit (dane_state);
925 gnutls_x509_crt_deinit (x509_cert);
926 return GNUNET_SYSERR;
927 }
928 dane_query_deinit (dane_query);
929 dane_state_deinit (dane_state);
930 /* success! */
871 } 931 }
872 else 932 else
933#endif
873 { 934 {
874 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 935 /* try LEHO or ordinary domain name X509 verification */
875 _("No LEHO or domain name available and TLSA/DANE is not yet implemented!\n")); 936 name = s5r->domain;
876 return GNUNET_SYSERR; 937 if (NULL != s5r->leho)
938 name = s5r->leho;
939 if (NULL != name)
940 {
941 if (0 == (rc = gnutls_x509_crt_check_hostname (x509_cert,
942 name)))
943 {
944 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
945 _("SSL certificate subject name (%s) does not match `%s'\n"),
946 certdn,
947 name);
948 gnutls_x509_crt_deinit (x509_cert);
949 return GNUNET_SYSERR;
950 }
951 }
952 else
953 {
954 /* we did not even have the domain name!? */
955 GNUNET_break (0);
956 return GNUNET_SYSERR;
957 }
877 } 958 }
878 gnutls_x509_crt_deinit (x509_cert); 959 gnutls_x509_crt_deinit (x509_cert);
879#if 0 960#if 0
@@ -2355,6 +2436,14 @@ handle_gns_result (void *cls,
2355 s5r->leho = GNUNET_strndup (r->data, 2436 s5r->leho = GNUNET_strndup (r->data,
2356 r->data_size); 2437 r->data_size);
2357 break; 2438 break;
2439 case GNUNET_DNSPARSER_TYPE_TLSA:
2440 GNUNET_free_non_null (s5r->dane_data);
2441 s5r->dane_data_len = r->data_size;
2442 s5r->dane_data = GNUNET_malloc (r->data_size);
2443 memcpy (s5r->dane_data,
2444 r->data,
2445 r->data_size);
2446 break;
2358 default: 2447 default:
2359 /* don't care */ 2448 /* don't care */
2360 break; 2449 break;