]> git.ipfire.org Git - people/ms/strongswan.git/commitdiff
charon-tkm: Reverse cert chain processing order
authorAdrian-Ken Rueegsegger <ken@codelabs.ch>
Thu, 22 Oct 2020 17:11:32 +0000 (19:11 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 8 Jan 2021 16:22:36 +0000 (17:22 +0100)
Verify certificate chains starting from the root CA certificate and
moving towards the leaf/user certificate.

Also update TKM-RPC and TKM in testing scripts to version supporting the
reworked CC handling.

src/charon-tkm/src/tkm/tkm_listener.c
testing/scripts/recipes/006_tkm-rpc.mk
testing/scripts/recipes/010_tkm.mk
testing/tests/tkm/host2host-initiator/evaltest.dat
testing/tests/tkm/host2host-responder/evaltest.dat
testing/tests/tkm/host2host-xfrmproxy/evaltest.dat
testing/tests/tkm/multiple-clients/evaltest.dat
testing/tests/tkm/net2net-initiator/evaltest.dat
testing/tests/tkm/net2net-xfrmproxy/evaltest.dat
testing/tests/tkm/xfrmproxy-expire/evaltest.dat
testing/tests/tkm/xfrmproxy-rekey/evaltest.dat

index 9e39308f82baf56c2f71cac62ad23f6c711c5aea..18e3a54d8f427cd7df1a795ae1ef2196fa658589 100644 (file)
@@ -18,6 +18,7 @@
 #include <inttypes.h>
 
 #include <daemon.h>
+#include <collections/array.h>
 #include <collections/hashtable.h>
 #include <encoding/payloads/auth_payload.h>
 #include <utils/chunk.h>
@@ -94,125 +95,132 @@ static bool build_cert_chain(const ike_sa_t * const ike_sa, cc_id_type cc_id)
        rounds = ike_sa->create_auth_cfg_enumerator((ike_sa_t *)ike_sa, FALSE);
        while (rounds->enumerate(rounds, &auth))
        {
-               cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+               cert = auth->get(auth, AUTH_RULE_CA_CERT);
                if (cert)
                {
-                       chunk_t enc_user_cert;
-                       ri_id_type ri_id;
-                       certificate_type user_cert;
                        auth_rule_t rule;
                        enumerator_t *enumerator;
+                       ca_id_type ca_id;
+                       public_key_t *pubkey;
+                       certificate_type ca_cert;
+                       chunk_t enc_ca_cert, fp;
+                       array_t *im_certs = NULL;
+                       uint64_t *raw_id;
+
+                       pubkey = cert->get_public_key(cert);
+                       if (!pubkey)
+                       {
+                               DBG1(DBG_IKE, "unable to get CA certificate pubkey");
+                               rounds->destroy(rounds);
+                               return FALSE;
+                       }
+                       if (!pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp))
+                       {
+                               DBG1(DBG_IKE, "unable to extract CA certificate fingerprint");
+                               rounds->destroy(rounds);
+                               pubkey->destroy(pubkey);
+                               return FALSE;
+                       }
+                       pubkey->destroy(pubkey);
+
+                       raw_id = ca_map->get(ca_map, &fp);
+                       if (!raw_id || *raw_id == 0)
+                       {
+                               DBG1(DBG_IKE, "error mapping CA certificate (fp: %#B) to "
+                                        "ID", &fp);
+                               rounds->destroy(rounds);
+                               return FALSE;
+                       }
+                       ca_id = *raw_id;
 
-                       /* set user certificate */
-                       if (!cert->get_encoding(cert, CERT_ASN1_DER, &enc_user_cert))
+                       if (!cert->get_encoding(cert, CERT_ASN1_DER, &enc_ca_cert))
                        {
-                               DBG1(DBG_IKE, "unable to extract encoded user certificate");
+                               DBG1(DBG_IKE, "unable to extract encoded CA certificate");
                                rounds->destroy(rounds);
                                return FALSE;
                        }
 
-                       ri_id = get_remote_identity_id(ike_sa->get_peer_cfg((ike_sa_t *)ike_sa));
-                       chunk_to_sequence(&enc_user_cert, &user_cert, sizeof(certificate_type));
-                       chunk_free(&enc_user_cert);
-                       if (ike_cc_set_user_certificate(cc_id, ri_id, 1, user_cert) != TKM_OK)
+                       chunk_to_sequence(&enc_ca_cert, &ca_cert,
+                                                         sizeof(certificate_type));
+                       chunk_free(&enc_ca_cert);
+
+                       if (ike_cc_check_ca(cc_id, ca_id, ca_cert) != TKM_OK)
                        {
-                               DBG1(DBG_IKE, "error setting user certificate of cert chain"
-                                        " (cc_id: %llu)", cc_id);
+                               DBG1(DBG_IKE, "CA certificate (fp: %#B, cc_id: %llu) does not"
+                                        " match trusted CA (ca_id: %llu)", &fp, cc_id, ca_id);
                                rounds->destroy(rounds);
                                return FALSE;
                        }
 
-                       /* process intermediate CA certificates */
+                       /* process intermediate CA certificates in reverse order */
                        enumerator = auth->create_enumerator(auth);
                        while (enumerator->enumerate(enumerator, &rule, &cert))
                        {
                                if (rule == AUTH_RULE_IM_CERT)
                                {
-                                       chunk_t enc_im_cert;
-                                       certificate_type im_cert;
-
-                                       if (!cert->get_encoding(cert, CERT_ASN1_DER, &enc_im_cert))
-                                       {
-                                               DBG1(DBG_IKE, "unable to extract encoded intermediate CA"
-                                                        " certificate");
-                                               rounds->destroy(rounds);
-                                               enumerator->destroy(enumerator);
-                                               return FALSE;
-                                       }
-
-                                       chunk_to_sequence(&enc_im_cert, &im_cert,
-                                                                         sizeof(certificate_type));
-                                       chunk_free(&enc_im_cert);
-                                       if (ike_cc_add_certificate(cc_id, 1, im_cert) != TKM_OK)
-                                       {
-                                               DBG1(DBG_IKE, "error adding intermediate certificate to"
-                                                        " cert chain (cc_id: %llu)", cc_id);
-                                               rounds->destroy(rounds);
-                                               enumerator->destroy(enumerator);
-                                               return FALSE;
-                                       }
+                                       array_insert_create(&im_certs, ARRAY_TAIL, cert);
                                }
                        }
                        enumerator->destroy(enumerator);
 
-                       /* finally add CA certificate */
-                       cert = auth->get(auth, AUTH_RULE_CA_CERT);
-                       if (cert)
+                       while (array_remove(im_certs, ARRAY_TAIL, &cert))
                        {
-                               ca_id_type ca_id;
-                               public_key_t *pubkey;
-                               certificate_type ca_cert;
-                               chunk_t enc_ca_cert, fp;
-                               uint64_t *raw_id;
-
-                               pubkey = cert->get_public_key(cert);
-                               if (!pubkey)
-                               {
-                                       DBG1(DBG_IKE, "unable to get CA certificate pubkey");
-                                       rounds->destroy(rounds);
-                                       return FALSE;
-                               }
-                               if (!pubkey->get_fingerprint(pubkey, KEYID_PUBKEY_SHA1, &fp))
+                               chunk_t enc_im_cert;
+                               certificate_type im_cert;
+
+                               if (!cert->get_encoding(cert, CERT_ASN1_DER, &enc_im_cert))
                                {
-                                       DBG1(DBG_IKE, "unable to extract CA certificate fingerprint");
+                                       DBG1(DBG_IKE, "unable to extract encoded intermediate CA"
+                                                " certificate");
                                        rounds->destroy(rounds);
-                                       pubkey->destroy(pubkey);
+                                       array_destroy(im_certs);
                                        return FALSE;
                                }
-                               pubkey->destroy(pubkey);
 
-                               raw_id = ca_map->get(ca_map, &fp);
-                               if (!raw_id || *raw_id == 0)
+                               chunk_to_sequence(&enc_im_cert, &im_cert,
+                                                                 sizeof(certificate_type));
+                               chunk_free(&enc_im_cert);
+                               if (ike_cc_add_certificate(cc_id, 1, im_cert) != TKM_OK)
                                {
-                                       DBG1(DBG_IKE, "error mapping CA certificate (fp: %#B) to "
-                                                "ID", &fp);
+                                       DBG1(DBG_IKE, "error adding intermediate certificate to"
+                                                " cert chain (cc_id: %llu)", cc_id);
                                        rounds->destroy(rounds);
+                                       array_destroy(im_certs);
                                        return FALSE;
                                }
-                               ca_id = *raw_id;
+                       }
+                       array_destroy(im_certs);
 
-                               if (!cert->get_encoding(cert, CERT_ASN1_DER, &enc_ca_cert))
+                       /* finally add user certificate and check chain */
+                       cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+                       if (cert)
+                       {
+                               chunk_t enc_user_cert;
+                               ri_id_type ri_id;
+                               certificate_type user_cert;
+
+                               /* set user certificate */
+                               if (!cert->get_encoding(cert, CERT_ASN1_DER, &enc_user_cert))
                                {
-                                       DBG1(DBG_IKE, "unable to extract encoded CA certificate");
+                                       DBG1(DBG_IKE, "unable to extract encoded user certificate");
                                        rounds->destroy(rounds);
                                        return FALSE;
                                }
 
-                               chunk_to_sequence(&enc_ca_cert, &ca_cert,
-                                                                 sizeof(certificate_type));
-                               chunk_free(&enc_ca_cert);
-                               if (ike_cc_add_certificate(cc_id, 1, ca_cert) != TKM_OK)
+                               chunk_to_sequence(&enc_user_cert, &user_cert, sizeof(certificate_type));
+                               chunk_free(&enc_user_cert);
+                               if (ike_cc_add_certificate(cc_id, 1, user_cert) != TKM_OK)
                                {
-                                       DBG1(DBG_IKE, "error adding CA certificate to cert chain "
-                                                "(cc_id: %llu)", cc_id);
+                                       DBG1(DBG_IKE, "error adding user certificate to cert chain"
+                                                " (cc_id: %llu)", cc_id);
                                        rounds->destroy(rounds);
                                        return FALSE;
                                }
 
-                               if (ike_cc_check_ca(cc_id, ca_id) != TKM_OK)
+                               ri_id = get_remote_identity_id(ike_sa->get_peer_cfg((ike_sa_t *)ike_sa));
+                               if (ike_cc_check_chain(cc_id, ri_id) != TKM_OK)
                                {
-                                       DBG1(DBG_IKE, "certificate chain (cc_id: %llu) not based on"
-                                                " trusted CA (ca_id: %llu)", cc_id, ca_id);
+                                       DBG1(DBG_IKE, "error checking cert chain (cc_id: %llu)", cc_id);
                                        rounds->destroy(rounds);
                                        return FALSE;
                                }
@@ -222,12 +230,12 @@ static bool build_cert_chain(const ike_sa_t * const ike_sa, cc_id_type cc_id)
                        }
                        else
                        {
-                               DBG1(DBG_IKE, "no CA certificate");
+                               DBG1(DBG_IKE, "no subject certificate for remote peer");
                        }
                }
                else
                {
-                       DBG1(DBG_IKE, "no subject certificate for remote peer");
+                       DBG1(DBG_IKE, "no CA certificate");
                }
        }
 
index 428ac2d1423a7a7678e953078de0c63399d313fa..a5db052e90d852a6133d3fa1f24ad1e9c8e1dd50 100644 (file)
@@ -2,7 +2,7 @@
 
 PKG = tkm-rpc
 SRC = https://git.codelabs.ch/git/$(PKG).git
-REV = 4d6cd3f5e6a8f0d33f56289ad3a07645f10edc91
+REV = 1f4e1c9c6ec473cdb391b5416f38d48b09cb6004
 
 PREFIX = /usr/local/ada
 
index 4d8af638a0a16859077f5d83b7c7f612b6ff776e..7918485d460dda52dccfa5d9f9f27be8d6870163 100644 (file)
@@ -2,7 +2,7 @@
 
 PKG = tkm
 SRC = https://git.codelabs.ch/git/$(PKG).git
-REV = 5320ec82f2221d9c4d5be106f6b90287bfb4acce
+REV = 8184cc0976a5b00c9d042bef2032223ae261f948
 
 export ADA_PROJECT_PATH=/usr/local/ada/lib/gnat
 
index 65b47c3c51a3551c1c96ead0f8328c0f0e7e25ad..4158625a13dfa0587db663a9df4cf27715c65b16 100644 (file)
@@ -7,7 +7,8 @@ sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES
 sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES
 moon::cat /tmp/tkm.log::RSA private key '/etc/tkm/moonKey.der' loaded::YES
 moon::cat /tmp/tkm.log::Adding policy \[ 1, 192.168.0.1 <-> 192.168.0.2 \]::YES
-moon::cat /tmp/tkm.log::Checked CA certificate of CC context 1::YES
+moon::cat /tmp/tkm.log::Linked CC context 1 with CA certificate 1::YES
+moon::cat /tmp/tkm.log::Certificate chain of CC context 1 is valid::YES
 moon::cat /tmp/tkm.log::Authentication of ISA context 1 successful::YES
 moon::cat /tmp/tkm.log::Adding ESA \[ 1, 192.168.0.1 <-> 192.168.0.2, SPI_in.*, SPI_out.*, soft 30, hard 60 \]::YES
 moon::DAEMON_NAME=charon-tkm ipsec down conn1 && sleep 1::no output expected::NO
index 9921960e0006ef5e9e4d559b88a3ff93d203b76c..2db775799dda27829450b586d89fc4114e0a2e83 100644 (file)
@@ -7,6 +7,7 @@ sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES
 sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES
 moon::cat /tmp/tkm.log::RSA private key '/etc/tkm/moonKey.der' loaded::YES
 moon::cat /tmp/tkm.log::Adding policy \[ 1, 192.168.0.1 <-> 192.168.0.2 \]::YES
-moon::cat /tmp/tkm.log::Checked CA certificate of CC context 1::YES
+moon::cat /tmp/tkm.log::Linked CC context 1 with CA certificate 1::YES
+moon::cat /tmp/tkm.log::Certificate chain of CC context 1 is valid::YES
 moon::cat /tmp/tkm.log::Authentication of ISA context 1 successful::YES
 moon::cat /tmp/tkm.log::Adding ESA \[ 1, 192.168.0.1 <-> 192.168.0.2, SPI_in.*, SPI_out.*, soft 30, hard 60 \]::YES
index eb954bdf844afd0467b084f3bb6fffc63378382c..74203f82d995302dd064dab8b55a84782d7eeb3e 100644 (file)
@@ -8,7 +8,8 @@ sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES
 moon::cat /var/log/daemon.log::ees: acquire received for reqid 1::YES
 moon::cat /tmp/tkm.log::RSA private key '/etc/tkm/moonKey.der' loaded::YES
 moon::cat /tmp/tkm.log::Adding policy \[ 1, 192.168.0.1 <-> 192.168.0.2 \]::YES
-moon::cat /tmp/tkm.log::Checked CA certificate of CC context 1::YES
+moon::cat /tmp/tkm.log::Linked CC context 1 with CA certificate 1::YES
+moon::cat /tmp/tkm.log::Certificate chain of CC context 1 is valid::YES
 moon::cat /tmp/tkm.log::Authentication of ISA context 1 successful::YES
 moon::cat /tmp/tkm.log::Adding ESA \[ 1, 192.168.0.1 <-> 192.168.0.2, SPI_in.*, SPI_out.*, soft 30, hard 60 \]::YES
 moon::cat /tmp/xfrm_proxy.log::Initiating ESA acquire for reqid 1::YES
index 045e583520f87198f52c3bc4de9da53e75870865..23f6151fc3b134c732ff79aa1097bec815aa3581 100644 (file)
@@ -15,7 +15,7 @@ dave::tcpdump::IP sun.strongswan.org > dave.strongswan.org: ESP::YES
 sun::cat /tmp/tkm.log::RSA private key '/etc/tkm/sunKey.der' loaded::YES
 sun::cat /tmp/tkm.log::Adding policy \[ 1, 192.168.0.2 <-> 192.168.0.100 \]::YES
 sun::cat /tmp/tkm.log::Adding policy \[ 2, 192.168.0.2 <-> 192.168.0.200 \]::YES
-sun::cat /tmp/tkm.log | grep "Checked CA certificate of CC context 1" | wc -l::2::YES
+sun::cat /tmp/tkm.log | grep "Certificate chain of CC context 1 is valid" | wc -l::2::YES
 sun::cat /tmp/tkm.log::Authentication of ISA context 1 successful::YES
 sun::cat /tmp/tkm.log::Authentication of ISA context 2 successful::YES
 sun::cat /tmp/tkm.log::Adding ESA \[ 1, 192.168.0.2 <-> 192.168.0.100, SPI_in.*, SPI_out.*, soft 30, hard 60 \]::YES
index 54b7ca4fae4e905230fabcbbfb1c8de3a0a4a8d1..f3a06c66b7e1cbfa52d4b666ca922416fd62069f 100644 (file)
@@ -7,6 +7,7 @@ sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES
 sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES
 moon::cat /tmp/tkm.log::RSA private key '/etc/tkm/moonKey.der' loaded::YES
 moon::cat /tmp/tkm.log::Adding policy \[ 1, 10.1.0.0/16 > 192.168.0.1 <=> 192.168.0.2 < 10.2.0.0/16 \]::YES
-moon::cat /tmp/tkm.log::Checked CA certificate of CC context 1::YES
+moon::cat /tmp/tkm.log::Linked CC context 1 with CA certificate 1::YES
+moon::cat /tmp/tkm.log::Certificate chain of CC context 1 is valid::YES
 moon::cat /tmp/tkm.log::Authentication of ISA context 1 successful::YES
 moon::cat /tmp/tkm.log::Adding ESA \[ 1, 10.1.0.0/16 > 192.168.0.1 <=> 192.168.0.2 < 10.2.0.0/16, SPI_in.*, SPI_out.*, soft 30, hard 60 \]::YES
index 3e61ea614aa6ee7c8ff3a9cb52d81d840a10226d..d4befada5ffc11e200c79858d091b706d49f4a25 100644 (file)
@@ -8,7 +8,8 @@ sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES
 moon::cat /var/log/daemon.log::ees: acquire received for reqid 1::YES
 moon::cat /tmp/tkm.log::RSA private key '/etc/tkm/moonKey.der' loaded::YES
 moon::cat /tmp/tkm.log::Adding policy \[ 1, 10.1.0.0/16 > 192.168.0.1 <=> 192.168.0.2 < 10.2.0.0/16 \]::YES
-moon::cat /tmp/tkm.log::Checked CA certificate of CC context 1::YES
+moon::cat /tmp/tkm.log::Linked CC context 1 with CA certificate 1::YES
+moon::cat /tmp/tkm.log::Certificate chain of CC context 1 is valid::YES
 moon::cat /tmp/tkm.log::Authentication of ISA context 1 successful::YES
 moon::cat /tmp/tkm.log::Adding ESA \[ 1, 10.1.0.0/16 > 192.168.0.1 <=> 192.168.0.2 < 10.2.0.0/16, SPI_in.*, SPI_out.*, soft 30, hard 60 \]::YES
 moon::cat /tmp/xfrm_proxy.log::Initiating ESA acquire for reqid 1::YES
index a3f45871ca12eb8d8389ad130a8907b8e681873a..421924c7ccb40cde6ccabaf6807a3626e23d94bf 100644 (file)
@@ -15,7 +15,8 @@ moon::cat /var/log/daemon.log::deleting child SA (esa: 1, spi:.*)::YES
 moon::ping -c 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_.eq=1::YES
 moon::cat /tmp/tkm.log::RSA private key '/etc/tkm/moonKey.der' loaded::YES
 moon::cat /tmp/tkm.log::Adding policy \[ 1, 192.168.0.1 <-> 192.168.0.2 \]::YES
-moon::cat /tmp/tkm.log::Checked CA certificate of CC context 1::YES
+moon::cat /tmp/tkm.log::Linked CC context 1 with CA certificate 1::YES
+moon::cat /tmp/tkm.log::Certificate chain of CC context 1 is valid::YES
 moon::cat /tmp/tkm.log::Authentication of ISA context 1 successful::YES
 moon::cat /tmp/tkm.log::Creating first new ESA context with ID 1 (Isa 1, Sp 1, Ea 1, Initiator TRUE, spi_loc.*, spi_rem.*)::YES
 moon::cat /tmp/tkm.log::Creating ESA context with ID 2 (Isa 1, Sp 1, Ea 1, Dh_Id 1, Nc_Loc_Id 1, Initiator TRUE, spi_loc.*, spi_rem.*)::YES
index 15bdf3b39aff47b275d8ae3322e786be8e526772..fbda21e0b407f0f7f2f399aa20212eb6d7101508 100644 (file)
@@ -13,7 +13,8 @@ moon::cat /var/log/daemon.log::deleting child SA (esa: 1, spi:.*)::YES
 moon::ping -c 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_.eq=1::YES
 moon::cat /tmp/tkm.log::RSA private key '/etc/tkm/moonKey.der' loaded::YES
 moon::cat /tmp/tkm.log::Adding policy \[ 1, 192.168.0.1 <-> 192.168.0.2 \]::YES
-moon::cat /tmp/tkm.log::Checked CA certificate of CC context 1::YES
+moon::cat /tmp/tkm.log::Linked CC context 1 with CA certificate 1::YES
+moon::cat /tmp/tkm.log::Certificate chain of CC context 1 is valid::YES
 moon::cat /tmp/tkm.log::Authentication of ISA context 1 successful::YES
 moon::cat /tmp/tkm.log::Creating first new ESA context with ID 1 (Isa 1, Sp 1, Ea 1, Initiator TRUE, spi_loc.*, spi_rem.*)::YES
 moon::cat /tmp/tkm.log::Creating ESA context with ID 2 (Isa 1, Sp 1, Ea 1, Dh_Id 1, Nc_Loc_Id 1, Initiator FALSE, spi_loc.*, spi_rem.*)::YES