Major revamp of credential and trust handling code, PKIX engine still needs work.
authorScott Cantor <cantor.2@osu.edu>
Mon, 26 Mar 2007 05:59:49 +0000 (05:59 +0000)
committerScott Cantor <cantor.2@osu.edu>
Mon, 26 Mar 2007 05:59:49 +0000 (05:59 +0000)
59 files changed:
.cdtproject
xmltooling/AbstractXMLObject.cpp
xmltooling/AbstractXMLObject.h
xmltooling/Makefile.am
xmltooling/Namespace.h
xmltooling/QName.h
xmltooling/XMLObject.h
xmltooling/XMLToolingConfig.cpp
xmltooling/XMLToolingConfig.h
xmltooling/encryption/Decrypter.h
xmltooling/encryption/EncryptedKeyResolver.h
xmltooling/encryption/Encrypter.h
xmltooling/encryption/impl/Decrypter.cpp
xmltooling/encryption/impl/EncryptedKeyResolver.cpp [new file with mode: 0644]
xmltooling/encryption/impl/Encrypter.cpp
xmltooling/impl/UnknownElement.cpp
xmltooling/impl/UnknownElement.h
xmltooling/io/AbstractXMLObjectMarshaller.cpp
xmltooling/io/AbstractXMLObjectMarshaller.h
xmltooling/io/AbstractXMLObjectUnmarshaller.cpp
xmltooling/security/AbstractPKIXTrustEngine.h
xmltooling/security/BasicX509Credential.h [new file with mode: 0644]
xmltooling/security/CachingKeyResolver.h [deleted file]
xmltooling/security/ChainingTrustEngine.h
xmltooling/security/Credential.h [new file with mode: 0644]
xmltooling/security/CredentialCriteria.h [new file with mode: 0644]
xmltooling/security/CredentialResolver.h
xmltooling/security/KeyInfoResolver.h [new file with mode: 0644]
xmltooling/security/KeyInfoSource.h [deleted file]
xmltooling/security/KeyResolver.h [deleted file]
xmltooling/security/OpenSSLCredential.h [moved from xmltooling/security/OpenSSLCredentialResolver.h with 55% similarity]
xmltooling/security/OpenSSLTrustEngine.h
xmltooling/security/TrustEngine.h
xmltooling/security/X509Credential.h [new file with mode: 0644]
xmltooling/security/X509TrustEngine.h
xmltooling/security/impl/AbstractPKIXTrustEngine.cpp
xmltooling/security/impl/BasicX509Credential.cpp [new file with mode: 0644]
xmltooling/security/impl/ChainingTrustEngine.cpp
xmltooling/security/impl/Credential.cpp [new file with mode: 0644]
xmltooling/security/impl/ExplicitKeyTrustEngine.cpp
xmltooling/security/impl/FilesystemCredentialResolver.cpp
xmltooling/security/impl/InlineKeyResolver.cpp
xmltooling/security/impl/KeyInfoResolver.cpp [new file with mode: 0644]
xmltooling/security/impl/KeyResolver.cpp [deleted file]
xmltooling/security/impl/TrustEngine.cpp
xmltooling/signature/Signature.h
xmltooling/signature/SignatureValidator.h
xmltooling/signature/impl/SignatureValidator.cpp
xmltooling/signature/impl/XMLSecSignatureImpl.cpp
xmltooling/soap/SOAPClient.h
xmltooling/soap/SOAPTransport.h
xmltooling/soap/impl/CURLSOAPTransport.cpp
xmltooling/soap/impl/SOAPClient.cpp
xmltooling/util/XMLHelper.h
xmltooling/xmltooling.vcproj
xmltoolingtest/EncryptionTest.h
xmltoolingtest/FilesystemCredentialResolverTest.h
xmltoolingtest/InlineKeyResolverTest.h
xmltoolingtest/SignatureTest.h

index 93032dc..874457c 100644 (file)
 <pathentry kind="out" path="debug"/>\r
 <pathentry kind="con" path="org.eclipse.cdt.make.core.DISCOVERED_SCANNER_INFO"/>\r
 <pathentry excluding="util/|io/|impl/|validation/|signature/|signature/impl/|encryption/|encryption/impl/|security/|security/impl/|soap/|soap/impl/" kind="src" path="xmltooling"/>\r
-<pathentry kind="src" path="xmltooling/util"/>\r
-<pathentry kind="src" path="xmltooling/io"/>\r
 <pathentry kind="src" path="xmltooling/impl"/>\r
-<pathentry kind="src" path="xmltoolingtest"/>\r
-<pathentry kind="src" path="xmltooling/validation"/>\r
-<pathentry excluding="impl/" kind="src" path="xmltooling/signature"/>\r
-<pathentry kind="src" path="xmltooling/signature/impl"/>\r
+<pathentry kind="src" path="xmltooling/io"/>\r
 <pathentry excluding="impl/" kind="src" path="xmltooling/encryption"/>\r
 <pathentry kind="src" path="xmltooling/encryption/impl"/>\r
+<pathentry excluding="impl/" kind="src" path="xmltooling/signature"/>\r
+<pathentry kind="src" path="xmltooling/signature/impl"/>\r
 <pathentry excluding="impl/" kind="src" path="xmltooling/security"/>\r
 <pathentry kind="src" path="xmltooling/security/impl"/>\r
 <pathentry excluding="impl/" kind="src" path="xmltooling/soap"/>\r
 <pathentry kind="src" path="xmltooling/soap/impl"/>\r
+<pathentry kind="src" path="xmltooling/util"/>\r
+<pathentry kind="src" path="xmltooling/validation"/>\r
+<pathentry kind="src" path="xmltoolingtest"/>\r
 <pathentry include="C:/log4cpp-0.3.5rc1/include" kind="inc" path="" system="true"/>\r
 <pathentry include="C:/xerces-c2_7_0-win32/include" kind="inc" path="" system="true"/>\r
 <pathentry include="C:/xml-security-c-1.2.0/include" kind="inc" path="" system="true"/>\r
index 63d3b73..3eee63a 100644 (file)
@@ -30,7 +30,7 @@
 using namespace xmltooling;
 
 AbstractXMLObject::AbstractXMLObject(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
-    : m_log(log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".XMLObject")), m_schemaLocation(NULL),
+    : m_log(log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".XMLObject")), m_schemaLocation(NULL), m_noNamespaceSchemaLocation(NULL),
         m_parent(NULL), m_elementQname(nsURI, localName, prefix), m_typeQname(NULL)
 {
     addNamespace(Namespace(nsURI, prefix));
@@ -42,6 +42,7 @@ AbstractXMLObject::AbstractXMLObject(const XMLCh* nsURI, const XMLCh* localName,
 
 AbstractXMLObject::AbstractXMLObject(const AbstractXMLObject& src)
     : m_namespaces(src.m_namespaces), m_log(src.m_log), m_schemaLocation(XMLString::replicate(src.m_schemaLocation)),
+        m_noNamespaceSchemaLocation(XMLString::replicate(src.m_noNamespaceSchemaLocation)),
         m_parent(NULL), m_elementQname(src.m_elementQname), m_typeQname(NULL)
 {
     if (src.m_typeQname)
index 4df58e4..576a7d0 100644 (file)
@@ -48,6 +48,7 @@ namespace xmltooling {
         virtual ~AbstractXMLObject() {
             delete m_typeQname;
             XMLString::release(&m_schemaLocation);
+            XMLString::release(&m_noNamespaceSchemaLocation);
         }
 
         void detach();
@@ -201,6 +202,11 @@ namespace xmltooling {
          */
         XMLCh* m_schemaLocation;
 
+        /**
+         * Stores off xsi:noNamespaceSchemaLocation attribute.
+         */
+        XMLCh* m_noNamespaceSchemaLocation;
+
     private:
         XMLObject* m_parent;
         QName m_elementQname;
index c3f76e2..2b26988 100644 (file)
@@ -58,13 +58,15 @@ ioinclude_HEADERS = \
 
 secinclude_HEADERS = \
        security/AbstractPKIXTrustEngine.h \
-       security/CachingKeyResolver.h \
+       security/BasicX509Credential.h \
        security/ChainingTrustEngine.h \
+       security/Credential.h \
+       security/CredentialCriteria.h \
        security/CredentialResolver.h \
-       security/KeyInfoSource.h \
-       security/KeyResolver.h \
-       security/OpenSSLCredentialResolver.h \
+       security/KeyInfoResolver.h \
+       security/OpenSSLCredential.h \
        security/TrustEngine.h \
+       security/X509Credential.h \
        security/X509TrustEngine.h \
        security/OpenSSLTrustEngine.h \
        security/XSECCryptoX509CRL.h \
@@ -107,17 +109,20 @@ noinst_HEADERS = \
 if BUILD_XMLSEC
 xmlsec_sources = \
        encryption/impl/Decrypter.cpp \
+       encryption/impl/EncryptedKeyResolver.cpp \
        encryption/impl/Encrypter.cpp \
-       security/impl/TrustEngine.cpp \
        security/impl/AbstractPKIXTrustEngine.cpp \
+       security/impl/BasicX509Credential.cpp \
        security/impl/ChainingTrustEngine.cpp \
+       security/impl/Credential.cpp \
        security/impl/CredentialResolver.cpp \
+       security/impl/ExplicitKeyTrustEngine.cpp \
        security/impl/FilesystemCredentialResolver.cpp \
        security/impl/InlineKeyResolver.cpp \
-       security/impl/ExplicitKeyTrustEngine.cpp \
-       security/impl/KeyResolver.cpp \
-       security/impl/XSECCryptoX509CRL.cpp \
+       security/impl/KeyInfoResolver.cpp \
        security/impl/OpenSSLCryptoX509CRL.cpp \
+       security/impl/TrustEngine.cpp \
+       security/impl/XSECCryptoX509CRL.cpp \
        signature/impl/SignatureValidator.cpp \
        signature/impl/XMLSecSignatureImpl.cpp
 else
index eafa000..9a1b55a 100644 (file)
 #include <xmltooling/unicode.h>
 
 namespace xmltooling {
-    
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4251 )
+#endif
+
     /**
      * A data structure for encapsulating XML Namespace attributes
      */
@@ -115,6 +120,10 @@ namespace xmltooling {
 #endif
     };
 
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
     /**
      * Returns true iff op1's namespace lexically compares less than op2's namespace,
      * or if equal, iff op1's prefix lexically compares less than op2's prefix.
index 67d1d40..bb672f1 100644 (file)
 #include <algorithm>
 
 namespace xmltooling {
-    
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4251 )
+#endif
+
     /**
      * A data structure for encapsulating XML QNames.
      * The Xerces class is too limited to use at the moment.
@@ -168,6 +173,10 @@ namespace xmltooling {
 #endif
     };
 
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
     /**
      * Returns true iff op1's namespace lexically compares less than op2's namespace,
      * or if equal, iff op1's prefix lexically compares less than op2's prefix.
index 1d86737..6dd887f 100644 (file)
@@ -46,6 +46,10 @@ namespace xmlsignature {
 
 namespace xmltooling {
 
+#ifndef XMLTOOLING_NO_XMLSEC
+    class XMLTOOL_API Credential;
+#endif
+
     /**
      * Object that represents an XML Element that has been unmarshalled into this C++ object.
      */
@@ -261,6 +265,7 @@ namespace xmltooling {
          * 
          * @param document  the DOM document the marshalled element will be placed in, or NULL
          * @param sigs      ordered array of signatures to create after marshalling is complete
+         * @param credential    optional credential to supply signing key and related info
          * @return the DOM element representing this XMLObject
          * 
          * @throws MarshallingException thrown if there is a problem marshalling the given object
@@ -270,6 +275,7 @@ namespace xmltooling {
             DOMDocument* document=NULL
 #ifndef XMLTOOLING_NO_XMLSEC
             ,const std::vector<xmlsignature::Signature*>* sigs=NULL
+            ,const Credential* credential=NULL
 #endif
             ) const=0;
         
@@ -281,6 +287,7 @@ namespace xmltooling {
          * 
          * @param parentElement the parent element to append the resulting DOM tree
          * @param sigs          ordered array of signatures to create after marshalling is complete
+         * @param credential    optional credential to supply signing key and related info
          * @return the marshalled element tree
 
          * @throws MarshallingException thrown if the given XMLObject can not be marshalled.
@@ -290,6 +297,7 @@ namespace xmltooling {
             DOMElement* parentElement
 #ifndef XMLTOOLING_NO_XMLSEC
             ,const std::vector<xmlsignature::Signature*>* sigs=NULL
+            ,const Credential* credential=NULL
 #endif
             ) const=0;
 
index 5b245d2..4a00d2a 100644 (file)
@@ -28,6 +28,8 @@
 #include "security/TrustEngine.h"
 #include "security/OpenSSLCryptoX509CRL.h"
 #include "security/CredentialResolver.h"
+#include "security/KeyInfoResolver.h"
+#include "signature/Signature.h"
 #include "soap/SOAP.h"
 #include "soap/SOAPTransport.h"
 #include "util/NDC.h"
@@ -234,8 +236,6 @@ bool XMLToolingInternalConfig::init()
         registerEncryptionClasses();
         registerSOAPClasses();
 
-        m_urlEncoder = new URLEncoder();
-        
         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(XMLParserException,xmltooling);
         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(XMLObjectException,xmltooling);
         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(MarshallingException,xmltooling);
@@ -250,7 +250,7 @@ bool XMLToolingInternalConfig::init()
         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(XMLSecurityException,xmltooling);
         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(SignatureException,xmlsignature);
         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(EncryptionException,xmlencryption);
-        registerKeyResolvers();
+        registerKeyInfoResolvers();
         registerCredentialResolvers();
         registerTrustEngines();
 #endif
@@ -258,6 +258,9 @@ bool XMLToolingInternalConfig::init()
         initSOAPTransports();
         registerStorageServices();
 
+        m_urlEncoder = new URLEncoder();
+        m_keyInfoResolver = KeyInfoResolverManager.newPlugin(INLINE_KEYINFO_RESOLVER,NULL);
+        
         // Register xml:id as an ID attribute.        
         static const XMLCh xmlid[] = UNICODE_LITERAL_2(i,d);
         AttributeExtensibleXMLObject::registerIDAttribute(QName(xmlconstants::XML_NS, xmlid)); 
@@ -297,9 +300,12 @@ void XMLToolingInternalConfig::term()
 #ifndef XMLTOOLING_NO_XMLSEC
     TrustEngineManager.deregisterFactories();
     CredentialResolverManager.deregisterFactories();
-    KeyResolverManager.deregisterFactories();
+    KeyInfoResolverManager.deregisterFactories();
 #endif
 
+    delete m_keyInfoResolver;
+    m_keyInfoResolver = NULL;
+
     delete m_replayCache;
     m_replayCache = NULL;
     
index cd04d71..a16b806 100644 (file)
@@ -31,7 +31,7 @@
 namespace xmltooling {
     class XMLTOOL_API CredentialResolver;
     class XMLTOOL_API KeyInfoSource;
-    class XMLTOOL_API KeyResolver;
+    class XMLTOOL_API KeyInfoResolver;
     class XMLTOOL_API TrustEngine;
     class XMLTOOL_API XSECCryptoX509CRL;
 };
@@ -61,8 +61,11 @@ namespace xmltooling {
     {
         MAKE_NONCOPYABLE(XMLToolingConfig);
     protected:
-        XMLToolingConfig() : m_replayCache(NULL), m_templateEngine(NULL), m_urlEncoder(NULL), clock_skew_secs(180) {}
+        XMLToolingConfig() : m_keyInfoResolver(NULL), m_replayCache(NULL), m_templateEngine(NULL), m_urlEncoder(NULL), clock_skew_secs(180) {}
         
+        /** Global KeyInfoResolver instance. */
+        KeyInfoResolver* m_keyInfoResolver;
+
         /** Global ReplayCache instance. */
         ReplayCache* m_replayCache;
         
@@ -145,6 +148,24 @@ namespace xmltooling {
         virtual ParserPool& getValidatingParser() const=0;
 
         /**
+         * Sets the global KeyInfoResolver instance.
+         * This method must be externally synchronized with any code that uses the object.
+         * Any previously set object is destroyed.
+         * 
+         * @param keyInfoResolver   new KeyInfoResolver instance to store
+         */
+        void setKeyInfoResolver(KeyInfoResolver* keyInfoResolver);
+
+        /**
+         * Returns the global KeyInfoResolver instance.
+         * 
+         * @return  global KeyInfoResolver or NULL
+         */
+        const KeyInfoResolver* getKeyInfoResolver() const {
+            return m_keyInfoResolver;
+        }
+
+        /**
          * Sets the global ReplayCache instance.
          * This method must be externally synchronized with any code that uses the object.
          * Any previously set object is destroyed.
@@ -218,9 +239,9 @@ namespace xmltooling {
         virtual XSECCryptoX509CRL* X509CRL() const=0;
 
         /**
-         * Manages factories for KeyResolver plugins.
+         * Manages factories for KeyInfoResolver plugins.
          */
-        PluginManager<KeyResolver,const DOMElement*> KeyResolverManager;
+        PluginManager<KeyInfoResolver,const DOMElement*> KeyInfoResolverManager;
 
         /**
          * Manages factories for CredentialResolver plugins.
@@ -235,8 +256,10 @@ namespace xmltooling {
 
         /**
          * Manages factories for SOAPTransport plugins.
+         * 
+         * <p>The factory interface takes a peer name/endpoint pair.
          */
-        PluginManager<SOAPTransport,std::pair<const KeyInfoSource*,const char*> > SOAPTransportManager;
+        PluginManager<SOAPTransport,std::pair<const char*,const char*> > SOAPTransportManager;
 
         /**
          * Manages factories for StorageService plugins.
index 0d5f27c..e23156a 100644 (file)
 #include <xsec/xenc/XENCCipher.hpp>
 
 namespace xmltooling {
+    class XMLTOOL_API CredentialCriteria;
     class XMLTOOL_API CredentialResolver;
-    class XMLTOOL_API KeyResolver;
 };
 
 namespace xmlencryption {
 
+    class XMLTOOL_API EncryptedKeyResolver;
+
     /**
      * Wrapper API for XML Decryption functionality.
      */
@@ -43,34 +45,57 @@ namespace xmlencryption {
         /**
          * Constructor.
          * 
-         * @param KEKresolver   locked credential resolver to supply key decryption key
-         * @param resolver      directly or indirectly resolves the data decryption key
+         * @param credResolver  locked credential resolver to supply decryption keys
+         * @param criteria      optional external criteria to use with resolver
+         * @param EKresolver    locates an EncryptedKey pertaining to the EncryptedData
          */
-        Decrypter(const xmltooling::CredentialResolver* KEKresolver=NULL, const xmltooling::KeyResolver* resolver=NULL)
-            : m_cipher(NULL), m_KEKresolver(KEKresolver), m_resolver(resolver) {
+        Decrypter(
+            const xmltooling::CredentialResolver* credResolver=NULL,
+            xmltooling::CredentialCriteria* criteria=NULL,
+            const EncryptedKeyResolver* EKResolver=NULL
+            ) : m_cipher(NULL), m_credResolver(credResolver), m_criteria(criteria), m_EKResolver(EKResolver) {
         }
 
         ~Decrypter();
         
         /**
-         * Replace the current data encryption KeyResolver interface, if any, with a new one.
+         * Replace the current EncryptedKeyResolver interface, if any, with a new one.
          * 
-         * @param resolver  the KeyResolver to attach 
+         * @param EKresolver  the EncryptedKeyResolver to attach 
          */
-        void setKeyResolver(const xmltooling::KeyResolver* resolver) {
-            m_resolver=resolver;
+        void setEncryptedKeyResolver(const EncryptedKeyResolver* EKResolver) {
+            m_EKResolver=EKResolver;
         }
 
         /**
-         * Replace the current key encryption CredentialResolver interface, if any, with a new one.
+         * Replace the current CredentialResolver interface, if any, with a new one.
          * 
-         * @param resolver  the locked CredentialResolver to attach 
+         * @param resolver  the locked CredentialResolver to attach, or NULL to clear
+         * @param criteria  optional external criteria to use with resolver
          */
-        void setKEKResolver(const xmltooling::CredentialResolver* resolver) {
-            m_KEKresolver=resolver;
+        void setKEKResolver(const xmltooling::CredentialResolver* resolver, xmltooling::CredentialCriteria* criteria) {
+            m_credResolver=resolver;
+            m_criteria=criteria;
         }
 
         /**
+         * Decrypts the supplied information using the supplied key, and returns
+         * the resulting as a DOM fragment owned by the document associated with the
+         * marshalled EncryptedData object.
+         * 
+         * Note that the DOM nodes will be invalidated once that document
+         * is released. The caller should therefore process the DOM fragment as
+         * required and drop all references to it before that happens. The usual
+         * approach should be to unmarshall the DOM and then release it, or the
+         * DOM can also be imported into a separately owned document.
+         * 
+         * @param encryptedData the data to decrypt
+         * @param key           the decryption key to use (it will not be freed internally)
+         * @return  the decrypted DOM fragment
+         */
+        DOMDocumentFragment* decryptData(const EncryptedData& encryptedData, XSECCryptoKey* key);
+
+        /**
          * Decrypts the supplied information and returns the resulting as a DOM
          * fragment owned by the document associated with the marshalled EncryptedData
          * object.
@@ -82,9 +107,10 @@ namespace xmlencryption {
          * DOM can also be imported into a separately owned document.
          * 
          * @param encryptedData the data to decrypt
+         * @param recipient identifier of decrypting entity for use in identifying multi-cast keys
          * @return  the decrypted DOM fragment
          */
-        DOMDocumentFragment* decryptData(EncryptedData& encryptedData);
+        DOMDocumentFragment* decryptData(const EncryptedData& encryptedData, const XMLCh* recipient=NULL);
         
         /**
          * Decrypts the supplied information and returns the resulting key.
@@ -96,12 +122,13 @@ namespace xmlencryption {
          * @param algorithm     the algorithm associated with the decrypted key
          * @return  the decrypted key
          */
-        XSECCryptoKey* decryptKey(EncryptedKey& encryptedKey, const XMLCh* algorithm);
+        XSECCryptoKey* decryptKey(const EncryptedKey& encryptedKey, const XMLCh* algorithm);
         
     private:
         XENCCipher* m_cipher;
-        const xmltooling::CredentialResolver* m_KEKresolver;
-        const xmltooling::KeyResolver* m_resolver;
+        const xmltooling::CredentialResolver* m_credResolver;
+        xmltooling::CredentialCriteria* m_criteria;
+        const EncryptedKeyResolver* m_EKResolver;
     };
 
     DECL_XMLTOOLING_EXCEPTION(DecryptionException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmlencryption,xmltooling::XMLToolingException,Exceptions in decryption processing);
index 73dccb3..440c465 100644 (file)
 #define __xmltooling_enckeyres_h__
 
 #include <xmltooling/encryption/Encryption.h>
-#include <xmltooling/security/KeyResolver.h>
 
 namespace xmlencryption {
 
     /**
      * An API for resolving encrypted decryption keys.
      */
-    class XMLTOOL_API EncryptedKeyResolver : public xmltooling::KeyResolver {
+    class XMLTOOL_API EncryptedKeyResolver {
+        MAKE_NONCOPYABLE(EncryptedKeyResolver);
     public:
+        EncryptedKeyResolver() {}
         virtual ~EncryptedKeyResolver() {}
         
         /**
          * Returns an encrypted key based on the supplied object's KeyInfo information.
          * 
          * @param encryptedData an encrypted object
+         * @param recipient identifier of recipient of encrypted key
          * @return  the resolved EncryptedKey object
          */
-        virtual EncryptedKey* resolveKey(EncryptedData& encryptedData) const=0;
+        virtual const EncryptedKey* resolveKey(const EncryptedData& encryptedData, const XMLCh* recipient=NULL) const;
     };
 
 };
index c562a22..1bf6945 100644 (file)
 #include <xsec/enc/XSECCryptoKey.hpp>
 #include <xsec/xenc/XENCCipher.hpp>
 
+namespace xmltooling {
+    class XMLTOOL_API Credential;
+};
+
 namespace xmlencryption {
 
     /**
@@ -60,34 +64,33 @@ namespace xmlencryption {
             
             /**
              * Constructor.
+             *
              * The algorithm constant and key buffer <strong>MUST</strong> be accessible for the life of
-             * the structure. The other objects will be destroyed if need be when the structure is destroyed. 
+             * the structure.
              * 
-             * @param algorithm     the XML Encryption key wrapping or transport algorithm constant
+             * @param algorithm     the XML Encryption algorithm constant
              * @param keyBuffer     buffer containing the raw key information
              * @param keyBufferSize the size of the raw key buffer in bytes  
-             * @param key           the key encryption key to use, or NULL
-             * @param keyInfo       a KeyInfo object to place within the EncryptedData structure
+             * @param credential    optional Credential supplying the encryption key
+             * @param compact       true iff the encrypted representation should be made as small as possible
              */
             EncryptionParams(
                 const XMLCh* algorithm=DSIGConstants::s_unicodeStrURIAES256_CBC,
                 const unsigned char* keyBuffer=NULL,
                 unsigned int keyBufferSize=0,
-                XSECCryptoKey* key=NULL,
-                xmlsignature::KeyInfo* keyInfo=NULL
-                ) : m_keyBuffer(keyBuffer), m_keyBufferSize(keyBufferSize), m_key(key), m_keyInfo(keyInfo), m_algorithm(algorithm) {
+                const xmltooling::Credential* credential=NULL,
+                bool compact=false
+                ) :  m_algorithm(algorithm), m_keyBuffer(keyBuffer), m_keyBufferSize(keyBufferSize),
+                    m_credential(credential), m_compact(compact) {
             }
 
-            ~EncryptionParams() {
-                delete m_key;
-                delete m_keyInfo;
-            }
+            ~EncryptionParams() {}
         private:
+            const XMLCh* m_algorithm;
             const unsigned char* m_keyBuffer;
             unsigned int m_keyBufferSize;
-            XSECCryptoKey* m_key;
-            xmlsignature::KeyInfo* m_keyInfo;
-            const XMLCh* m_algorithm;
+            const xmltooling::Credential* m_credential;
+            bool m_compact;
             
             friend class Encrypter;
         };
@@ -99,32 +102,23 @@ namespace xmlencryption {
             
             /**
              * Constructor.
-             * The algorithm and recipient constants <strong>MUST</strong> be accessible for the life of the
-             * structure. Using a static constant suffices for this. The other objects will be destroyed if
-             * when the structure is destroyed. 
              * 
+             * @param credential    a Credential supplying the key encryption key
              * @param algorithm     the XML Encryption key wrapping or transport algorithm constant
-             * @param key           the key encryption key to use
              * @param recipient     optional name of recipient of encrypted key
-             * @param keyInfo       a KeyInfo object to place within the EncryptedKey structure that describes the KEK
              */
             KeyEncryptionParams(
+                const xmltooling::Credential& credential,
                 const XMLCh* algorithm,
-                XSECCryptoKey* key,
-                const XMLCh* recipient=NULL,
-                xmlsignature::KeyInfo* keyInfo=NULL
-                ) : m_algorithm(algorithm), m_key(key), m_recipient(recipient), m_keyInfo(keyInfo) {
+                const XMLCh* recipient=NULL
+                ) : m_credential(credential), m_algorithm(algorithm), m_recipient(recipient) {
             }
         
-            ~KeyEncryptionParams() {
-                delete m_key;
-                delete m_keyInfo;
-            }
+            ~KeyEncryptionParams() {}
         private:
+            const xmltooling::Credential& m_credential;
             const XMLCh* m_algorithm;
-            XSECCryptoKey* m_key;
             const XMLCh* m_recipient;
-            xmlsignature::KeyInfo* m_keyInfo;
             
             friend class Encrypter;
         };
@@ -190,9 +184,10 @@ namespace xmlencryption {
          * @param keyBuffer     raw key material to encrypt
          * @param keyBufferSize size in bytes of raw key material
          * @param kencParams    key encryption settings
+         * @param compact       true iff the encrypted representation should be made as small as possible
          * @return a stand-alone EncryptedKey object, unconnected to any DOM 
          */
-        EncryptedKey* encryptKey(const unsigned char* keyBuffer, unsigned int keyBufferSize, KeyEncryptionParams& kencParams);
+        EncryptedKey* encryptKey(const unsigned char* keyBuffer, unsigned int keyBufferSize, KeyEncryptionParams& kencParams, bool compact=false);
         
     private:
         void checkParams(EncryptionParams& encParams, KeyEncryptionParams* kencParams);
index 2f2afe2..aaeed9d 100644 (file)
@@ -23,6 +23,8 @@
 #include "internal.h"
 #include "encryption/Decrypter.h"
 #include "encryption/EncryptedKeyResolver.h"
+#include "security/Credential.h"
+#include "security/CredentialCriteria.h"
 #include "security/CredentialResolver.h"
 
 #include <log4cpp/Category.hh>
@@ -44,11 +46,11 @@ Decrypter::~Decrypter()
         XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseCipher(m_cipher);
 }
 
-DOMDocumentFragment* Decrypter::decryptData(EncryptedData& encryptedData)
+DOMDocumentFragment* Decrypter::decryptData(const EncryptedData& encryptedData, XSECCryptoKey* key)
 {
     if (encryptedData.getDOM()==NULL)
         throw DecryptionException("The object must be marshalled before decryption.");
-    
+
     // We can reuse the cipher object if the document hasn't changed.
 
     if (m_cipher && m_cipher->getDocument()!=encryptedData.getDOM()->getOwnerDocument()) {
@@ -58,56 +60,9 @@ DOMDocumentFragment* Decrypter::decryptData(EncryptedData& encryptedData)
     
     if (!m_cipher)
         m_cipher=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newCipher(encryptedData.getDOM()->getOwnerDocument());
-    
-    try {
-        // Resolve decryption key.
-        XSECCryptoKey* key=NULL;
-        if (m_resolver)
-            key=m_resolver->resolveKey(encryptedData.getKeyInfo());
-
-        if (!key && m_KEKresolver) {
-            // See if there's an encrypted key available. We'll need the algorithm...
-            const XMLCh* algorithm=
-                encryptedData.getEncryptionMethod() ? encryptedData.getEncryptionMethod()->getAlgorithm() : NULL;
-            if (!algorithm)
-                throw DecryptionException("No EncryptionMethod/@Algorithm set, key decryption cannot proceed.");
-            
-            if (encryptedData.getKeyInfo()) {
-                const vector<XMLObject*>& others=const_cast<const KeyInfo*>(encryptedData.getKeyInfo())->getUnknownXMLObjects();
-                for (vector<XMLObject*>::const_iterator i=others.begin(); i!=others.end(); i++) {
-                    EncryptedKey* encKey=dynamic_cast<EncryptedKey*>(*i);
-                    if (encKey) {
-                        try {
-                            key=decryptKey(*encKey, algorithm);
-                        }
-                        catch (DecryptionException& e) {
-                            log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".Decrypter").warn(e.what());
-                        }
-                    }
-                }
-            }
-            
-            if (!key) {
-                // Check for a non-trivial resolver.
-                const EncryptedKeyResolver* ekr=dynamic_cast<const EncryptedKeyResolver*>(m_resolver);
-                if (ekr) {
-                    EncryptedKey* encKey=ekr->resolveKey(encryptedData);
-                    if (encKey) {
-                        try {
-                            key=decryptKey(*encKey, algorithm);
-                        }
-                        catch (DecryptionException& e) {
-                            log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".Decrypter").warn(e.what());
-                        }
-                    }
-                }
-            }
-        }
 
-        if (!key)
-            throw DecryptionException("Unable to resolve a decryption key.");
-        
-        m_cipher->setKey(key);
+    try {
+        m_cipher->setKey(key->clone());
         DOMNode* ret=m_cipher->decryptElementDetached(encryptedData.getDOM());
         if (ret->getNodeType()!=DOMNode::DOCUMENT_FRAGMENT_NODE) {
             ret->release();
@@ -124,8 +79,78 @@ DOMDocumentFragment* Decrypter::decryptData(EncryptedData& encryptedData)
     }
 }
 
-XSECCryptoKey* Decrypter::decryptKey(EncryptedKey& encryptedKey, const XMLCh* algorithm)
+DOMDocumentFragment* Decrypter::decryptData(const EncryptedData& encryptedData, const XMLCh* recipient)
 {
+    if (!m_credResolver)
+        throw DecryptionException("No CredentialResolver supplied to provide decryption keys.");
+
+    // Resolve a decryption key directly.
+    vector<const Credential*> creds;
+    if (m_criteria) {
+        m_criteria->setUsage(CredentialCriteria::ENCRYPTION_CREDENTIAL);
+        m_criteria->setKeyInfo(encryptedData.getKeyInfo());
+        const EncryptionMethod* meth = encryptedData.getEncryptionMethod();
+        if (meth) {
+            auto_ptr_char alg(meth->getAlgorithm());
+            m_criteria->setKeyAlgorithm(alg.get());
+        }
+        m_credResolver->resolve(creds,m_criteria);
+    }
+    else {
+        CredentialCriteria criteria;
+        criteria.setUsage(CredentialCriteria::ENCRYPTION_CREDENTIAL);
+        criteria.setKeyInfo(encryptedData.getKeyInfo());
+        const EncryptionMethod* meth = encryptedData.getEncryptionMethod();
+        if (meth) {
+            auto_ptr_char alg(meth->getAlgorithm());
+            criteria.setKeyAlgorithm(alg.get());
+        }
+        m_credResolver->resolve(creds,&criteria);
+    }
+
+    // Loop over them and try each one.
+    XSECCryptoKey* key;
+    for (vector<const Credential*>::const_iterator cred = creds.begin(); cred!=creds.end(); ++cred) {
+        try {
+            key = (*cred)->getPrivateKey();
+            if (!key)
+                continue;
+            return decryptData(encryptedData, key);
+        }
+        catch(DecryptionException& ex) {
+            log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".Decrypter").warn(ex.what());
+        }
+    }
+
+    // We need to find an encrypted decryption key somewhere. We'll need the underlying algorithm...
+    const XMLCh* algorithm=
+        encryptedData.getEncryptionMethod() ? encryptedData.getEncryptionMethod()->getAlgorithm() : NULL;
+    if (!algorithm)
+        throw DecryptionException("No EncryptionMethod/@Algorithm set, key decryption cannot proceed.");
+    
+    // Check for external resolver.
+    const EncryptedKey* encKey=NULL;
+    if (m_EKResolver)
+        encKey = m_EKResolver->resolveKey(encryptedData, recipient);
+    else {
+        EncryptedKeyResolver ekr;
+        encKey = ekr.resolveKey(encryptedData, recipient);
+    }
+
+    if (!encKey)
+        throw DecryptionException("Unable to locate an encrypted key.");
+
+    auto_ptr<XSECCryptoKey> keywrapper(decryptKey(*encKey, algorithm));
+    if (!keywrapper.get())
+        throw DecryptionException("Unable to decrypt the encrypted key.");
+    return decryptData(encryptedData, keywrapper.get());
+}
+
+XSECCryptoKey* Decrypter::decryptKey(const EncryptedKey& encryptedKey, const XMLCh* algorithm)
+{
+    if (!m_credResolver)
+        throw DecryptionException("No CredentialResolver supplied to provide decryption keys.");
+
     if (encryptedKey.getDOM()==NULL)
         throw DecryptionException("The object must be marshalled before decryption.");
     
@@ -139,31 +164,52 @@ XSECCryptoKey* Decrypter::decryptKey(EncryptedKey& encryptedKey, const XMLCh* al
     if (!m_cipher)
         m_cipher=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newCipher(encryptedKey.getDOM()->getOwnerDocument());
     
+    // Resolve key decryption key. We can't loop over possible credentials because
+    // we can't tell a valid decrypt from an invalid one.
+    const Credential* cred=NULL;
+    if (m_criteria) {
+        m_criteria->setUsage(CredentialCriteria::ENCRYPTION_CREDENTIAL);
+        m_criteria->setKeyInfo(encryptedKey.getKeyInfo());
+        const EncryptionMethod* meth = encryptedKey.getEncryptionMethod();
+        if (meth) {
+            auto_ptr_char alg(meth->getAlgorithm());
+            m_criteria->setKeyAlgorithm(alg.get());
+        }
+        cred = m_credResolver->resolve(m_criteria);
+    }
+    else {
+        CredentialCriteria criteria;
+        criteria.setUsage(CredentialCriteria::ENCRYPTION_CREDENTIAL);
+        criteria.setKeyInfo(encryptedKey.getKeyInfo());
+        const EncryptionMethod* meth = encryptedKey.getEncryptionMethod();
+        if (meth) {
+            auto_ptr_char alg(meth->getAlgorithm());
+            criteria.setKeyAlgorithm(alg.get());
+        }
+        cred = m_credResolver->resolve(&criteria);
+    }
+    if (!cred || !cred->getPrivateKey())
+        throw DecryptionException("Unable to resolve a key decryption key.");
+
     try {
-        // Resolve key decryption key.
-        XSECCryptoKey* key=NULL;
-        if (m_KEKresolver)
-            key=m_KEKresolver->getKey(encryptedKey.getKeyInfo());
-        if (!key)
-            throw DecryptionException("Unable to resolve a key decryption key.");
-        m_cipher->setKEK(key);
-        
+        m_cipher->setKEK(cred->getPrivateKey()->clone());
         XMLByte buffer[1024];
+        memset(buffer,0,sizeof(buffer));
         int keySize = m_cipher->decryptKey(encryptedKey.getDOM(), buffer, 1024);
-        if (keySize > 0) {
-            // Try to map the key.
-            XSECAlgorithmHandler* handler = XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(algorithm);
-            if (handler != NULL)
-                return handler->createKeyForURI(algorithm, buffer, keySize);
-            throw DecryptionException("Unrecognized algorithm, could not build object around decrypted key.");
-        }
-        throw DecryptionException("Unable to decrypt key.");
+        if (keySize<=0)
+            throw DecryptionException("Unable to decrypt key.");
+
+        // Try to map the key.
+        XSECAlgorithmHandler* handler = XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(algorithm);
+        if (handler != NULL)
+            return handler->createKeyForURI(algorithm, buffer, keySize);
+        throw DecryptionException("Unrecognized algorithm, could not build object around decrypted key.");
     }
     catch(XSECException& e) {
         auto_ptr_char temp(e.getMsg());
-        throw DecryptionException(string("XMLSecurity exception while decrypting: ") + temp.get());
+        throw DecryptionException(string("XMLSecurity exception while decrypting key: ") + temp.get());
     }
     catch(XSECCryptoException& e) {
-        throw DecryptionException(string("XMLSecurity exception while decrypting: ") + e.getMsg());
+        throw DecryptionException(string("XMLSecurity exception while decrypting key: ") + e.getMsg());
     }
 }
diff --git a/xmltooling/encryption/impl/EncryptedKeyResolver.cpp b/xmltooling/encryption/impl/EncryptedKeyResolver.cpp
new file mode 100644 (file)
index 0000000..5afe82e
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * EncryptedKeyResolver.cpp
+ * 
+ * Resolves encrypted keys based on EncryptedData information or other external factors.
+ */
+
+#include "internal.h"
+#include "encryption/EncryptedKeyResolver.h"
+
+using namespace xmlencryption;
+using namespace xmlsignature;
+using namespace xmltooling;
+using namespace std;
+
+const EncryptedKey* EncryptedKeyResolver::resolveKey(const EncryptedData& encryptedData, const XMLCh* recipient) const
+{
+    if (!encryptedData.getKeyInfo())
+        return NULL;
+
+    const vector<XMLObject*>& others=const_cast<const KeyInfo*>(encryptedData.getKeyInfo())->getUnknownXMLObjects();
+    for (vector<XMLObject*>::const_iterator i=others.begin(); i!=others.end(); i++) {
+        EncryptedKey* encKey=dynamic_cast<EncryptedKey*>(*i);
+        if (encKey && (!recipient || !encKey->getRecipient() || XMLString::equals(recipient,encKey->getRecipient())))
+            return encKey;
+    }
+
+    return NULL;
+}
index 1a5563c..45e9e07 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "internal.h"
 #include "encryption/Encrypter.h"
+#include "security/Credential.h"
 
 #include <xsec/enc/XSECCryptoException.hpp>
 #include <xsec/framework/XSECException.hpp>
@@ -44,11 +45,11 @@ Encrypter::~Encrypter()
 void Encrypter::checkParams(EncryptionParams& encParams, KeyEncryptionParams* kencParams)
 {
     if (encParams.m_keyBufferSize==0) {
-        if (encParams.m_key) {
+        if (encParams.m_credential) {
             if (kencParams)
                 throw EncryptionException("Generating EncryptedKey inline requires the encryption key in raw form.");
         }
-        else if (!encParams.m_key) {
+        else if (!encParams.m_credential) {
             if (!kencParams)
                 throw EncryptionException("Using a generated encryption key requires a KeyEncryptionParams object.");
 
@@ -60,20 +61,27 @@ void Encrypter::checkParams(EncryptionParams& encParams, KeyEncryptionParams* ke
         }
     }
     
-    if (!encParams.m_key) {
+    XSECCryptoKey* key=NULL;
+    if (encParams.m_credential) {
+        key = encParams.m_credential->getPrivateKey();
+        if (!key)
+            throw EncryptionException("Credential in EncryptionParams structure did not supply a private/secret key.");
+        // Set the encryption key.
+        m_cipher->setKey(key->clone());
+    }
+    else {
         // We have to have a raw key now, so we need to build a wrapper around it.
         XSECAlgorithmHandler* handler =XSECPlatformUtils::g_algorithmMapper->mapURIToHandler(encParams.m_algorithm);
         if (handler != NULL)
-            encParams.m_key = handler->createKeyForURI(
+            key = handler->createKeyForURI(
                 encParams.m_algorithm,const_cast<unsigned char*>(encParams.m_keyBuffer),encParams.m_keyBufferSize
                 );
 
-        if (!encParams.m_key)
+        if (!key)
             throw EncryptionException("Unable to build wrapper for key, unknown algorithm?");
+        // Set the encryption key.
+        m_cipher->setKey(key);
     }
-    
-    // Set the encryption key.
-    m_cipher->setKey(encParams.m_key->clone());
 }
 
 EncryptedData* Encrypter::encryptElement(DOMElement* element, EncryptionParams& encParams, KeyEncryptionParams* kencParams)
@@ -151,8 +159,7 @@ EncryptedData* Encrypter::encryptStream(istream& input, EncryptionParams& encPar
         checkParams(encParams,kencParams);
         StreamInputSource::StreamBinInputStream xstream(input);
         m_cipher->encryptBinInputStream(&xstream, ENCRYPT_NONE, encParams.m_algorithm);
-        EncryptedData* xmlEncData = decorateAndUnmarshall(encParams, kencParams);
-        return xmlEncData;
+        return decorateAndUnmarshall(encParams, kencParams);
     }
     catch(XSECException& e) {
         auto_ptr_char temp(e.getMsg());
@@ -179,14 +186,17 @@ EncryptedData* Encrypter::decorateAndUnmarshall(EncryptionParams& encParams, Key
     xmlEncData->releaseThisAndChildrenDOM();
     
     // KeyInfo?
-    if (encParams.m_keyInfo) {
-        xmlEncData->setKeyInfo(encParams.m_keyInfo);
-        encParams.m_keyInfo=NULL;   // transfer ownership
-    }
+    const KeyInfo* kinfo = encParams.m_credential ? encParams.m_credential->getKeyInfo(encParams.m_compact) : NULL;
+    if (kinfo)
+        xmlEncData->setKeyInfo(kinfo->cloneKeyInfo());
     
     // Are we doing a key encryption?
     if (kencParams) {
-        m_cipher->setKEK(kencParams->m_key->clone());
+        XSECCryptoKey* kek = kencParams->m_credential.getPublicKey();
+        if (!kek)
+            throw EncryptionException("Credential in KeyEncryptionParams structure did not supply a public key.");
+
+        m_cipher->setKEK(kek->clone());
         // ownership of this belongs to us, for some reason...
         auto_ptr<XENCEncryptedKey> encKey(
             m_cipher->encryptKey(encParams.m_keyBuffer, encParams.m_keyBufferSize, ENCRYPT_NONE, kencParams->m_algorithm)
@@ -203,12 +213,11 @@ EncryptedData* Encrypter::decorateAndUnmarshall(EncryptionParams& encParams, Key
             xmlEncKey->setRecipient(kencParams->m_recipient);
         
         // KeyInfo?
-        if (kencParams->m_keyInfo) {
-            xmlEncKey->setKeyInfo(kencParams->m_keyInfo);
-            kencParams->m_keyInfo=NULL;   // transfer ownership
-        }
+        kinfo = kencParams->m_credential.getKeyInfo(encParams.m_compact);
+        if (kinfo)
+            xmlEncKey->setKeyInfo(kinfo->cloneKeyInfo());
         
-        // Add the EncryptedKey.
+        // Add the EncryptedKey inline.
         if (!xmlEncData->getKeyInfo())
             xmlEncData->setKeyInfo(KeyInfoBuilder::buildKeyInfo());
         xmlEncData->getKeyInfo()->getUnknownXMLObjects().push_back(xmlEncKey);
@@ -219,7 +228,7 @@ EncryptedData* Encrypter::decorateAndUnmarshall(EncryptionParams& encParams, Key
     return xmlEncData;
 }
 
-EncryptedKey* Encrypter::encryptKey(const unsigned char* keyBuffer, unsigned int keyBufferSize, KeyEncryptionParams& kencParams)
+EncryptedKey* Encrypter::encryptKey(const unsigned char* keyBuffer, unsigned int keyBufferSize, KeyEncryptionParams& kencParams, bool compact)
 {
     // Get a fresh cipher object and document.
 
@@ -227,14 +236,18 @@ EncryptedKey* Encrypter::encryptKey(const unsigned char* keyBuffer, unsigned int
         XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->releaseCipher(m_cipher);
         m_cipher=NULL;
     }
-    
+
+    XSECCryptoKey* kek = kencParams.m_credential.getPublicKey();
+    if (!kek)
+        throw EncryptionException("Credential in KeyEncryptionParams structure did not supply a public key.");
+
     DOMDocument* doc=NULL;
     try {
         doc=XMLToolingConfig::getConfig().getParser().newDocument();
         XercesJanitor<DOMDocument> janitor(doc);
         m_cipher=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newCipher(doc);
         m_cipher->setExclusiveC14nSerialisation(false);
-        m_cipher->setKEK(kencParams.m_key->clone());
+        m_cipher->setKEK(kek->clone());
         auto_ptr<XENCEncryptedKey> encKey(m_cipher->encryptKey(keyBuffer, keyBufferSize, ENCRYPT_NONE, kencParams.m_algorithm));
         
         EncryptedKey* xmlEncKey=NULL;
@@ -249,10 +262,9 @@ EncryptedKey* Encrypter::encryptKey(const unsigned char* keyBuffer, unsigned int
             xmlEncKey->setRecipient(kencParams.m_recipient);
 
         // KeyInfo?
-        if (kencParams.m_keyInfo) {
-            xmlEncKey->setKeyInfo(kencParams.m_keyInfo);
-            kencParams.m_keyInfo=NULL;   // transfer ownership
-        }
+        const KeyInfo* kinfo = kencParams.m_credential.getKeyInfo(compact);
+        if (kinfo)
+            xmlEncKey->setKeyInfo(kinfo->cloneKeyInfo());
 
         xmlObjectKey.release();
         return xmlEncKey;
index bf5ed9c..83ba6b8 100644 (file)
@@ -34,6 +34,7 @@
 using namespace xmltooling;
 using namespace log4cpp;
 using namespace std;
+using xmlsignature::Signature;
 
 void UnknownElementImpl::releaseDOM() const
 {
@@ -73,7 +74,8 @@ void UnknownElementImpl::serialize(string& s) const
 DOMElement* UnknownElementImpl::marshall(
     DOMDocument* document
 #ifndef XMLTOOLING_NO_XMLSEC
-    ,const std::vector<xmlsignature::Signature*>* sigs
+    ,const vector<Signature*>* sigs
+    ,const Credential* credential
 #endif
     ) const
 {
@@ -140,7 +142,8 @@ DOMElement* UnknownElementImpl::marshall(
 DOMElement* UnknownElementImpl::marshall(
     DOMElement* parentElement
 #ifndef XMLTOOLING_NO_XMLSEC
-    ,const std::vector<xmlsignature::Signature*>* sigs
+    ,const vector<Signature*>* sigs
+    ,const Credential* credential
 #endif
     ) const
 {
index aa4cd31..e9aee3c 100644 (file)
@@ -61,6 +61,7 @@ namespace xmltooling {
             DOMDocument* document=NULL
 #ifndef XMLTOOLING_NO_XMLSEC
             ,const std::vector<xmlsignature::Signature*>* sigs=NULL
+            ,const Credential* credential=NULL
 #endif
             ) const;
 
@@ -68,6 +69,7 @@ namespace xmltooling {
             DOMElement* parentElement
 #ifndef XMLTOOLING_NO_XMLSEC
             ,const std::vector<xmlsignature::Signature*>* sigs=NULL
+            ,const Credential* credential=NULL
 #endif
             ) const;
         XMLObject* unmarshall(DOMElement* element, bool bindDocument=false);
index 3ef702a..87e0087 100644 (file)
@@ -24,6 +24,7 @@
 #include "exceptions.h"
 #include "io/AbstractXMLObjectMarshaller.h"
 #ifndef XMLTOOLING_NO_XMLSEC
+    #include "security/Credential.h"
     #include "signature/Signature.h"
 #endif
 #include "util/NDC.h"
@@ -44,7 +45,8 @@ using namespace std;
 DOMElement* AbstractXMLObjectMarshaller::marshall(
     DOMDocument* document
 #ifndef XMLTOOLING_NO_XMLSEC
-    ,const std::vector<xmlsignature::Signature*>* sigs
+    ,const vector<Signature*>* sigs
+    ,const Credential* credential
 #endif
     ) const
 {
@@ -91,7 +93,7 @@ DOMElement* AbstractXMLObjectMarshaller::marshall(
         );
     setDocumentElement(document, domElement);
 #ifndef XMLTOOLING_NO_XMLSEC
-    marshallInto(domElement, sigs);
+    marshallInto(domElement, sigs, credential);
 #else
     marshallInto(domElement);
 #endif
@@ -107,7 +109,8 @@ DOMElement* AbstractXMLObjectMarshaller::marshall(
 DOMElement* AbstractXMLObjectMarshaller::marshall(
     DOMElement* parentElement
 #ifndef XMLTOOLING_NO_XMLSEC
-    ,const std::vector<xmlsignature::Signature*>* sigs
+    ,const vector<Signature*>* sigs
+    ,const Credential* credential
 #endif
     ) const
 {
@@ -146,7 +149,7 @@ DOMElement* AbstractXMLObjectMarshaller::marshall(
         );
     parentElement->appendChild(domElement);
 #ifndef XMLTOOLING_NO_XMLSEC
-    marshallInto(domElement, sigs);
+    marshallInto(domElement, sigs, credential);
 #else
     marshallInto(domElement);
 #endif
@@ -162,28 +165,45 @@ DOMElement* AbstractXMLObjectMarshaller::marshall(
 void AbstractXMLObjectMarshaller::marshallInto(
     DOMElement* targetElement
 #ifndef XMLTOOLING_NO_XMLSEC
-    ,const std::vector<xmlsignature::Signature*>* sigs
+    ,const vector<Signature*>* sigs
+    ,const Credential* credential
 #endif
     ) const
 {
     if (getElementQName().hasPrefix())
         targetElement->setPrefix(getElementQName().getPrefix());
 
-    if (m_schemaLocation) {
-        static const XMLCh schemaLocation[]= UNICODE_LITERAL_14(s,c,h,e,m,a,L,o,c,a,t,i,o,n);
-        if (targetElement->getParentNode()==NULL || targetElement->getParentNode()->getNodeType()==DOMNode::DOCUMENT_NODE)
-            targetElement->setAttributeNS(XSI_NS,schemaLocation,m_schemaLocation); 
+    if (m_schemaLocation || m_noNamespaceSchemaLocation) {
+        static const XMLCh schemaLocation[] = {
+            chLatin_x, chLatin_s, chLatin_i, chColon,
+            chLatin_s, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a,
+            chLatin_L, chLatin_o, chLatin_c, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull
+            };
+        static const XMLCh noNamespaceSchemaLocation[] = {
+            chLatin_x, chLatin_s, chLatin_i, chColon,
+            chLatin_n, chLatin_o, chLatin_N, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chLatin_p, chLatin_a, chLatin_c, chLatin_e,
+            chLatin_S, chLatin_c, chLatin_h, chLatin_e, chLatin_m, chLatin_a,
+            chLatin_L, chLatin_o, chLatin_c, chLatin_a, chLatin_t, chLatin_i, chLatin_o, chLatin_n, chNull
+            };
+        if (targetElement->getParentNode()==NULL || targetElement->getParentNode()->getNodeType()==DOMNode::DOCUMENT_NODE) {
+            if (m_schemaLocation)
+                targetElement->setAttributeNS(XSI_NS,schemaLocation,m_schemaLocation); 
+            if (m_noNamespaceSchemaLocation)
+                targetElement->setAttributeNS(XSI_NS,noNamespaceSchemaLocation,m_noNamespaceSchemaLocation); 
+        }
     }
 
     marshallElementType(targetElement);
     marshallNamespaces(targetElement);
     marshallAttributes(targetElement);
-    marshallContent(targetElement);
     
 #ifndef XMLTOOLING_NO_XMLSEC
+    marshallContent(targetElement,credential);
     if (sigs) {
-        for_each(sigs->begin(),sigs->end(),mem_fun<void,Signature>(&Signature::sign));
+        for_each(sigs->begin(),sigs->end(),bind2nd(mem_fun1<void,Signature,const Credential*>(&Signature::sign),credential));
     }
+#else
+    marshallContent(targetElement);
 #endif
 }
 
@@ -216,7 +236,7 @@ void AbstractXMLObjectMarshaller::marshallElementType(DOMElement* domElement) co
         if (xsivalue != typeLocalName)
             XMLString::release(&xsivalue);
 
-        m_log.debug("Adding XSI namespace to list of namespaces used by XMLObject");
+        m_log.debug("adding XSI namespace to list of namespaces used by XMLObject");
         addNamespace(Namespace(XSI_NS, XSI_PREFIX));
     }
 }
@@ -287,7 +307,12 @@ void AbstractXMLObjectMarshaller::marshallNamespaces(DOMElement* domElement) con
     for_each(namespaces.begin(),namespaces.end(),bind1st(_addns(),domElement));
 }
 
-void AbstractXMLObjectMarshaller::marshallContent(DOMElement* domElement) const
+void AbstractXMLObjectMarshaller::marshallContent(
+    DOMElement* domElement
+#ifndef XMLTOOLING_NO_XMLSEC
+    ,const Credential* credential
+#endif
+    ) const
 {
     m_log.debug("marshalling text and child elements for XMLObject");
     
@@ -298,8 +323,13 @@ void AbstractXMLObjectMarshaller::marshallContent(DOMElement* domElement) const
         val = getTextContent(pos);
         if (val && *val)
             domElement->appendChild(domElement->getOwnerDocument()->createTextNode(val));
-        if (*i)
+        if (*i) {
+#ifndef XMLTOOLING_NO_XMLSEC
+            (*i)->marshall(domElement,NULL,credential);
+#else
             (*i)->marshall(domElement);
+#endif
+        }
     }
     val = getTextContent(pos);
     if (val && *val)
index d4c574d..2eaedaf 100644 (file)
@@ -44,6 +44,7 @@ namespace xmltooling {
             DOMDocument* document=NULL
 #ifndef XMLTOOLING_NO_XMLSEC
             ,const std::vector<xmlsignature::Signature*>* sigs=NULL
+            ,const Credential* credential=NULL
 #endif
             ) const;
 
@@ -51,6 +52,7 @@ namespace xmltooling {
             DOMElement* parentElement
 #ifndef XMLTOOLING_NO_XMLSEC
             ,const std::vector<xmlsignature::Signature*>* sigs=NULL
+            ,const Credential* credential=NULL
 #endif
             ) const;
         
@@ -79,11 +81,14 @@ namespace xmltooling {
          * 
          * @param targetElement the Element into which the XMLObject is marshalled into
          * @param sigs          optional array of signatures to create after marshalling          
+         * @param credential    optional credential to supply signing key and related info
          * 
          * @throws MarshallingException thrown if there is a problem marshalling the object
          * @throws SignatureException thrown if a problem occurs during signature creation 
          */
-        void marshallInto(DOMElement* targetElement, const std::vector<xmlsignature::Signature*>* sigs) const;
+        void marshallInto(
+            DOMElement* targetElement, const std::vector<xmlsignature::Signature*>* sigs, const Credential* credential=NULL
+            ) const;
 #else
         /**
          * Marshalls the XMLObject into the given DOM Element.
@@ -113,6 +118,17 @@ namespace xmltooling {
          */
         void marshallNamespaces(DOMElement* domElement) const;
     
+#ifndef XMLTOOLING_NO_XMLSEC
+        /**
+         * Marshalls the text content and/or child elements of the XMLObject.
+         * 
+         * @param domElement the DOM element that will recieved the marshalled children
+         * @param credential    optional credential to supply signing key and related info
+         * 
+         * @throws MarshallingException thrown if there is a problem marshalling a child element
+         */
+        void marshallContent(DOMElement* domElement, const Credential* credential) const;
+#else
         /**
          * Marshalls the text content and/or child elements of the XMLObject.
          * 
@@ -121,6 +137,7 @@ namespace xmltooling {
          * @throws MarshallingException thrown if there is a problem marshalling a child element
          */
         void marshallContent(DOMElement* domElement) const;
+#endif
 
         /**
          * Marshalls the attributes from the XMLObject into the given DOM element.
index 8a98bbd..75f5e4e 100644 (file)
@@ -110,6 +110,7 @@ void AbstractXMLObjectUnmarshaller::unmarshallAttributes(const DOMElement* domEl
         else if (XMLString::equals(nsuri,XSI_NS)) {
             static const XMLCh type[]= UNICODE_LITERAL_4(t,y,p,e);
             static const XMLCh schemaLocation[]= UNICODE_LITERAL_14(s,c,h,e,m,a,L,o,c,a,t,i,o,n);
+            static const XMLCh noNamespaceSchemaLocation[]= UNICODE_LITERAL_25(n,o,N,a,m,e,s,p,a,c,e,S,c,h,e,m,a,L,o,c,a,t,i,o,n);
             if (XMLString::equals(attribute->getLocalName(),type)) {
                 m_log.debug("skipping xsi:type declaration");
                 continue;
@@ -121,6 +122,14 @@ void AbstractXMLObjectUnmarshaller::unmarshallAttributes(const DOMElement* domEl
                 m_schemaLocation=XMLString::replicate(attribute->getValue());
                 continue;
             }
+            else if (XMLString::equals(attribute->getLocalName(),noNamespaceSchemaLocation)) {
+                m_log.debug("storing off xsi:noNamespaceSchemaLocation attribute");
+                if (m_noNamespaceSchemaLocation)
+                    XMLString::release(&m_noNamespaceSchemaLocation);
+                m_schemaLocation=XMLString::replicate(attribute->getValue());
+                m_noNamespaceSchemaLocation=XMLString::replicate(attribute->getValue());
+                continue;
+            }
         }
         else if (nsuri && !XMLString::equals(nsuri,XML_NS)) {
             m_log.debug("found namespace-qualified attribute, adding prefix to the list of namespaces on the XMLObject");
index f0a98c5..02f692c 100644 (file)
@@ -17,8 +17,8 @@
 /**
  * @file xmltooling/security/AbstractPKIXTrustEngine.h
  * 
- * A trust engine that uses X.509 trust anchors and CRLs associated with a KeyInfoSource
- * to perform PKIX validation of signatures and certificates.
+ * A trust engine that uses X.509 trust anchors and CRLs associated with a peer
+ * to perform PKIX validation of signatures and credentials.
  */
 
 #if !defined(__xmltooling_pkixtrust_h__) && !defined(XMLTOOLING_NO_XMLSEC)
@@ -30,8 +30,8 @@
 namespace xmltooling {
 
     /**
-     * A trust engine that uses X.509 trust anchors and CRLs associated with a KeyInfoSource
-     * to perform PKIX validation of signatures and certificates.
+     * A trust engine that uses X.509 trust anchors and CRLs associated with a peer
+     * to perform PKIX validation of signatures and credentials.
      */
     class XMLTOOL_API AbstractPKIXTrustEngine : public OpenSSLTrustEngine
     {
@@ -42,37 +42,34 @@ namespace xmltooling {
          * If a DOM is supplied, the following XML content is supported:
          * 
          * <ul>
-         *  <li>&lt;KeyResolver&gt; elements with a type attribute
+         *  <li>&lt;KeyInfoResolver&gt; elements with a type attribute
          * </ul>
          * 
          * XML namespaces are ignored in the processing of this content.
          * 
          * @param e DOM to supply configuration for provider
          */
-        AbstractPKIXTrustEngine(const DOMElement* e=NULL);
+        AbstractPKIXTrustEngine(const DOMElement* e=NULL) : OpenSSLTrustEngine(e) {}
         
         /**
-         * Checks that either the ID for the entity with the given role or the key names
-         * for the given role match the subject or subject alternate names
-         * of the entity's certificate.
+         * Checks that either the name of the peer with the given credentials or the names
+         * of the credentials match the subject or subject alternate names of the certificate.
          * 
          * @param certEE        the credential for the entity to validate
-         * @param keyInfoSource supplies KeyInfo objects to the TrustEngine
+         * @param credResolver  source of credentials
+         * @param criteria      criteria for selecting credentials, including the peer name
          * 
          * @return true the name check succeeds, false if not
          */
-        bool checkEntityNames(X509* certEE, const KeyInfoSource& keyInfoSource) const;
-        
-        /** An inline KeyResolver for extracting certificates out of a signature. */
-        KeyResolver* m_inlineResolver;
+        bool checkEntityNames(X509* certEE, const CredentialResolver& credResolver, const CredentialCriteria& criteria) const;
         
     public:
-        virtual ~AbstractPKIXTrustEngine();
+        virtual ~AbstractPKIXTrustEngine() {}
 
         virtual bool validate(
             xmlsignature::Signature& sig,
-            const KeyInfoSource& keyInfoSource,
-            const KeyResolver* keyResolver=NULL
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL
             ) const;
 
         virtual bool validate(
@@ -81,24 +78,22 @@ namespace xmltooling {
             xmlsignature::KeyInfo* keyInfo,
             const char* in,
             unsigned int in_len,
-            const KeyInfoSource& keyInfoSource,
-            const KeyResolver* keyResolver=NULL
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL
             ) const;
 
         virtual bool validate(
             XSECCryptoX509* certEE,
             const std::vector<XSECCryptoX509*>& certChain,
-            const KeyInfoSource& keyInfoSource,
-            bool checkName=true,
-            const KeyResolver* keyResolver=NULL
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL
             ) const;
 
         virtual bool validate(
             X509* certEE,
             STACK_OF(X509)* certChain,
-            const KeyInfoSource& keyInfoSource,
-            bool checkName=true,
-            const KeyResolver* keyResolver=NULL
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL
             ) const;
 
         /**
@@ -110,15 +105,7 @@ namespace xmltooling {
         class XMLTOOL_API PKIXValidationInfoIterator {
             MAKE_NONCOPYABLE(PKIXValidationInfoIterator);
         protected:
-            /** Reference to KeyResolver to use. */
-            const KeyResolver& m_keyResolver;
-            
-            /**
-             * Constructor
-             * 
-             * @param keyResolver   reference to KeyResolver to use
-             */
-            PKIXValidationInfoIterator(const KeyResolver& keyResolver) : m_keyResolver(keyResolver) {}
+            PKIXValidationInfoIterator() {}
             
         public:
             virtual ~PKIXValidationInfoIterator() {}
@@ -160,18 +147,20 @@ namespace xmltooling {
         };
         
         /**
-         * Provides access to the information necessary, for the given key source, for
+         * Provides access to the information necessary, for the given credential source, for
          * PKIX validation of credentials. Each set of validation information returned
          * will be tried, in turn, until one succeeds or no more remain.
          * The caller must free the returned interface when finished with it.
          * 
-         * @param pkixSource    the peer for which validation rules are required
-         * @param keyResolver   reference to KeyResolver to use for any KeyInfo operations
+         * @param pkixSource        the peer for which validation rules are required
+         * @param criteria          criteria for selecting validation rules
+         * @param keyInfoResolver   custom KeyInfoResolver to use for KeyInfo extraction
          * @return interface for obtaining validation data
          */
         virtual PKIXValidationInfoIterator* getPKIXValidationInfoIterator(
-            const KeyInfoSource& pkixSource,
-            const KeyResolver& keyResolver
+            const CredentialResolver& pkixSource,
+            CredentialCriteria* criteria=NULL,
+            const KeyInfoResolver* keyInfoResolver=NULL
             ) const=0;
     };
 };
diff --git a/xmltooling/security/BasicX509Credential.h b/xmltooling/security/BasicX509Credential.h
new file mode 100644 (file)
index 0000000..6225f69
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file xmltooling/security/BasicX509Credential.h
+ * 
+ * Wraps an X.509-based Credential by storing key/cert objects inside. 
+ */
+
+#if !defined(__xmltooling_basicx509cred_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_basicx509cred_h__
+
+#include <xmltooling/security/X509Credential.h>
+
+#include <algorithm>
+
+namespace xmlsignature {
+    class XMLTOOL_API KeyInfo;
+};
+
+namespace xmltooling {
+
+    /**
+     * Wraps an X.509-based Credential by storing key/cert objects inside.
+     */
+    class XMLTOOL_API BasicX509Credential : public virtual X509Credential
+    {
+    protected:
+        BasicX509Credential(bool ownCerts) : m_key(NULL), m_ownCerts(ownCerts), m_crl(NULL), m_keyInfo(NULL), m_compactKeyInfo(NULL) {
+        }
+
+        /**
+         * Constructor.
+         * 
+         * @param key   key pair or secret key
+         * @param certs array of X.509 certificates, the first entry being the entity certificate
+         * @param crl   optional CRL
+         */
+        BasicX509Credential(XSECCryptoKey* key, const std::vector<XSECCryptoX509*>& certs, XSECCryptoX509CRL* crl=NULL)
+                : m_key(key), m_xseccerts(certs), m_ownCerts(true), m_crl(crl), m_keyInfo(NULL), m_compactKeyInfo(NULL) {
+        }
+
+        /** The private/secret key/keypair. */
+        XSECCryptoKey* m_key;
+
+        /** The X.509 certificate chain. */
+        std::vector<XSECCryptoX509*> m_xseccerts;
+
+        /** Indicates whether to destroy certificates. */
+        bool m_ownCerts;
+
+        /** The X.509 CRL. */
+        XSECCryptoX509CRL* m_crl;
+
+        /** The KeyInfo object representing the information. */
+        xmlsignature::KeyInfo* m_keyInfo;
+
+        /** The KeyInfo object representing the information in compact form. */
+        xmlsignature::KeyInfo* m_compactKeyInfo;
+
+        /**
+         * Initializes (or reinitializes) a ds:KeyInfo to represent the Credential.
+         */
+        void initKeyInfo();
+        
+    public:
+        virtual ~BasicX509Credential();
+        
+        XSECCryptoKey* getPrivateKey() const {
+            if (m_key) {
+                XSECCryptoKey::KeyType type = m_key->getKeyType();
+                if (type!=XSECCryptoKey::KEY_RSA_PUBLIC && type!=XSECCryptoKey::KEY_DSA_PUBLIC)
+                    return m_key;
+            }
+            return NULL;
+        }
+
+        XSECCryptoKey* getPublicKey() const {
+            if (m_key) {
+                XSECCryptoKey::KeyType type = m_key->getKeyType();
+                if (type!=XSECCryptoKey::KEY_RSA_PRIVATE && type!=XSECCryptoKey::KEY_DSA_PRIVATE)
+                    return m_key;
+            }
+            return NULL;
+        }
+
+        std::vector<std::string>::size_type getKeyNames(std::vector<std::string>& results) const;
+
+        const xmlsignature::KeyInfo* getKeyInfo(bool compact=false) const {
+            return compact ? m_compactKeyInfo : (m_keyInfo ? m_keyInfo : m_compactKeyInfo);
+        }
+        
+        /**
+         * Gets an immutable collection of certificates in the entity's trust chain. The entity certificate is contained
+         * within this list. No specific ordering of the certificates is guaranteed.
+         * 
+         * @return a certificate chain
+         */
+        const std::vector<XSECCryptoX509*>& getEntityCertificateChain() const {
+            return m_xseccerts;
+        }
+
+        XSECCryptoX509CRL* getCRL() const {
+            return m_crl;
+        }
+    };
+};
+
+#endif /* __xmltooling_basicx509cred_h__ */
diff --git a/xmltooling/security/CachingKeyResolver.h b/xmltooling/security/CachingKeyResolver.h
deleted file mode 100644 (file)
index fe30bc7..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  Copyright 2001-2007 Internet2
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file xmltooling/security/CachingKeyResolver.h
- * 
- * A KeyResolver that caches content across method calls.
- */
-
-#if !defined(__xmltooling_cachekeyres_h__) && !defined(XMLTOOLING_NO_XMLSEC)
-#define __xmltooling_cachekeyres_h__
-
-#include <xmltooling/security/KeyResolver.h>
-
-namespace xmltooling {
-
-    /**
-     * An API for resolving encrypted decryption keys.
-     */
-    class XMLTOOL_API CachingKeyResolver : public KeyResolver {
-    public:
-        virtual ~CachingKeyResolver() {}
-        
-        /**
-         * Clears any cache state.
-         */
-        virtual void clearCache()=0;
-    };
-
-};
-
-#endif /* __xmltooling_cachekeyres_h__ */
index d273c1e..65f972b 100644 (file)
@@ -79,8 +79,8 @@ namespace xmltooling {
 
         bool validate(
             xmlsignature::Signature& sig,
-            const KeyInfoSource& keyInfoSource,
-            const KeyResolver* keyResolver=NULL
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL
             ) const;
         bool validate(
             const XMLCh* sigAlgorithm,
@@ -88,22 +88,20 @@ namespace xmltooling {
             xmlsignature::KeyInfo* keyInfo,
             const char* in,
             unsigned int in_len,
-            const KeyInfoSource& keyInfoSource,
-            const KeyResolver* keyResolver=NULL
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL
             ) const;
         bool validate(
             XSECCryptoX509* certEE,
             const std::vector<XSECCryptoX509*>& certChain,
-            const KeyInfoSource& keyInfoSource,
-            bool checkName=true,
-            const KeyResolver* keyResolver=NULL
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL
             ) const;
         bool validate(
             X509* certEE,
             STACK_OF(X509)* certChain,
-            const KeyInfoSource& keyInfoSource,
-            bool checkName=true,
-            const KeyResolver* keyResolver=NULL
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL
             ) const;
     private:
         std::vector<TrustEngine*> m_engines;
diff --git a/xmltooling/security/Credential.h b/xmltooling/security/Credential.h
new file mode 100644 (file)
index 0000000..c8d7756
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file xmltooling/security/Credential.h
+ * 
+ * Wraps keys and related functionality. 
+ */
+
+#if !defined(__xmltooling_cred_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_cred_h__
+
+#include <xmltooling/base.h>
+
+#include <xsec/enc/XSECCryptoKey.hpp>
+
+namespace xmlsignature {
+    class XMLTOOL_API KeyInfo;
+};
+
+namespace xmltooling {
+
+    /**
+     * Wraps keys and related functionality.
+     *
+     * <p>Shared credential implementations should implement reference counting
+     * and honor any locking parameters to ensure appropriate synchronization.
+     */
+    class XMLTOOL_API Credential
+    {
+        MAKE_NONCOPYABLE(Credential);
+    protected:
+        Credential() {}
+        
+    public:
+        virtual ~Credential() {}
+        
+        enum ResolveTypes {
+            RESOLVE_KEYS = 1
+        };
+
+        /**
+         * Returns a secret or private key to use for signing or decryption operations.
+         * 
+         * @return  a secret or private key
+         */
+        virtual XSECCryptoKey* getPrivateKey() const=0;
+
+        /**
+         * Returns a secret or public key to use for verification or encryption operations.
+         * 
+         * @return  a secret or public key
+         */
+        virtual XSECCryptoKey* getPublicKey() const=0;
+        
+        /**
+         * Returns names representing the Credential, generally when the Credential itself merely
+         * points to a Credential rather than containing one.
+         * 
+         * @param results   array to populate with names
+         * @return  the number of names returned
+         */
+        virtual std::vector<std::string>::size_type getKeyNames(std::vector<std::string>& results) const=0;
+        
+        /**
+         * Returns a ds:KeyInfo object representing the Credential for use in
+         * communicating with other entities.
+         * 
+         * @param compact   true iff the communication medium is such that only compact forms should be included
+         * @return reference to a KeyInfo object
+         */
+        virtual const xmlsignature::KeyInfo* getKeyInfo(bool compact=false) const=0;
+
+        /**
+         * Compares the public key inside the Credential to a second public key.
+         *
+         * @param key   the public key to compare
+         * @return true iff the keys are equal
+         */
+        virtual bool isEqual(XSECCryptoKey& key) const;
+    };
+};
+
+#endif /* __xmltooling_cred_h__ */
diff --git a/xmltooling/security/CredentialCriteria.h b/xmltooling/security/CredentialCriteria.h
new file mode 100644 (file)
index 0000000..6777bd4
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file xmltooling/security/CredentialCriteria.h
+ * 
+ * Class for specifying criteria by which a CredentialResolver should resolve credentials. 
+ */
+
+#if !defined(__xmltooling_credcrit_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_credcrit_h__
+
+#include <xmltooling/unicode.h>
+#include <xmltooling/signature/KeyInfo.h>
+#include <xmltooling/signature/Signature.h>
+
+#include <string>
+#include <xsec/dsig/DSIGKeyInfoList.hpp>
+#include <xsec/dsig/DSIGKeyInfoName.hpp>
+
+namespace xmltooling {
+
+    /**
+     * Class for specifying criteria by which a CredentialResolver should resolve credentials.
+     */
+    class XMLTOOL_API CredentialCriteria
+    {
+        MAKE_NONCOPYABLE(CredentialCriteria);
+    public:
+        CredentialCriteria() : m_keyUsage(UNSPECIFIED_CREDENTIAL), m_keyInfo(NULL), m_nativeKeyInfo(NULL) {}
+        virtual ~CredentialCriteria() {}
+
+        enum UsageType {
+            UNSPECIFIED_CREDENTIAL,
+            SIGNING_CREDENTIAL,
+            TLS_CREDENTIAL,
+            ENCRYPTION_CREDENTIAL
+        };
+        
+        /**
+         * Get the key usage criteria.
+         * 
+         * @return the usage.
+         */
+        UsageType getUsage() const {
+            return m_keyUsage;
+        }
+    
+        /**
+         * Set the key usage criteria.
+         * 
+         * @param usage the usage to set
+         */
+        void setUsage(UsageType usage) {
+            m_keyUsage = usage;
+        }
+
+        /**
+         * Get the peer name criteria.
+         * 
+         * @return the peer name
+         */
+        const char* getPeerName() const {
+            return m_peerName.c_str();
+        }
+    
+        /**
+         * Set the peer name criteria.
+         * 
+         * @param peerName peer name to set
+         */
+        void setPeerName(const char* peerName) {
+            m_peerName.erase();
+            if (peerName)
+                m_peerName = peerName;
+        }
+    
+        /**
+         * Get the key algorithm criteria.
+         * 
+         * @return returns the keyAlgorithm.
+         */
+        const char* getKeyAlgorithm() const {
+            return m_keyAlgorithm.c_str();
+        }
+    
+        /**
+         * Set the key algorithm criteria.
+         * 
+         * @param keyAlgorithm The keyAlgorithm to set.
+         */
+        void setKeyAlgorithm(const char* keyAlgorithm) {
+            m_keyAlgorithm.erase();
+            if (keyAlgorithm)
+                m_keyAlgorithm = keyAlgorithm;
+        }
+    
+        /**
+         * Get the key name criteria.
+         * 
+         * @return the key name
+         */
+        const char* getKeyName() const {
+            return m_keyName.c_str();
+        }
+    
+        /**
+         * Set the key name criteria.
+         * 
+         * @param keyName key name to set
+         */
+        void setKeyName(const char* keyName) {
+            m_keyName.erase();
+            if (keyName)
+                m_keyName = keyName;
+        }
+        
+        /**
+         * Gets the KeyInfo criteria.
+         * 
+         * @return the KeyInfo criteria
+         */
+        const xmlsignature::KeyInfo* getKeyInfo() const {
+            return m_keyInfo;
+        }
+    
+        /**
+         * Sets the KeyInfo criteria.
+         * 
+         * @param keyInfo   the KeyInfo criteria
+         */
+        void setKeyInfo(const xmlsignature::KeyInfo* keyInfo) {
+            m_keyInfo = keyInfo;
+        } 
+
+        /**
+         * Gets the native KeyInfo criteria.
+         * 
+         * @return the native KeyInfo criteria
+         */
+        DSIGKeyInfoList* getNativeKeyInfo() const {
+            return m_nativeKeyInfo;
+        }
+
+        /**
+         * Sets the KeyInfo criteria.
+         * 
+         * @param keyInfo   the KeyInfo criteria
+         */
+        void setNativeKeyInfo(DSIGKeyInfoList* keyInfo) {
+            m_nativeKeyInfo = keyInfo;
+        }
+
+        void setSignature(const xmlsignature::Signature& sig) {
+            xmlsignature::KeyInfo* k = sig.getKeyInfo();
+            if (k)
+                return setKeyInfo(k);
+            DSIGSignature* dsig = sig.getXMLSignature();
+            if (dsig)
+                setNativeKeyInfo(dsig->getKeyInfoList());
+        }
+
+    private:
+        UsageType m_keyUsage;
+        std::string m_peerName,m_keyAlgorithm,m_keyName;
+        const xmlsignature::KeyInfo* m_keyInfo;
+        DSIGKeyInfoList* m_nativeKeyInfo;
+    };
+};
+
+#endif /* __xmltooling_credcrit_h__ */
index a9324ee..68d675f 100644 (file)
@@ -15,9 +15,9 @@
  */
 
 /**
- * @file xmltooling/signature/CredentialResolver.h
+ * @file xmltooling/security/CredentialResolver.h
  * 
- * Resolves keys and certificates "owned" by an entity 
+ * An API for resolving keys and certificates based on application criteria.
  */
 
 #if !defined(__xmltooling_credres_h__) && !defined(XMLTOOLING_NO_XMLSEC)
 
 #include <xmltooling/Lockable.h>
 
-#include <vector>
-#include <xsec/enc/XSECCryptoKey.hpp>
-#include <xsec/enc/XSECCryptoX509.hpp>
-
-namespace xmlsignature {
-    class XMLTOOL_API KeyInfo;
-};
-
 namespace xmltooling {
 
+    class XMLTOOL_API Credential;
+    class XMLTOOL_API CredentialCriteria;
+
     /**
-     * An API for resolving local/owned keys and certificates
+     * An API for resolving keys and certificates based on application criteria.
      */
-    class XMLTOOL_API CredentialResolver : public Lockable
+    class XMLTOOL_API CredentialResolver : public virtual Lockable
     {
         MAKE_NONCOPYABLE(CredentialResolver);
     protected:
@@ -48,21 +43,23 @@ namespace xmltooling {
         virtual ~CredentialResolver() {}
         
         /**
-         * Returns a secret or private key to use for signing or decryption operations.
-         * The caller is responsible for deleting the key when finished with it.
+         * Returns a single Credential according to the supplied criteria.
          * 
-         * @param keyInfo   optional material identifying a decryption key 
-         * @return  a secret or private key
+         * @param criteria   an optional CredentialCriteria object 
+         * @return  a Credential, or NULL if none could be found
          */
-        virtual XSECCryptoKey* getKey(const xmlsignature::KeyInfo* keyInfo=NULL) const=0;
-        
+        virtual const Credential* resolve(const CredentialCriteria* criteria=NULL) const=0;
+
         /**
-         * Returns a set of certificates to publish during signing operations.
-         * The certificates must be cloned if kept beyond the scope of a lock.
+         * Returns all matching Credentials according to the supplied criteria.
          * 
-         * @return  a set of certificates
+         * @param results   array to store matching Credentials
+         * @param criteria  an optional CredentialCriteria object 
+         * @return  number of credentials found
          */
-        virtual const std::vector<XSECCryptoX509*>& getCertificates() const=0;
+        virtual std::vector<const Credential*>::size_type resolve(
+            std::vector<const Credential*>& results, const CredentialCriteria* criteria=NULL
+            ) const=0;
     };
 
     /**
@@ -70,7 +67,7 @@ namespace xmltooling {
      */
     void XMLTOOL_API registerCredentialResolvers();
 
-    /** CredentialResolver based on local files */
+    /** CredentialResolver based on local files with no criteria support. */
     #define FILESYSTEM_CREDENTIAL_RESOLVER  "File"
 };
 
diff --git a/xmltooling/security/KeyInfoResolver.h b/xmltooling/security/KeyInfoResolver.h
new file mode 100644 (file)
index 0000000..61c5bf2
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file xmltooling/security/KeyInfoResolver.h
+ * 
+ * Resolves credentials from KeyInfo information.
+ */
+
+#if !defined(__xmltooling_keyres_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_keyres_h__
+
+#include <xsec/dsig/DSIGKeyInfoList.hpp>
+
+namespace xmlsignature {
+    class XMLTOOL_API KeyInfo;
+    class XMLTOOL_API Signature;
+};
+
+namespace xmltooling {
+
+    class XMLTOOL_API Credential;
+    class XMLTOOL_API CredentialCriteria;
+
+    /**
+     * Resolves credentials from KeyInfo information.
+     *
+     * <p>Credential-specific bitmasks can be provided to control what to resolve.
+     */
+    class XMLTOOL_API KeyInfoResolver {
+        MAKE_NONCOPYABLE(KeyInfoResolver);
+    protected:
+        KeyInfoResolver() {}
+    public:
+        virtual ~KeyInfoResolver() {}
+        
+        /**
+         * Returns a credential based on the supplied KeyInfo information.
+         * The caller must release the credential when done with it.
+         * 
+         * @param keyInfo   the key information
+         * @param types     types of credentials to resolve, or 0 for any/all
+         * @return  the resolved credential, or NULL
+         */
+        virtual Credential* resolve(const xmlsignature::KeyInfo* keyInfo, int types=0) const=0;
+
+        /**
+         * Returns a credential based on the supplied KeyInfo information.
+         * The caller must release the credential when done with it.
+         * 
+         * @param keyInfo   the key information
+         * @param types     types of credentials to resolve, or 0 for any/all
+         * @return  the resolved credential, or NULL
+         */
+        virtual Credential* resolve(DSIGKeyInfoList* keyInfo, int types=0) const=0;
+
+        /**
+         * Returns a credential based on the supplied KeyInfo information.
+         * The caller must release the credential when done with it.
+         * 
+         * @param sig   signature containing the key information
+         * @param types types of credentials to resolve, or 0 for any/all
+         * @return  the resolved credential, or NULL
+         */
+        Credential* resolve(const xmlsignature::Signature* sig, int types=0) const;
+
+        /**
+         * Returns a credential based on the KeyInfo information in the supplied
+         * criteria. The caller must release the credential when done with it.
+         * 
+         * @param criteria   criteria containing the key information
+         * @param types types of credentials to resolve, or 0 for any/all
+         * @return  the resolved credential, or NULL
+         */
+        Credential* resolve(const CredentialCriteria& criteria, int types=0) const;
+    };
+
+    /**
+     * Registers KeyInfoResolver classes into the runtime.
+     */
+    void XMLTOOL_API registerKeyInfoResolvers();
+
+    /** KeyInfoResolver based on extracting by value directly out of a KeyInfo */
+    #define INLINE_KEYINFO_RESOLVER  "Inline"
+};
+
+#endif /* __xmltooling_keyres_h__ */
diff --git a/xmltooling/security/KeyInfoSource.h b/xmltooling/security/KeyInfoSource.h
deleted file mode 100644 (file)
index dc4ab0e..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *  Copyright 2001-2007 Internet2
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file xmltooling/security/KeyInfoSource.h
- * 
- * Interface for objects that can supply KeyInfo objects to a TrustEngine
- * via the KeyInfoIterator interface.
- */
-
-#if !defined(__xmltooling_keysource_h__) && !defined(XMLTOOLING_NO_XMLSEC)
-#define __xmltooling_keysource_h__
-
-#include <xmltooling/base.h>
-#include <string>
-
-namespace xmlsignature {
-    class XMLTOOL_API KeyInfo;
-};
-
-namespace xmltooling {
-
-    /**
-     * Callback interface to supply KeyInfo objects to a TrustEngine.
-     * Applications can adapt TrustEngines to their environment by supplying
-     * implementations of this interface. 
-     */
-    class XMLTOOL_API KeyInfoIterator {
-        MAKE_NONCOPYABLE(KeyInfoIterator);
-    protected:
-        KeyInfoIterator() {}
-    public:
-        virtual ~KeyInfoIterator() {}
-        
-        /**
-         * Indicates whether additional KeyInfo objects are available.
-         * 
-         * @return true iff another KeyInfo object can be fetched
-         */
-        virtual bool hasNext() const=0;
-        
-        /**
-         * Returns the next KeyInfo object available.
-         * 
-         * @return the next KeyInfo object, or NULL if none are left
-         */
-        virtual const xmlsignature::KeyInfo* next()=0;
-    };
-
-    /**
-     * Interface for objects that can supply KeyInfo objects to a TrustEngine
-     * via the KeyInfoIterator interface.
-     */
-    class XMLTOOL_API KeyInfoSource {
-    protected:
-        KeyInfoSource() {}
-    public:
-        virtual ~KeyInfoSource() {}
-
-        /**
-         * Returns the name of this source of keys, for example a peer entity name
-         * or a principal's name.
-         * 
-         * @return  name of key source, or empty string
-         */
-        virtual std::string getName() const=0;
-        
-        /**
-         * Provides access to the KeyInfo information associated with the source.
-         * The caller must free the returned interface when finished with it.
-         * 
-         * @return interface for obtaining KeyInfo data  
-         */
-        virtual KeyInfoIterator* getKeyInfoIterator() const=0;
-    };
-
-};
-
-#endif /* __xmltooling_keysource_h__ */
diff --git a/xmltooling/security/KeyResolver.h b/xmltooling/security/KeyResolver.h
deleted file mode 100644 (file)
index 6d7762c..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- *  Copyright 2001-2007 Internet2
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file xmltooling/security/KeyResolver.h
- * 
- * Resolves public keys and certificates based on KeyInfo information or
- * external factors. 
- */
-
-#if !defined(__xmltooling_keyres_h__) && !defined(XMLTOOLING_NO_XMLSEC)
-#define __xmltooling_keyres_h__
-
-#include <xmltooling/security/XSECCryptoX509CRL.h>
-
-#include <xsec/dsig/DSIGKeyInfoList.hpp>
-#include <xsec/enc/XSECCryptoKey.hpp>
-#include <xsec/enc/XSECCryptoX509.hpp>
-
-#include <algorithm>
-#include <vector>
-
-namespace xmlsignature {
-    class XMLTOOL_API KeyInfo;
-    class XMLTOOL_API Signature;
-};
-
-namespace xmltooling {
-
-    /**
-     * An API for resolving keys. The default/simple implementation
-     * allows a hard-wired key to be supplied. This is mostly
-     * useful for testing, or to adapt another mechanism for supplying
-     * keys to this interface.
-     */
-    class XMLTOOL_API KeyResolver {
-        MAKE_NONCOPYABLE(KeyResolver);
-    public:
-        /**
-         * Constructor based on a single externally supplied key.
-         * The key will be destroyed when the resolver is. 
-         * 
-         * @param key   external key
-         */
-        KeyResolver(XSECCryptoKey* key=NULL) : m_key(key) {}
-        
-        virtual ~KeyResolver() {
-            delete m_key;
-        }
-        
-        /**
-         * Returns a key based on the supplied KeyInfo information.
-         * The caller must delete the key when done with it.
-         * 
-         * @param keyInfo   the key information
-         * @return  the resolved key
-         */
-        virtual XSECCryptoKey* resolveKey(const xmlsignature::KeyInfo* keyInfo) const {
-            return m_key ? m_key->clone() : NULL;
-        }
-
-        /**
-         * Returns a key based on the supplied KeyInfo information.
-         * The caller must delete the key when done with it.
-         * 
-         * @param keyInfo   the key information
-         * @return  the resolved key
-         */
-        virtual XSECCryptoKey* resolveKey(DSIGKeyInfoList* keyInfo) const {
-            return m_key ? m_key->clone() : NULL;
-        }
-
-        /**
-         * Returns a key based on the supplied KeyInfo information.
-         * The caller must delete the key when done with it.
-         * 
-         * @param sig   signature containing the key information
-         * @return  the resolved key
-         */
-        XSECCryptoKey* resolveKey(const xmlsignature::Signature* sig) const;
-
-        /**
-         * A wrapper that handles disposal of certificates when required.
-         */
-        class XMLTOOL_API ResolvedCertificates {
-            MAKE_NONCOPYABLE(ResolvedCertificates);
-            bool m_owned;
-            std::vector<XSECCryptoX509*> m_certs;
-        public:
-            ResolvedCertificates() : m_owned(false) {}
-            
-            ~ResolvedCertificates() {
-                clear();
-            }
-            
-            /**
-             * Empties the container and frees any held resources.
-             */
-            void clear() {
-                if (m_owned) {
-                    std::for_each(m_certs.begin(), m_certs.end(), xmltooling::cleanup<XSECCryptoX509>());
-                    m_owned = false;
-                }
-                m_certs.clear();
-            }
-            
-            /**
-             * Transfers ownership of certificates outside wrapper.
-             * 
-             * @param writeTo   a container into which to move the certificates
-             * @return  true iff the certificates must be freed by caller
-             */
-            bool release(std::vector<XSECCryptoX509*>& writeTo) {
-                writeTo.assign(m_certs.begin(),m_certs.end());
-                m_certs.clear();
-                if (m_owned) {
-                    m_owned=false;
-                    return true;
-                }
-                return false;
-            }
-            
-            /**
-             * Accesses the underlying array of certificates.
-             * 
-             * @return reference to certificate container
-             */
-            const std::vector<XSECCryptoX509*>& v() const {
-                return m_certs;
-            }
-            
-            friend class XMLTOOL_API KeyResolver;
-        };
-
-        /**
-         * Returns a set of certificates based on the supplied KeyInfo information.
-         * The certificates must be cloned if kept beyond the lifetime of the KeyInfo source.
-         * 
-         * @param keyInfo   the key information
-         * @param certs     reference to object to hold certificates
-         * @return  number of certificates returned
-         */
-        virtual std::vector<XSECCryptoX509*>::size_type resolveCertificates(
-            const xmlsignature::KeyInfo* keyInfo, ResolvedCertificates& certs
-            ) const;
-        
-        /**
-         * Returns a set of certificates based on the supplied KeyInfo information.
-         * The certificates must be cloned if kept beyond the lifetime of the KeyInfo source.
-         * 
-         * @param keyInfo   the key information
-         * @param certs     reference to object to hold certificates
-         * @return  number of certificates returned
-         */
-        virtual std::vector<XSECCryptoX509*>::size_type resolveCertificates(
-            DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs 
-            ) const;
-
-        /**
-         * Returns a set of certificates based on the supplied KeyInfo information.
-         * The certificates must be cloned if kept beyond the lifetime of the KeyInfo source.
-         * 
-         * @param sig   signature containing the key information
-         * @param certs     reference to object to hold certificates
-         * @return  number of certificates returned
-         */
-        std::vector<XSECCryptoX509*>::size_type resolveCertificates(
-            const xmlsignature::Signature* sig, ResolvedCertificates& certs
-            ) const;
-
-        /**
-         * Returns a CRL based on the supplied KeyInfo information.
-         * The caller must delete the CRL when done with it.
-         * 
-         * @param keyInfo   the key information
-         * @return  the resolved CRL
-         */
-        virtual XSECCryptoX509CRL* resolveCRL(const xmlsignature::KeyInfo* keyInfo) const;
-        
-        /**
-         * Returns a CRL based on the supplied KeyInfo information.
-         * The caller must delete the CRL when done with it.
-         * 
-         * @param keyInfo   the key information
-         * @return  the resolved CRL
-         */
-        virtual XSECCryptoX509CRL* resolveCRL(DSIGKeyInfoList* keyInfo) const;
-
-        /**
-         * Returns a CRL based on the supplied KeyInfo information.
-         * The caller must delete the CRL when done with it.
-         * 
-         * @param sig   signature containing the key information
-         * @return  the resolved CRL
-         */
-        XSECCryptoX509CRL* resolveCRL(const xmlsignature::Signature* sig) const;
-
-    protected:
-        /** Stores an explicit key. */
-        XSECCryptoKey* m_key;
-
-        /**
-         * Accessor for certificate vector from derived KeyResolver classes.
-         *
-         * @param certs certificate wrapper to access
-         * @return modifiable reference to vector inside wrapper
-         */
-        std::vector<XSECCryptoX509*>& accessCertificates(ResolvedCertificates& certs) const {
-            return certs.m_certs;
-        }
-
-        /**
-         * Accessor for certificate ownership flag from derived KeyResolver classes.
-         *
-         * @param certs certificate wrapper to access
-         * @return modifiable reference to ownership flag inside wrapper
-         */
-        bool& accessOwned(ResolvedCertificates& certs) const {
-            return certs.m_owned;
-        }
-    };
-
-    /**
-     * Registers KeyResolver classes into the runtime.
-     */
-    void XMLTOOL_API registerKeyResolvers();
-
-    /** KeyResolver based on hard-wired key */
-    #define FILESYSTEM_KEY_RESOLVER  "File"
-
-    /** KeyResolver based on extracting information directly out of a KeyInfo */
-    #define INLINE_KEY_RESOLVER  "Inline"
-};
-
-#endif /* __xmltooling_keyres_h__ */
similarity index 55%
rename from xmltooling/security/OpenSSLCredentialResolver.h
rename to xmltooling/security/OpenSSLCredential.h
index 7e9ace5..73915dc 100644 (file)
  */
 
 /**
- * @file xmltooling/security/OpenSSLCredentialResolver.h
+ * @file xmltooling/security/OpenSSLCredential.h
  * 
- * OpenSSL-specific credential resolver
+ * OpenSSL-specific credential
  */
 
-#if !defined(__xmltooling_opensslcredres_h__) && !defined(XMLTOOLING_NO_XMLSEC)
-#define __xmltooling_opensslcredres_h__
+#if !defined(__xmltooling_opensslcred_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_opensslcred_h__
 
-#include <xmltooling/security/CredentialResolver.h>
+#include <xmltooling/security/X509Credential.h>
 
 #include <openssl/ssl.h>
 
 namespace xmltooling {
 
     /**
-     * An OpenSSL-specific API for resolving local/owned keys and certificates
+     * An OpenSSL-specific credential
      */
-    class XMLTOOL_API OpenSSLCredentialResolver : public CredentialResolver
+    class XMLTOOL_API OpenSSLCredential : public virtual X509Credential
     {
     protected:
-        OpenSSLCredentialResolver() {}
+        OpenSSLCredential() {}
         
     public:
-        virtual ~OpenSSLCredentialResolver() {}
+        virtual ~OpenSSLCredential() {}
         
         /**
-         * Attaches credentials to an OpenSSL SSL context object.
-         * The resolver <strong>MUST</strong> be unlockable after attachment.
+         * Attaches credential to an OpenSSL SSL context object.
+         * The credential <strong>MUST</strong> be disposable after attachment.
          * 
          * @param ctx   an SSL context
          */
@@ -51,4 +51,4 @@ namespace xmltooling {
 
 };
 
-#endif /* __xmltooling_opensslcredres_h__ */
+#endif /* __xmltooling_opensslcred_h__ */
index b343449..a44cd56 100644 (file)
@@ -42,7 +42,7 @@ namespace xmltooling {
          * If a DOM is supplied, the following XML content is supported:
          * 
          * <ul>
-         *  <li>&lt;KeyResolver&gt; elements with a type attribute
+         *  <li>&lt;KeyInfoResolver&gt; elements with a type attribute
          * </ul>
          * 
          * XML namespaces are ignored in the processing of this content.
@@ -56,26 +56,26 @@ namespace xmltooling {
         
         /**
          * Determines whether an X.509 credential is valid with respect to the
-         * source of KeyInfo data supplied. It is the responsibility of the
-         * application to ensure that the KeyInfo information supplied is in fact
-         * associated with the peer who presented the credential. 
+         * source of credentials supplied.
          * 
-         * A custom KeyResolver can be supplied from outside the TrustEngine.
-         * Alternatively, one may be specified to the plugin constructor.
-         * A non-caching, inline resolver will be used as a fallback.
+         * <p>It is the responsibility of the application to ensure that the credentials
+         * supplied are in fact associated with the peer who presented the credential.
+         * 
+         * <p>If criteria with a peer name are supplied, the "name" of the EE certificate
+         * may also be checked to ensure that it identifies the intended peer.
+         * The peer name itself or implementation-specific rules based on the content of the
+         * peer credentials may be applied. Implementations may omit this check if they
+         * deem it unnecessary.
          * 
          * @param certEE        end-entity certificate to validate
-         * @param certChain     stack of certificates presented for validation (includes certEE)
-         * @param keyInfoSource supplies KeyInfo objects to the TrustEngine
-         * @param checkName     true iff certificate subject/name checking has <b>NOT</b> already occurred
-         * @param keyResolver   optional externally supplied KeyResolver, or NULL
+         * @param certChain     the complete set of certificates presented for validation (includes certEE)
+         * @param credResolver  a locked resolver to supply trusted peer credentials to the TrustEngine
+         * @param criteria      criteria for selecting peer credentials
          */
         virtual bool validate(
-            X509* certEE,
-            STACK_OF(X509)* certChain,
-            const KeyInfoSource& keyInfoSource,
-            bool checkName=true,
-            const KeyResolver* keyResolver=NULL
+            X509* certEE, STACK_OF(X509)* certChain,
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL
             ) const=0;
     };
     
index 35382b5..cf4c257 100644 (file)
 /**
  * @file xmltooling/security/TrustEngine.h
  * 
- * Evaluates the trustworthiness and validity of XML Signatures against
+ * Evaluates the trustworthiness and validity of signatures against
  * implementation-specific requirements.
  */
 
 #if !defined(__xmltooling_trust_h__) && !defined(XMLTOOLING_NO_XMLSEC)
 #define __xmltooling_trust_h__
 
-#include <xmltooling/security/KeyInfoSource.h>
-#include <xmltooling/security/KeyResolver.h>
-#include <xmltooling/signature/Signature.h>
+#include <xmltooling/base.h>
+
+namespace xmlsignature {
+    class XMLTOOL_API KeyInfo;
+    class XMLTOOL_API Signature;
+};
 
 namespace xmltooling {
 
+    class XMLTOOL_API CredentialCriteria;
+    class XMLTOOL_API CredentialResolver;
+    class XMLTOOL_API KeyInfoResolver;
+
     /**
      * Evaluates the trustworthiness and validity of XML or raw Signatures against
      * implementation-specific requirements.
@@ -43,7 +50,7 @@ namespace xmltooling {
          * If a DOM is supplied, the following XML content is supported:
          * 
          * <ul>
-         *  <li>&lt;KeyResolver&gt; elements with a type attribute
+         *  <li>&lt;KeyInfoResolver&gt; elements with a type attribute
          * </ul>
          * 
          * XML namespaces are ignored in the processing of this content.
@@ -52,45 +59,60 @@ namespace xmltooling {
          */
         TrustEngine(const DOMElement* e=NULL);
         
-        /** Default KeyResolver instance. */
-        KeyResolver* m_keyResolver;
+        /** Custom KeyInfoResolver instance. */
+        KeyInfoResolver* m_keyInfoResolver;
         
     public:
         virtual ~TrustEngine();
-        
+
+        /**
+         * Supplies a KeyInfoResolver instance.
+         * <p>This method must be externally synchronized with any code that uses the object.
+         * Any previously set object is destroyed.
+         * 
+         * @param keyInfoResolver   new KeyInfoResolver instance to use
+         */
+        void setKeyInfoResolver(KeyInfoResolver* keyInfoResolver);
+
         /**
          * Determines whether an XML signature is correct and valid with respect to
-         * the source of KeyInfo data supplied. It is the responsibility of the
-         * application to ensure that the KeyInfo information supplied is in fact
-         * associated with the peer who created the signature. 
+         * the source of credentials supplied.
+         * 
+         * <p>It is the responsibility of the application to ensure that the credentials
+         * supplied are in fact associated with the peer who created the signature.
          * 
-         * <p>A custom KeyResolver can be supplied from outside the TrustEngine.
-         * Alternatively, one may be specified to the plugin constructor.
-         * A non-caching, inline resolver will be used as a fallback.
+         * <p>If criteria with a peer name are supplied, the "name" of the Credential that verifies
+         * the signature may also be checked to ensure that it identifies the intended peer.
+         * The peer name itself or implementation-specific rules based on the content of the
+         * peer credentials may be applied. Implementations may omit this check if they
+         * deem it unnecessary.
          * 
          * @param sig           reference to a signature object to validate
-         * @param keyInfoSource supplies KeyInfo objects to the TrustEngine
-         * @param keyResolver   optional externally supplied KeyResolver, or NULL
+         * @param credResolver  a locked resolver to supply trusted peer credentials to the TrustEngine
+         * @param criteria      criteria for selecting peer credentials
          * @return  true iff the signature validates
          */
         virtual bool validate(
             xmlsignature::Signature& sig,
-            const KeyInfoSource& keyInfoSource,
-            const KeyResolver* keyResolver=NULL
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL
             ) const=0;
 
         /**
          * Determines whether a raw signature is correct and valid with respect to
-         * the source of KeyInfo data supplied. It is the responsibility of the
-         * application to ensure that the KeyInfo information supplied is in fact
-         * associated with the peer who created the signature.
+         * the source of credentials supplied.
          * 
-         * <p>A custom KeyResolver can be supplied from outside the TrustEngine.
-         * Alternatively, one may be specified to the plugin constructor.
-         * A non-caching, inline resolver will be used as a fallback.
+         * <p>It is the responsibility of the application to ensure that the Credentials
+         * supplied are in fact associated with the peer who created the signature.
          * 
+         * <p>If criteria with a peer name are supplied, the "name" of the Credential that verifies
+         * the signature may also be checked to ensure that it identifies the intended peer.
+         * The peer name itself or implementation-specific rules based on the content of the
+         * peer credentials may be applied. Implementations may omit this check if they
+         * deem it unnecessary.
+         *
          * <p>Note that the keyInfo parameter is not part of the implicitly trusted
-         * set of key information supplied via the KeyInfoSource, but rather advisory
+         * set of information supplied via the CredentialResolver, but rather advisory
          * data that may have accompanied the signature itself.
          * 
          * @param sigAlgorithm  XML Signature identifier for the algorithm used
@@ -98,8 +120,8 @@ namespace xmltooling {
          * @param keyInfo       KeyInfo object accompanying the signature, if any
          * @param in            the input data over which the signature was created
          * @param in_len        size of input data in bytes
-         * @param keyInfoSource supplies KeyInfo objects to the TrustEngine
-         * @param keyResolver   optional externally supplied KeyResolver, or NULL
+         * @param credResolver  a locked resolver to supply trusted peer credentials to the TrustEngine
+         * @param criteria      criteria for selecting peer credentials
          * @return  true iff the signature validates
          */
         virtual bool validate(
@@ -108,8 +130,8 @@ namespace xmltooling {
             xmlsignature::KeyInfo* keyInfo,
             const char* in,
             unsigned int in_len,
-            const KeyInfoSource& keyInfoSource,
-            const KeyResolver* keyResolver=NULL
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL
             ) const=0;
     };
 
diff --git a/xmltooling/security/X509Credential.h b/xmltooling/security/X509Credential.h
new file mode 100644 (file)
index 0000000..764d82f
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file xmltooling/security/X509Credential.h
+ * 
+ * Wraps an X.509-based Credential. 
+ */
+
+#if !defined(__xmltooling_x509cred_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_x509cred_h__
+
+#include <xmltooling/security/Credential.h>
+#include <xmltooling/security/XSECCryptoX509CRL.h>
+
+#include <vector>
+#include <xsec/enc/XSECCryptoX509.hpp>
+
+namespace xmltooling {
+
+    /**
+     * Wraps an X.509-based Credential.
+     */
+    class XMLTOOL_API X509Credential : public virtual Credential
+    {
+    protected:
+        X509Credential() {}
+        
+    public:
+        virtual ~X509Credential() {}
+
+        enum ResolveTypes {
+            RESOLVE_CERTS = 2,
+            RESOLVE_CRLS = 4
+        };
+
+        /**
+         * Gets an immutable collection of certificates in the entity's trust chain. The entity certificate is contained
+         * within this list. No specific ordering of the certificates is guaranteed.
+         * 
+         * @return a certificate chain
+         */
+        virtual const std::vector<XSECCryptoX509*>& getEntityCertificateChain() const=0;
+
+        /**
+         * Gets a CRL associated with the credential.
+         * 
+         * @return CRL associated with the credential
+         */
+        virtual XSECCryptoX509CRL* getCRL() const=0;
+    };
+};
+
+#endif /* __xmltooling_x509cred_h__ */
index 6387baf..097e630 100644 (file)
@@ -38,7 +38,7 @@ namespace xmltooling {
          * If a DOM is supplied, the following XML content is supported:
          * 
          * <ul>
-         *  <li>&lt;KeyResolver&gt; elements with a type attribute
+         *  <li>&lt;KeyInfoResolver&gt; elements with a type attribute
          * </ul>
          * 
          * XML namespaces are ignored in the processing of this content.
@@ -52,26 +52,27 @@ namespace xmltooling {
         
         /**
          * Determines whether an X.509 credential is valid with respect to the
-         * source of KeyInfo data supplied. It is the responsibility of the
-         * application to ensure that the KeyInfo information supplied is in fact
-         * associated with the peer who presented the credential. 
+         * source of credentials supplied.
          * 
-         * A custom KeyResolver can be supplied from outside the TrustEngine.
-         * Alternatively, one may be specified to the plugin constructor.
-         * A non-caching, inline resolver will be used as a fallback.
+         * <p>It is the responsibility of the application to ensure that the credentials
+         * supplied are in fact associated with the peer who presented the credential.
+         * 
+         * <p>If criteria with a peer name are supplied, the "name" of the EE certificate
+         * may also be checked to ensure that it identifies the intended peer.
+         * The peer name itself or implementation-specific rules based on the content of the
+         * peer credentials may be applied. Implementations may omit this check if they
+         * deem it unnecessary.
          * 
          * @param certEE        end-entity certificate to validate
          * @param certChain     the complete set of certificates presented for validation (includes certEE)
-         * @param keyInfoSource supplies KeyInfo objects to the TrustEngine
-         * @param checkName     true iff certificate subject/name checking has <b>NOT</b> already occurred
-         * @param keyResolver   optional externally supplied KeyResolver, or NULL
+         * @param credResolver  a locked resolver to supply trusted peer credentials to the TrustEngine
+         * @param criteria      criteria for selecting peer credentials
          */
         virtual bool validate(
             XSECCryptoX509* certEE,
             const std::vector<XSECCryptoX509*>& certChain,
-            const KeyInfoSource& keyInfoSource,
-            bool checkName=true,
-            const KeyResolver* keyResolver=NULL
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL
             ) const=0;
     };
     
index 8065543..a891f7d 100644 (file)
 #include <log4cpp/Category.hh>
 #include <openssl/x509_vfy.h>
 #include <openssl/x509v3.h>
+#include <xmltooling/security/CredentialCriteria.h>
+#include <xmltooling/security/CredentialResolver.h>
+#include <xmltooling/security/KeyInfoResolver.h>
 #include <xmltooling/security/OpenSSLCryptoX509CRL.h>
+#include <xmltooling/security/X509Credential.h>
 #include <xmltooling/signature/SignatureValidator.h>
 #include <xmltooling/util/NDC.h>
 #include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
@@ -38,15 +42,6 @@ using namespace xmltooling;
 using namespace log4cpp;
 using namespace std;
 
-AbstractPKIXTrustEngine::AbstractPKIXTrustEngine(const DOMElement* e) : OpenSSLTrustEngine(e), m_inlineResolver(NULL)
-{
-    m_inlineResolver = XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(INLINE_KEY_RESOLVER,NULL);
-}
-
-AbstractPKIXTrustEngine::~AbstractPKIXTrustEngine()
-{
-    delete m_inlineResolver;
-}
 
 namespace {
     static int XMLTOOL_DLLLOCAL error_callback(int ok, X509_STORE_CTX* ctx)
@@ -91,10 +86,7 @@ namespace {
         for (vector<XSECCryptoX509CRL*>::const_iterator j=crls.begin(); j!=crls.end(); ++j) {
             if ((*j)->getProviderName()==DSIGConstants::s_unicodeStrPROVOpenSSL) {
                 // owned by store
-                X509_STORE_add_crl(
-                    store,
-                    X509_CRL_dup(static_cast<OpenSSLCryptoX509CRL*>(*j)->getOpenSSLX509CRL())
-                    );
+                X509_STORE_add_crl(store, X509_CRL_dup(static_cast<OpenSSLCryptoX509CRL*>(*j)->getOpenSSLX509CRL()));
             }
         }
      
@@ -144,31 +136,20 @@ namespace {
     }
 };
 
-bool AbstractPKIXTrustEngine::checkEntityNames(X509* certEE, const KeyInfoSource& keyInfoSource) const
+bool AbstractPKIXTrustEngine::checkEntityNames(
+    X509* certEE, const CredentialResolver& credResolver, const CredentialCriteria& criteria
+    ) const
 {
     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".TrustEngine");
-    
-    // Build a list of acceptable names. Transcode the possible key "names" to UTF-8.
-    // For some simple cases, this should handle UTF-8 encoded DNs in certificates.
-    vector<string> keynames;
-    auto_ptr<KeyInfoIterator> keyInfoIter(keyInfoSource.getKeyInfoIterator());
-    while (keyInfoIter->hasNext()) {
-        const KeyInfo* keyInfo = keyInfoIter->next();
-        const vector<KeyName*>& knames=keyInfo->getKeyNames();
-        for (vector<KeyName*>::const_iterator kn_i=knames.begin(); kn_i!=knames.end(); ++kn_i) {
-            const XMLCh* n=(*kn_i)->getName();
-            if (n && *n) {
-                char* kn=toUTF8(n);
-                keynames.push_back(kn);
-                delete[] kn;
-            }
-        }
-    }
 
-    string peername = keyInfoSource.getName();
-    if (!peername.empty())
-        keynames.push_back(peername);
-    
+    vector<const Credential*> creds;
+    credResolver.resolve(creds,&criteria);
+
+    // Build a list of acceptable names.
+    vector<string> keynames(1,criteria.getPeerName());
+    for (vector<const Credential*>::const_iterator cred = creds.begin(); cred!=creds.end(); ++cred)
+        (*cred)->getKeyNames(keynames);
+
     char buf[256];
     X509_NAME* subject=X509_get_subject_name(certEE);
     if (subject) {
@@ -264,9 +245,8 @@ bool AbstractPKIXTrustEngine::checkEntityNames(X509* certEE, const KeyInfoSource
 bool AbstractPKIXTrustEngine::validate(
     X509* certEE,
     STACK_OF(X509)* certChain,
-    const KeyInfoSource& keyInfoSource,
-    bool checkName,
-    const KeyResolver* keyResolver
+    const CredentialResolver& credResolver,
+    CredentialCriteria* criteria
     ) const
 {
 #ifdef _DEBUG
@@ -279,19 +259,19 @@ bool AbstractPKIXTrustEngine::validate(
         return false;
     }
 
-    if (checkName) {
+    if (criteria && criteria->getPeerName() && *(criteria->getPeerName())) {
         log.debug("checking that the certificate name is acceptable");
-        if (!checkEntityNames(certEE,keyInfoSource)) {
-            log.debug("certificate name was not acceptable");
+        if (criteria->getUsage()==CredentialCriteria::UNSPECIFIED_CREDENTIAL)
+            criteria->setUsage(CredentialCriteria::SIGNING_CREDENTIAL);
+        if (!checkEntityNames(certEE,credResolver,*criteria)) {
+            log.error("certificate name was not acceptable");
             return false;
         }
     }
     
     log.debug("performing certificate path validation...");
 
-    auto_ptr<PKIXValidationInfoIterator> pkix(
-        getPKIXValidationInfoIterator(keyInfoSource, *(keyResolver ? keyResolver : m_inlineResolver))
-        );
+    auto_ptr<PKIXValidationInfoIterator> pkix(getPKIXValidationInfoIterator(credResolver, criteria, m_keyInfoResolver));
     while (pkix->next()) {
         if (::validate(certEE,certChain,pkix.get())) {
             return true;
@@ -305,9 +285,8 @@ bool AbstractPKIXTrustEngine::validate(
 bool AbstractPKIXTrustEngine::validate(
     XSECCryptoX509* certEE,
     const vector<XSECCryptoX509*>& certChain,
-    const KeyInfoSource& keyInfoSource,
-    bool checkName,
-    const KeyResolver* keyResolver
+    const CredentialResolver& credResolver,
+    CredentialCriteria* criteria
     ) const
 {
 #ifdef _DEBUG
@@ -326,15 +305,15 @@ bool AbstractPKIXTrustEngine::validate(
     for (vector<XSECCryptoX509*>::const_iterator i=certChain.begin(); i!=certChain.end(); ++i)
         sk_X509_push(untrusted,static_cast<OpenSSLCryptoX509*>(*i)->getOpenSSLX509());
 
-    bool ret = validate(static_cast<OpenSSLCryptoX509*>(certEE)->getOpenSSLX509(),untrusted,keyInfoSource,checkName,keyResolver);
+    bool ret = validate(static_cast<OpenSSLCryptoX509*>(certEE)->getOpenSSLX509(), untrusted, credResolver, criteria);
     sk_X509_free(untrusted);
     return ret;
 }
 
 bool AbstractPKIXTrustEngine::validate(
     Signature& sig,
-    const KeyInfoSource& keyInfoSource,
-    const KeyResolver* keyResolver
+    const CredentialResolver& credResolver,
+    CredentialCriteria* criteria
     ) const
 {
 #ifdef _DEBUG
@@ -342,9 +321,23 @@ bool AbstractPKIXTrustEngine::validate(
 #endif
     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".TrustEngine");
 
-    // Pull the certificate chain out of the signature using an inline KeyResolver.
-    KeyResolver::ResolvedCertificates certs;
-    if (0==m_inlineResolver->resolveCertificates(&sig, certs)) {
+    const KeyInfoResolver* inlineResolver = m_keyInfoResolver;
+    if (!inlineResolver)
+        inlineResolver = XMLToolingConfig::getConfig().getKeyInfoResolver();
+    if (!inlineResolver) {
+        log.error("unable to perform PKIX validation, no KeyInfoResolver available");
+        return false;
+    }
+
+    // Pull the certificate chain out of the signature.
+    X509Credential* x509cred;
+    auto_ptr<Credential> cred(inlineResolver->resolve(&sig,X509Credential::RESOLVE_CERTS));
+    if (!cred.get() || !(x509cred=dynamic_cast<X509Credential*>(cred.get()))) {
+        log.error("unable to perform PKIX validation, signature does not contain any certificates");
+        return false;
+    }
+    const vector<XSECCryptoX509*>& certs = x509cred->getEntityCertificateChain();
+    if (certs.empty()) {
         log.error("unable to perform PKIX validation, signature does not contain any certificates");
         return false;
     }
@@ -355,20 +348,21 @@ bool AbstractPKIXTrustEngine::validate(
     // Most of the time, this will be the first one anyway.
     XSECCryptoX509* certEE=NULL;
     SignatureValidator keyValidator;
-    for (vector<XSECCryptoX509*>::const_iterator i=certs.v().begin(); !certEE && i!=certs.v().end(); ++i) {
+    for (vector<XSECCryptoX509*>::const_iterator i=certs.begin(); !certEE && i!=certs.end(); ++i) {
         try {
-            keyValidator.setKey((*i)->clonePublicKey());
+            auto_ptr<XSECCryptoKey> key((*i)->clonePublicKey());
+            keyValidator.setKey(key.get());
             keyValidator.validate(&sig);
             log.debug("signature verified with key inside signature, attempting certificate validation...");
             certEE=(*i);
         }
-        catch (ValidationException&) {
-            // trap failures
+        catch (ValidationException& ex) {
+            log.debug(ex.what());
         }
     }
     
     if (certEE)
-        return validate(certEE,certs.v(),keyInfoSource,true,keyResolver);
+        return validate(certEE,certs,credResolver,criteria);
         
     log.debug("failed to verify signature with embedded certificates");
     return false;
@@ -380,8 +374,8 @@ bool AbstractPKIXTrustEngine::validate(
     KeyInfo* keyInfo,
     const char* in,
     unsigned int in_len,
-    const KeyInfoSource& keyInfoSource,
-    const KeyResolver* keyResolver
+    const CredentialResolver& credResolver,
+    CredentialCriteria* criteria
     ) const
 {
 #ifdef _DEBUG
@@ -389,9 +383,28 @@ bool AbstractPKIXTrustEngine::validate(
 #endif
     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".TrustEngine");
 
-    // Pull the certificate chain out of the KeyInfo using an inline KeyResolver.
-    KeyResolver::ResolvedCertificates certs;
-    if (!keyInfo || 0==m_inlineResolver->resolveCertificates(keyInfo, certs)) {
+    if (!keyInfo) {
+        log.error("unable to perform PKIX validation, KeyInfo not present");
+        return false;
+    }
+
+    const KeyInfoResolver* inlineResolver = m_keyInfoResolver;
+    if (!inlineResolver)
+        inlineResolver = XMLToolingConfig::getConfig().getKeyInfoResolver();
+    if (!inlineResolver) {
+        log.error("unable to perform PKIX validation, no KeyInfoResolver available");
+        return false;
+    }
+
+    // Pull the certificate chain out of the signature.
+    X509Credential* x509cred;
+    auto_ptr<Credential> cred(inlineResolver->resolve(keyInfo,X509Credential::RESOLVE_CERTS));
+    if (!cred.get() || !(x509cred=dynamic_cast<X509Credential*>(cred.get()))) {
+        log.error("unable to perform PKIX validation, KeyInfo does not contain any certificates");
+        return false;
+    }
+    const vector<XSECCryptoX509*>& certs = x509cred->getEntityCertificateChain();
+    if (certs.empty()) {
         log.error("unable to perform PKIX validation, KeyInfo does not contain any certificates");
         return false;
     }
@@ -401,8 +414,7 @@ bool AbstractPKIXTrustEngine::validate(
     // Find and save off a pointer to the certificate that unlocks the object.
     // Most of the time, this will be the first one anyway.
     XSECCryptoX509* certEE=NULL;
-    SignatureValidator keyValidator;
-    for (vector<XSECCryptoX509*>::const_iterator i=certs.v().begin(); !certEE && i!=certs.v().end(); ++i) {
+    for (vector<XSECCryptoX509*>::const_iterator i=certs.begin(); !certEE && i!=certs.end(); ++i) {
         try {
             auto_ptr<XSECCryptoKey> key((*i)->clonePublicKey());
             if (Signature::verifyRawSignature(key.get(), sigAlgorithm, sig, in, in_len)) {
@@ -410,13 +422,13 @@ bool AbstractPKIXTrustEngine::validate(
                 certEE=(*i);
             }
         }
-        catch (SignatureException&) {
-            // trap failures
+        catch (SignatureException& ex) {
+            log.debug(ex.what());
         }
     }
     
     if (certEE)
-        return validate(certEE,certs.v(),keyInfoSource,true,keyResolver);
+        return validate(certEE,certs,credResolver,criteria);
         
     log.debug("failed to verify signature with embedded certificates");
     return false;
diff --git a/xmltooling/security/impl/BasicX509Credential.cpp b/xmltooling/security/impl/BasicX509Credential.cpp
new file mode 100644 (file)
index 0000000..d6f41da
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * BasicX509Credential.cpp
+ * 
+ * Wraps an X.509-based Credential by storing key/cert objects inside. 
+ */
+
+#include "internal.h"
+#include "security/BasicX509Credential.h"
+#include "signature/KeyInfo.h"
+
+#include <algorithm>
+#include <openssl/x509v3.h>
+#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
+
+using namespace xmlsignature;
+using namespace xmltooling;
+using namespace std;
+
+BasicX509Credential::~BasicX509Credential()
+{
+    delete m_key;
+    if (m_ownCerts)
+        for_each(m_xseccerts.begin(), m_xseccerts.end(), xmltooling::cleanup<XSECCryptoX509>());
+    delete m_crl;
+    delete m_keyInfo;
+    delete m_compactKeyInfo;
+}
+
+void BasicX509Credential::initKeyInfo()
+{
+    delete m_keyInfo;
+    m_keyInfo = NULL;
+    delete m_compactKeyInfo;
+    m_compactKeyInfo = NULL;
+
+    vector<string> names;
+    if (getKeyNames(names)>0) {
+        m_compactKeyInfo = KeyInfoBuilder::buildKeyInfo();
+        VectorOf(KeyName) knames = m_compactKeyInfo->getKeyNames();
+        for (vector<string>::const_iterator n = names.begin(); n!=names.end(); ++n) {
+            xmltooling::auto_ptr_XMLCh wide(n->c_str());
+            KeyName* kname = KeyNameBuilder::buildKeyName();
+            kname->setName(wide.get());
+            knames.push_back(kname);
+        }
+    }
+    
+    if (!m_xseccerts.empty()) {
+        m_keyInfo = m_compactKeyInfo ? m_compactKeyInfo->cloneKeyInfo() : KeyInfoBuilder::buildKeyInfo();
+        X509Data* x509Data=X509DataBuilder::buildX509Data();
+        m_keyInfo->getX509Datas().push_back(x509Data);
+        for (vector<XSECCryptoX509*>::const_iterator x = m_xseccerts.begin(); x!=m_xseccerts.end(); ++x) {
+            safeBuffer& buf=(*x)->getDEREncodingSB();
+            X509Certificate* x509=X509CertificateBuilder::buildX509Certificate();
+            x509->setValue(buf.sbStrToXMLCh());
+            x509Data->getX509Certificates().push_back(x509);
+        }
+    }
+}
+
+vector<string>::size_type BasicX509Credential::getKeyNames(vector<string>& results) const
+{
+    if (m_xseccerts.empty() || m_xseccerts.front()->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL)
+        return 0;
+    
+    X509* cert = static_cast<OpenSSLCryptoX509*>(m_xseccerts.front())->getOpenSSLX509();
+    if (!cert)
+        return 0;
+        
+    X509_NAME* subject=X509_get_subject_name(cert);
+    if (subject) {
+        char buf[256];
+        memset(buf,0,sizeof(buf));
+        if (X509_NAME_get_text_by_NID(subject,NID_commonName,buf,255)>0)
+            results.push_back(buf);
+
+        STACK_OF(GENERAL_NAME)* altnames=(STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
+        if (altnames) {
+            string alt;
+            int numalts = sk_GENERAL_NAME_num(altnames);
+            for (int an=0; an<numalts; an++) {
+                const GENERAL_NAME* check = sk_GENERAL_NAME_value(altnames, an);
+                if (check->type==GEN_DNS || check->type==GEN_URI) {
+                    const char* altptr = (char*)ASN1_STRING_data(check->d.ia5);
+                    const int altlen = ASN1_STRING_length(check->d.ia5);
+                    if (altlen>0) {
+                        alt.erase();
+                        alt.append(altptr,altlen);
+                        results.push_back(alt);
+                    }
+                }
+            }
+        }
+        GENERAL_NAMES_free(altnames);
+    }
+
+    return results.size();
+}
index 41e04b1..1834aab 100644 (file)
@@ -23,6 +23,7 @@
 #include "internal.h"
 #include "exceptions.h"
 #include "security/ChainingTrustEngine.h"
+#include "util/XMLHelper.h"
 
 #include <log4cpp/Category.hh>
 #include <xercesc/util/XMLUniDefs.hpp>
@@ -65,14 +66,10 @@ ChainingTrustEngine::~ChainingTrustEngine() {
     for_each(m_engines.begin(), m_engines.end(), xmltooling::cleanup<TrustEngine>());
 }
 
-bool ChainingTrustEngine::validate(
-    Signature& sig,
-    const KeyInfoSource& keyInfoSource,
-    const KeyResolver* keyResolver
-    ) const
+bool ChainingTrustEngine::validate(Signature& sig, const CredentialResolver& credResolver, CredentialCriteria* criteria) const
 {
     for (vector<TrustEngine*>::const_iterator i=m_engines.begin(); i!=m_engines.end(); ++i) {
-        if ((*i)->validate(sig,keyInfoSource,keyResolver))
+        if ((*i)->validate(sig,credResolver,criteria))
             return true;
     }
     return false;
@@ -84,12 +81,12 @@ bool ChainingTrustEngine::validate(
     KeyInfo* keyInfo,
     const char* in,
     unsigned int in_len,
-    const KeyInfoSource& keyInfoSource,
-    const KeyResolver* keyResolver
+    const CredentialResolver& credResolver,
+    CredentialCriteria* criteria
     ) const
 {
     for (vector<TrustEngine*>::const_iterator i=m_engines.begin(); i!=m_engines.end(); ++i) {
-        if ((*i)->validate(sigAlgorithm, sig, keyInfo, in, in_len, keyInfoSource, keyResolver))
+        if ((*i)->validate(sigAlgorithm, sig, keyInfo, in, in_len, credResolver, criteria))
             return true;
     }
     return false;
@@ -98,15 +95,14 @@ bool ChainingTrustEngine::validate(
 bool ChainingTrustEngine::validate(
     XSECCryptoX509* certEE,
     const vector<XSECCryptoX509*>& certChain,
-    const KeyInfoSource& keyInfoSource,
-    bool checkName,
-    const KeyResolver* keyResolver
+    const CredentialResolver& credResolver,
+    CredentialCriteria* criteria
     ) const
 {
     X509TrustEngine* down;
     for (vector<TrustEngine*>::const_iterator i=m_engines.begin(); i!=m_engines.end(); ++i) {
         if ((down = dynamic_cast<X509TrustEngine*>(*i)) &&
-                down->validate(certEE,certChain,keyInfoSource,checkName,keyResolver))
+                down->validate(certEE,certChain,credResolver,criteria))
             return true;
     }
     return false;
@@ -115,15 +111,13 @@ bool ChainingTrustEngine::validate(
 bool ChainingTrustEngine::validate(
     X509* certEE,
     STACK_OF(X509)* certChain,
-    const KeyInfoSource& keyInfoSource,
-    bool checkName,
-    const KeyResolver* keyResolver
+    const CredentialResolver& credResolver,
+    CredentialCriteria* criteria
     ) const
 {
     OpenSSLTrustEngine* down;
     for (vector<TrustEngine*>::const_iterator i=m_engines.begin(); i!=m_engines.end(); ++i) {
-        if ((down = dynamic_cast<OpenSSLTrustEngine*>(*i)) &&
-                down->validate(certEE,certChain,keyInfoSource,checkName,keyResolver))
+        if ((down = dynamic_cast<OpenSSLTrustEngine*>(*i)) && down->validate(certEE,certChain,credResolver,criteria))
             return true;
     }
     return false;
diff --git a/xmltooling/security/impl/Credential.cpp b/xmltooling/security/impl/Credential.cpp
new file mode 100644 (file)
index 0000000..2656f8d
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Credential.cpp
+ * 
+ * Wraps keys and related functionality. 
+ */
+
+#include "internal.h"
+#include "security/Credential.h"
+
+#include <log4cpp/Category.hh>
+#include <openssl/dsa.h>
+#include <openssl/rsa.h>
+#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyDSA.hpp>
+#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>
+
+using namespace xmltooling;
+
+bool Credential::isEqual(XSECCryptoKey& key) const
+{
+    XSECCryptoKey* key2 = getPublicKey();
+    if (!key2) {
+        log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".Credential").warn("no public key in credential for comparison");
+        return false;
+    }
+
+    if (key.getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL ||
+        key2->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) {
+        log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".Credential").warn("non-OpenSSL credentials are not supported.");
+        return false;
+    }
+
+    if (key.getKeyType()==XSECCryptoKey::KEY_RSA_PUBLIC || key.getKeyType()==XSECCryptoKey::KEY_RSA_PAIR) {
+        if (key2->getKeyType()!=XSECCryptoKey::KEY_RSA_PUBLIC && key2->getKeyType()==XSECCryptoKey::KEY_RSA_PAIR)
+            return false;
+        RSA* rsa1 = static_cast<OpenSSLCryptoKeyRSA*>(&key)->getOpenSSLRSA();
+        RSA* rsa2 = static_cast<OpenSSLCryptoKeyRSA*>(key2)->getOpenSSLRSA();
+        return (BN_cmp(rsa1->n,rsa2->n) == 0 && BN_cmp(rsa1->e,rsa2->e) == 0);
+    }
+
+    if (key.getKeyType()==XSECCryptoKey::KEY_DSA_PUBLIC || key.getKeyType()==XSECCryptoKey::KEY_DSA_PAIR) {
+        if (key2->getKeyType()!=XSECCryptoKey::KEY_DSA_PUBLIC && key2->getKeyType()==XSECCryptoKey::KEY_DSA_PAIR)
+            return false;
+        DSA* dsa1 = static_cast<OpenSSLCryptoKeyDSA*>(&key)->getOpenSSLDSA();
+        DSA* dsa2 = static_cast<OpenSSLCryptoKeyDSA*>(key2)->getOpenSSLDSA();
+        return (BN_cmp(dsa1->pub_key,dsa2->pub_key) == 0);
+    }
+    
+    log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".Credential").warn("unsupported key type for comparison");
+    return false;
+}
index 08a30bd..7646bc5 100644 (file)
@@ -21,6 +21,9 @@
  */
 
 #include "internal.h"
+#include "security/Credential.h"
+#include "security/CredentialCriteria.h"
+#include "security/CredentialResolver.h"
 #include "security/OpenSSLTrustEngine.h"
 #include "signature/SignatureValidator.h"
 #include "util/NDC.h"
@@ -45,8 +48,8 @@ namespace xmltooling {
 
         virtual bool validate(
             Signature& sig,
-            const KeyInfoSource& keyInfoSource,
-            const KeyResolver* keyResolver=NULL
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL
             ) const;
         virtual bool validate(
             const XMLCh* sigAlgorithm,
@@ -54,22 +57,20 @@ namespace xmltooling {
             KeyInfo* keyInfo,
             const char* in,
             unsigned int in_len,
-            const KeyInfoSource& keyInfoSource,
-            const KeyResolver* keyResolver=NULL
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL
             ) const;
         virtual bool validate(
             XSECCryptoX509* certEE,
             const vector<XSECCryptoX509*>& certChain,
-            const KeyInfoSource& keyInfoSource,
-            bool checkName=true,
-            const KeyResolver* keyResolver=NULL
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL
             ) const;
         virtual bool validate(
             X509* certEE,
             STACK_OF(X509)* certChain,
-            const KeyInfoSource& keyInfoSource,
-            bool checkName=true,
-            const KeyResolver* keyResolver=NULL
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL
             ) const;
     };
 
@@ -81,43 +82,47 @@ namespace xmltooling {
 
 bool ExplicitKeyTrustEngine::validate(
     Signature& sig,
-    const KeyInfoSource& keyInfoSource,
-    const KeyResolver* keyResolver
+    const CredentialResolver& credResolver,
+    CredentialCriteria* criteria
     ) const
 {
 #ifdef _DEBUG
     NDC ndc("validate");
 #endif
     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".TrustEngine");
-    
-    auto_ptr<KeyInfoIterator> keyInfoIter(keyInfoSource.getKeyInfoIterator());
-    if (!keyInfoIter->hasNext()) {
-        log.warn("unable to validate signature, no key information available for peer");
+
+    vector<const Credential*> credentials;
+    if (criteria) {
+        criteria->setUsage(CredentialCriteria::SIGNING_CREDENTIAL);
+        criteria->setSignature(sig);
+        credResolver.resolve(credentials,criteria);
+    }
+    else {
+        CredentialCriteria cc;
+        cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL);
+        cc.setSignature(sig);
+        credResolver.resolve(credentials,&cc);
+    }
+    if (credentials.empty()) {
+        log.warn("unable to validate signature, no credentials available from peer");
         return false;
     }
     
-    log.debug("attempting to validate signature with the key information for peer");
+    log.debug("attempting to validate signature with the peer's credentials");
     SignatureValidator sigValidator;
-    while (keyInfoIter->hasNext()) {
-        XSECCryptoKey* key = (keyResolver ? keyResolver : m_keyResolver)->resolveKey(keyInfoIter->next());
-        if (key) {
-            log.debug("attempting to validate signature with public key...");
-            try {
-                sigValidator.setKey(key);   // key now owned by validator
-                sigValidator.validate(&sig);
-                log.debug("signature validated with public key");
-                return true;
-            }
-            catch (ValidationException& e) {
-                log.debug("public key did not validate signature: %s", e.what());
-            }
+    for (vector<const Credential*>::const_iterator c=credentials.begin(); c!=credentials.end(); ++c) {
+        sigValidator.setCredential(*c);
+        try {
+            sigValidator.validate(&sig);
+            log.debug("signature validated with credential");
+            return true;
         }
-        else {
-            log.debug("key information does not resolve to a public key, skipping it");
+        catch (ValidationException& e) {
+            log.debug("public key did not validate signature: %s", e.what());
         }
     }
 
-    log.error("no peer key information validated the signature");
+    log.error("no peer credentials validated the signature");
     return false;
 }
 
@@ -127,8 +132,8 @@ bool ExplicitKeyTrustEngine::validate(
     KeyInfo* keyInfo,
     const char* in,
     unsigned int in_len,
-    const KeyInfoSource& keyInfoSource,
-    const KeyResolver* keyResolver
+    const CredentialResolver& credResolver,
+    CredentialCriteria* criteria
     ) const
 {
 #ifdef _DEBUG
@@ -136,19 +141,28 @@ bool ExplicitKeyTrustEngine::validate(
 #endif
     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".TrustEngine");
     
-    auto_ptr<KeyInfoIterator> keyInfoIter(keyInfoSource.getKeyInfoIterator());
-    if (!keyInfoIter->hasNext()) {
-        log.warn("unable to validate signature, no key information available for peer");
+    vector<const Credential*> credentials;
+    if (criteria) {
+        criteria->setUsage(CredentialCriteria::SIGNING_CREDENTIAL);
+        criteria->setKeyInfo(keyInfo);
+        credResolver.resolve(credentials,criteria);
+    }
+    else {
+        CredentialCriteria cc;
+        cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL);
+        cc.setKeyInfo(keyInfo);
+        credResolver.resolve(credentials,&cc);
+    }
+    if (credentials.empty()) {
+        log.warn("unable to validate signature, no credentials available from peer");
         return false;
     }
     
-    log.debug("attempting to validate signature with the key information for peer");
-    while (keyInfoIter->hasNext()) {
-        auto_ptr<XSECCryptoKey> key((keyResolver ? keyResolver : m_keyResolver)->resolveKey(keyInfoIter->next()));
-        if (key.get()) {
-            log.debug("attempting to validate signature with public key...");
+    log.debug("attempting to validate signature with the peer's credentials");
+    for (vector<const Credential*>::const_iterator c=credentials.begin(); c!=credentials.end(); ++c) {
+        if ((*c)->getPublicKey()) {
             try {
-                if (Signature::verifyRawSignature(key.get(), sigAlgorithm, sig, in, in_len)) {
+                if (Signature::verifyRawSignature((*c)->getPublicKey(), sigAlgorithm, sig, in, in_len)) {
                     log.debug("signature validated with public key");
                     return true;
                 }
@@ -159,21 +173,17 @@ bool ExplicitKeyTrustEngine::validate(
                 }
             }
         }
-        else {
-            log.debug("key information does not resolve to a public key, skipping it");
-        }
     }
 
-    log.error("no peer key information validated the signature");
+    log.error("no peer credentials validated the signature");
     return false;
 }
 
 bool ExplicitKeyTrustEngine::validate(
     XSECCryptoX509* certEE,
     const vector<XSECCryptoX509*>& certChain,
-    const KeyInfoSource& keyInfoSource,
-    bool checkName,
-    const KeyResolver* keyResolver
+    const CredentialResolver& credResolver,
+    CredentialCriteria* criteria
     ) const
 {
 #ifdef _DEBUG
@@ -188,15 +198,14 @@ bool ExplicitKeyTrustEngine::validate(
         return false;
     }
 
-    return validate(static_cast<OpenSSLCryptoX509*>(certEE)->getOpenSSLX509(), NULL, keyInfoSource, checkName, keyResolver);
+    return validate(static_cast<OpenSSLCryptoX509*>(certEE)->getOpenSSLX509(), NULL, credResolver, criteria);
 }
 
 bool ExplicitKeyTrustEngine::validate(
     X509* certEE,
     STACK_OF(X509)* certChain,
-    const KeyInfoSource& keyInfoSource,
-    bool checkName,
-    const KeyResolver* keyResolver
+    const CredentialResolver& credResolver,
+    CredentialCriteria* criteria
     ) const
 {
 #ifdef _DEBUG
@@ -209,19 +218,29 @@ bool ExplicitKeyTrustEngine::validate(
         return false;
     }
 
-    auto_ptr<KeyInfoIterator> keyInfoIter(keyInfoSource.getKeyInfoIterator());
-    if (!keyInfoIter->hasNext()) {
-        log.warn("unable to validate, no key information available for peer");
+    vector<const Credential*> credentials;
+    if (criteria) {
+        if (criteria->getUsage()==CredentialCriteria::UNSPECIFIED_CREDENTIAL)
+            criteria->setUsage(CredentialCriteria::SIGNING_CREDENTIAL);
+        credResolver.resolve(credentials,criteria);
+    }
+    else {
+        CredentialCriteria cc;
+        cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL);
+        credResolver.resolve(credentials,&cc);
+    }
+    if (credentials.empty()) {
+        log.warn("unable to validate certificate, no credentials available from peer");
         return false;
     }
 
     // The "explicit" trust implementation relies solely on keys living within the
-    // peer interface to verify the EE certificate.
+    // peer resolver to verify the EE certificate.
 
-    log.debug("attempting to match key information from peer with end-entity certificate");
-    while (keyInfoIter->hasNext()) {
-        auto_ptr<XSECCryptoKey> key((keyResolver ? keyResolver : m_keyResolver)->resolveKey(keyInfoIter->next()));
-        if (key.get()) {
+    log.debug("attempting to match credentials from peer with end-entity certificate");
+    for (vector<const Credential*>::const_iterator c=credentials.begin(); c!=credentials.end(); ++c) {
+        XSECCryptoKey* key = (*c)->getPublicKey();
+        if (key) {
             log.debug("checking if peer key matches end-entity certificate");
             if (key->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) {
                 log.error("only the OpenSSL XSEC provider is supported");
@@ -230,13 +249,13 @@ bool ExplicitKeyTrustEngine::validate(
             switch (key->getKeyType()) {
                 case XSECCryptoKey::KEY_RSA_PUBLIC:
                 {
-                    RSA* rsa = static_cast<OpenSSLCryptoKeyRSA*>(key.get())->getOpenSSLRSA();
+                    RSA* rsa = static_cast<OpenSSLCryptoKeyRSA*>(key)->getOpenSSLRSA();
                     EVP_PKEY* evp = X509_PUBKEY_get(X509_get_X509_PUBKEY(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) {
-                        log.debug("end-entity certificate matches peer RSA key information");
                         if (evp)
                             EVP_PKEY_free(evp);
+                        log.debug("end-entity certificate matches peer RSA key information");
                         return true;
                     }
                     if (evp)
@@ -246,12 +265,12 @@ bool ExplicitKeyTrustEngine::validate(
                 
                 case XSECCryptoKey::KEY_DSA_PUBLIC:
                 {
-                    DSA* dsa = static_cast<OpenSSLCryptoKeyDSA*>(key.get())->getOpenSSLDSA();
+                    DSA* dsa = static_cast<OpenSSLCryptoKeyDSA*>(key)->getOpenSSLDSA();
                     EVP_PKEY* evp = X509_PUBKEY_get(X509_get_X509_PUBKEY(certEE));
                     if (dsa && evp && evp->type == EVP_PKEY_DSA && BN_cmp(dsa->pub_key,evp->pkey.dsa->pub_key) == 0) {
-                        log.debug("end-entity certificate matches peer DSA key information");
                         if (evp)
                             EVP_PKEY_free(evp);
+                        log.debug("end-entity certificate matches peer DSA key information");
                         return true;
                     }
                     if (evp)
@@ -263,9 +282,6 @@ bool ExplicitKeyTrustEngine::validate(
                     log.warn("unknown peer key type, skipping...");
             }
         }
-        else {
-            log.debug("key information does not resolve to a public key, skipping it");
-        }
     }
 
     log.debug("no keys within this peer's key information matched the given end-entity certificate");
index a026fdb..1e81da0 100644 (file)
  */
 
 #include "internal.h"
-#include "security/KeyResolver.h"
-#include "security/OpenSSLCredentialResolver.h"
+#include "security/BasicX509Credential.h"
+#include "security/CredentialCriteria.h"
+#include "security/CredentialResolver.h"
+#include "security/KeyInfoResolver.h"
+#include "security/OpenSSLCredential.h"
 #include "util/NDC.h"
 #include "util/XMLHelper.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <algorithm>
 #include <openssl/pkcs12.h>
 #include <log4cpp/Category.hh>
 #include <xercesc/util/XMLUniDefs.hpp>
@@ -56,35 +58,84 @@ static int passwd_callback(char* buf, int len, int verify, void* passwd)
 }
 
 namespace xmltooling {
-    class XMLTOOL_DLLLOCAL FilesystemCredentialResolver : public OpenSSLCredentialResolver, public KeyResolver
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 )
+#endif
+
+    class XMLTOOL_DLLLOCAL FilesystemCredentialResolver;
+    class XMLTOOL_DLLLOCAL FilesystemCredential : public OpenSSLCredential, public BasicX509Credential
+    {
+    public:
+        FilesystemCredential(FilesystemCredentialResolver* resolver, XSECCryptoKey* key, const std::vector<XSECCryptoX509*>& xseccerts)
+                : BasicX509Credential(key, xseccerts), m_resolver(resolver) {
+            initKeyInfo();
+        }
+        virtual ~FilesystemCredential() {}
+        void attach(SSL_CTX* ctx) const;
+
+        FilesystemCredentialResolver* m_resolver;
+    };
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+    class XMLTOOL_DLLLOCAL FilesystemCredentialResolver : public CredentialResolver
     {
     public:
         FilesystemCredentialResolver(const DOMElement* e);
-        virtual ~FilesystemCredentialResolver();
+        virtual ~FilesystemCredentialResolver() {
+            delete m_credential;
+            for_each(m_certs.begin(),m_certs.end(),X509_free);
+        }
 
         Lockable* lock() { return this; }
         void unlock() {}
         
-        XSECCryptoKey* loadKey();
-        
-        XSECCryptoKey* getKey(const KeyInfo* keyInfo=NULL) const { return m_key ? m_key->clone() : NULL; }
-        const vector<XSECCryptoX509*>& getCertificates() const { return m_xseccerts; }
-        void attach(SSL_CTX* ctx) const;
-        
-        XSECCryptoKey* resolveKey(const KeyInfo* keyInfo) const { return m_key ? m_key->clone() : NULL; }
-        XSECCryptoKey* resolveKey(DSIGKeyInfoList* keyInfo) const { return m_key ? m_key->clone() : NULL; }
-        vector<XSECCryptoX509*>::size_type resolveCertificates(const KeyInfo* keyInfo, ResolvedCertificates& certs) const {
-            accessCertificates(certs).assign(m_xseccerts.begin(), m_xseccerts.end());
-            accessOwned(certs) = false;
-            return accessCertificates(certs).size();
+        const Credential* resolve(const CredentialCriteria* criteria=NULL) const {
+            return matches(criteria) ? m_credential : NULL;
         }
-        vector<XSECCryptoX509*>::size_type resolveCertificates(DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs) const {
-            accessCertificates(certs).assign(m_xseccerts.begin(), m_xseccerts.end());
-            accessOwned(certs) = false;
-            return accessCertificates(certs).size();
+
+        virtual vector<const Credential*>::size_type resolve(
+            vector<const Credential*>& results, const CredentialCriteria* criteria=NULL
+            ) const {
+            if (matches(criteria)) {
+                results.push_back(m_credential);
+                return 1;
+            }
+            return 0;
         }
-        
+
+        void attach(SSL_CTX* ctx) const;
+
     private:
+        XSECCryptoKey* loadKey();
+        bool matches(const CredentialCriteria* criteria) const {
+            bool match = true;
+            if (criteria) {
+                // See if algorithm is kosher.
+                const char* alg = criteria->getKeyAlgorithm();
+                if (alg && *alg) {
+                    match = false;
+                    for (vector<string>::const_iterator a = m_algorithms.begin(); a!=m_algorithms.end(); ++a) {
+                        if (strstr(alg, a->c_str()))
+                            match = true;
+                    }
+                }
+                if (match && m_credential->getPublicKey()) {
+                    // See if we have to match a specific key.
+                    auto_ptr<Credential> cred(
+                        XMLToolingConfig::getConfig().getKeyInfoResolver()->resolve(*criteria,Credential::RESOLVE_KEYS)
+                        );
+                    if (cred.get())
+                        match = cred->isEqual(*(m_credential->getPublicKey()));
+                }
+            }
+            return match;
+        }
+        
         enum format_t { PEM=SSL_FILETYPE_PEM, DER=SSL_FILETYPE_ASN1, _PKCS12, UNKNOWN };
     
         format_t getEncodingFormat(BIO* in) const;
@@ -94,21 +145,17 @@ namespace xmltooling {
         format_t m_keyformat;
         string m_keypath,m_keypass;
         vector<X509*> m_certs;
-        vector<XSECCryptoX509*> m_xseccerts;
-        XSECCryptoKey* m_key;
+        FilesystemCredential* m_credential;
+        vector<string> m_algorithms;
     };
 
     CredentialResolver* XMLTOOL_DLLLOCAL FilesystemCredentialResolverFactory(const DOMElement* const & e)
     {
         return new FilesystemCredentialResolver(e);
     }
-
-    KeyResolver* XMLTOOL_DLLLOCAL FilesystemKeyResolverFactory(const DOMElement* const & e)
-    {
-        return new FilesystemCredentialResolver(e);
-    }
 };
 
+static const XMLCh AlgorithmPrefix[] =  UNICODE_LITERAL_15(A,l,g,o,r,i,t,h,m,P,r,e,f,i,x);
 static const XMLCh CAPath[] =           UNICODE_LITERAL_6(C,A,P,a,t,h);
 static const XMLCh Certificate[] =      UNICODE_LITERAL_11(C,e,r,t,i,f,i,c,a,t,e);
 static const XMLCh format[] =           UNICODE_LITERAL_6(f,o,r,m,a,t);
@@ -116,19 +163,38 @@ static const XMLCh Key[] =              UNICODE_LITERAL_3(K,e,y);
 static const XMLCh password[] =         UNICODE_LITERAL_8(p,a,s,s,w,o,r,d);
 static const XMLCh Path[] =             UNICODE_LITERAL_4(P,a,t,h);
 
-FilesystemCredentialResolver::FilesystemCredentialResolver(const DOMElement* e) : m_key(NULL)
+FilesystemCredentialResolver::FilesystemCredentialResolver(const DOMElement* e) : m_credential(NULL)
 {
 #ifdef _DEBUG
     NDC ndc("FilesystemCredentialResolver");
 #endif
     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".CredentialResolver");
 
+    const DOMElement* root=e;
+    e=XMLHelper::getFirstChildElement(root,AlgorithmPrefix);
+    while (e) {
+        if (e->hasChildNodes()) {
+            auto_ptr_char alg(e->getFirstChild()->getNodeValue());
+            if (alg.get())
+                m_algorithms.push_back(alg.get());
+        }
+        e=XMLHelper::getNextSiblingElement(e,AlgorithmPrefix);
+    }
+
+    if (m_algorithms.empty()) {
+        m_algorithms.push_back(URI_ID_SIG_BASE);
+        m_algorithms.push_back(URI_ID_SIG_BASEMORE);
+        m_algorithms.push_back("http://www.w3.org/2001/04/xmlenc#rsa");
+    }
+
+    XSECCryptoKey* key=NULL;
+    vector<XSECCryptoX509*> xseccerts;
+
     format_t fformat;
     const XMLCh* format_xml=NULL;
     BIO* in = NULL;
     
     // Move to Key
-    const DOMElement* root=e;
     e=XMLHelper::getFirstChildElement(root,Key);
     if (e) {
 
@@ -192,18 +258,21 @@ FilesystemCredentialResolver::FilesystemCredentialResolver(const DOMElement* e)
         }
         
         // Load the key.
-        m_key = loadKey();
+        key = loadKey();
     }
         
     // Check for Certificate
     e=XMLHelper::getFirstChildElement(root,Certificate);
-    if (!e)
+    if (!e) {
+        m_credential = new FilesystemCredential(this,key,xseccerts);
         return;
+    }
     auto_ptr_char certpass(e->getAttributeNS(NULL,password));
     
     DOMElement* ep=XMLHelper::getFirstChildElement(e,Path);
     if (!ep || !ep->hasChildNodes()) {
         log.error("Path element missing inside Certificate element or is empty");
+        delete key;
         throw XMLSecurityException("FilesystemCredentialResolver can't access certificate file, missing or empty Path element.");
     }
     
@@ -214,6 +283,7 @@ FilesystemCredentialResolver::FilesystemCredentialResolver(const DOMElement* e)
         if (fformat == UNKNOWN) {
             auto_ptr_char unknown(format_xml);
             log.error("configuration specifies unknown certificate encoding format (%s)", unknown.get());
+            delete key;
             throw XMLSecurityException("FilesystemCredentialResolver configuration contains unknown certificate encoding format ($1)",params(1,unknown.get()));
         }
     }
@@ -276,9 +346,8 @@ FilesystemCredentialResolver::FilesystemCredentialResolver(const DOMElement* e)
             in=NULL;
         }
 
-        if (m_certs.empty()) {
+        if (m_certs.empty())
             throw XMLSecurityException("FilesystemCredentialResolver unable to load any certificate(s)");
-        }
 
         // Load any extra CA files.
         DOMElement* extra=XMLHelper::getFirstChildElement(e,CAPath);
@@ -348,14 +417,17 @@ FilesystemCredentialResolver::FilesystemCredentialResolver(const DOMElement* e)
         }
     }
     catch (XMLToolingException&) {
-        for (vector<X509*>::iterator j=m_certs.begin(); j!=m_certs.end(); j++)
-            X509_free(*j);
+        delete key;
+        for_each(m_certs.begin(), m_certs.end(), X509_free);
         throw;
     }
 
-    // Reflect certs over to XSEC form.
+    // Reflect certs over to XSEC form and wrap with credential object.
     for (vector<X509*>::iterator j=m_certs.begin(); j!=m_certs.end(); j++)
-        m_xseccerts.push_back(new OpenSSLCryptoX509(*j));
+        xseccerts.push_back(new OpenSSLCryptoX509(*j));
+    if (!key && !xseccerts.empty())
+        key = xseccerts.front()->clonePublicKey();
+    m_credential = new FilesystemCredential(this, key, xseccerts);
 }
 
 XSECCryptoKey* FilesystemCredentialResolver::loadKey()
@@ -413,77 +485,6 @@ XSECCryptoKey* FilesystemCredentialResolver::loadKey()
     throw XMLSecurityException("FilesystemCredentialResolver unable to load private key from file."); 
 }
 
-FilesystemCredentialResolver::~FilesystemCredentialResolver()
-{
-    delete m_key;
-    for_each(m_certs.begin(),m_certs.end(),X509_free);
-    for_each(m_xseccerts.begin(),m_xseccerts.end(),xmltooling::cleanup<XSECCryptoX509>());
-}
-
-void FilesystemCredentialResolver::attach(SSL_CTX* ctx) const
-{
-#ifdef _DEBUG
-    NDC ndc("attach");
-#endif
-    
-    // Attach key.
-    SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
-    SSL_CTX_set_default_passwd_cb_userdata(ctx, const_cast<char*>(m_keypass.c_str()));
-
-    int ret=0;
-    switch (m_keyformat) {
-        case PEM:
-            ret=SSL_CTX_use_PrivateKey_file(ctx, m_keypath.c_str(), m_keyformat);
-            break;
-            
-        case DER:
-            ret=SSL_CTX_use_RSAPrivateKey_file(ctx, m_keypath.c_str(), m_keyformat);
-            break;
-            
-        default: {
-            BIO* in=BIO_new(BIO_s_file_internal());
-            if (in && BIO_read_filename(in,m_keypath.c_str())>0) {
-                EVP_PKEY* pkey=NULL;
-                PKCS12* p12 = d2i_PKCS12_bio(in, NULL);
-                if (p12) {
-                    PKCS12_parse(p12, const_cast<char*>(m_keypass.c_str()), &pkey, NULL, NULL);
-                    PKCS12_free(p12);
-                    if (pkey) {
-                        ret=SSL_CTX_use_PrivateKey(ctx, pkey);
-                        EVP_PKEY_free(pkey);
-                    }
-                }
-            }
-            if (in)
-                BIO_free(in);
-        }
-    }
-    
-    if (ret!=1) {
-        log_openssl();
-        throw XMLSecurityException("Unable to attach private key to SSL context.");
-    }
-
-    // Attach certs.
-    for (vector<X509*>::const_iterator i=m_certs.begin(); i!=m_certs.end(); i++) {
-        if (i==m_certs.begin()) {
-            if (SSL_CTX_use_certificate(ctx, *i) != 1) {
-                log_openssl();
-                throw XMLSecurityException("Unable to attach client certificate to SSL context.");
-            }
-        }
-        else {
-            // When we add certs, they don't get ref counted, so we need to duplicate them.
-            X509* dup = X509_dup(*i);
-            if (SSL_CTX_add_extra_chain_cert(ctx, dup) != 1) {
-                X509_free(dup);
-                log_openssl();
-                throw XMLSecurityException("Unable to attach CA certificate to SSL context.");
-            }
-        }
-    }
-}
-
 // Used to determine the encoding format of credentials files
 // dynamically. Supports: PEM, DER, PKCS12.
 FilesystemCredentialResolver::format_t FilesystemCredentialResolver::getEncodingFormat(BIO* in) const
@@ -572,3 +573,72 @@ FilesystemCredentialResolver::format_t FilesystemCredentialResolver::xmlFormatTo
 
     return format;
 }
+
+void FilesystemCredentialResolver::attach(SSL_CTX* ctx) const
+{
+#ifdef _DEBUG
+    NDC ndc("attach");
+#endif
+    
+    // Attach key.
+    SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
+    SSL_CTX_set_default_passwd_cb_userdata(ctx, const_cast<char*>(m_keypass.c_str()));
+
+    int ret=0;
+    switch (m_keyformat) {
+        case PEM:
+            ret=SSL_CTX_use_PrivateKey_file(ctx, m_keypath.c_str(), m_keyformat);
+            break;
+            
+        case DER:
+            ret=SSL_CTX_use_RSAPrivateKey_file(ctx, m_keypath.c_str(), m_keyformat);
+            break;
+            
+        default: {
+            BIO* in=BIO_new(BIO_s_file_internal());
+            if (in && BIO_read_filename(in,m_keypath.c_str())>0) {
+                EVP_PKEY* pkey=NULL;
+                PKCS12* p12 = d2i_PKCS12_bio(in, NULL);
+                if (p12) {
+                    PKCS12_parse(p12, const_cast<char*>(m_keypass.c_str()), &pkey, NULL, NULL);
+                    PKCS12_free(p12);
+                    if (pkey) {
+                        ret=SSL_CTX_use_PrivateKey(ctx, pkey);
+                        EVP_PKEY_free(pkey);
+                    }
+                }
+            }
+            if (in)
+                BIO_free(in);
+        }
+    }
+    
+    if (ret!=1) {
+        log_openssl();
+        throw XMLSecurityException("Unable to attach private key to SSL context.");
+    }
+
+    // Attach certs.
+    for (vector<X509*>::const_iterator i=m_certs.begin(); i!=m_certs.end(); i++) {
+        if (i==m_certs.begin()) {
+            if (SSL_CTX_use_certificate(ctx, *i) != 1) {
+                log_openssl();
+                throw XMLSecurityException("Unable to attach client certificate to SSL context.");
+            }
+        }
+        else {
+            // When we add certs, they don't get ref counted, so we need to duplicate them.
+            X509* dup = X509_dup(*i);
+            if (SSL_CTX_add_extra_chain_cert(ctx, dup) != 1) {
+                X509_free(dup);
+                log_openssl();
+                throw XMLSecurityException("Unable to attach CA certificate to SSL context.");
+            }
+        }
+    }
+}
+
+void FilesystemCredential::attach(SSL_CTX* ctx) const
+{
+    return m_resolver->attach(ctx);
+}
index 311fd06..30e9dee 100644 (file)
@@ -21,7 +21,8 @@
  */
 
 #include "internal.h"
-#include "security/CachingKeyResolver.h"
+#include "security/BasicX509Credential.h"
+#include "security/KeyInfoResolver.h"
 #include "signature/KeyInfo.h"
 #include "util/NDC.h"
 #include "util/Threads.h"
@@ -44,116 +45,122 @@ using namespace log4cpp;
 using namespace std;
 
 namespace xmltooling {
-    class XMLTOOL_DLLLOCAL InlineKeyResolver : public CachingKeyResolver
+
+    class XMLTOOL_DLLLOCAL InlineCredential : public BasicX509Credential
     {
+        const KeyInfo* m_inlineKeyInfo;
+        DSIGKeyInfoList* m_nativeKeyInfo;
     public:
-        InlineKeyResolver(const DOMElement* e);
-        virtual ~InlineKeyResolver();
-
-        XSECCryptoKey* resolveKey(const KeyInfo* keyInfo) const;
-        XSECCryptoKey* resolveKey(DSIGKeyInfoList* keyInfo) const;
-        vector<XSECCryptoX509*>::size_type resolveCertificates(const KeyInfo* keyInfo, ResolvedCertificates& certs) const;
-        vector<XSECCryptoX509*>::size_type resolveCertificates(DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs) const;
-        XSECCryptoX509CRL* resolveCRL(const KeyInfo* keyInfo) const;
-        XSECCryptoX509CRL* resolveCRL(DSIGKeyInfoList* keyInfo) const;
-        
-        void clearCache() {
-            if (m_lock)
-                m_lock->wrlock();
-            m_cache.clear();
-            if (m_lock)
-                m_lock->unlock();
+        InlineCredential(const KeyInfo* keyInfo=NULL)
+            : BasicX509Credential(keyInfo!=NULL), m_inlineKeyInfo(keyInfo), m_nativeKeyInfo(NULL) {
+        }
+        InlineCredential(DSIGKeyInfoList* keyInfo)
+            : BasicX509Credential(false), m_inlineKeyInfo(NULL), m_nativeKeyInfo(keyInfo) {
+        }
+        virtual ~InlineCredential() {}
+
+        XSECCryptoKey* getPrivateKey() const {
+            return NULL;
+        }
+
+        const KeyInfo* getKeyInfo(bool compact=false) const {
+            return m_inlineKeyInfo;
         }
         
-    private:
-        struct XMLTOOL_DLLLOCAL CacheEntry {
-            CacheEntry() : m_key(NULL), m_crl(NULL) {}
-            ~CacheEntry() {
-                delete m_key;
-                for_each(m_certs.begin(),m_certs.end(),xmltooling::cleanup<XSECCryptoX509>());
-                delete m_crl;
+        vector<string>::size_type getKeyNames(vector<string>& results) const {
+            if (m_inlineKeyInfo) {
+                const vector<KeyName*>& knames=m_inlineKeyInfo->getKeyNames();
+                for (vector<KeyName*>::const_iterator kn_i=knames.begin(); kn_i!=knames.end(); ++kn_i) {
+                    const XMLCh* n=(*kn_i)->getName();
+                    if (n && *n) {
+                        char* kn=toUTF8(n);
+                        results.push_back(kn);
+                        delete[] kn;
+                    }
+                }
+            }
+            else if (m_nativeKeyInfo) {
+                for (size_t s=0; s<m_nativeKeyInfo->getSize(); s++) {
+                    const XMLCh* n=m_nativeKeyInfo->item(s)->getKeyName();
+                    if (n && *n) {
+                        char* kn=toUTF8(n);
+                        results.push_back(kn);
+                        delete[] kn;
+                    }
+                }
             }
-            XSECCryptoKey* m_key;
-            vector<XSECCryptoX509*> m_certs;
-            XSECCryptoX509CRL* m_crl;
-        };
-
-        void _resolve(const KeyInfo* keyInfo, CacheEntry& entry) const;
-        XSECCryptoKey* _resolveKey(const KeyInfo* keyInfo) const;
-        vector<XSECCryptoX509*>::size_type _resolveCertificates(const KeyInfo* keyInfo, vector<XSECCryptoX509*>& certs) const;
-        XSECCryptoX509CRL* _resolveCRL(const KeyInfo* keyInfo) const;
-
-        RWLock* m_lock;
-        mutable map<const KeyInfo*,CacheEntry> m_cache;
+            return results.size();
+        }
+
+        void setKey(XSECCryptoKey* key) {
+            m_key = key;
+        }
+
+        void addCert(XSECCryptoX509* cert) {
+            m_xseccerts.push_back(cert);
+        }
+
+        void setCRL(XSECCryptoX509CRL* crl) {
+            m_crl = crl;
+        }
     };
 
-    KeyResolver* XMLTOOL_DLLLOCAL InlineKeyResolverFactory(const DOMElement* const & e)
+    class XMLTOOL_DLLLOCAL InlineKeyResolver : public KeyInfoResolver
     {
-        return new InlineKeyResolver(e);
-    }
-};
-
-static const XMLCh cache[] = UNICODE_LITERAL_5(c,a,c,h,e);
+    public:
+        InlineKeyResolver() : m_log(Category::getInstance(XMLTOOLING_LOGCAT".KeyInfoResolver")) {}
+        virtual ~InlineKeyResolver() {}
 
-InlineKeyResolver::InlineKeyResolver(const DOMElement* e) : m_lock(NULL)
-{
-    const XMLCh* flag = e ? e->getAttributeNS(NULL,cache) : NULL;
-    if (flag && XMLString::equals(flag,xmlconstants::XML_TRUE) || XMLString::equals(flag,xmlconstants::XML_ONE))
-        m_lock=RWLock::create();
-}
+        Credential* resolve(const KeyInfo* keyInfo, int types=0) const;
+        Credential* resolve(DSIGKeyInfoList* keyInfo, int types=0) const;
+    
+    private:
+        bool resolveCerts(const KeyInfo* keyInfo, InlineCredential* credential) const;
+        bool resolveKey(const KeyInfo* keyInfo, InlineCredential* credential) const;
+        bool resolveCRL(const KeyInfo* keyInfo, InlineCredential* credential) const;
 
-InlineKeyResolver::~InlineKeyResolver()
-{
-    clearCache();
-    delete m_lock;
-}
+        Category& m_log;
+    };
 
-void InlineKeyResolver::_resolve(const KeyInfo* keyInfo, CacheEntry& entry) const
-{
-    if (_resolveCertificates(keyInfo, entry.m_certs)>0)
-        entry.m_key = entry.m_certs.front()->clonePublicKey();
-    else
-        entry.m_key = _resolveKey(keyInfo);
-    entry.m_crl = _resolveCRL(keyInfo);
-}
+    KeyInfoResolver* XMLTOOL_DLLLOCAL InlineKeyInfoResolverFactory(const DOMElement* const & e)
+    {
+        return new InlineKeyResolver();
+    }
+};
 
-XSECCryptoKey* InlineKeyResolver::_resolveKey(const KeyInfo* keyInfo) const
+Credential* InlineKeyResolver::resolve(const KeyInfo* keyInfo, int types) const
 {
 #ifdef _DEBUG
-    NDC ndc("_resolveKey");
+    NDC ndc("resolve");
 #endif
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver");
 
     if (!keyInfo)
         return NULL;
 
-    // Check for ds:X509Data
-    const vector<X509Data*>& x509Datas=keyInfo->getX509Datas();
-    for (vector<X509Data*>::const_iterator j=x509Datas.begin(); j!=x509Datas.end(); ++j) {
-        try {
-            const vector<X509Certificate*> x509Certs=const_cast<const X509Data*>(*j)->getX509Certificates();
-            if (!x509Certs.empty()) {
-                auto_ptr_char x(x509Certs.front()->getValue());
-                if (!x.get()) {
-                    log.warn("skipping empty ds:X509Certificate");
-                }
-                else {
-                    log.debug("resolving ds:X509Certificate");
-                    auto_ptr<XSECCryptoX509> x509(XSECPlatformUtils::g_cryptoProvider->X509());
-                    x509->loadX509Base64Bin(x.get(), strlen(x.get()));
-                    return x509->clonePublicKey();
-                }
-            }
-        }
-        catch(XSECException& e) {
-            auto_ptr_char temp(e.getMsg());
-            log.error("caught XML-Security exception loading certificate: %s", temp.get());
-        }
-        catch(XSECCryptoException& e) {
-            log.error("caught XML-Security exception loading certificate: %s", e.getMsg());
-        }
+    auto_ptr<InlineCredential> credential(new InlineCredential(keyInfo));
+    if (types == 0)
+        types = Credential::RESOLVE_KEYS|X509Credential::RESOLVE_CERTS|X509Credential::RESOLVE_CRLS;
+
+    if (types & X509Credential::RESOLVE_CERTS)
+        resolveCerts(keyInfo, credential.get());
+    
+    if (types & Credential::RESOLVE_KEYS) {
+        // If we have a cert, just use it.
+        if (types & X509Credential::RESOLVE_CERTS && !credential->getEntityCertificateChain().empty())
+            credential->setKey(credential->getEntityCertificateChain().front()->clonePublicKey());
+        // Otherwise try directly for a key and then go for certs if none is found.
+        else if (!resolveKey(keyInfo, credential.get()) && resolveCerts(keyInfo, credential.get()))
+            credential->setKey(credential->getEntityCertificateChain().front()->clonePublicKey());
     }
 
+    if (types & X509Credential::RESOLVE_CRLS)
+        resolveCRL(keyInfo, credential.get());
+
+    return credential.release();
+}
+
+bool InlineKeyResolver::resolveKey(const KeyInfo* keyInfo, InlineCredential* credential) const
+{
     // Check for ds:KeyValue
     const vector<KeyValue*>& keyValues = keyInfo->getKeyValues();
     for (vector<KeyValue*>::const_iterator i=keyValues.begin(); i!=keyValues.end(); ++i) {
@@ -161,17 +168,18 @@ XSECCryptoKey* InlineKeyResolver::_resolveKey(const KeyInfo* keyInfo) const
             SchemaValidators.validate(*i);    // see if it's a "valid" key
             RSAKeyValue* rsakv = (*i)->getRSAKeyValue();
             if (rsakv) {
-                log.debug("resolving ds:RSAKeyValue");
+                m_log.debug("resolving ds:RSAKeyValue");
                 auto_ptr_char mod(rsakv->getModulus()->getValue());
                 auto_ptr_char exp(rsakv->getExponent()->getValue());
                 auto_ptr<XSECCryptoKeyRSA> rsa(XSECPlatformUtils::g_cryptoProvider->keyRSA());
                 rsa->loadPublicModulusBase64BigNums(mod.get(), strlen(mod.get()));
                 rsa->loadPublicExponentBase64BigNums(exp.get(), strlen(exp.get()));
-                return rsa.release();
+                credential->setKey(rsa.release());
+                return true;
             }
             DSAKeyValue* dsakv = (*i)->getDSAKeyValue();
             if (dsakv) {
-                log.debug("resolving ds:DSAKeyValue");
+                m_log.debug("resolving ds:DSAKeyValue");
                 auto_ptr<XSECCryptoKeyDSA> dsa(XSECPlatformUtils::g_cryptoProvider->keyDSA());
                 auto_ptr_char y(dsakv->getY()->getValue());
                 dsa->loadYBase64BigNums(y.get(), strlen(y.get()));
@@ -187,34 +195,33 @@ XSECCryptoKey* InlineKeyResolver::_resolveKey(const KeyInfo* keyInfo) const
                     auto_ptr_char g(dsakv->getG()->getValue());
                     dsa->loadGBase64BigNums(g.get(), strlen(g.get()));
                 }
-                return dsa.release();
+                credential->setKey(dsa.release());
+                return true;
             }
         }
         catch (ValidationException& ex) {
-            log.warn("skipping invalid ds:KeyValue (%s)", ex.what());
+            m_log.warn("skipping invalid ds:KeyValue (%s)", ex.what());
         }
         catch(XSECException& e) {
             auto_ptr_char temp(e.getMsg());
-            log.error("caught XML-Security exception loading key: %s", temp.get());
+            m_log.error("caught XML-Security exception loading key: %s", temp.get());
         }
         catch(XSECCryptoException& e) {
-            log.error("caught XML-Security exception loading key: %s", e.getMsg());
+            m_log.error("caught XML-Security exception loading key: %s", e.getMsg());
         }
     }
 
     // Check for RetrievalMethod.
     const XMLCh* fragID=NULL;
     const XMLObject* treeRoot=NULL;
-    XSECCryptoKey* remote=NULL;
-    const vector<RetrievalMethod*> methods=keyInfo->getRetrievalMethods();
+    const vector<RetrievalMethod*>& methods=keyInfo->getRetrievalMethods();
     for (vector<RetrievalMethod*>::const_iterator m=methods.begin(); m!=methods.end(); ++m) {
-        if (!XMLString::equals((*m)->getType(),RetrievalMethod::TYPE_X509DATA) &&
-            !XMLString::equals((*m)->getType(),RetrievalMethod::TYPE_RSAKEYVALUE) &&
+        if (!XMLString::equals((*m)->getType(),RetrievalMethod::TYPE_RSAKEYVALUE) &&
             !XMLString::equals((*m)->getType(),RetrievalMethod::TYPE_DSAKEYVALUE))
             continue;
         fragID = (*m)->getURI();
         if (!fragID || *fragID != chPound || !*(fragID+1)) {
-            log.warn("skipping ds:RetrievalMethod with an empty or non-local reference");
+            m_log.warn("skipping ds:RetrievalMethod with an empty or non-local reference");
             continue;
         }
         if (!treeRoot) {
@@ -224,68 +231,55 @@ XSECCryptoKey* InlineKeyResolver::_resolveKey(const KeyInfo* keyInfo) const
         }
         keyInfo = dynamic_cast<const KeyInfo*>(XMLHelper::getXMLObjectById(*treeRoot, fragID+1));
         if (!keyInfo) {
-            log.warn("skipping ds:RetrievalMethod, local reference did not resolve to a ds:KeyInfo");
+            m_log.warn("skipping ds:RetrievalMethod, local reference did not resolve to a ds:KeyInfo");
             continue;
         }
-        remote = _resolveKey(keyInfo);
-        if (remote)
-            return remote;
+        if (resolveKey(keyInfo,credential))
+            return true;
     }
-
-    log.warn("unable to resolve key");
-    return NULL;
+    return false;
 }
 
-vector<XSECCryptoX509*>::size_type InlineKeyResolver::_resolveCertificates(
-    const KeyInfo* keyInfo, vector<XSECCryptoX509*>& certs
-    ) const
+bool InlineKeyResolver::resolveCerts(const KeyInfo* keyInfo, InlineCredential* credential) const
 {
-#ifdef _DEBUG
-    NDC ndc("_resolveCertificates");
-#endif
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver");
-
-    if (!keyInfo)
-        return 0;
-
     // Check for ds:X509Data
     const vector<X509Data*>& x509Datas=keyInfo->getX509Datas();
-    for (vector<X509Data*>::const_iterator j=x509Datas.begin(); certs.empty() && j!=x509Datas.end(); ++j) {
+    for (vector<X509Data*>::const_iterator j=x509Datas.begin(); credential->getEntityCertificateChain().empty() && j!=x509Datas.end(); ++j) {
         const vector<X509Certificate*> x509Certs=const_cast<const X509Data*>(*j)->getX509Certificates();
         for (vector<X509Certificate*>::const_iterator k=x509Certs.begin(); k!=x509Certs.end(); ++k) {
             try {
                 auto_ptr_char x((*k)->getValue());
                 if (!x.get()) {
-                    log.warn("skipping empty ds:X509Certificate");
+                    m_log.warn("skipping empty ds:X509Certificate");
                 }
                 else {
-                    log.debug("resolving ds:X509Certificate");
+                    m_log.debug("resolving ds:X509Certificate");
                     auto_ptr<XSECCryptoX509> x509(XSECPlatformUtils::g_cryptoProvider->X509());
                     x509->loadX509Base64Bin(x.get(), strlen(x.get()));
-                    certs.push_back(x509.release());
+                    credential->addCert(x509.release());
                 }
             }
             catch(XSECException& e) {
                 auto_ptr_char temp(e.getMsg());
-                log.error("caught XML-Security exception loading certificate: %s", temp.get());
+                m_log.error("caught XML-Security exception loading certificate: %s", temp.get());
             }
             catch(XSECCryptoException& e) {
-                log.error("caught XML-Security exception loading certificate: %s", e.getMsg());
+                m_log.error("caught XML-Security exception loading certificate: %s", e.getMsg());
             }
         }
     }
-    
-    if (certs.empty()) {
+
+    if (credential->getEntityCertificateChain().empty()) {
         // Check for RetrievalMethod.
         const XMLCh* fragID=NULL;
         const XMLObject* treeRoot=NULL;
         const vector<RetrievalMethod*> methods=keyInfo->getRetrievalMethods();
-        for (vector<RetrievalMethod*>::const_iterator m=methods.begin(); certs.empty() && m!=methods.end(); ++m) {
+        for (vector<RetrievalMethod*>::const_iterator m=methods.begin(); m!=methods.end(); ++m) {
             if (!XMLString::equals((*m)->getType(),RetrievalMethod::TYPE_X509DATA))
                 continue;
             fragID = (*m)->getURI();
             if (!fragID || *fragID != chPound || !*(fragID+1)) {
-                log.warn("skipping ds:RetrievalMethod with an empty or non-local reference");
+                m_log.warn("skipping ds:RetrievalMethod with an empty or non-local reference");
                 continue;
             }
             if (!treeRoot) {
@@ -295,29 +289,23 @@ vector<XSECCryptoX509*>::size_type InlineKeyResolver::_resolveCertificates(
             }
             keyInfo = dynamic_cast<const KeyInfo*>(XMLHelper::getXMLObjectById(*treeRoot, fragID+1));
             if (!keyInfo) {
-                log.warn("skipping ds:RetrievalMethod, local reference did not resolve to a ds:KeyInfo");
+                m_log.warn("skipping ds:RetrievalMethod, local reference did not resolve to a ds:KeyInfo");
                 continue;
             }
-            _resolveCertificates(keyInfo, certs);
+            if (resolveCerts(keyInfo,credential))
+                return true;
         }
+        return false;
     }
     
-    if (log.isDebugEnabled()) {
-        log.debug("resolved %d certificate%s", certs.size(), certs.size()==1 ? "" : "s");
+    if (m_log.isDebugEnabled()) {
+        m_log.debug("resolved %d certificate(s)", credential->getEntityCertificateChain().size());
     }
-    return certs.size();
+    return !credential->getEntityCertificateChain().empty();
 }
 
-XSECCryptoX509CRL* InlineKeyResolver::_resolveCRL(const KeyInfo* keyInfo) const
+bool InlineKeyResolver::resolveCRL(const KeyInfo* keyInfo, InlineCredential* credential) const
 {
-#ifdef _DEBUG
-    NDC ndc("_resolveCRL");
-#endif
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver");
-
-    if (!keyInfo)
-        return NULL;
-
     // Check for ds:X509Data
     const vector<X509Data*>& x509Datas=keyInfo->getX509Datas();
     for (vector<X509Data*>::const_iterator j=x509Datas.begin(); j!=x509Datas.end(); ++j) {
@@ -326,21 +314,22 @@ XSECCryptoX509CRL* InlineKeyResolver::_resolveCRL(const KeyInfo* keyInfo) const
             try {
                 auto_ptr_char x((*k)->getValue());
                 if (!x.get()) {
-                    log.warn("skipping empty ds:X509CRL");
+                    m_log.warn("skipping empty ds:X509CRL");
                 }
                 else {
-                    log.debug("resolving ds:X509CRL");
+                    m_log.debug("resolving ds:X509CRL");
                     auto_ptr<XSECCryptoX509CRL> crl(XMLToolingConfig::getConfig().X509CRL());
                     crl->loadX509CRLBase64Bin(x.get(), strlen(x.get()));
-                    return crl.release();
+                    credential->setCRL(crl.release());
+                    return true;
                 }
             }
             catch(XSECException& e) {
                 auto_ptr_char temp(e.getMsg());
-                log.error("caught XML-Security exception loading certificate: %s", temp.get());
+                m_log.error("caught XML-Security exception loading certificate: %s", temp.get());
             }
             catch(XSECCryptoException& e) {
-                log.error("caught XML-Security exception loading certificate: %s", e.getMsg());
+                m_log.error("caught XML-Security exception loading certificate: %s", e.getMsg());
             }
         }
     }
@@ -348,14 +337,13 @@ XSECCryptoX509CRL* InlineKeyResolver::_resolveCRL(const KeyInfo* keyInfo) const
     // Check for RetrievalMethod.
     const XMLCh* fragID=NULL;
     const XMLObject* treeRoot=NULL;
-    XSECCryptoX509CRL* remote=NULL;
     const vector<RetrievalMethod*> methods=keyInfo->getRetrievalMethods();
     for (vector<RetrievalMethod*>::const_iterator m=methods.begin(); m!=methods.end(); ++m) {
         if (!XMLString::equals((*m)->getType(),RetrievalMethod::TYPE_X509DATA))
             continue;
         fragID = (*m)->getURI();
         if (!fragID || *fragID != chPound || !*(fragID+1)) {
-            log.warn("skipping ds:RetrievalMethod with an empty or non-local reference");
+            m_log.warn("skipping ds:RetrievalMethod with an empty or non-local reference");
             continue;
         }
         if (!treeRoot) {
@@ -365,186 +353,83 @@ XSECCryptoX509CRL* InlineKeyResolver::_resolveCRL(const KeyInfo* keyInfo) const
         }
         keyInfo = dynamic_cast<const KeyInfo*>(XMLHelper::getXMLObjectById(*treeRoot, fragID+1));
         if (!keyInfo) {
-            log.warn("skipping ds:RetrievalMethod, local reference did not resolve to a ds:KeyInfo");
+            m_log.warn("skipping ds:RetrievalMethod, local reference did not resolve to a ds:KeyInfo");
             continue;
         }
-        remote = _resolveCRL(keyInfo);
-        if (remote)
-            return remote;
-    }
-
-    return NULL;
-}
-
-XSECCryptoKey* InlineKeyResolver::resolveKey(const KeyInfo* keyInfo) const
-{
-    // Caching?
-    if (m_lock) {
-        // Get read lock.
-        m_lock->rdlock();
-        map<const KeyInfo*,CacheEntry>::iterator i=m_cache.find(keyInfo);
-        if (i != m_cache.end()) {
-            // Found in cache, so just return the results.
-            SharedLock locker(m_lock,false);
-            return i->second.m_key ? i->second.m_key->clone() : NULL;
-        }
-        else {
-            // Elevate lock.
-            m_lock->unlock();
-            m_lock->wrlock();
-            SharedLock locker(m_lock,false);
-            // Recheck cache.
-            i=m_cache.find(keyInfo);
-            if (i == m_cache.end()) {
-                i = m_cache.insert(make_pair(keyInfo,CacheEntry())).first;
-                _resolve(i->first, i->second);
-            }
-            return i->second.m_key ? i->second.m_key->clone() : NULL;
-        }
+        if (resolveCRL(keyInfo,credential))
+            return true;
     }
-    return _resolveKey(keyInfo);
-}
 
-XSECCryptoX509CRL* InlineKeyResolver::resolveCRL(const KeyInfo* keyInfo) const
-{
-    // Caching?
-    if (m_lock) {
-        // Get read lock.
-        m_lock->rdlock();
-        map<const KeyInfo*,CacheEntry>::iterator i=m_cache.find(keyInfo);
-        if (i != m_cache.end()) {
-            // Found in cache, so just return the results.
-            SharedLock locker(m_lock,false);
-            return i->second.m_crl ? i->second.m_crl->clone() : NULL;
-        }
-        else {
-            // Elevate lock.
-            m_lock->unlock();
-            m_lock->wrlock();
-            SharedLock locker(m_lock,false);
-            // Recheck cache.
-            i=m_cache.find(keyInfo);
-            if (i == m_cache.end()) {
-                i = m_cache.insert(make_pair(keyInfo,CacheEntry())).first;
-                _resolve(i->first, i->second);
-            }
-            return i->second.m_crl ? i->second.m_crl->clone() : NULL;
-        }
-    }
-    return _resolveCRL(keyInfo);
-}
-
-vector<XSECCryptoX509*>::size_type InlineKeyResolver::resolveCertificates(
-    const KeyInfo* keyInfo, ResolvedCertificates& certs
-    ) const
-{
-    // Caching?
-    if (m_lock) {
-        // Get read lock.
-        m_lock->rdlock();
-        map<const KeyInfo*,CacheEntry>::iterator i=m_cache.find(keyInfo);
-        if (i != m_cache.end()) {
-            // Found in cache, so just return the results.
-            SharedLock locker(m_lock,false);
-            accessCertificates(certs).assign(i->second.m_certs.begin(), i->second.m_certs.end());
-            accessOwned(certs) = false;
-            return accessCertificates(certs).size();
-        }
-        else {
-            // Elevate lock.
-            m_lock->unlock();
-            m_lock->wrlock();
-            SharedLock locker(m_lock,false);
-            // Recheck cache.
-            i=m_cache.find(keyInfo);
-            if (i == m_cache.end()) {
-                i = m_cache.insert(make_pair(keyInfo,CacheEntry())).first;
-                _resolve(i->first, i->second);
-            }
-            accessCertificates(certs).assign(i->second.m_certs.begin(), i->second.m_certs.end());
-            accessOwned(certs) = false;
-            return accessCertificates(certs).size();
-        }
-    }
-    accessOwned(certs) = true;
-    return _resolveCertificates(keyInfo, accessCertificates(certs));
+    return false;
 }
 
-XSECCryptoKey* InlineKeyResolver::resolveKey(DSIGKeyInfoList* keyInfo) const
+Credential* InlineKeyResolver::resolve(DSIGKeyInfoList* keyInfo, int types) const
 {
 #ifdef _DEBUG
-    NDC ndc("resolveKey");
+    NDC ndc("resolve");
 #endif
 
     if (!keyInfo)
         return NULL;
 
-    // Default resolver handles RSA/DSAKeyValue and X509Certificate elements.
-    try {
-        XSECKeyInfoResolverDefault def;
-        return def.resolveKey(keyInfo);
-    }
-    catch(XSECException& e) {
-        auto_ptr_char temp(e.getMsg());
-        Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading certificate: %s", temp.get());
-    }
-    catch(XSECCryptoException& e) {
-        Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading certificate: %s", e.getMsg());
-    }
-    return NULL;
-}
+    if (types == 0)
+        types = Credential::RESOLVE_KEYS|X509Credential::RESOLVE_CERTS|X509Credential::RESOLVE_CRLS;
 
-vector<XSECCryptoX509*>::size_type InlineKeyResolver::resolveCertificates(
-    DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs
-    ) const
-{
-    accessCertificates(certs).clear();
-    accessOwned(certs) = false;
+    auto_ptr<InlineCredential> credential(new InlineCredential(keyInfo));
 
-    if (!keyInfo)
-        return 0;
+    if (types & Credential::RESOLVE_KEYS) {
+        // Default resolver handles RSA/DSAKeyValue and X509Certificate elements.
+        try {
+            XSECKeyInfoResolverDefault def;
+            credential->setKey(def.resolveKey(keyInfo));
+        }
+        catch(XSECException& e) {
+            auto_ptr_char temp(e.getMsg());
+            Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading certificate: %s", temp.get());
+        }
+        catch(XSECCryptoException& e) {
+            Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading certificate: %s", e.getMsg());
+        }
+    }
 
        DSIGKeyInfoList::size_type sz = keyInfo->getSize();
-    for (DSIGKeyInfoList::size_type i=0; accessCertificates(certs).empty() && i<sz; ++i) {
-        if (keyInfo->item(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) {
-            DSIGKeyInfoX509* x509 = static_cast<DSIGKeyInfoX509*>(keyInfo->item(i));
-            int count = x509->getCertificateListSize();
-            for (int j=0; j<count; ++j) {
-                accessCertificates(certs).push_back(x509->getCertificateCryptoItem(j));
+
+    if (types & X509Credential::RESOLVE_CERTS) {
+        for (DSIGKeyInfoList::size_type i=0; i<sz; ++i) {
+            if (keyInfo->item(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) {
+                DSIGKeyInfoX509* x509 = static_cast<DSIGKeyInfoX509*>(keyInfo->item(i));
+                int count = x509->getCertificateListSize();
+                if (count) {
+                    for (int j=0; j<count; ++j)
+                        credential->addCert(x509->getCertificateCryptoItem(j));
+                    break;
+                }
             }
         }
     }
-    return accessCertificates(certs).size();
-}
 
-XSECCryptoX509CRL* InlineKeyResolver::resolveCRL(DSIGKeyInfoList* keyInfo) const
-{
-#ifdef _DEBUG
-    NDC ndc("resolveCRL");
-#endif
-
-    if (!keyInfo)
-        return NULL;
-
-    DSIGKeyInfoList::size_type sz = keyInfo->getSize();
-    for (DSIGKeyInfoList::size_type i=0; i<sz; ++i) {
-        if (keyInfo->item(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) {
-            auto_ptr_char buf(static_cast<DSIGKeyInfoX509*>(keyInfo->item(i))->getX509CRL());
-            if (buf.get()) {
-                try {
-                    auto_ptr<XSECCryptoX509CRL> crlobj(XMLToolingConfig::getConfig().X509CRL());
-                    crlobj->loadX509CRLBase64Bin(buf.get(), strlen(buf.get()));
-                    return crlobj.release();
-                }
-                catch(XSECException& e) {
-                    auto_ptr_char temp(e.getMsg());
-                    Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading CRL: %s", temp.get());
-                }
-                catch(XSECCryptoException& e) {
-                    Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading CRL: %s", e.getMsg());
+    if (types & X509Credential::RESOLVE_CRLS) {
+        for (DSIGKeyInfoList::size_type i=0; i<sz; ++i) {
+            if (keyInfo->item(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) {
+                auto_ptr_char buf(static_cast<DSIGKeyInfoX509*>(keyInfo->item(i))->getX509CRL());
+                if (buf.get()) {
+                    try {
+                        auto_ptr<XSECCryptoX509CRL> crlobj(XMLToolingConfig::getConfig().X509CRL());
+                        crlobj->loadX509CRLBase64Bin(buf.get(), strlen(buf.get()));
+                        credential->setCRL(crlobj.release());
+                        break;
+                    }
+                    catch(XSECException& e) {
+                        auto_ptr_char temp(e.getMsg());
+                        Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading CRL: %s", temp.get());
+                    }
+                    catch(XSECCryptoException& e) {
+                        Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver").error("caught XML-Security exception loading CRL: %s", e.getMsg());
+                    }
                 }
             }
         }
     }
-    return NULL;
+
+    return credential.release();
 }
diff --git a/xmltooling/security/impl/KeyInfoResolver.cpp b/xmltooling/security/impl/KeyInfoResolver.cpp
new file mode 100644 (file)
index 0000000..dda9367
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * KeyInfoResolver.cpp
+ * 
+ * Registration of factories for built-in resolvers
+ */
+
+#include "internal.h"
+#include "security/CredentialCriteria.h"
+#include "security/KeyInfoResolver.h"
+#include "signature/Signature.h"
+
+using namespace xmlsignature;
+using namespace xmltooling;
+using namespace std;
+
+namespace xmltooling {
+    XMLTOOL_DLLLOCAL PluginManager<KeyInfoResolver,const DOMElement*>::Factory InlineKeyInfoResolverFactory;
+};
+
+void XMLTOOL_API xmltooling::registerKeyInfoResolvers()
+{
+    XMLToolingConfig& conf=XMLToolingConfig::getConfig();
+    conf.KeyInfoResolverManager.registerFactory(INLINE_KEYINFO_RESOLVER, InlineKeyInfoResolverFactory);
+}
+
+Credential* KeyInfoResolver::resolve(const Signature* sig, int types) const
+{
+    const KeyInfo* keyInfo = sig->getKeyInfo();
+    if (keyInfo)
+        return resolve(keyInfo, types);
+    DSIGSignature* native = sig->getXMLSignature();
+    return resolve(native ? native->getKeyInfoList() : (DSIGKeyInfoList*)NULL, types);
+}
+
+Credential* KeyInfoResolver::resolve(const CredentialCriteria& criteria, int types) const
+{
+    const KeyInfo* keyInfo = criteria.getKeyInfo();
+    if (keyInfo)
+        return resolve(keyInfo, types);
+    DSIGKeyInfoList* native = criteria.getNativeKeyInfo();
+    return native ? resolve(native, types) : NULL;
+}
diff --git a/xmltooling/security/impl/KeyResolver.cpp b/xmltooling/security/impl/KeyResolver.cpp
deleted file mode 100644 (file)
index c319b78..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- *  Copyright 2001-2007 Internet2
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * KeyResolver.cpp
- * 
- * Registration of factories for built-in resolvers
- */
-
-#include "internal.h"
-#include "security/KeyResolver.h"
-#include "signature/Signature.h"
-
-using namespace xmlsignature;
-using namespace xmltooling;
-using namespace std;
-
-namespace xmltooling {
-    XMLTOOL_DLLLOCAL PluginManager<KeyResolver,const DOMElement*>::Factory FilesystemKeyResolverFactory;
-    XMLTOOL_DLLLOCAL PluginManager<KeyResolver,const DOMElement*>::Factory InlineKeyResolverFactory;
-};
-
-void XMLTOOL_API xmltooling::registerKeyResolvers()
-{
-    XMLToolingConfig& conf=XMLToolingConfig::getConfig();
-    conf.KeyResolverManager.registerFactory(FILESYSTEM_KEY_RESOLVER, FilesystemKeyResolverFactory);
-    conf.KeyResolverManager.registerFactory(INLINE_KEY_RESOLVER, InlineKeyResolverFactory);
-}
-
-XSECCryptoKey* KeyResolver::resolveKey(const Signature* sig) const
-{
-    const KeyInfo* keyInfo = sig->getKeyInfo();
-    if (keyInfo)
-        return resolveKey(keyInfo);
-    DSIGSignature* native = sig->getXMLSignature();
-    return resolveKey(native ? native->getKeyInfoList() : (DSIGKeyInfoList*)NULL);
-}
-
-vector<XSECCryptoX509*>::size_type KeyResolver::resolveCertificates(
-    const KeyInfo* keyInfo, ResolvedCertificates& certs
-    ) const
-{
-    return 0;
-}
-
-vector<XSECCryptoX509*>::size_type KeyResolver::resolveCertificates(
-    DSIGKeyInfoList* keyInfo, ResolvedCertificates& certs
-    ) const
-{
-    return 0;
-}
-
-vector<XSECCryptoX509*>::size_type KeyResolver::resolveCertificates(
-    const Signature* sig, ResolvedCertificates& certs
-    ) const
-{
-    const KeyInfo* keyInfo = sig->getKeyInfo();
-    if (keyInfo)
-        return resolveCertificates(keyInfo, certs);
-    DSIGSignature* native = sig->getXMLSignature();
-    return resolveCertificates(native ? native->getKeyInfoList() : (DSIGKeyInfoList*)NULL, certs);
-}
-
-XSECCryptoX509CRL* KeyResolver::resolveCRL(const KeyInfo* keyInfo) const
-{
-    return NULL;
-}
-
-XSECCryptoX509CRL* KeyResolver::resolveCRL(DSIGKeyInfoList* keyInfo) const
-{
-    return NULL;
-}
-
-XSECCryptoX509CRL* KeyResolver::resolveCRL(const Signature* sig) const
-{
-    const KeyInfo* keyInfo = sig->getKeyInfo();
-    if (keyInfo)
-        return resolveCRL(keyInfo);
-    DSIGSignature* native = sig->getXMLSignature();
-    return resolveCRL(native ? native->getKeyInfoList() : (DSIGKeyInfoList*)NULL);
-}
index c2b56d7..adc2c2e 100644 (file)
@@ -21,7 +21,9 @@
  */
 
 #include "internal.h"
+#include "security/KeyInfoResolver.h"
 #include "security/TrustEngine.h"
+#include "util/XMLHelper.h"
 
 #include <xercesc/util/XMLUniDefs.hpp>
 
@@ -40,25 +42,22 @@ void XMLTOOL_API xmltooling::registerTrustEngines()
     conf.TrustEngineManager.registerFactory(CHAINING_TRUSTENGINE, ChainingTrustEngineFactory);
 }
 
-static const XMLCh GenericKeyResolver[] =           UNICODE_LITERAL_11(K,e,y,R,e,s,o,l,v,e,r);
-static const XMLCh type[] =                         UNICODE_LITERAL_4(t,y,p,e);
+static const XMLCh _KeyInfoResolver[] = UNICODE_LITERAL_15(K,e,y,I,n,f,o,R,e,s,o,l,v,e,r);
+static const XMLCh type[] =             UNICODE_LITERAL_4(t,y,p,e);
 
-TrustEngine::TrustEngine(const DOMElement* e) : m_keyResolver(NULL)
+TrustEngine::TrustEngine(const DOMElement* e) : m_keyInfoResolver(NULL)
 {
-    DOMElement* child = e ? XMLHelper::getFirstChildElement(e,GenericKeyResolver) : NULL;
+    DOMElement* child = e ? XMLHelper::getFirstChildElement(e,_KeyInfoResolver) : NULL;
     if (child) {
         auto_ptr_char t(child->getAttributeNS(NULL,type));
         if (t.get())
-            m_keyResolver = XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(t.get(),child);
+            m_keyInfoResolver = XMLToolingConfig::getConfig().KeyInfoResolverManager.newPlugin(t.get(),child);
         else
-            throw UnknownExtensionException("<KeyResolver> element found with no type attribute");
-    }
-    else if (!m_keyResolver) {
-        m_keyResolver = XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(INLINE_KEY_RESOLVER, child);
+            throw UnknownExtensionException("<KeyInfoResolver> element found with no type attribute");
     }
 }
 
 TrustEngine::~TrustEngine()
 {
-    delete m_keyResolver;
+    delete m_keyInfoResolver;
 }
index a86bd71..d26ccb8 100644 (file)
@@ -122,8 +122,10 @@ namespace xmlsignature {
         /**
          * Compute and append the signature based on the assigned
          * ContentReference, KeyInfo, and signing key.
+         *
+         * @param credential    optional source of signing key and KeyInfo
          */
-        virtual void sign()=0;
+        virtual void sign(const xmltooling::Credential* credential=NULL)=0;
 
         /**
          * Type-safe clone operation.
index 0e6ec5a..a082c39 100644 (file)
 #if !defined(__xmltooling_sigval_h__) && !defined(XMLTOOLING_NO_XMLSEC)
 #define __xmltooling_sigval_h__
 
-#include <xmltooling/security/KeyResolver.h>
+#include <xmltooling/security/Credential.h>
 #include <xmltooling/signature/Signature.h>
 #include <xmltooling/validation/Validator.h>
 
 namespace xmlsignature {
 
     /**
-     * Validator for signatures based on a Key or a KeyResolver
+     * Validator for signatures based on a Credential
      */
     class XMLTOOL_API SignatureValidator : public xmltooling::Validator
     {
     public:
         /**
-         * Constructor using a KeyResolver
+         * Constructor using a key
          * 
-         * @param resolver the key resolver to use, will be freed by Validator
+         * @param key the key to use
          */
-        SignatureValidator(xmltooling::KeyResolver* resolver) : m_key(NULL), m_resolver(resolver) {
-        }
+        SignatureValidator(XSECCryptoKey* key=NULL) : m_key(key), m_credential(NULL) {}
 
         /**
-         * Constructor using a Key
+         * Constructor using a Credential
          * 
-         * @param key the verification key to use, will be freed by Validator
+         * @param credential the credential to use
          */
-        SignatureValidator(XSECCryptoKey* key=NULL) : m_key(key), m_resolver(NULL) {
-        }
-        
-        virtual ~SignatureValidator() {
-            delete m_key;
-            delete m_resolver;
-        }
+        SignatureValidator(const xmltooling::Credential* credential) : m_key(NULL), m_credential(credential) {}
+
+        virtual ~SignatureValidator() {}
 
         virtual void validate(const xmltooling::XMLObject* xmlObject) const;
 
@@ -66,35 +61,31 @@ namespace xmlsignature {
         virtual void validate(const Signature* signature) const;
         
         /**
-         * Replace the current Key, if any, with a new one.
+         * Replace the current key, if any, with a new one.
          * 
-         * @param key  the Key to attach 
+         * @param key  the key to attach 
          */
         void setKey(XSECCryptoKey* key) {
-            delete m_key;
-            delete m_resolver;
-            m_resolver=NULL;
-            m_key=key;
+            m_key = key;
+            m_credential = NULL;
         }
 
         /**
-         * Replace the current KeyResolver, if any, with a new one.
+         * Replace the current Credential, if any, with a new one.
          * 
-         * @param resolver  the KeyResolver to attach 
+         * @param credential  the Credential to attach 
          */
-        void setKeyResolver(xmltooling::KeyResolver* resolver) {
-            delete m_key;
-            delete m_resolver;
-            m_key=NULL;
-            m_resolver=resolver;
+        void setCredential(const xmltooling::Credential* credential) {
+            m_key = NULL;
+            m_credential = credential;
         }
     
     protected:
         /** Verification key. */
         XSECCryptoKey* m_key;
-        
-        /** KeyResolver to use against signature. */
-        xmltooling::KeyResolver* m_resolver;
+
+        /** Verification credential. */
+        const xmltooling::Credential* m_credential;
     };
 
 };
index dab1311..667a439 100644 (file)
@@ -43,16 +43,17 @@ void SignatureValidator::validate(const Signature* sigObj) const
     DSIGSignature* sig=sigObj->getXMLSignature();
     if (!sig)
         throw ValidationException("Signature does not exist yet.");
-    else if (!m_key && !m_resolver)
-        throw ValidationException("No KeyResolver or signing key set on Validator.");
+    else if (!m_key && !m_credential)
+        throw ValidationException("No Credential or key set on Validator.");
+
+    XSECCryptoKey* key = m_key ? m_key : (m_credential ? m_credential->getPublicKey() : NULL);
+    if (!key)
+        throw ValidationException("Credential did not contain a verification key.");
 
     try {
-        XSECCryptoKey* key = m_key ? m_key->clone() : m_resolver->resolveKey(sig->getKeyInfoList());
-        if (!key)
-            throw ValidationException("Unable to resolve signing key.");
-        sig->setSigningKey(key);
+        sig->setSigningKey(key->clone());
         if (!sig->verify())
-            throw ValidationException("Digital signature does not validate with the given key.");
+            throw ValidationException("Digital signature does not validate with the supplied key.");
     }
     catch(XSECException& e) {
         auto_ptr_char temp(e.getMsg());
index b96b6ac..51a5119 100644 (file)
@@ -23,6 +23,7 @@
 #include "internal.h"
 #include "exceptions.h"
 #include "impl/UnknownElement.h"
+#include "security/Credential.h"
 #include "signature/KeyInfo.h"
 #include "signature/Signature.h"
 #include "util/NDC.h"
@@ -75,8 +76,8 @@ namespace xmlsignature {
         XMLObject* clone() const;
         Signature* cloneSignature() const;
 
-        DOMElement* marshall(DOMDocument* document=NULL, const vector<Signature*>* sigs=NULL) const;
-        DOMElement* marshall(DOMElement* parentElement, const vector<Signature*>* sigs=NULL) const;
+        DOMElement* marshall(DOMDocument* document=NULL, const vector<Signature*>* sigs=NULL, const Credential* credential=NULL) const;
+        DOMElement* marshall(DOMElement* parentElement, const vector<Signature*>* sigs=NULL, const Credential* credential=NULL) const;
         XMLObject* unmarshall(DOMElement* element, bool bindDocument=false);
         
         // Getters
@@ -102,14 +103,14 @@ namespace xmlsignature {
             m_reference=reference;
         }
         
-        void sign();
+        void sign(const Credential* credential=NULL);
 
     private:
         mutable DSIGSignature* m_signature;
         XMLCh* m_c14n;
         XMLCh* m_sm;
         XSECCryptoKey* m_key;
-        KeyInfo* m_keyInfo;
+        mutable KeyInfo* m_keyInfo;
         ContentReference* m_reference;
     };
     
@@ -171,18 +172,20 @@ Signature* XMLSecSignatureImpl::cloneSignature() const
     return ret;
 }
 
-void XMLSecSignatureImpl::sign()
+void XMLSecSignatureImpl::sign(const Credential* credential)
 {
     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature");
     log.debug("applying signature");
 
     if (!m_signature)
         throw SignatureException("Only a marshalled Signature object can be signed.");
-    else if (!m_key)
-        throw SignatureException("No signing key available for signature creation.");
     else if (!m_reference)
         throw SignatureException("No ContentReference object set for signature creation.");
 
+    XSECCryptoKey* key = credential ? credential->getPrivateKey() : m_key;
+    if (!key)
+        throw SignatureException("No signing key available for signature creation.");
+
     try {
         log.debug("creating signature reference(s)");
         DSIGReferenceList* refs = m_signature->getReferenceList();
@@ -191,7 +194,7 @@ void XMLSecSignatureImpl::sign()
         m_reference->createReferences(m_signature);
         
         log.debug("computing signature");
-        m_signature->setSigningKey(m_key->clone());
+        m_signature->setSigningKey(key->clone());
         m_signature->sign();
     }
     catch(XSECException& e) {
@@ -203,7 +206,7 @@ void XMLSecSignatureImpl::sign()
     }
 }
 
-DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Signature*>* sigs) const
+DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Signature*>* sigs, const Credential* credential) const
 {
 #ifdef _DEBUG
     xmltooling::NDC ndc("marshall");
@@ -285,6 +288,13 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Si
     }
     
     // Marshall KeyInfo data.
+    if (credential) {
+        delete m_keyInfo;
+        m_keyInfo = NULL;
+        const KeyInfo* fromcred = credential->getKeyInfo();
+        if (fromcred)
+            m_keyInfo = fromcred->cloneKeyInfo();
+    }
     if (m_keyInfo && (!m_signature->getKeyInfoList() || m_signature->getKeyInfoList()->isEmpty())) {
         m_keyInfo->marshall(cachedDOM);
     }
@@ -298,7 +308,7 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Si
     return cachedDOM;
 }
 
-DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vector<Signature*>* sigs) const
+DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vector<Signature*>* sigs, const Credential* credential) const
 {
 #ifdef _DEBUG
     xmltooling::NDC ndc("marshall");
@@ -364,6 +374,13 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vecto
     }
 
     // Marshall KeyInfo data.
+    if (credential) {
+        delete m_keyInfo;
+        m_keyInfo = NULL;
+        const KeyInfo* fromcred = credential->getKeyInfo();
+        if (fromcred)
+            m_keyInfo = fromcred->cloneKeyInfo();
+    }
     if (m_keyInfo && (!m_signature->getKeyInfoList() || m_signature->getKeyInfoList()->isEmpty())) {
         m_keyInfo->marshall(cachedDOM);
     }
index ee33004..6e27d40 100644 (file)
@@ -23,7 +23,7 @@
 #ifndef __xmltooling_soap11client_h__
 #define __xmltooling_soap11client_h__
 
-#include <xmltooling/security/KeyInfoSource.h>
+#include <xmltooling/security/CredentialResolver.h>
 #include <xmltooling/soap/SOAPTransport.h>
 
 namespace soap11 {
@@ -68,11 +68,15 @@ namespace soap11 {
          * appropriate for the endpoint URL provided and supply it to the
          * prepareTransport() method below.
          * 
-         * @param env       SOAP envelope to send
-         * @param peer      peer to send message to, expressed in TrustEngine terms
-         * @param endpoint  URL of endpoint to recieve message
+         * <p>To authenticate the server end, the transport layer object
+         * exposes a method to load a TrustEngine and CredentialResolver
+         * in a subclass-specific version of the prepareTransport() method.   
+         * 
+         * @param env           SOAP envelope to send
+         * @param peerName      name of peer
+         * @param endpoint      URL of endpoint to recieve message
          */
-        virtual void send(const Envelope& env, const xmltooling::KeyInfoSource& peer, const char* endpoint);
+        virtual void send(const Envelope& env, const char* peerName, const char* endpoint);
         
         /**
          * Returns the response message, if any. As long as a response is
index e044da3..d3b8bc5 100644 (file)
@@ -28,8 +28,8 @@
 
 namespace xmltooling {
     
+    class XMLTOOL_API Credential;
     class XMLTOOL_API CredentialResolver;
-    class XMLTOOL_API KeyResolver;
     class XMLTOOL_API X509TrustEngine;
     
     /**
@@ -92,30 +92,31 @@ namespace xmltooling {
 
 #ifndef XMLTOOLING_NO_XMLSEC
         /**
-         * Provides a CredentialResolver to the transport to supply transport credentials.
-         * The lifetime of the resolver must be longer than the lifetime of this object.
+         * Supplies transport credentials.
+         *
+         * <p>The lifetime of the credential must be longer than the lifetime of this object.
          * 
-         * <p>The CredentialResolver <strong>MUST</strong> be locked by the caller. 
-         * 
-         * @param credResolver  a locked CredentialResolver instance, or NULL
-         * @return true iff the transport supports the use of a CredentialResolver
+         * @param credential  a Credential instance, or NULL
+         * @return true iff the transport supports the use of the Credential
          */
-        virtual bool setCredentialResolver(const CredentialResolver* credResolver)=0;
+        virtual bool setCredential(const Credential* credential=NULL)=0;
 
         /**
-         * Provides a TrustEngine to the transport to authenticate the transport peer.
+         * Provides an X509TrustEngine to the transport to authenticate the transport peer.
          * The lifetime of the engine must be longer than the lifetime of this object.
          * 
-         * @param trustEngine   a TrustEngine instance, or NULL
+         * @param trustEngine   an X509TrustEngine instance, or NULL
+         * @param credResolver  a CredentialResolver to supply the peer's trusted credentials, or NULL
+         * @param criteria      optional criteria for selecting peer credentials
          * @param mandatory     flag controls whether message is sent at all if the
          *                      transport isn't authenticated using the TrustEngine
-         * @param keyResolver   optional externally supplied KeyResolver, or NULL
          * @return true iff the transport supports the use of a TrustEngine
          */
         virtual bool setTrustEngine(
-            const X509TrustEngine* trustEngine,
-            bool mandatory=true,
-            const KeyResolver* keyResolver=NULL
+            const X509TrustEngine* trustEngine=NULL,
+            const CredentialResolver* credResolver=NULL,
+            CredentialCriteria* criteria=NULL,
+            bool mandatory=true
             )=0;
 #endif
 
index 314940b..043e613 100644 (file)
@@ -22,8 +22,9 @@
 
 #include "internal.h"
 #include "exceptions.h"
+#include "security/CredentialCriteria.h"
 #include "security/OpenSSLTrustEngine.h"
-#include "security/OpenSSLCredentialResolver.h"
+#include "security/OpenSSLCredential.h"
 #include "soap/HTTPSOAPTransport.h"
 #include "soap/OpenSSLSOAPTransport.h"
 #include "util/NDC.h"
@@ -48,8 +49,8 @@ namespace xmltooling {
             m_log(Category::getInstance(XMLTOOLING_LOGCAT".SOAPTransport.CURLPool")) {}
         ~CURLPool();
         
-        CURL* get(const string& to, const char* endpoint);
-        void put(const string& to, const char* endpoint, CURL* handle);
+        CURL* get(const char* to, const char* endpoint);
+        void put(const char* to, const char* endpoint, CURL* handle);
     
     private:    
         typedef map<string,vector<CURL*> > poolmap_t;
@@ -65,13 +66,13 @@ namespace xmltooling {
     class XMLTOOL_DLLLOCAL CURLSOAPTransport : public HTTPSOAPTransport, public OpenSSLSOAPTransport
     {
     public:
-        CURLSOAPTransport(const KeyInfoSource& peer, const char* endpoint)
-                : m_peer(peer), m_endpoint(endpoint), m_handle(NULL), m_headers(NULL),
+        CURLSOAPTransport(const char* peerName, const char* endpoint)
+                : m_peerName(peerName ? peerName : ""), m_endpoint(endpoint), m_handle(NULL), m_headers(NULL),
 #ifndef XMLTOOLING_NO_XMLSEC
-                    m_credResolver(NULL), m_trustEngine(NULL), m_mandatory(false), m_keyResolver(NULL),
+                    m_cred(NULL), m_trustEngine(NULL), m_peerResolver(NULL), m_mandatory(false),
 #endif
                     m_ssl_callback(NULL), m_ssl_userptr(NULL), m_chunked(true), m_secure(false) {
-            m_handle = g_CURLPool->get(peer.getName(), endpoint);
+            m_handle = g_CURLPool->get(peerName, endpoint);
             curl_easy_setopt(m_handle,CURLOPT_URL,endpoint);
             curl_easy_setopt(m_handle,CURLOPT_CONNECTTIMEOUT,15);
             curl_easy_setopt(m_handle,CURLOPT_TIMEOUT,30);
@@ -85,7 +86,7 @@ namespace xmltooling {
             curl_slist_free_all(m_headers);
             curl_easy_setopt(m_handle,CURLOPT_ERRORBUFFER,NULL);
             curl_easy_setopt(m_handle,CURLOPT_PRIVATE,m_secure ? "secure" : NULL); // Save off security "state".
-            g_CURLPool->put(m_peer.getName(), m_endpoint.c_str(), m_handle);
+            g_CURLPool->put(m_peerName.c_str(), m_endpoint.c_str(), m_handle);
         }
 
         bool isConfidential() const {
@@ -103,25 +104,32 @@ namespace xmltooling {
         bool setAuth(transport_auth_t authType, const char* username=NULL, const char* password=NULL);
         
 #ifndef XMLTOOLING_NO_XMLSEC
-        bool setCredentialResolver(const CredentialResolver* credResolver) {
-            const OpenSSLCredentialResolver* down = dynamic_cast<const OpenSSLCredentialResolver*>(credResolver);
+        bool setCredential(const Credential* cred=NULL) {
+            const OpenSSLCredential* down = dynamic_cast<const OpenSSLCredential*>(cred);
             if (!down) {
-                m_credResolver = NULL;
-                return (credResolver==NULL);
+                m_cred = NULL;
+                return (cred==NULL);
             }
-            m_credResolver = down;
+            m_cred = down;
             return true;
         }
         
-        bool setTrustEngine(const X509TrustEngine* trustEngine, bool mandatory=true, const KeyResolver* keyResolver=NULL) {
+        bool setTrustEngine(
+            const X509TrustEngine* trustEngine=NULL,
+            const CredentialResolver* peerResolver=NULL,
+            CredentialCriteria* criteria=NULL,
+            bool mandatory=true
+            ) {
             const OpenSSLTrustEngine* down = dynamic_cast<const OpenSSLTrustEngine*>(trustEngine);
             if (!down) {
                 m_trustEngine = NULL;
-                m_keyResolver = NULL;
+                m_peerResolver = NULL;
+                m_criteria = NULL;
                 return (trustEngine==NULL);
             }
             m_trustEngine = down;
-            m_keyResolver = keyResolver;
+            m_peerResolver = peerResolver;
+            m_criteria = criteria;
             m_mandatory = mandatory;
             return true;
         }
@@ -166,17 +174,17 @@ namespace xmltooling {
 
     private:        
         // per-call state
-        const KeyInfoSource& m_peer;
-        string m_endpoint;
+        string m_peerName,m_endpoint;
         CURL* m_handle;
         stringstream m_stream;
         struct curl_slist* m_headers;
         map<string,vector<string> > m_response_headers;
 #ifndef XMLTOOLING_NO_XMLSEC
-        const OpenSSLCredentialResolver* m_credResolver;
+        const OpenSSLCredential* m_cred;
         const OpenSSLTrustEngine* m_trustEngine;
+        const CredentialResolver* m_peerResolver;
+        CredentialCriteria* m_criteria;
         bool m_mandatory;
-        const KeyResolver* m_keyResolver;
 #endif
         ssl_ctx_callback_fn m_ssl_callback;
         void* m_ssl_userptr;
@@ -198,9 +206,9 @@ namespace xmltooling {
     int XMLTOOL_DLLLOCAL verify_callback(X509_STORE_CTX* x509_ctx, void* arg);
 #endif
 
-    SOAPTransport* CURLSOAPTransportFactory(const pair<const KeyInfoSource*,const char*>& dest)
+    SOAPTransport* CURLSOAPTransportFactory(const pair<const char*,const char*>& dest)
     {
-        return new CURLSOAPTransport(*dest.first, dest.second);
+        return new CURLSOAPTransport(dest.first, dest.second);
     }
 };
 
@@ -231,14 +239,14 @@ CURLPool::~CURLPool()
     delete m_lock;
 }
 
-CURL* CURLPool::get(const string& to, const char* endpoint)
+CURL* CURLPool::get(const char* to, const char* endpoint)
 {
 #ifdef _DEBUG
     xmltooling::NDC("get");
 #endif
     m_log.debug("getting connection handle to %s", endpoint);
     m_lock->lock();
-    poolmap_t::iterator i=m_bindingMap.find(to + "|" + endpoint);
+    poolmap_t::iterator i=m_bindingMap.find(string(to) + "|" + endpoint);
     
     if (i!=m_bindingMap.end()) {
         // Move this pool to the front of the list.
@@ -277,9 +285,9 @@ CURL* CURLPool::get(const string& to, const char* endpoint)
     return handle;
 }
 
-void CURLPool::put(const string& to, const char* endpoint, CURL* handle)
+void CURLPool::put(const char* to, const char* endpoint, CURL* handle)
 {
-    string key = to + "|" + endpoint;
+    string key = string(to) + "|" + endpoint;
     m_lock->lock();
     poolmap_t::iterator i=m_bindingMap.find(key);
     if (i==m_bindingMap.end())
@@ -404,7 +412,7 @@ void CURLSOAPTransport::send(istream& in)
     // Set request headers.
     curl_easy_setopt(m_handle,CURLOPT_HTTPHEADER,m_headers);
 
-    if (m_ssl_callback || m_credResolver || m_trustEngine) {
+    if (m_ssl_callback || m_cred || m_trustEngine) {
         curl_easy_setopt(m_handle,CURLOPT_SSL_CTX_FUNCTION,xml_ssl_ctx_callback);
         curl_easy_setopt(m_handle,CURLOPT_SSL_CTX_DATA,this);
 
@@ -504,8 +512,21 @@ int xmltooling::verify_callback(X509_STORE_CTX* x509_ctx, void* arg)
         );
 #endif
 
-     // Bypass name check (handled for us by curl).
-    if (!ctx->m_trustEngine->validate(x509_ctx->cert,x509_ctx->untrusted,ctx->m_peer,false,ctx->m_keyResolver)) {
+    bool success=false;
+    if (ctx->m_criteria) {
+        ctx->m_criteria->setUsage(CredentialCriteria::TLS_CREDENTIAL);
+        // Bypass name check (handled for us by curl).
+        ctx->m_criteria->setPeerName(NULL);
+        success = ctx->m_trustEngine->validate(x509_ctx->cert,x509_ctx->untrusted,*(ctx->m_peerResolver),ctx->m_criteria);
+    }
+    else {
+        // Bypass name check (handled for us by curl).
+        CredentialCriteria cc;
+        cc.setUsage(CredentialCriteria::TLS_CREDENTIAL);
+        success = ctx->m_trustEngine->validate(x509_ctx->cert,x509_ctx->untrusted,*(ctx->m_peerResolver),&cc);
+    }
+    
+    if (!success) {
         log.error("supplied TrustEngine failed to validate SSL/TLS server certificate");
         x509_ctx->error=X509_V_ERR_APPLICATION_VERIFICATION;     // generic error, check log for plugin specifics
         ctx->setSecure(false);
@@ -524,8 +545,8 @@ CURLcode xmltooling::xml_ssl_ctx_callback(CURL* curl, SSL_CTX* ssl_ctx, void* us
     CURLSOAPTransport* conf = reinterpret_cast<CURLSOAPTransport*>(userptr);
 
 #ifndef XMLTOOLING_NO_XMLSEC
-    if (conf->m_credResolver)
-        conf->m_credResolver->attach(ssl_ctx);
+    if (conf->m_cred)
+        conf->m_cred->attach(ssl_ctx);
 
     if (conf->m_trustEngine) {
         SSL_CTX_set_verify(ssl_ctx,SSL_VERIFY_PEER,NULL);
index fbfc1bd..2a56979 100644 (file)
@@ -46,14 +46,14 @@ void SOAPClient::reset()
     m_transport=NULL;
 }
 
-void SOAPClient::send(const Envelope& env, const KeyInfoSource& peer, const char* endpoint)
+void SOAPClient::send(const Envelope& env, const char* peerName, const char* endpoint)
 {
     // Prepare a transport object.
     const char* pch = strchr(endpoint,':');
     if (!pch)
         throw IOException("SOAP endpoint was not a URL.");
     string scheme(endpoint, pch-endpoint);
-    m_transport = XMLToolingConfig::getConfig().SOAPTransportManager.newPlugin(scheme.c_str(), make_pair(&peer,endpoint));
+    m_transport = XMLToolingConfig::getConfig().SOAPTransportManager.newPlugin(scheme.c_str(), make_pair(peerName,endpoint));
     prepareTransport(*m_transport);
     
     // Serialize envelope.
index f7c9034..66ce0ab 100644 (file)
@@ -53,6 +53,24 @@ namespace xmltooling {
         }
         
         /**
+         * Returns resource held by this object.
+         * 
+         * @return  the resource held or NULL
+         */
+        T* get() {
+            return m_held;
+        }
+
+        /**
+         * Returns resource held by this object.
+         * 
+         * @return  the resource held or NULL
+         */
+        T* operator->() {
+            return m_held;
+        }
+
+        /**
          * Returns resource held by this object and releases it to the caller.
          * 
          * @return  the resource held or NULL
index 6846084..9334729 100644 (file)
                                                >\r
                                        </File>\r
                                        <File\r
+                                               RelativePath=".\encryption\impl\EncryptedKeyResolver.cpp"\r
+                                               >\r
+                                       </File>\r
+                                       <File\r
                                                RelativePath=".\encryption\impl\Encrypter.cpp"\r
                                                >\r
                                        </File>\r
                                                >\r
                                        </File>\r
                                        <File\r
+                                               RelativePath=".\security\impl\BasicX509Credential.cpp"\r
+                                               >\r
+                                       </File>\r
+                                       <File\r
                                                RelativePath=".\security\impl\ChainingTrustEngine.cpp"\r
                                                >\r
                                        </File>\r
                                        <File\r
+                                               RelativePath=".\security\impl\Credential.cpp"\r
+                                               >\r
+                                       </File>\r
+                                       <File\r
                                                RelativePath=".\security\impl\CredentialResolver.cpp"\r
                                                >\r
                                        </File>\r
                                                >\r
                                        </File>\r
                                        <File\r
-                                               RelativePath=".\security\impl\KeyResolver.cpp"\r
+                                               RelativePath=".\security\impl\KeyInfoResolver.cpp"\r
                                                >\r
                                        </File>\r
                                        <File\r
                                >\r
                        </File>\r
                        <File\r
-                               RelativePath=".\MixedElement.h"\r
-                               >\r
-                       </File>\r
-                       <File\r
                                RelativePath=".\Namespace.h"\r
                                >\r
                        </File>\r
                                        >\r
                                </File>\r
                                <File\r
-                                       RelativePath=".\security\CachingKeyResolver.h"\r
+                                       RelativePath=".\security\BasicX509Credential.h"\r
                                        >\r
                                </File>\r
                                <File\r
                                        >\r
                                </File>\r
                                <File\r
-                                       RelativePath=".\security\CredentialResolver.h"\r
+                                       RelativePath=".\security\Credential.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\security\CredentialCriteria.h"\r
                                        >\r
                                </File>\r
                                <File\r
-                                       RelativePath=".\security\KeyInfoSource.h"\r
+                                       RelativePath=".\security\CredentialResolver.h"\r
                                        >\r
                                </File>\r
                                <File\r
-                                       RelativePath=".\security\KeyResolver.h"\r
+                                       RelativePath=".\security\KeyInfoResolver.h"\r
                                        >\r
                                </File>\r
                                <File\r
-                                       RelativePath=".\security\OpenSSLCredentialResolver.h"\r
+                                       RelativePath=".\security\OpenSSLCredential.h"\r
                                        >\r
                                </File>\r
                                <File\r
                                        >\r
                                </File>\r
                                <File\r
+                                       RelativePath=".\security\X509Credential.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
                                        RelativePath=".\security\X509TrustEngine.h"\r
                                        >\r
                                </File>\r
index 4f6f0b5..f3de66a 100644 (file)
@@ -18,6 +18,8 @@
 
 #include <xmltooling/encryption/Decrypter.h>
 #include <xmltooling/encryption/Encrypter.h>
+#include <xmltooling/security/Credential.h>
+#include <xmltooling/security/CredentialCriteria.h>
 #include <xmltooling/security/CredentialResolver.h>
 
 #include <fstream>
 
 using namespace xmlencryption;
 
-class _addcert : public std::binary_function<X509Data*,XSECCryptoX509*,void> {
-public:
-    void operator()(X509Data* bag, XSECCryptoX509* cert) const {
-        safeBuffer& buf=cert->getDEREncodingSB();
-        X509Certificate* x=X509CertificateBuilder::buildX509Certificate();
-        x->setValue(buf.sbStrToXMLCh());
-        bag->getX509Certificates().push_back(x);
-    }
-};
-
 class EncryptionTest : public CxxTest::TestSuite {
     CredentialResolver* m_resolver;
 public:
@@ -61,14 +53,20 @@ public:
         TS_ASSERT(doc!=NULL);
 
         try {
+            CredentialCriteria cc;
+            cc.setUsage(CredentialCriteria::ENCRYPTION_CREDENTIAL);
             Locker locker(m_resolver);
+            const Credential* cred=m_resolver->resolve(&cc);
+            TSM_ASSERT("Retrieved credential was null", cred!=NULL);
+
             Encrypter encrypter;
             Encrypter::EncryptionParams ep;
-            Encrypter::KeyEncryptionParams kep(DSIGConstants::s_unicodeStrURIRSA_1_5,m_resolver->getKey());
+            Encrypter::KeyEncryptionParams kep(*cred,DSIGConstants::s_unicodeStrURIRSA_1_5);
             auto_ptr<EncryptedData> encData(encrypter.encryptElement(doc->getDocumentElement(),ep,&kep));
 
             string buf;
             XMLHelper::serialize(encData->marshall(), buf);
+            //TS_TRACE(buf.c_str());
             istringstream is(buf);
             DOMDocument* doc2=XMLToolingConfig::getConfig().getValidatingParser().parse(is);
             auto_ptr<EncryptedData> encData2(
index 8091870..a396685 100644 (file)
@@ -17,6 +17,7 @@
 #include "XMLObjectBaseTestCase.h"
 
 #include <xmltooling/security/CredentialResolver.h>
+#include <xmltooling/security/X509Credential.h>
 
 #include <fstream>
 
@@ -41,8 +42,9 @@ public:
             );
 
         Locker locker(credResolver.get());
-        auto_ptr<XSECCryptoKey> key(credResolver->getKey());
-        TSM_ASSERT("Retrieved key was null", key.get()!=NULL);
-        TSM_ASSERT_EQUALS("Unexpected number of certificates", 1, credResolver->getCertificates().size());
+        const X509Credential* cred=dynamic_cast<const X509Credential*>(credResolver->resolve());
+        TSM_ASSERT("Retrieved credential was null", cred!=NULL);
+        TSM_ASSERT("Retrieved key was null", cred->getPrivateKey()!=NULL);
+        TSM_ASSERT_EQUALS("Unexpected number of certificates", 1, cred->getEntityCertificateChain().size());
     }
 };
index d59b0b3..007af8c 100644 (file)
 #include "XMLObjectBaseTestCase.h"
 
 #include <fstream>
+#include <xmltooling/security/X509Credential.h>
+#include <xmltooling/security/KeyInfoResolver.h>
 #include <xmltooling/signature/KeyInfo.h>
-#include <xmltooling/security/KeyResolver.h>
 
 using namespace xmlsignature;
 
 class InlineKeyResolverTest : public CxxTest::TestSuite {
-    KeyResolver* m_resolver;
+    KeyInfoResolver* m_resolver;
 public:
     InlineKeyResolverTest() : m_resolver(NULL) {}
 
@@ -32,7 +33,7 @@ public:
         ifstream in(config.c_str());
         DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);
         XercesJanitor<DOMDocument> janitor(doc);
-        m_resolver=XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(INLINE_KEY_RESOLVER,doc->getDocumentElement());
+        m_resolver=XMLToolingConfig::getConfig().KeyInfoResolverManager.newPlugin(INLINE_KEYINFO_RESOLVER,doc->getDocumentElement());
     }
 
     void tearDown() {
@@ -50,14 +51,12 @@ public:
         auto_ptr<KeyInfo> kiObject(dynamic_cast<KeyInfo*>(b->buildFromDocument(doc)));
         TS_ASSERT(kiObject.get()!=NULL);
 
-        auto_ptr<XSECCryptoKey> key(m_resolver->resolveKey(kiObject.get()));
-        TSM_ASSERT("Unable to resolve public key.", key.get()!=NULL);
-        TSM_ASSERT_EQUALS("Unexpected key type.", key->getKeyType(), XSECCryptoKey::KEY_RSA_PUBLIC);
+        auto_ptr<X509Credential> cred(dynamic_cast<X509Credential*>(m_resolver->resolve(kiObject.get())));
+        TSM_ASSERT("Unable to resolve KeyInfo into Credential.", cred.get()!=NULL);
 
-        auto_ptr<XSECCryptoX509CRL> crl(m_resolver->resolveCRL(kiObject.get()));
-        TSM_ASSERT("Unable to resolve CRL.", crl.get()!=NULL);
-
-        KeyResolver::ResolvedCertificates certs;
-        TSM_ASSERT_EQUALS("Wrong certificate count.", m_resolver->resolveCertificates(kiObject.get(), certs), 1);
+        TSM_ASSERT("Unable to resolve public key.", cred->getPublicKey()!=NULL);
+        TSM_ASSERT_EQUALS("Unexpected key type.", cred->getPublicKey()->getKeyType(), XSECCryptoKey::KEY_RSA_PUBLIC);
+        TSM_ASSERT_EQUALS("Wrong certificate count.", cred->getEntityCertificateChain().size(), 1);
+        TSM_ASSERT("Unable to resolve CRL.", cred->getCRL()!=NULL);
     }
 };
index 394583e..8e05cce 100644 (file)
@@ -16,6 +16,8 @@
 
 #include "XMLObjectBaseTestCase.h"
 
+#include <xmltooling/security/Credential.h>
+#include <xmltooling/security/CredentialCriteria.h>
 #include <xmltooling/security/CredentialResolver.h>
 #include <xmltooling/signature/KeyInfo.h>
 #include <xmltooling/signature/SignatureValidator.h>
@@ -49,7 +51,7 @@ class TestValidator : public SignatureValidator
     XMLCh* m_uri;
     
 public:
-    TestValidator(const XMLCh* uri) : SignatureValidator(XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(INLINE_KEY_RESOLVER,NULL)) {
+    TestValidator(const XMLCh* uri, const Credential* credential) : SignatureValidator(credential) {
         m_uri=XMLString::replicate(uri);
     }
     
@@ -67,16 +69,6 @@ public:
     }
 };
 
-class _addcert : public std::binary_function<X509Data*,XSECCryptoX509*,void> {
-public:
-    void operator()(X509Data* bag, XSECCryptoX509* cert) const {
-        safeBuffer& buf=cert->getDEREncodingSB();
-        X509Certificate* x=X509CertificateBuilder::buildX509Certificate();
-        x->setValue(buf.sbStrToXMLCh());
-        bag->getX509Certificates().push_back(x);
-    }
-};
-
 class SignatureTest : public CxxTest::TestSuite {
     CredentialResolver* m_resolver;
 public:
@@ -126,20 +118,16 @@ public:
         sxObject->setSignature(sig);
         sig->setContentReference(new TestContext(&chNull));
 
+        CredentialCriteria cc;
+        cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL);
         Locker locker(m_resolver);
-        sig->setSigningKey(m_resolver->getKey());
-        
-        // Build KeyInfo.
-        KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo();
-        X509Data* x509Data=X509DataBuilder::buildX509Data();
-        keyInfo->getX509Datas().push_back(x509Data);
-        for_each(m_resolver->getCertificates().begin(),m_resolver->getCertificates().end(),bind1st(_addcert(),x509Data));
-        sig->setKeyInfo(keyInfo);
+        const Credential* cred = m_resolver->resolve(&cc);
+        TSM_ASSERT("Retrieved credential was null", cred!=NULL);
         
         DOMElement* rootElement = NULL;
         try {
-            rootElement=sxObject->marshall((DOMDocument*)NULL);
-            sig->sign();
+            vector<Signature*> sigs(1,sig);
+            rootElement=sxObject->marshall((DOMDocument*)NULL,&sigs,cred);
         }
         catch (XMLToolingException& e) {
             TS_TRACE(e.what());
@@ -157,7 +145,7 @@ public:
         TS_ASSERT(sxObject2->getSignature()!=NULL);
         
         try {
-            TestValidator tv(&chNull);
+            TestValidator tv(&chNull, cred);
             tv.validate(sxObject2->getSignature());
         }
         catch (XMLToolingException& e) {