Integrated credential resolver API with signing context.
[shibboleth/cpp-xmltooling.git] / xmltooling / signature / impl / XMLSecSignatureImpl.cpp
index d320a3d..cf3afd2 100644 (file)
@@ -23,7 +23,7 @@
 #include "internal.h"\r
 #include "exceptions.h"\r
 #include "impl/UnknownElement.h"\r
-#include "signature/impl/XMLSecSignatureImpl.h"\r
+#include "signature/Signature.h"\r
 #include "util/NDC.h"\r
 #include "util/XMLConstants.h"\r
 #include "util/XMLHelper.h"\r
 #include <log4cpp/Category.hh>\r
 #include <xercesc/framework/MemBufInputSource.hpp>\r
 #include <xercesc/framework/Wrapper4InputSource.hpp>\r
+#include <xercesc/util/XMLUniDefs.hpp>\r
 #include <xsec/dsig/DSIGKeyInfoX509.hpp>\r
 #include <xsec/enc/XSECCryptoException.hpp>\r
 #include <xsec/framework/XSECException.hpp>\r
 \r
+using namespace xmlsignature;\r
 using namespace xmltooling;\r
 using namespace log4cpp;\r
 using namespace std;\r
@@ -44,7 +46,7 @@ using namespace std;
     #pragma warning( disable : 4250 4251 )\r
 #endif\r
 \r
-namespace xmltooling {\r
+namespace xmlsignature {\r
     \r
     class XMLTOOL_DLLLOCAL XMLSecSignatureImpl : public UnknownElementImpl, public virtual Signature\r
     {\r
@@ -55,6 +57,7 @@ namespace xmltooling {
         \r
         void releaseDOM();\r
         XMLObject* clone() const;\r
+        Signature* cloneSignature() const;\r
 \r
         DOMElement* marshall(DOMDocument* document=NULL, MarshallingContext* ctx=NULL) const;\r
         DOMElement* marshall(DOMElement* parentElement, MarshallingContext* ctx=NULL) const;\r
@@ -68,7 +71,7 @@ namespace xmltooling {
         void setCanonicalizationMethod(const XMLCh* c14n) { m_c14n = prepareForAssignment(m_c14n,c14n); }\r
         void setSignatureAlgorithm(const XMLCh* sm) { m_sm = prepareForAssignment(m_sm,sm); }\r
 \r
-        void sign(const SigningContext& ctx);\r
+        void sign(SigningContext& ctx);\r
         void verify(const VerifyingContext& ctx) const;\r
 \r
     private:\r
@@ -107,6 +110,11 @@ void XMLSecSignatureImpl::releaseDOM()
 \r
 XMLObject* XMLSecSignatureImpl::clone() const\r
 {\r
+    return cloneSignature();\r
+}\r
+\r
+Signature* XMLSecSignatureImpl::cloneSignature() const\r
+{\r
     XMLSecSignatureImpl* ret=new XMLSecSignatureImpl();\r
 \r
     ret->m_c14n=XMLString::replicate(m_c14n);\r
@@ -129,7 +137,7 @@ public:
     }\r
 };\r
 \r
-void XMLSecSignatureImpl::sign(const SigningContext& ctx)\r
+void XMLSecSignatureImpl::sign(SigningContext& ctx)\r
 {\r
     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature");\r
     log.debug("applying signature");\r
@@ -139,15 +147,29 @@ void XMLSecSignatureImpl::sign(const SigningContext& ctx)
 \r
     try {\r
         log.debug("creating signature content");\r
-        ctx.createSignature(m_signature);\r
-        const std::vector<XSECCryptoX509*>& certs=ctx.getX509Certificates();\r
-        if (!certs.empty()) {\r
-            DSIGKeyInfoX509* x509Data=m_signature->appendX509Data();\r
-            for_each(certs.begin(),certs.end(),bind1st(_addcert(),x509Data));\r
+        CredentialResolver& cr=ctx.getCredentialResolver();\r
+        if (!ctx.createSignature(m_signature)) {\r
+            auto_ptr<KeyInfo> keyInfo(ctx.getKeyInfo());\r
+            if (keyInfo.get()) {\r
+                DOMElement* domElement=keyInfo->marshall(m_signature->getParentDocument());\r
+                getDOM()->appendChild(domElement);\r
+            }\r
+            else {\r
+                Locker locker1(cr);\r
+                const std::vector<XSECCryptoX509*>* certs=cr.getX509Certificates();\r
+                if (certs && !certs->empty()) {\r
+                    DSIGKeyInfoX509* x509Data=m_signature->appendX509Data();\r
+                    for_each(certs->begin(),certs->end(),bind1st(_addcert(),x509Data));\r
+                }\r
+            }\r
         }\r
         \r
         log.debug("computing signature");\r
-        m_signature->setSigningKey(ctx.getSigningKey());\r
+        Locker locker2(cr);\r
+        XSECCryptoKey* key=cr.getPrivateKey();\r
+        if (!key)\r
+            throw SignatureException(string("Unable to obtain signing key from CredentialResolver (") + cr.getId() + ")");\r
+        m_signature->setSigningKey(key->clone());\r
         m_signature->sign();\r
     }\r
     catch(XSECException& e) {\r
@@ -236,7 +258,7 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, MarshallingCont
             bindDocument=true;\r
         }\r
         m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature();\r
-        m_signature->setDSIGNSPrefix(Signature::PREFIX);\r
+        m_signature->setDSIGNSPrefix(XMLConstants::XMLSIG_PREFIX);\r
         cachedDOM=m_signature->createBlankSignature(document, getCanonicalizationMethod(), getSignatureAlgorithm());\r
     }\r
     else {\r
@@ -244,7 +266,7 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, MarshallingCont
         MemBufInputSource src(reinterpret_cast<const XMLByte*>(m_xml.c_str()),m_xml.length(),"XMLSecSignatureImpl");\r
         Wrapper4InputSource dsrc(&src,false);\r
         log.debug("parsing Signature XML back into DOM tree");\r
-        DOMDocument* internalDoc=XMLToolingInternalConfig::getInternalConfig().m_parserPool->parse(dsrc);\r
+        DOMDocument* internalDoc=XMLToolingConfig::getConfig().getParser().parse(dsrc);\r
         if (document) {\r
             // The caller insists on using his own document, so we now have to import the thing\r
             // into it. Then we're just dumping the one we built.\r
@@ -339,7 +361,7 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, Marshalling
         // Fresh signature, so we just create an empty one.\r
         log.debug("creating empty Signature element");\r
         m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature();\r
-        m_signature->setDSIGNSPrefix(Signature::PREFIX);\r
+        m_signature->setDSIGNSPrefix(XMLConstants::XMLSIG_PREFIX);\r
         cachedDOM=m_signature->createBlankSignature(\r
             parentElement->getOwnerDocument(), getCanonicalizationMethod(), getSignatureAlgorithm()\r
             );\r
@@ -348,7 +370,7 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, Marshalling
         MemBufInputSource src(reinterpret_cast<const XMLByte*>(m_xml.c_str()),m_xml.length(),"XMLSecSignatureImpl");\r
         Wrapper4InputSource dsrc(&src,false);\r
         log.debug("parsing XML back into DOM tree");\r
-        DOMDocument* internalDoc=XMLToolingInternalConfig::getInternalConfig().m_parserPool->parse(dsrc);\r
+        DOMDocument* internalDoc=XMLToolingConfig::getConfig().getParser().parse(dsrc);\r
         \r
         log.debug("reimporting new DOM into caller-supplied document");\r
         cachedDOM=static_cast<DOMElement*>(parentElement->getOwnerDocument()->importNode(internalDoc->getDocumentElement(),true));\r
@@ -401,7 +423,7 @@ XMLObject* XMLSecSignatureImpl::unmarshall(DOMElement* element, bool bindDocumen
     return this;\r
 }\r
 \r
-Signature* XMLSecSignatureBuilder::buildObject(\r
+Signature* SignatureBuilder::buildObject(\r
     const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType\r
     ) const\r
 {\r
@@ -410,7 +432,9 @@ Signature* XMLSecSignatureBuilder::buildObject(
     return buildObject();\r
 }\r
 \r
-Signature* XMLSecSignatureBuilder::buildObject() const\r
+Signature* SignatureBuilder::buildObject() const\r
 {\r
     return new XMLSecSignatureImpl();\r
 }\r
+\r
+const XMLCh Signature::LOCAL_NAME[] = UNICODE_LITERAL_9(S,i,g,n,a,t,u,r,e);\r