Wrap importNode call in exception handler.
[shibboleth/xmltooling.git] / xmltooling / signature / impl / XMLSecSignatureImpl.cpp
index 1ef0838..6880452 100644 (file)
@@ -1,5 +1,5 @@
 /*
-*  Copyright 2001-2009 Internet2
+*  Copyright 2001-2010 Internet2
  * 
 * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -53,12 +53,12 @@ using namespace std;
 using xmlconstants::XMLSIG_NS;
 using xmlconstants::XMLSIG_PREFIX;
 
+namespace xmlsignature {
+
 #if defined (_MSC_VER)
     #pragma warning( push )
     #pragma warning( disable : 4250 4251 )
 #endif
-
-namespace xmlsignature {
     
     class XMLTOOL_DLLLOCAL XMLSecSignatureImpl : public UnknownElementImpl, public virtual Signature
     {
@@ -91,12 +91,15 @@ namespace xmlsignature {
         }
         const XMLCh* getSignatureAlgorithm() const {
             if (!m_sm && m_signature) {
+#ifdef XMLTOOLING_XMLSEC_SIGALGORITHM
+                m_sm = XMLString::replicate(m_signature->getAlgorithmURI());
+#else
                 safeBuffer sURI;
-                if (signatureHashMethod2URI(sURI, m_signature->getSignatureMethod(), m_signature->getHashMethod()) == false)
-                    return NULL;
-                m_sm = XMLString::replicate(sURI.sbStrToXMLCh());
+                if (signatureHashMethod2URI(sURI, m_signature->getSignatureMethod(), m_signature->getHashMethod()))
+                    m_sm = XMLString::replicate(sURI.sbStrToXMLCh());
+#endif
             }
-            return m_sm ? m_sm : DSIGConstants::s_unicodeStrURIRSA_SHA1;
+            return m_sm;
         }
 
         KeyInfo* getKeyInfo() const { return m_keyInfo; }
@@ -129,12 +132,27 @@ namespace xmlsignature {
         mutable KeyInfo* m_keyInfo;
         ContentReference* m_reference;
     };
-    
-};
 
 #if defined (_MSC_VER)
     #pragma warning( pop )
 #endif
+};
+
+ContentReference::ContentReference()
+{
+}
+
+ContentReference::~ContentReference()
+{
+}
+
+Signature::Signature()
+{
+}
+
+Signature::~Signature()
+{
+}
 
 XMLSecSignatureImpl::~XMLSecSignatureImpl()
 {
@@ -261,7 +279,10 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Si
         }
         DSIGSignature* temp=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature();
         temp->setDSIGNSPrefix(XMLSIG_PREFIX);
-        cachedDOM=temp->createBlankSignature(document, getCanonicalizationMethod(), getSignatureAlgorithm());
+        const XMLCh* alg = getSignatureAlgorithm();
+        if (!alg)
+            alg = DSIGConstants::s_unicodeStrURIRSA_SHA1;
+        cachedDOM=temp->createBlankSignature(document, getCanonicalizationMethod(), alg);
         m_signature = temp;
     }
     else {
@@ -274,7 +295,16 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Si
             // The caller insists on using his own document, so we now have to import the thing
             // into it. Then we're just dumping the one we built.
             log.debug("reimporting new DOM into caller-supplied document");
-            cachedDOM=static_cast<DOMElement*>(document->importNode(internalDoc->getDocumentElement(), true));
+            try {
+                cachedDOM=static_cast<DOMElement*>(document->importNode(internalDoc->getDocumentElement(), true));
+            }
+            catch (XMLException& ex) {
+                internalDoc->release();
+                auto_ptr_char temp(ex.getMessage());
+                throw XMLParserException(
+                    string("Error importing DOM into caller-supplied document: ") + (temp.get() ? temp.get() : "no message")
+                    );
+            }
             internalDoc->release();
         }
         else {
@@ -358,7 +388,10 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vecto
         log.debug("creating empty Signature element");
         DSIGSignature* temp=XMLToolingInternalConfig::getInternalConfig().m_xsecProvider->newSignature();
         temp->setDSIGNSPrefix(XMLSIG_PREFIX);
-        cachedDOM=temp->createBlankSignature(parentElement->getOwnerDocument(), getCanonicalizationMethod(), getSignatureAlgorithm());
+        const XMLCh* alg = getSignatureAlgorithm();
+        if (!alg)
+            alg = DSIGConstants::s_unicodeStrURIRSA_SHA1;
+        cachedDOM=temp->createBlankSignature(parentElement->getOwnerDocument(), getCanonicalizationMethod(), alg);
         m_signature = temp;
     }
     else {
@@ -368,7 +401,16 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vecto
         DOMDocument* internalDoc=XMLToolingConfig::getConfig().getParser().parse(dsrc);
         
         log.debug("reimporting new DOM into caller-supplied document");
-        cachedDOM=static_cast<DOMElement*>(parentElement->getOwnerDocument()->importNode(internalDoc->getDocumentElement(),true));
+        try {
+            cachedDOM=static_cast<DOMElement*>(parentElement->getOwnerDocument()->importNode(internalDoc->getDocumentElement(),true));
+        }
+        catch (XMLException& ex) {
+            internalDoc->release();
+            auto_ptr_char temp(ex.getMessage());
+            throw XMLParserException(
+                string("Error importing DOM into caller-supplied document: ") + (temp.get() ? temp.get() : "no message")
+                );
+        }
         internalDoc->release();
 
         // Now reload the signature from the DOM.