charon-tkm: Reverse cert chain processing order
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.
This commit is contained in:
committed by
Tobias Brunner
parent
532023dcf1
commit
a0a0571bd1
@@ -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;
|
||||
|
||||
/* set user certificate */
|
||||
if (!cert->get_encoding(cert, CERT_ASN1_DER, &enc_user_cert))
|
||||
pubkey = cert->get_public_key(cert);
|
||||
if (!pubkey)
|
||||
{
|
||||
DBG1(DBG_IKE, "unable to extract encoded user certificate");
|
||||
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;
|
||||
|
||||
if (!cert->get_encoding(cert, CERT_ASN1_DER, &enc_ca_cert))
|
||||
{
|
||||
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);
|
||||
while (array_remove(im_certs, ARRAY_TAIL, &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);
|
||||
array_destroy(im_certs);
|
||||
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);
|
||||
array_destroy(im_certs);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
array_destroy(im_certs);
|
||||
|
||||
/* finally add user certificate and check chain */
|
||||
cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
|
||||
if (cert)
|
||||
{
|
||||
ca_id_type ca_id;
|
||||
public_key_t *pubkey;
|
||||
certificate_type ca_cert;
|
||||
chunk_t enc_ca_cert, fp;
|
||||
uint64_t *raw_id;
|
||||
chunk_t enc_user_cert;
|
||||
ri_id_type ri_id;
|
||||
certificate_type user_cert;
|
||||
|
||||
pubkey = cert->get_public_key(cert);
|
||||
if (!pubkey)
|
||||
/* set user certificate */
|
||||
if (!cert->get_encoding(cert, CERT_ASN1_DER, &enc_user_cert))
|
||||
{
|
||||
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;
|
||||
|
||||
if (!cert->get_encoding(cert, CERT_ASN1_DER, &enc_ca_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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
PKG = tkm-rpc
|
||||
SRC = https://git.codelabs.ch/git/$(PKG).git
|
||||
REV = 4d6cd3f5e6a8f0d33f56289ad3a07645f10edc91
|
||||
REV = 1f4e1c9c6ec473cdb391b5416f38d48b09cb6004
|
||||
|
||||
PREFIX = /usr/local/ada
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user