<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
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));
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)
virtual ~AbstractXMLObject() {
delete m_typeQname;
XMLString::release(&m_schemaLocation);
+ XMLString::release(&m_noNamespaceSchemaLocation);
}
void detach();
*/
XMLCh* m_schemaLocation;
+ /**
+ * Stores off xsi:noNamespaceSchemaLocation attribute.
+ */
+ XMLCh* m_noNamespaceSchemaLocation;
+
private:
XMLObject* m_parent;
QName m_elementQname;
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 \
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
#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
*/
#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.
#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.
#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.
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.
*/
*
* @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
DOMDocument* document=NULL
#ifndef XMLTOOLING_NO_XMLSEC
,const std::vector<xmlsignature::Signature*>* sigs=NULL
+ ,const Credential* credential=NULL
#endif
) const=0;
*
* @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.
DOMElement* parentElement
#ifndef XMLTOOLING_NO_XMLSEC
,const std::vector<xmlsignature::Signature*>* sigs=NULL
+ ,const Credential* credential=NULL
#endif
) const=0;
#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"
registerEncryptionClasses();
registerSOAPClasses();
- m_urlEncoder = new URLEncoder();
-
REGISTER_XMLTOOLING_EXCEPTION_FACTORY(XMLParserException,xmltooling);
REGISTER_XMLTOOLING_EXCEPTION_FACTORY(XMLObjectException,xmltooling);
REGISTER_XMLTOOLING_EXCEPTION_FACTORY(MarshallingException,xmltooling);
REGISTER_XMLTOOLING_EXCEPTION_FACTORY(XMLSecurityException,xmltooling);
REGISTER_XMLTOOLING_EXCEPTION_FACTORY(SignatureException,xmlsignature);
REGISTER_XMLTOOLING_EXCEPTION_FACTORY(EncryptionException,xmlencryption);
- registerKeyResolvers();
+ registerKeyInfoResolvers();
registerCredentialResolvers();
registerTrustEngines();
#endif
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));
#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;
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;
};
{
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;
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.
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.
/**
* 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.
#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.
*/
/**
* 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.
* 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.
* @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);
#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;
};
};
#include <xsec/enc/XSECCryptoKey.hpp>
#include <xsec/xenc/XENCCipher.hpp>
+namespace xmltooling {
+ class XMLTOOL_API Credential;
+};
+
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;
};
/**
* 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;
};
* @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);
#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>
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()) {
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();
}
}
-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.");
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());
}
}
--- /dev/null
+/*
+ * 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;
+}
#include "internal.h"
#include "encryption/Encrypter.h"
+#include "security/Credential.h"
#include <xsec/enc/XSECCryptoException.hpp>
#include <xsec/framework/XSECException.hpp>
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.");
}
}
- 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)
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());
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)
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);
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.
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;
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;
using namespace xmltooling;
using namespace log4cpp;
using namespace std;
+using xmlsignature::Signature;
void UnknownElementImpl::releaseDOM() 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
{
DOMElement* UnknownElementImpl::marshall(
DOMElement* parentElement
#ifndef XMLTOOLING_NO_XMLSEC
- ,const std::vector<xmlsignature::Signature*>* sigs
+ ,const vector<Signature*>* sigs
+ ,const Credential* credential
#endif
) const
{
DOMDocument* document=NULL
#ifndef XMLTOOLING_NO_XMLSEC
,const std::vector<xmlsignature::Signature*>* sigs=NULL
+ ,const Credential* credential=NULL
#endif
) const;
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);
#include "exceptions.h"
#include "io/AbstractXMLObjectMarshaller.h"
#ifndef XMLTOOLING_NO_XMLSEC
+ #include "security/Credential.h"
#include "signature/Signature.h"
#endif
#include "util/NDC.h"
DOMElement* AbstractXMLObjectMarshaller::marshall(
DOMDocument* document
#ifndef XMLTOOLING_NO_XMLSEC
- ,const std::vector<xmlsignature::Signature*>* sigs
+ ,const vector<Signature*>* sigs
+ ,const Credential* credential
#endif
) const
{
);
setDocumentElement(document, domElement);
#ifndef XMLTOOLING_NO_XMLSEC
- marshallInto(domElement, sigs);
+ marshallInto(domElement, sigs, credential);
#else
marshallInto(domElement);
#endif
DOMElement* AbstractXMLObjectMarshaller::marshall(
DOMElement* parentElement
#ifndef XMLTOOLING_NO_XMLSEC
- ,const std::vector<xmlsignature::Signature*>* sigs
+ ,const vector<Signature*>* sigs
+ ,const Credential* credential
#endif
) const
{
);
parentElement->appendChild(domElement);
#ifndef XMLTOOLING_NO_XMLSEC
- marshallInto(domElement, sigs);
+ marshallInto(domElement, sigs, credential);
#else
marshallInto(domElement);
#endif
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
}
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));
}
}
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");
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)
DOMDocument* document=NULL
#ifndef XMLTOOLING_NO_XMLSEC
,const std::vector<xmlsignature::Signature*>* sigs=NULL
+ ,const Credential* credential=NULL
#endif
) const;
DOMElement* parentElement
#ifndef XMLTOOLING_NO_XMLSEC
,const std::vector<xmlsignature::Signature*>* sigs=NULL
+ ,const Credential* credential=NULL
#endif
) const;
*
* @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.
*/
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.
*
* @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.
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;
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");
/**
* @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)
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
{
* If a DOM is supplied, the following XML content is supported:
*
* <ul>
- * <li><KeyResolver> elements with a type attribute
+ * <li><KeyInfoResolver> 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(
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;
/**
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() {}
};
/**
- * 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;
};
};
--- /dev/null
+/*
+ * 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__ */
+++ /dev/null
-/*
- * 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__ */
bool validate(
xmlsignature::Signature& sig,
- const KeyInfoSource& keyInfoSource,
- const KeyResolver* keyResolver=NULL
+ const CredentialResolver& credResolver,
+ CredentialCriteria* criteria=NULL
) const;
bool validate(
const XMLCh* sigAlgorithm,
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;
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__ */
*/
/**
- * @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:
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;
};
/**
*/
void XMLTOOL_API registerCredentialResolvers();
- /** CredentialResolver based on local files */
+ /** CredentialResolver based on local files with no criteria support. */
#define FILESYSTEM_CREDENTIAL_RESOLVER "File"
};
--- /dev/null
+/*
+ * 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__ */
+++ /dev/null
-/*
- * 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__ */
+++ /dev/null
-/*
- * 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__ */
*/
/**
- * @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
*/
};
-#endif /* __xmltooling_opensslcredres_h__ */
+#endif /* __xmltooling_opensslcred_h__ */
* If a DOM is supplied, the following XML content is supported:
*
* <ul>
- * <li><KeyResolver> elements with a type attribute
+ * <li><KeyInfoResolver> elements with a type attribute
* </ul>
*
* XML namespaces are ignored in the processing of this content.
/**
* 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;
};
/**
* @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.
* If a DOM is supplied, the following XML content is supported:
*
* <ul>
- * <li><KeyResolver> elements with a type attribute
+ * <li><KeyInfoResolver> elements with a type attribute
* </ul>
*
* XML namespaces are ignored in the processing of this content.
*/
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
* @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(
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;
};
--- /dev/null
+/*
+ * 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__ */
* If a DOM is supplied, the following XML content is supported:
*
* <ul>
- * <li><KeyResolver> elements with a type attribute
+ * <li><KeyInfoResolver> elements with a type attribute
* </ul>
*
* XML namespaces are ignored in the processing of this content.
/**
* 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;
};
#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>
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)
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()));
}
}
}
};
-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) {
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
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;
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
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
#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;
}
// 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;
KeyInfo* keyInfo,
const char* in,
unsigned int in_len,
- const KeyInfoSource& keyInfoSource,
- const KeyResolver* keyResolver
+ const CredentialResolver& credResolver,
+ CredentialCriteria* criteria
) const
{
#ifdef _DEBUG
#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;
}
// 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)) {
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;
--- /dev/null
+/*
+ * 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();
+}
#include "internal.h"
#include "exceptions.h"
#include "security/ChainingTrustEngine.h"
+#include "util/XMLHelper.h"
#include <log4cpp/Category.hh>
#include <xercesc/util/XMLUniDefs.hpp>
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;
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;
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;
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;
--- /dev/null
+/*
+ * 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;
+}
*/
#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"
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,
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;
};
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;
}
KeyInfo* keyInfo,
const char* in,
unsigned int in_len,
- const KeyInfoSource& keyInfoSource,
- const KeyResolver* keyResolver
+ const CredentialResolver& credResolver,
+ CredentialCriteria* criteria
) const
{
#ifdef _DEBUG
#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;
}
}
}
}
- 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
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
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");
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)
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)
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");
*/
#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>
}
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;
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);
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) {
}
// 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.");
}
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()));
}
}
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);
}
}
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()
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
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);
+}
*/
#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"
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) {
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()));
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) {
}
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) {
}
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) {
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());
}
}
}
// 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) {
}
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();
}
--- /dev/null
+/*
+ * 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;
+}
+++ /dev/null
-/*
- * 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);
-}
*/
#include "internal.h"
+#include "security/KeyInfoResolver.h"
#include "security/TrustEngine.h"
+#include "util/XMLHelper.h"
#include <xercesc/util/XMLUniDefs.hpp>
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;
}
/**
* 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.
#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;
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;
};
};
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());
#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"
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
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;
};
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();
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) {
}
}
-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");
}
// 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);
}
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");
}
// 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);
}
#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 {
* 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
namespace xmltooling {
+ class XMLTOOL_API Credential;
class XMLTOOL_API CredentialResolver;
- class XMLTOOL_API KeyResolver;
class XMLTOOL_API X509TrustEngine;
/**
#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
#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"
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;
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);
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 {
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;
}
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;
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);
}
};
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.
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())
// 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);
);
#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);
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);
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.
}
/**
+ * 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
>\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
#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:
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(
#include "XMLObjectBaseTestCase.h"
#include <xmltooling/security/CredentialResolver.h>
+#include <xmltooling/security/X509Credential.h>
#include <fstream>
);
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());
}
};
#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) {}
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() {
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);
}
};
#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>
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);
}
}
};
-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:
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());
TS_ASSERT(sxObject2->getSignature()!=NULL);
try {
- TestValidator tv(&chNull);
+ TestValidator tv(&chNull, cred);
tv.validate(sxObject2->getSignature());
}
catch (XMLToolingException& e) {