Partial implementation of signature verification with libxmlsec.
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Sun, 20 Oct 2002 22:57:26 +0000 (22:57 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Sun, 20 Oct 2002 22:57:26 +0000 (22:57 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@158 cb58f699-b61c-0410-a6fe-9272a202ed29

12 files changed:
shib/ClubShibPOSTProfile.cpp
shib/Constants.cpp
shib/SAMLBindingFactory.cpp
shib/ShibConfig.cpp
shib/ShibPOSTProfile.cpp
shib/ShibPOSTProfileFactory.cpp
shib/XML.cpp
shib/XMLOriginSiteMapper.cpp
shib/config_win32.h [new file with mode: 0644]
shib/internal.h [new file with mode: 0644]
shib/shib.dsp
shib/shib.h

index 48cd63a..315c8f4 100644 (file)
    $History:$
 */
 
-#ifdef WIN32
-# define SHIB_EXPORTS __declspec(dllexport)
-#endif
+#include "internal.h"
 
-#include "shib.h"
 using namespace shibboleth;
 using namespace saml;
 using namespace std;
@@ -100,20 +97,18 @@ SAMLResponse* ClubShibPOSTProfile::prepare(const XMLCh* recipient,
                                            const saml::Key& responseKey, const saml::X509Certificate* responseCert,
                                            const saml::Key* assertionKey, const saml::X509Certificate* assertionCert)
 {
-    if (responseKey.getType()!=Key::RSA)
-        throw InvalidCryptoException(SAMLException::RESPONDER, "ClubShibPOSTProfile::prepare() requires the response key be an RSA private key");
-    if (assertionKey && assertionKey->getType()!=Key::RSA)
-        throw InvalidCryptoException(SAMLException::RESPONDER, "ClubShibPOSTProfile::prepare() requires the assertion key be an RSA private key");
+    if (responseKey.getType()!=Key::RSA_PRIV)
+        throw TrustException(SAMLException::RESPONDER, "ClubShibPOSTProfile::prepare() requires the response key be an RSA private key");
+    if (assertionKey && assertionKey->getType()!=Key::RSA_PRIV)
+        throw TrustException(SAMLException::RESPONDER, "ClubShibPOSTProfile::prepare() requires the assertion key be an RSA private key");
 
     return ShibPOSTProfile::prepare(recipient,name,nameQualifier,subjectIP,authMethod,authInstant,bindings,
                                     responseKey,responseCert,assertionKey,assertionCert);
 }
 
-bool ClubShibPOSTProfile::verifySignature(const SAMLSignedObject& obj, const XMLCh* signerName,
-                                          const saml::Iterator<saml::X509Certificate*>& roots,
-                                          const saml::Key* knownKey)
+void ClubShibPOSTProfile::verifySignature(const SAMLSignedObject& obj, const XMLCh* signerName, const saml::Key* knownKey)
 {
-    if (!ShibPOSTProfile::verifySignature(obj,signerName,roots,knownKey))
-        return false;
-    return (obj.getSignatureAlgorithm()==SAMLSignedObject::RSA_SHA1);
+    ShibPOSTProfile::verifySignature(obj,signerName,knownKey);
+    if (obj.getSignatureAlgorithm()!=SAMLSignedObject::RSA_SHA1)
+        throw TrustException("ClubShibPOSTProfile::verifySignature() requires the RSA-SHA1 signature algorithm");
 }
index a97af6b..4b5ef4f 100644 (file)
    $History:$
 */
 
-#ifdef WIN32
-# define SHIB_EXPORTS __declspec(dllexport)
-#endif
-
-#include "shib.h"
+#include "internal.h"
 
 const XMLCh shibboleth::Constants::POLICY_CLUBSHIB[] = // http://middleware.internet2.edu/shibboleth/clubs/clubshib/2002/05/
 { chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,
index 5eccd21..374dff0 100644 (file)
    $History:$
 */
 
-#ifdef WIN32
-# define SHIB_EXPORTS __declspec(dllexport)
-#endif
+#include "internal.h"
 
-#include "shib.h"
 using namespace shibboleth;
 using namespace saml;
 
index 3e941af..4187daa 100644 (file)
    $History:$
 */
 
-#ifdef WIN32
-# define SHIB_EXPORTS __declspec(dllexport)
-#endif
+#include "internal.h"
+#include <log4cpp/Category.hh>
 
-#include "shib.h"
+using namespace saml;
 using namespace shibboleth;
 
 namespace {
-    ShibConfig g_config;
+    ShibInternalConfig g_config;
 }
 
-bool ShibConfig::init()
+bool ShibInternalConfig::init()
 {
+    saml::NDC ndc("init");
+
     // Register extension schema.
     saml::XML::registerSchema(XML::SHIB_NS,XML::SHIB_SCHEMA_ID);
 
+    m_manager=xmlSecSimpleKeysMngrCreate();
+    if (origin_mapper && origin_mapper->getTrustedRoots() &&
+        xmlSecSimpleKeysMngrLoadPemCert(m_manager,origin_mapper->getTrustedRoots(),true) < 0)
+    {
+        log4cpp::Category::getInstance(SHIB_LOGCAT".ShibConfig").fatal("init: failed to load CAs into simple key manager");
+        xmlSecSimpleKeysMngrDestroy(m_manager);
+        m_manager=NULL;
+        return false;
+    }
+    SAMLConfig::getConfig().xmlsig_ptr=m_manager;
+
     return true;
 }
 
-void ShibConfig::term()
+void ShibInternalConfig::term()
 {
+    if (m_manager)
+        xmlSecSimpleKeysMngrDestroy(m_manager);
 }
 
 ShibConfig& ShibConfig::getConfig()
index 543a23b..87dcf60 100644 (file)
    $History:$
 */
 
-#ifdef WIN32
-# define SHIB_EXPORTS __declspec(dllexport)
-#endif
+#include "internal.h"
 
 #include <ctime>
-#include "shib.h"
+
 using namespace shibboleth;
 using namespace saml;
 using namespace std;
@@ -144,14 +142,12 @@ SAMLResponse* ShibPOSTProfile::accept(const XMLByte* buf)
         throw SAMLException(SAMLException::RESPONDER, "ShibPOSTProfile::accept() detected an untrusted HS for the origin site");
 
     const Key* hsKey=ShibConfig::getConfig().origin_mapper->getHandleServiceKey(handleService);
-    Iterator<X509Certificate*> roots=ShibConfig::getConfig().origin_mapper->getTrustedRoots();
 
     // Signature verification now takes place. We check the assertion and the response.
     // Assertion signing is optional, response signing is mandatory.
-    if (assertion->isSigned() && !verifySignature(*assertion, handleService, roots, hsKey))
-        throw SAMLException(SAMLException::RESPONDER, "ShibPOSTProfile::accept() detected an invalid assertion signature");
-    if (!verifySignature(*r, handleService, roots, hsKey))
-        throw SAMLException(SAMLException::RESPONDER, "ShibPOSTProfile::accept() detected an invalid response signature");
+    if (assertion->isSigned())
+        verifySignature(*assertion, handleService, hsKey);
+    verifySignature(*r, handleService, hsKey);
 
     return r;
 }
@@ -180,9 +176,15 @@ SAMLResponse* ShibPOSTProfile::prepare(const XMLCh* recipient,
     SAMLResponse* r = SAMLPOSTProfile::prepare(recipient,m_issuer,Iterator<const XMLCh*>(m_policies),name,
                                                nameQualifier,NULL,subjectIP,authMethod,authDateTime,bindings);
     if (assertionKey)
-        (r->getAssertions().next())->sign(m_algorithm,*assertionKey,assertionCert);
+    {
+        const X509Certificate* acerts[]={ assertionCert };
+        (r->getAssertions().next())->sign(m_algorithm,*assertionKey,
+            assertionCert ? ArrayIterator<const X509Certificate*>(acerts) : Iterator<const X509Certificate*>());
+    }
 
-    r->sign(m_algorithm,responseKey,responseCert);
+    const X509Certificate* rcerts[]={ responseCert };
+    r->sign(m_algorithm,responseKey,
+        assertionCert ? ArrayIterator<const X509Certificate*>(rcerts) : Iterator<const X509Certificate*>());
 
     return r;
 }
@@ -193,9 +195,10 @@ bool ShibPOSTProfile::checkReplayCache(const SAMLAssertion& a)
     return SAMLPOSTProfile::checkReplayCache(a);
 }
 
-bool ShibPOSTProfile::verifySignature(const SAMLSignedObject& obj, const XMLCh* signerName,
-                                      const saml::Iterator<saml::X509Certificate*>& roots,
-                                      const saml::Key* knownKey)
+void ShibPOSTProfile::verifySignature(const SAMLSignedObject& obj, const XMLCh* signerName, const saml::Key* knownKey)
 {
-    return knownKey ? obj.verify(*knownKey) : obj.verify();
+    if (knownKey)
+        obj.verify(*knownKey);
+    else
+        obj.verify();
 }
index fbd4070..6bf18b8 100644 (file)
    $History:$
 */
 
-#ifdef WIN32
-# define SHIB_EXPORTS __declspec(dllexport)
-#endif
+#include "internal.h"
 
-#include "shib.h"
 using namespace shibboleth;
 using namespace saml;
 using namespace std;
index 1adb912..132794e 100644 (file)
    $History:$
 */
 
-#ifdef WIN32
-# define SHIB_EXPORTS __declspec(dllexport)
-#endif
+#include "internal.h"
 
-#include "shib.h"
 using namespace shibboleth;
 
 
index 3771b43..ed418ce 100644 (file)
    $History:$
 */
 
-#ifdef WIN32
-# define SHIB_EXPORTS __declspec(dllexport)
-#endif
-
-#include "shib.h"
+#include "internal.h"
 #include <log4cpp/Category.hh>
+
+#include <xmlsec/xmltree.h>
+#include <xmlsec/xmldsig.h>
+
 using namespace shibboleth;
 using namespace saml;
 using namespace log4cpp;
@@ -68,9 +68,8 @@ using namespace std;
 
 #include <xercesc/framework/URLInputSource.hpp>
 
-XMLOriginSiteMapper::XMLOriginSiteMapper(const char* registryURI,
-                                         const Iterator<X509Certificate*>& roots,
-                                         Key* verifyKey)
+
+XMLOriginSiteMapper::XMLOriginSiteMapper(const char* registryURI, const char* calist, const X509Certificate* verifyKey)
 {
     NDC ndc("XMLOriginSiteMapper");
     Category& log=Category::getInstance(SHIB_LOGCAT".XMLOriginSiteMapper");
@@ -78,6 +77,9 @@ XMLOriginSiteMapper::XMLOriginSiteMapper(const char* registryURI,
     // Register extension schema.
     saml::XML::registerSchema(XML::SHIB_NS,XML::SHIB_SCHEMA_ID);
 
+    if (calist)
+        m_calist=calist;
+
     saml::XML::Parser p;
     DOMDocument* doc=NULL;
        try
@@ -155,12 +157,12 @@ XMLOriginSiteMapper::XMLOriginSiteMapper(const char* registryURI,
 
                if (verifyKey)
         {
-                       log.info("Initialized with a key: attempting to verify document signature.");
-            log.error("Signature verification not implemented yet, this may be a forged file!");
-                       // validateSignature(verifyKey, e);
+                       log.info("initialized with a key: attempting to verify document signature");
+                       validateSignature(verifyKey, e);
+                       log.info("verified document signature");
                }
         else
-                       log.info("Initialized without key: skipping signature verification.");
+                       log.info("initialized without key: skipping signature verification");
     }
     catch (SAMLException& e)
     {
@@ -183,67 +185,10 @@ XMLOriginSiteMapper::~XMLOriginSiteMapper()
 {
     for (map<xstring,OriginSite*>::iterator i=m_sites.begin(); i!=m_sites.end(); i++)
         delete i->second;
+    for (map<xstring,Key*>::iterator j=m_hsKeys.begin(); j!=m_hsKeys.end(); j++)
+        delete j->second;
 }
 
-/* TBD...
-private void validateSignature(Key verifyKey, Element e) throws OriginSiteMapperException {
-
-       Node n = e.getLastChild();
-       while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
-               n = n.getPreviousSibling();
-
-       if (n != null
-               && org.opensaml.XML.XMLSIG_NS.equals(n.getNamespaceURI())
-               && "Signature".equals(n.getLocalName())) {
-                       log.info("Located signature in document... verifying.");
-               try {
-                       XMLSignature sig = new XMLSignature((Element) n, null);
-                       if (sig.checkSignatureValue(verifyKey)) {
-                               // Now we verify that what is signed is what we expect.
-                               SignedInfo sinfo = sig.getSignedInfo();
-                               if (sinfo.getLength() == 1
-                                       && (sinfo
-                                               .getCanonicalizationMethodURI()
-                                               .equals(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS)
-                                               || sinfo.getCanonicalizationMethodURI().equals(
-                                                       Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS))) {
-                                       Reference ref = sinfo.item(0);
-                                       if (ref.getURI() == null || ref.getURI().equals("")) {
-                                               Transforms trans = ref.getTransforms();
-                                               if (trans.getLength() == 1
-                                                       && trans.item(0).getURI().equals(Transforms.TRANSFORM_ENVELOPED_SIGNATURE))
-                                                       log.info("Signature verification successful.");
-                                                       return;
-                                       }
-                                       log.error(
-                                               "Unable to verify signature on registry file: Unsupported dsig reference or transform data submitted with signature.");
-                                       throw new OriginSiteMapperException("Unable to verify signature on registry file: Unsupported dsig reference or transform data submitted with signature.");
-                               } else {
-                                       log.error(
-                                               "Unable to verify signature on registry file: Unsupported canonicalization method.");
-                                       throw new OriginSiteMapperException("Unable to verify signature on registry file: Unsupported canonicalization method.");
-                               }
-                       } else {
-                               log.error(
-                                       "Unable to verify signature on registry file: signature cannot be verified with the specified key.");
-                               throw new OriginSiteMapperException("Unable to verify signature on registry file: signature cannot be verified with the specified key.");
-                       }
-               } catch (Exception sigE) {
-                       log.error(
-                               "Unable to verify signature on registry file: An error occured while attempting to verify the signature:"
-                                       + sigE);
-                       throw new OriginSiteMapperException(
-                               "Unable to verify signature on registry file: An error occured while attempting to verify the signature:"
-                                       + sigE);
-               }
-       } else {
-               log.error("Unable to verify signature on registry file: no signature found in document.");
-               throw new OriginSiteMapperException("Unable to verify signature on registry file: no signature found in document.");
-       }
-
-}
-*/
-
 Iterator<xstring> XMLOriginSiteMapper::getHandleServiceNames(const XMLCh* originSite)
 {
     map<xstring,OriginSite*>::const_iterator i=m_sites.find(originSite);
@@ -252,7 +197,7 @@ Iterator<xstring> XMLOriginSiteMapper::getHandleServiceNames(const XMLCh* origin
     return Iterator<xstring>(i->second->m_handleServices);
 }
 
-Key* XMLOriginSiteMapper::getHandleServiceKey(const XMLCh* handleService)
+const Key* XMLOriginSiteMapper::getHandleServiceKey(const XMLCh* handleService)
 {
     map<xstring,Key*>::const_iterator i=m_hsKeys.find(handleService);
     return (i!=m_hsKeys.end()) ? i->second : NULL;
@@ -266,8 +211,146 @@ Iterator<xstring> XMLOriginSiteMapper::getSecurityDomains(const XMLCh* originSit
     return Iterator<xstring>(i->second->m_domains);
 }
 
-Iterator<X509Certificate*> XMLOriginSiteMapper::getTrustedRoots()
+const char* XMLOriginSiteMapper::getTrustedRoots()
 {
-       return Iterator<X509Certificate*>(m_roots);
+    return m_calist.c_str();
 }
 
+void XMLOriginSiteMapper::validateSignature(const X509Certificate* verifyKey, DOMElement* e)
+{
+    if (verifyKey->getFormat()!=X509Certificate::PEM)
+        throw OriginSiteMapperException("XMLOriginSiteMapper::validateSignature() requires a PEM certificate");
+
+    ostringstream os;
+    os << *e;
+    string libxmlbuf(os.str());
+
+    // Parse the document with libxml
+    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+    xmlSubstituteEntitiesDefault(1);
+    xmlDocPtr libxmlDoc=xmlParseMemory(libxmlbuf.c_str(),libxmlbuf.length());
+    if (!libxmlDoc || !xmlDocGetRootElement(libxmlDoc))
+        throw OriginSiteMapperException("XMLOriginSiteMapper::validateSignature() unable to parse with libxml");
+
+    // Look for a ds:Signature below the root element.
+    xmlNodePtr sigNode=xmlSecFindNode(xmlDocGetRootElement(libxmlDoc),(xmlChar*)"Signature",xmlSecDSigNs);
+    if (!sigNode)
+    {
+        xmlFreeDoc(libxmlDoc);
+        throw OriginSiteMapperException("XMLOriginSiteMapper::validateSignature() unable to find a ds:Signature");
+    }
+
+    // To get the bloody key to work, we have to do things to fool xmlsec into allowing it.
+    // First we load the cert in as a trusted root.
+    xmlSecX509StorePtr pStore=xmlSecX509StoreCreate();
+    if (!pStore)
+    {
+        xmlFreeDoc(libxmlDoc);
+        throw bad_alloc();
+    }
+
+    int ret=xmlSecX509StoreLoadPemCert(pStore,verifyKey->getPath(),1);
+    if (ret<0)
+    {
+        xmlSecX509StoreDestroy(pStore);
+        xmlFreeDoc(libxmlDoc);
+        throw OriginSiteMapperException(
+            string("XMLOriginSiteMapper::validateSignature() unable to load certificate from file: ") + verifyKey->getPath());
+    }
+
+    xmlSecX509DataPtr pX509=xmlSecX509DataCreate();
+    if (!pX509)
+    {
+        xmlSecX509StoreDestroy(pStore);
+        xmlFreeDoc(libxmlDoc);
+        throw bad_alloc();
+    }
+
+    // Now load the cert again and "verify" the cert against itself, which will mark it verified.
+    if (xmlSecX509DataReadPemCert(pX509,verifyKey->getPath())<0 || xmlSecX509StoreVerify(pStore,pX509)<0)
+    {
+        xmlSecX509DataDestroy(pX509);
+        xmlSecX509StoreDestroy(pStore);
+        xmlFreeDoc(libxmlDoc);
+        throw OriginSiteMapperException("XMLOriginSiteMapper::validateSignature() unable to load certificate and verify against itself");
+    }
+
+    // Now we can get the key out.
+    xmlSecKeyPtr key=xmlSecX509DataCreateKey(pX509);
+    if (!key)
+    {
+//        xmlSecX509DataDestroy(pX509);
+        xmlSecX509StoreDestroy(pStore);
+        xmlFreeDoc(libxmlDoc);
+        throw OriginSiteMapperException("XMLOriginSiteMapper::validateSignature() failed to extract key from certificate");
+    }
+
+    // Set up for validation.
+    xmlSecKeysMngrPtr keymgr=xmlSecSimpleKeysMngrCreate();
+    if (!keymgr)
+    {
+        xmlSecKeyDestroy(key);
+//        xmlSecX509DataDestroy(pX509);
+        xmlSecX509StoreDestroy(pStore);
+        xmlFreeDoc(libxmlDoc);
+        throw bad_alloc();
+    }
+
+    xmlSecDSigCtxPtr context=xmlSecDSigCtxCreate(keymgr);
+    if (!context)
+    {
+        xmlSecSimpleKeysMngrDestroy(keymgr);
+        xmlSecKeyDestroy(key);
+//        xmlSecX509DataDestroy(pX509);
+        xmlSecX509StoreDestroy(pStore);
+        xmlFreeDoc(libxmlDoc);
+        throw bad_alloc();
+    }
+    context->processManifests=0;
+    context->storeSignatures=0;
+    context->storeReferences=0;
+    context->fakeSignatures=0;
+
+    // Finally...check the bloody thing.
+    xmlSecDSigResultPtr result=NULL;
+    ret=xmlSecDSigValidate(context,NULL,key,sigNode,&result);
+    xmlSecKeyDestroy(key);
+//    xmlSecX509DataDestroy(pX509);
+    xmlSecX509StoreDestroy(pStore);
+    if (ret<0 || result->result!=xmlSecTransformStatusOk)
+    {
+        if (result)
+            xmlSecDSigResultDestroy(result);
+        xmlSecDSigCtxDestroy(context);
+        xmlSecSimpleKeysMngrDestroy(keymgr);
+        xmlFreeDoc(libxmlDoc);
+        throw InvalidCryptoException("XMLOriginSiteMapper::validateSignature() failed to validate signature");
+    }
+
+    // Now check for any trust violations (wrong stuff signed, etc.)
+    string msg;
+
+    if (result->signMethod!=xmlSecSignRsaSha1)
+        msg="XMLOriginSiteMapper::validateSignature() rejected signature algorithm";
+    else if (result->firstSignRef!=result->lastSignRef)
+        msg="XMLOriginSiteMapper::validateSignature() found more than one ds:Reference";
+    else
+    {
+        xmlSecReferenceResultPtr ref=result->firstSignRef;
+        if (ref->digestMethod!=xmlSecDigestSha1)
+            msg="XMLOriginSiteMapper::validateSignature() rejected digest algorithm";
+        else if (ref->uri && ref->uri[0])
+            msg="XMLOriginSiteMapper::validateSignature() found a ds:Reference with a non-empty URL";
+        else
+        {
+        }
+    }
+    
+    xmlSecDSigResultDestroy(result);
+    xmlSecDSigCtxDestroy(context);
+    xmlSecSimpleKeysMngrDestroy(keymgr);
+    xmlFreeDoc(libxmlDoc);
+
+    if (!msg.empty())
+        throw TrustException(msg);
+}
diff --git a/shib/config_win32.h b/shib/config_win32.h
new file mode 100644 (file)
index 0000000..0d8808c
--- /dev/null
@@ -0,0 +1,113 @@
+/* config_win32.h.  Copied from a ./configure on Unix */
+
+/* Define to 1 if you have the <dlfcn.h> header file.
+#define HAVE_DLFCN_H 1
+*/
+
+/* Define to 1 if you have the `gmtime_r' function. */
+/* #undef HAVE_GMTIME_R */
+
+/* Define to 1 if you have the <inttypes.h> header file.
+#define HAVE_INTTYPES_H 1
+*/
+
+/* Define to 1 if you have the `crypto' library (-lcrypto). */
+#define HAVE_LIBCRYPTO 1
+
+/* Define to 1 if you have the `curl' library (-lcurl). */
+#define HAVE_LIBCURL 1
+
+/* Define if log4cpp library was found */
+#define HAVE_LIBLOG4CPP 1
+
+/* Define to 1 if you have the `ssl' library (-lssl). */
+#define HAVE_LIBSSL 1
+
+/* Define to 1 if you have the `uuid' library (-luuid).
+#define HAVE_LIBUUID 1
+*/
+
+/* Define if Xerces-C library was found */
+#define HAVE_LIBXERCESC 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* define if the compiler implements namespaces */
+#define HAVE_NAMESPACES 1
+
+/* Define if you have POSIX threads libraries and header files.
+#define HAVE_PTHREAD 1
+*/
+
+/* Define to 1 if you have the <stdint.h> header file. */
+/* #undef HAVE_STDINT_H */
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strchr' function. */
+#define HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strftime' function. */
+/* #undef HAVE_STRFTIME */
+
+/* Define to 1 if you have the <strings.h> header file.
+#define HAVE_STRINGS_H 1
+*/
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strstr' function. */
+#define HAVE_STRSTR 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file.
+#define HAVE_UNISTD_H 1
+*/
+
+/* Name of package */
+#define PACKAGE "shibboleth"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "mace-shib-users@internet2.edu"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "shibboleth"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "shibboleth 0.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "shibboleth"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.1"
+
+/* Define to the necessary symbol if this constant uses a non-standard name on
+   your system. */
+/* #undef PTHREAD_CREATE_JOINABLE */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+/* #undef TM_IN_SYS_TIME */
+
+/* Version number of package */
+#define VERSION "0.1"
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+/* #undef size_t */
diff --git a/shib/internal.h b/shib/internal.h
new file mode 100644 (file)
index 0000000..b336b8b
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * The OpenSAML License, Version 1.
+ * Copyright (c) 2002
+ * University Corporation for Advanced Internet Development, Inc.
+ * All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
+ * acknowledgments normally appear.
+ *
+ * Neither the name of OpenSAML nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
+ * please contact opensaml@opensaml.org
+ *
+ * Products derived from this software may not be called OpenSAML, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may OpenSAML appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/* internal.h - internally visible classes
+
+   Scott Cantor
+   9/6/02
+
+   $History:$
+*/
+
+#ifndef __shib_internal_h__
+#define __shib_internal_h__
+
+#ifdef WIN32
+# define SHIB_EXPORTS __declspec(dllexport)
+#endif
+
+// eventually we might be able to support autoconf via cygwin...
+#if defined (_MSC_VER) || defined(__BORLANDC__)
+# include "config_win32.h"
+#else
+# include "config.h"
+#endif
+
+#include <xmlsec/keysmngr.h>
+
+#include "shib.h"
+
+#define SHIB_LOGCAT "Shibboleth"
+
+namespace shibboleth
+{
+    class ShibInternalConfig : public ShibConfig
+    {
+    public:
+        ShibInternalConfig() : m_manager(NULL) {}
+
+        // global per-process setup and shutdown of runtime
+        bool init();
+        void term();
+
+    private:
+        xmlSecKeysMngrPtr m_manager;
+    };
+}
+
+#endif
index 15bc03d..8385ff4 100644 (file)
@@ -43,7 +43,7 @@ RSC=rc.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SHIB_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "." /I "C:\log4cpp\include" /I "C:\curl\include" /I "C:\openssl\include" /I "C:\xerces-c\include" /I "..\..\..\opensaml\c" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "C:\xmlsec\include" /I "C:\xml2\include" /I "C:\iconv\include" /I "C:\xslt\include" /I "." /I "C:\log4cpp\include" /I "C:\curl\include" /I "C:\openssl\include" /I "C:\xerces-c\include" /I "..\..\..\opensaml\c" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x409 /d "NDEBUG"
@@ -53,7 +53,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 log4cpp.lib xerces-c_2.lib saml.lib /nologo /dll /machine:I386 /libpath:"C:\log4cpp\lib" /libpath:"C:\xerces-c\lib" /libpath:"..\..\..\opensaml\c\saml\Release"
+# ADD LINK32 log4cpp.lib xerces-c_2.lib saml.lib libxmlsec.lib libxml2.lib /nologo /dll /machine:I386 /libpath:"C:\log4cpp\lib" /libpath:"C:\xerces-c\lib" /libpath:"..\..\..\opensaml\c\saml\Release" /libpath:"C:\xmlsec\lib" /libpath:"C:\xml2\lib"
 
 !ELSEIF  "$(CFG)" == "shib - Win32 Debug"
 
@@ -69,7 +69,7 @@ LINK32=link.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SHIB_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I "." /I "C:\log4cpp\include" /I "C:\curl\include" /I "C:\openssl\include" /I "C:\xerces-c\include" /I "..\..\..\opensaml\c" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I "C:\xmlsec\include" /I "C:\xml2\include" /I "C:\iconv\include" /I "C:\xslt\include" /I "." /I "C:\log4cpp\include" /I "C:\curl\include" /I "C:\openssl\include" /I "C:\xerces-c\include" /I "..\..\..\opensaml\c" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /GZ /c
 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
 # ADD BASE RSC /l 0x409 /d "_DEBUG"
@@ -79,7 +79,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 log4cppD.lib xerces-c_2D.lib saml.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"C:\debug\log4cpp\lib" /libpath:"C:\debug\xerces-c\lib" /libpath:"..\..\..\opensaml\c\saml\Debug"
+# ADD LINK32 log4cppD.lib libxmlsec.lib libxml2.lib xerces-c_2D.lib saml.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"C:\debug\log4cpp\lib" /libpath:"C:\xmlsec\lib" /libpath:"C:\xml2\lib" /libpath:"..\..\..\opensaml\c\saml\Debug" /libpath:"C:\debug\xerces-c\lib"
 
 !ENDIF 
 
@@ -93,10 +93,18 @@ SOURCE=.\ClubShibPOSTProfile.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\config_win32.h
+# End Source File
+# Begin Source File
+
 SOURCE=.\Constants.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\internal.h
+# End Source File
+# Begin Source File
+
 SOURCE=.\SAMLBindingFactory.cpp
 # End Source File
 # Begin Source File
index 436c11f..9f57e78 100644 (file)
@@ -61,8 +61,6 @@
 
 #include <saml/saml.h>
 
-#define SHIB_LOGCAT "Shibboleth"
-
 #ifdef WIN32
 # ifndef SHIB_EXPORTS
 #  define SHIB_EXPORTS __declspec(dllimport)
@@ -94,32 +92,32 @@ namespace shibboleth
     struct SHIB_EXPORTS IOriginSiteMapper
     {
         virtual saml::Iterator<saml::xstring> getHandleServiceNames(const XMLCh* originSite)=0;
-        virtual saml::Key* getHandleServiceKey(const XMLCh* handleService)=0;
+        virtual const saml::Key* getHandleServiceKey(const XMLCh* handleService)=0;
         virtual saml::Iterator<saml::xstring> getSecurityDomains(const XMLCh* originSite)=0;
-        virtual saml::Iterator<saml::X509Certificate*> getTrustedRoots()=0;
+        virtual const char* getTrustedRoots()=0;
     };
 
     class SHIB_EXPORTS XMLOriginSiteMapper : public IOriginSiteMapper
     {
     public:
-        XMLOriginSiteMapper(const char* registryURI,
-                            const saml::Iterator<saml::X509Certificate*>& roots,
-                            saml::Key* verifyKey=NULL);
+        XMLOriginSiteMapper(const char* registryURI, const char* calist, const saml::X509Certificate* verifyKey=NULL);
         ~XMLOriginSiteMapper();
 
         virtual saml::Iterator<saml::xstring> getHandleServiceNames(const XMLCh* originSite);
-        virtual saml::Key* getHandleServiceKey(const XMLCh* handleService);
+        virtual const saml::Key* getHandleServiceKey(const XMLCh* handleService);
         virtual saml::Iterator<saml::xstring> getSecurityDomains(const XMLCh* originSite);
-        virtual saml::Iterator<saml::X509Certificate*> getTrustedRoots();
+        virtual const char* getTrustedRoots();
 
     private:
+        void validateSignature(const saml::X509Certificate* verifyKey, DOMElement* e);
+
         struct OriginSite
         {
             std::vector<saml::xstring> m_handleServices;
             std::vector<saml::xstring> m_domains;
         };
 
-        std::vector<saml::X509Certificate*> m_roots;
+        std::string m_calist;
         std::map<saml::xstring,OriginSite*> m_sites;
         std::map<saml::xstring,saml::Key*> m_hsKeys;
     };
@@ -146,8 +144,7 @@ namespace shibboleth
         virtual bool checkReplayCache(const saml::SAMLAssertion& a);
 
     protected:
-        virtual bool verifySignature(const saml::SAMLSignedObject& obj, const XMLCh* signerName,
-                                     const saml::Iterator<saml::X509Certificate*>& roots, const saml::Key* knownKey);
+        virtual void verifySignature(const saml::SAMLSignedObject& obj, const XMLCh* signerName, const saml::Key* knownKey);
 
         saml::SAMLSignedObject::sigs_t m_algorithm;
         std::vector<const XMLCh*> m_policies;
@@ -178,8 +175,7 @@ namespace shibboleth
                                             const saml::Key* assertionKey=NULL, const saml::X509Certificate* assertionCert=NULL);
 
     protected:
-        virtual bool verifySignature(const saml::SAMLSignedObject& obj, const XMLCh* signerName,
-                                     const saml::Iterator<saml::X509Certificate*>& roots, const saml::Key* knownKey);
+        virtual void verifySignature(const saml::SAMLSignedObject& obj, const XMLCh* signerName, const saml::Key* knownKey);
     };
 
     class SHIB_EXPORTS ShibPOSTProfileFactory
@@ -193,8 +189,8 @@ namespace shibboleth
     {
     public:
         // global per-process setup and shutdown of Shibboleth runtime
-        virtual bool init();
-        virtual void term();
+        virtual bool init()=0;
+        virtual void term()=0;
 
         // enables runtime and clients to access configuration
         static ShibConfig& getConfig();