aboutsummaryrefslogtreecommitdiff
path: root/src/namestore/plugin_gtk_namestore_tlsa.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-03-10 21:32:05 +0100
committerChristian Grothoff <christian@grothoff.org>2018-03-10 21:32:05 +0100
commiteac1312f563a3db362e189c8b2c915d666110dca (patch)
tree7097bc7fc3a91a1cfa497efbd8c40e611943e87e /src/namestore/plugin_gtk_namestore_tlsa.c
parentd439a97be0eaf8bc005f2ce60d744e62d3920a93 (diff)
downloadgnunet-gtk-eac1312f563a3db362e189c8b2c915d666110dca.tar.gz
gnunet-gtk-eac1312f563a3db362e189c8b2c915d666110dca.zip
be precise about which cert from the chain to use for TLSA record
Diffstat (limited to 'src/namestore/plugin_gtk_namestore_tlsa.c')
-rw-r--r--src/namestore/plugin_gtk_namestore_tlsa.c157
1 files changed, 113 insertions, 44 deletions
diff --git a/src/namestore/plugin_gtk_namestore_tlsa.c b/src/namestore/plugin_gtk_namestore_tlsa.c
index 2a8ba21a..1fc970e4 100644
--- a/src/namestore/plugin_gtk_namestore_tlsa.c
+++ b/src/namestore/plugin_gtk_namestore_tlsa.c
@@ -567,20 +567,55 @@ tlsa_validate (void *cls,
567 567
568 568
569/** 569/**
570 * Context for TLS certificate import from network.
571 */
572struct ImportContext
573{
574
575 /**
576 * Network handle for the session.
577 */
578 struct GNUNET_NETWORK_Handle *sock;
579
580 /**
581 * DNS resolution request to resolve the domain name.
582 */
583 struct GNUNET_RESOLVER_RequestHandle *rh;
584
585 /**
586 * Builder for accessing widgets.
587 */
588 GtkBuilder *builder;
589
590 /**
591 * Domain name of the site we use to get the TLS cert record from.
592 */
593 char *name;
594
595 /**
596 * We succeeded with our TLS handshake, ignore further DNS replies.
597 */
598 int done;
599};
600
601
602/**
570 * We have successfully established a TLS session to 603 * We have successfully established a TLS session to
571 * import a certificate from the server. Import the 604 * import a certificate from the server. Import the
572 * X509 certificate into the GUI. 605 * X509 certificate into the GUI.
573 * 606 *
574 * @param session TLS session to import from 607 * @param session TLS session to import from
575 * @param builder GTK builder to update GUI 608 * @param ic the import context
576 */ 609 */
577static void 610static void
578import_x509_certificate (gnutls_session_t session, 611import_x509_certificate (gnutls_session_t session,
579 GtkBuilder *builder) 612 struct ImportContext *ic)
580{ 613{
614 GtkBuilder *builder = ic->builder;
581 const gnutls_datum_t *cert_list; 615 const gnutls_datum_t *cert_list;
582 unsigned int cert_list_size = 0; 616 unsigned int cert_list_size = 0;
583 gnutls_x509_crt_t cert; 617 gnutls_x509_crt_t cert;
618 unsigned int usage;
584 unsigned int matching_type; 619 unsigned int matching_type;
585 unsigned int selector; 620 unsigned int selector;
586 gnutls_pubkey_t pk; 621 gnutls_pubkey_t pk;
@@ -592,6 +627,7 @@ import_x509_certificate (gnutls_session_t session,
592 uint8_t sha512[512/8]; 627 uint8_t sha512[512/8];
593 size_t ssize; 628 size_t ssize;
594 GtkTextBuffer *tb; 629 GtkTextBuffer *tb;
630 unsigned int i;
595 631
596 cert_list = gnutls_certificate_get_peers (session, 632 cert_list = gnutls_certificate_get_peers (session,
597 &cert_list_size); 633 &cert_list_size);
@@ -602,17 +638,82 @@ import_x509_certificate (gnutls_session_t session,
602 GNUNET_break (0); 638 GNUNET_break (0);
603 return; 639 return;
604 } 640 }
605 /* we only import the first certificate. */ 641
606 gnutls_x509_crt_init (&cert); 642 usage = get_selected_radio_value (builder,
607 if (GNUTLS_E_SUCCESS != 643 usage_buttons);
608 gnutls_x509_crt_import (cert, 644 /* Find out which certificate we care about based on usage */
609 &cert_list[0], 645 for (i=0;i<cert_list_size;i++)
610 GNUTLS_X509_FMT_DER))
611 { 646 {
612 GNUNET_break (0); 647 char san[256];
648 size_t san_size = sizeof (san);
649 unsigned int critical;
650 int matches_dn;
651 gnutls_x509_dn_t dn;
652 gnutls_datum_t str;
653
654 gnutls_x509_crt_init (&cert);
655 if (GNUTLS_E_SUCCESS !=
656 gnutls_x509_crt_import (cert,
657 &cert_list[i],
658 GNUTLS_X509_FMT_DER))
659 {
660 GNUNET_break (0);
661 gnutls_x509_crt_deinit (cert);
662 return;
663 }
664 if (1 == usage)
665 break; /* RFC 6394: first certificate (i==0) is to be pinned */
666 matches_dn = GNUNET_NO;
667 if ( (0 == gnutls_x509_crt_get_subject (cert,
668 &dn)) &&
669 (0 == gnutls_x509_dn_get_str (dn,
670 &str)) )
671 {
672 const char *cn;
673
674 cn = memmem (str.data,
675 str.size,
676 ",CN=",
677 4);
678 if ( (NULL != cn) &&
679 ( ('\0' == cn[4 + strlen (ic->name)]) ||
680 (',' == cn[4 + strlen (ic->name)]) ) &&
681 (0 == strncasecmp (cn + 4,
682 ic->name,
683 strlen (ic->name))) )
684 matches_dn = GNUNET_YES;
685 }
686 for (unsigned int seq=0;
687 GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE != gnutls_x509_crt_get_subject_alt_name (cert,
688 seq,
689 san,
690 &san_size,
691 &critical);
692 seq++)
693 {
694 if (0 == strcasecmp (san,
695 ic->name))
696 {
697 matches_dn = GNUNET_YES;
698 break;
699 }
700 }
701 /* usage = 3: we want to match DN, otherwise we do NOT want to
702 match DN */
703 if ( (GNUNET_NO == matches_dn) ^ /* XOR */
704 (3 == usage) /* Domain issued certificate */ )
705 break;
613 gnutls_x509_crt_deinit (cert); 706 gnutls_x509_crt_deinit (cert);
707 }
708 if (i == cert_list_size)
709 {
710 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
711 "None of the %u certificates matches the usage %u\n",
712 cert_list_size,
713 usage);
614 return; 714 return;
615 } 715 }
716
616 selector = get_selected_radio_value (builder, 717 selector = get_selected_radio_value (builder,
617 selector_buttons); 718 selector_buttons);
618 switch (selector) 719 switch (selector)
@@ -720,39 +821,6 @@ import_x509_certificate (gnutls_session_t session,
720 821
721 822
722/** 823/**
723 * Context for TLS certificate import from network.
724 */
725struct ImportContext
726{
727
728 /**
729 * Network handle for the session.
730 */
731 struct GNUNET_NETWORK_Handle *sock;
732
733 /**
734 * DNS resolution request to resolve the domain name.
735 */
736 struct GNUNET_RESOLVER_RequestHandle *rh;
737
738 /**
739 * Builder for accessing widgets.
740 */
741 GtkBuilder *builder;
742
743 /**
744 * Domain name of the site we use to get the TLS cert record from.
745 */
746 char *name;
747
748 /**
749 * We succeeded with our TLS handshake, ignore further DNS replies.
750 */
751 int done;
752};
753
754
755/**
756 * We got an address from DNS, start TLS handshake. 824 * We got an address from DNS, start TLS handshake.
757 * 825 *
758 * @param cls our `struct ImportContext` 826 * @param cls our `struct ImportContext`
@@ -837,7 +905,8 @@ import_address_cb (void *cls,
837 905
838 /* initialize TLS session */ 906 /* initialize TLS session */
839 gnutls_init (&session, GNUTLS_CLIENT); 907 gnutls_init (&session, GNUTLS_CLIENT);
840 gnutls_session_set_ptr (session, ic); 908 gnutls_session_set_ptr (session,
909 ic);
841 gnutls_server_name_set (session, 910 gnutls_server_name_set (session,
842 GNUTLS_NAME_DNS, 911 GNUTLS_NAME_DNS,
843 ic->name, 912 ic->name,
@@ -886,7 +955,7 @@ import_address_cb (void *cls,
886 break; 955 break;
887 case GNUTLS_CRT_X509: 956 case GNUTLS_CRT_X509:
888 import_x509_certificate (session, 957 import_x509_certificate (session,
889 ic->builder); 958 ic);
890 break; 959 break;
891 case GNUTLS_CRT_OPENPGP: 960 case GNUTLS_CRT_OPENPGP:
892 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 961 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,