From 5bf6a7459c6fa151f5f9d618dccfa3e1c8e9f5b8 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Wed, 24 Oct 2007 15:50:02 +0000 Subject: [PATCH] Backport key compare approach to certificate validation. Check for xmlsec 1.3.0 in projects. --- configure.ac | 12 ++++++++++- shib/BasicTrust.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++----------- shibboleth.spec.in | 2 +- 3 files changed, 58 insertions(+), 14 deletions(-) diff --git a/configure.ac b/configure.ac index bf65e8c..3119592 100644 --- a/configure.ac +++ b/configure.ac @@ -237,7 +237,17 @@ AC_ARG_WITH(xmlsec, CPPFLAGS="-I${with_xmlsec}/include $CPPFLAGS" fi]) LIBS="-lxml-security-c $LIBS" -AC_CHECK_HEADER([xsec/xenc/XENCEncryptionMethod.hpp],,AC_MSG_ERROR([unable to find xml-security 1.1 header files]),[#include ]) +AC_CHECK_HEADER([xsec/xenc/XENCEncryptionMethod.hpp],,AC_MSG_ERROR([unable to find xml-security header files]),[#include ]) +AC_MSG_CHECKING([XML-Security version]) +AC_PREPROC_IFELSE( + [AC_LANG_PROGRAM([#include ], + [#if XSEC_VERSION_MAJOR > 1 || (XSEC_VERSION_MAJOR == 1 && XSEC_VERSION_MEDIUM > 2) +int i = 0; +#else +#error need version 1.3.0 or later +#endif])], + [AC_MSG_RESULT(OK)], + [AC_MSG_FAILURE([XML-Security version 1.3.0 or greater is required.])]) AC_TRY_LINK( [#include ], [XSECPlatformUtils::Initialise()], diff --git a/shib/BasicTrust.cpp b/shib/BasicTrust.cpp index 3de204e..c588a42 100644 --- a/shib/BasicTrust.cpp +++ b/shib/BasicTrust.cpp @@ -25,6 +25,8 @@ #include "internal.h" #include +#include +#include #include using namespace shibboleth::logging; @@ -104,7 +106,7 @@ bool BasicTrust::validate(void* certEE, const Iterator& certChain, const // The new "basic" trust implementation relies solely on certificates living within the // role interface to verify the EE certificate. - log.debug("comparing certificate to KeyDescriptors"); + log.debug("comparing key inside certificate to KeyDescriptors"); Iterator kd_i=role->getKeyDescriptors(); while (kd_i.hasNext()) { const IKeyDescriptor* kd=kd_i.next(); @@ -115,24 +117,56 @@ bool BasicTrust::validate(void* certEE, const Iterator& certChain, const continue; Iterator resolvers(m_resolvers); while (resolvers.hasNext()) { - XSECCryptoX509* cert=resolvers.next()->resolveCert(KIL); - if (cert) { - log.debug("KeyDescriptor resolved into a certificate, comparing it..."); - if (cert->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) { - log.warn("only the OpenSSL XSEC provider is supported"); + XSECCryptoKey* key=((XSECKeyInfoResolver*)*resolvers.next())->resolveKey(KIL); + if (key) { + log.debug("KeyDescriptor resolved into a key, comparing it..."); + if (key->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) { + log.error("only the OpenSSL XSEC provider is supported"); continue; } - else if (!X509_cmp(reinterpret_cast(certEE),static_cast(cert)->getOpenSSLX509())) { - log.info("certificate match found in KeyDescriptor"); - return true; + + switch (key->getKeyType()) { + case XSECCryptoKey::KEY_RSA_PUBLIC: + case XSECCryptoKey::KEY_RSA_PAIR: + { + RSA* rsa = static_cast(key)->getOpenSSLRSA(); + EVP_PKEY* evp = X509_PUBKEY_get(X509_get_X509_PUBKEY(reinterpret_cast(certEE))); + if (rsa && evp && evp->type == EVP_PKEY_RSA && + BN_cmp(rsa->n,evp->pkey.rsa->n) == 0 && BN_cmp(rsa->e,evp->pkey.rsa->e) == 0) { + if (evp) + EVP_PKEY_free(evp); + log.debug("matching key found in KeyDescriptor"); + return true; + } + if (evp) + EVP_PKEY_free(evp); + break; + } + + case XSECCryptoKey::KEY_DSA_PUBLIC: + case XSECCryptoKey::KEY_DSA_PAIR: + { + DSA* dsa = static_cast(key)->getOpenSSLDSA(); + EVP_PKEY* evp = X509_PUBKEY_get(X509_get_X509_PUBKEY(reinterpret_cast(certEE))); + if (dsa && evp && evp->type == EVP_PKEY_DSA && BN_cmp(dsa->pub_key,evp->pkey.dsa->pub_key) == 0) { + if (evp) + EVP_PKEY_free(evp); + log.debug("matching key found in KeyDescriptor"); + return true; + } + if (evp) + EVP_PKEY_free(evp); + break; + } + + default: + log.warn("unknown key type in KeyDescriptor, skipping..."); } - else - log.debug("certificate did not match"); } } } - log.debug("failed to find an exact match for certificate in KeyDescriptors"); + log.debug("failed to find a matching key for certificate in KeyDescriptors"); return false; } diff --git a/shibboleth.spec.in b/shibboleth.spec.in index ec8afca..7309b39 100644 --- a/shibboleth.spec.in +++ b/shibboleth.spec.in @@ -10,7 +10,7 @@ Source0: http://shibboleth.internet2.edu/downloads/%{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-root BuildRequires: openssl-devel, curl-devel >= 7.10.6 -BuildRequires: xerces%{?xercesver}-c-devel >= 2.8.0, xml-security-c-devel >= 1.1.0 +BuildRequires: xerces%{?xercesver}-c-devel >= 2.8.0, xml-security-c-devel >= 1.3.0 BuildRequires: zlib-devel, opensaml-devel >= 1.1.1, opensaml-devel < 2.0 %{?_with_log4cpp:BuildRequires: log4cpp-devel >= 1.0} %{!?_with_log4cpp:BuildRequires: log4shib-devel} -- 2.1.4