Multi-line svn commit, see body.
[shibboleth/cpp-xmltooling.git] / xmltooling / signature / impl / XMLSecSignatureImpl.cpp
index 51a5119..938a684 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "internal.h"
 #include "exceptions.h"
+#include "logging.h"
 #include "impl/UnknownElement.h"
 #include "security/Credential.h"
 #include "signature/KeyInfo.h"
@@ -30,7 +31,6 @@
 #include "util/XMLConstants.h"
 #include "util/XMLHelper.h"
 
-#include <log4cpp/Category.hh>
 #include <xercesc/framework/MemBufInputSource.hpp>
 #include <xercesc/framework/Wrapper4InputSource.hpp>
 #include <xercesc/util/XMLUniDefs.hpp>
@@ -45,8 +45,8 @@
 #include <xsec/transformers/TXFMOutputFile.hpp>
 
 using namespace xmlsignature;
+using namespace xmltooling::logging;
 using namespace xmltooling;
-using namespace log4cpp;
 using namespace std;
 using xmlconstants::XMLSIG_NS;
 using xmlconstants::XMLSIG_PREFIX;
@@ -61,7 +61,8 @@ namespace xmlsignature {
     class XMLTOOL_DLLLOCAL XMLSecSignatureImpl : public UnknownElementImpl, public virtual Signature
     {
     public:
-        XMLSecSignatureImpl() : UnknownElementImpl(XMLSIG_NS, Signature::LOCAL_NAME, XMLSIG_PREFIX),
+        XMLSecSignatureImpl() : AbstractXMLObject(XMLSIG_NS, Signature::LOCAL_NAME, XMLSIG_PREFIX),
+            UnknownElementImpl(XMLSIG_NS, Signature::LOCAL_NAME, XMLSIG_PREFIX),
             m_signature(NULL), m_c14n(NULL), m_sm(NULL), m_key(NULL), m_keyInfo(NULL), m_reference(NULL) {}
         virtual ~XMLSecSignatureImpl();
         
@@ -81,8 +82,21 @@ namespace xmlsignature {
         XMLObject* unmarshall(DOMElement* element, bool bindDocument=false);
         
         // Getters
-        const XMLCh* getCanonicalizationMethod() const { return m_c14n ? m_c14n : DSIGConstants::s_unicodeStrURIEXC_C14N_NOC; }
-        const XMLCh* getSignatureAlgorithm() const { return m_sm ? m_sm : DSIGConstants::s_unicodeStrURIRSA_SHA1; }
+        const XMLCh* getCanonicalizationMethod() const {
+            if (m_signature)
+                return canonicalizationMethod2UNICODEURI(m_signature->getCanonicalizationMethod());
+            return m_c14n ? m_c14n : DSIGConstants::s_unicodeStrURIEXC_C14N_NOC;
+        }
+        const XMLCh* getSignatureAlgorithm() const {
+            if (!m_sm && m_signature) {
+                safeBuffer sURI;
+                if (signatureHashMethod2URI(sURI, m_signature->getSignatureMethod(), m_signature->getHashMethod()) == false)
+                    return NULL;
+                m_sm = XMLString::replicate(sURI.sbStrToXMLCh());
+            }
+            return m_sm ? m_sm : DSIGConstants::s_unicodeStrURIRSA_SHA1;
+        }
+
         KeyInfo* getKeyInfo() const { return m_keyInfo; }
         ContentReference* getContentReference() const { return m_reference; }
         DSIGSignature* getXMLSignature() const { return m_signature; }
@@ -108,7 +122,7 @@ namespace xmlsignature {
     private:
         mutable DSIGSignature* m_signature;
         XMLCh* m_c14n;
-        XMLCh* m_sm;
+        mutable XMLCh* m_sm;
         XSECCryptoKey* m_key;
         mutable KeyInfo* m_keyInfo;
         ContentReference* m_reference;
@@ -243,9 +257,10 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Si
             document=DOMImplementationRegistry::getDOMImplementation(NULL)->createDocument();
             bindDocument=true;
         }
-        m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature();
-        m_signature->setDSIGNSPrefix(XMLSIG_PREFIX);
-        cachedDOM=m_signature->createBlankSignature(document, getCanonicalizationMethod(), getSignatureAlgorithm());
+        DSIGSignature* temp=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature();
+        temp->setDSIGNSPrefix(XMLSIG_PREFIX);
+        cachedDOM=temp->createBlankSignature(document, getCanonicalizationMethod(), getSignatureAlgorithm());
+        m_signature = temp;
     }
     else {
         // We need to reparse the XML we saved off into a new DOM.
@@ -291,9 +306,7 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Si
     if (credential) {
         delete m_keyInfo;
         m_keyInfo = NULL;
-        const KeyInfo* fromcred = credential->getKeyInfo();
-        if (fromcred)
-            m_keyInfo = fromcred->cloneKeyInfo();
+        m_keyInfo = credential->getKeyInfo();
     }
     if (m_keyInfo && (!m_signature->getKeyInfoList() || m_signature->getKeyInfoList()->isEmpty())) {
         m_keyInfo->marshall(cachedDOM);
@@ -341,11 +354,10 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vecto
     if (m_xml.empty()) {
         // Fresh signature, so we just create an empty one.
         log.debug("creating empty Signature element");
-        m_signature=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature();
-        m_signature->setDSIGNSPrefix(XMLSIG_PREFIX);
-        cachedDOM=m_signature->createBlankSignature(
-            parentElement->getOwnerDocument(), getCanonicalizationMethod(), getSignatureAlgorithm()
-            );
+        DSIGSignature* temp=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature();
+        temp->setDSIGNSPrefix(XMLSIG_PREFIX);
+        cachedDOM=temp->createBlankSignature(parentElement->getOwnerDocument(), getCanonicalizationMethod(), getSignatureAlgorithm());
+        m_signature = temp;
     }
     else {
         MemBufInputSource src(reinterpret_cast<const XMLByte*>(m_xml.c_str()),m_xml.length(),"XMLSecSignatureImpl");
@@ -377,9 +389,7 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vecto
     if (credential) {
         delete m_keyInfo;
         m_keyInfo = NULL;
-        const KeyInfo* fromcred = credential->getKeyInfo();
-        if (fromcred)
-            m_keyInfo = fromcred->cloneKeyInfo();
+        m_keyInfo = credential->getKeyInfo();
     }
     if (m_keyInfo && (!m_signature->getKeyInfoList() || m_signature->getKeyInfoList()->isEmpty())) {
         m_keyInfo->marshall(cachedDOM);
@@ -519,3 +529,18 @@ bool Signature::verifyRawSignature(
         throw SignatureException(string("Caught an XMLSecurity exception while verifying raw signature: ") + e.getMsg());
     }
 }
+
+void Signature::extractNames(DSIGKeyInfoList* keyInfo, set<string>& names)
+{
+    char* kn;
+    const XMLCh* n;
+
+    for (size_t s=0; s<keyInfo->getSize(); s++) {
+        n=keyInfo->item(s)->getKeyName();
+        if (n && *n) {
+            kn=toUTF8(n);
+            names.insert(kn);
+            delete[] kn;
+        }
+    }
+}