Refactored Signature signing/validation, various Validator bugs fixed.
authorScott Cantor <cantor.2@osu.edu>
Thu, 18 May 2006 04:21:33 +0000 (04:21 +0000)
committerScott Cantor <cantor.2@osu.edu>
Thu, 18 May 2006 04:21:33 +0000 (04:21 +0000)
18 files changed:
xmltooling/AbstractXMLObject.cpp
xmltooling/Makefile.am
xmltooling/XMLObject.h
xmltooling/impl/UnknownElement.cpp
xmltooling/impl/UnknownElement.h
xmltooling/io/AbstractXMLObjectMarshaller.cpp
xmltooling/io/AbstractXMLObjectMarshaller.h
xmltooling/signature/ContentReference.h [new file with mode: 0644]
xmltooling/signature/Signature.h
xmltooling/signature/SigningContext.h [deleted file]
xmltooling/signature/VerifyingContext.h [deleted file]
xmltooling/signature/impl/XMLSecSignatureImpl.cpp
xmltooling/util/CredentialResolver.h [deleted file]
xmltooling/validation/AbstractValidatingXMLObject.cpp
xmltooling/validation/AbstractValidatingXMLObject.h
xmltooling/validation/ValidatingXMLObject.h
xmltooling/xmltooling.vcproj
xmltoolingtest/SignatureTest.h

index 3111c8d..3a47620 100644 (file)
-/*
-*  Copyright 2001-2006 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.
- */
-
-/**
- * AbstractXMLObject.cpp
- * 
- * An abstract implementation of XMLObject.
- */
-
-#include "internal.h"
-#include "AbstractXMLObject.h"
-#include "exceptions.h"
-
-#include <algorithm>
-#include <log4cpp/Category.hh>
-
-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_parent(NULL), m_elementQname(nsURI, localName, prefix), m_typeQname(NULL)
-{
-    addNamespace(Namespace(nsURI, prefix));
-    if (schemaType) {
-        m_typeQname = new QName(*schemaType);
-        addNamespace(Namespace(m_typeQname->getNamespaceURI(), m_typeQname->getPrefix()));
-    }
-}
-
-AbstractXMLObject::AbstractXMLObject(const AbstractXMLObject& src)
-    : m_namespaces(src.m_namespaces), m_log(src.m_log), m_parent(NULL), m_elementQname(src.m_elementQname), m_typeQname(NULL)
-{
-    if (src.m_typeQname)
-        m_typeQname=new QName(*src.m_typeQname);
-}
-
-XMLCh* AbstractXMLObject::prepareForAssignment(XMLCh* oldValue, const XMLCh* newValue)
-{
-    XMLCh* newString = XMLString::replicate(newValue);
-    XMLString::trim(newString);
-    if (!XMLString::equals(oldValue,newValue)) {
-        releaseThisandParentDOM();
-        XMLString::release(&oldValue);
-        return newString;
-    }
-    XMLString::release(&newString);
-    return oldValue;            
-}
-
-QName* AbstractXMLObject::prepareForAssignment(QName* oldValue, const QName* newValue)
-{
-    if (!oldValue) {
-        if (newValue) {
-            releaseThisandParentDOM();
+/*\r
+*  Copyright 2001-2006 Internet2\r
+ * \r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * AbstractXMLObject.cpp\r
+ * \r
+ * An abstract implementation of XMLObject.\r
+ */\r
+\r
+#include "internal.h"\r
+#include "AbstractXMLObject.h"\r
+#include "exceptions.h"\r
+\r
+#include <algorithm>\r
+#include <log4cpp/Category.hh>\r
+\r
+using namespace xmltooling;\r
+\r
+AbstractXMLObject::AbstractXMLObject(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)\r
+    : m_log(&log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".XMLObject")),\r
+        m_parent(NULL), m_elementQname(nsURI, localName, prefix), m_typeQname(NULL)\r
+{\r
+    addNamespace(Namespace(nsURI, prefix));\r
+    if (schemaType) {\r
+        m_typeQname = new QName(*schemaType);\r
+        addNamespace(Namespace(m_typeQname->getNamespaceURI(), m_typeQname->getPrefix()));\r
+    }\r
+}\r
+\r
+AbstractXMLObject::AbstractXMLObject(const AbstractXMLObject& src)\r
+    : m_namespaces(src.m_namespaces), m_log(src.m_log), m_parent(NULL), m_elementQname(src.m_elementQname), m_typeQname(NULL)\r
+{\r
+    if (src.m_typeQname)\r
+        m_typeQname=new QName(*src.m_typeQname);\r
+}\r
+\r
+XMLCh* AbstractXMLObject::prepareForAssignment(XMLCh* oldValue, const XMLCh* newValue)\r
+{\r
+    XMLCh* newString = XMLString::replicate(newValue);\r
+    XMLString::trim(newString);\r
+    if (!XMLString::equals(oldValue,newValue)) {\r
+        releaseThisandParentDOM();\r
+        XMLString::release(&oldValue);\r
+        return newString;\r
+    }\r
+    XMLString::release(&newString);\r
+    return oldValue;            \r
+}\r
+\r
+QName* AbstractXMLObject::prepareForAssignment(QName* oldValue, const QName* newValue)\r
+{\r
+    if (!oldValue) {\r
+        if (newValue) {\r
+            releaseThisandParentDOM();\r
             Namespace newNamespace(newValue->getNamespaceURI(), newValue->getPrefix());\r
             addNamespace(newNamespace);\r
-            return new QName(*newValue);
-        }
-        return NULL;
-    }
-
-    delete oldValue;
-    releaseThisandParentDOM();
-    if (newValue) {
+            return new QName(*newValue);\r
+        }\r
+        return NULL;\r
+    }\r
+\r
+    delete oldValue;\r
+    releaseThisandParentDOM();\r
+    if (newValue) {\r
         Namespace newNamespace(newValue->getNamespaceURI(), newValue->getPrefix());\r
         addNamespace(newNamespace);\r
         return new QName(*newValue);\r
-    }
-    return NULL;
-}
-
-DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, const DateTime* newValue)
-{
-    if (!oldValue) {
-        if (newValue) {
-            releaseThisandParentDOM();
-            return new DateTime(*newValue);
-        }
-        return NULL;
-    }
-
-    delete oldValue;
-    releaseThisandParentDOM();
-    return newValue ? new DateTime(*newValue) : NULL;
-}
-
-DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, time_t newValue)
-{
-    delete oldValue;
-    releaseThisandParentDOM();
-    DateTime* ret = new DateTime(newValue);
-    ret->parseDateTime();
-    return ret;
-}
-
-DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, const XMLCh* newValue)
-{
-    delete oldValue;
-    releaseThisandParentDOM();
-    DateTime* ret = new DateTime(newValue);
-    ret->parseDateTime();
-    return ret;
-}
-
-XMLObject* AbstractXMLObject::prepareForAssignment(XMLObject* oldValue, XMLObject* newValue)
-{
-    if (newValue && newValue->hasParent())
-        throw XMLObjectException("child XMLObject cannot be added - it is already the child of another XMLObject");
-
-    if (!oldValue) {
-        if (newValue) {
-            releaseThisandParentDOM();
-            newValue->setParent(this);
-        }
-        return newValue;
-    }
-
-    if (oldValue != newValue) {
-        delete oldValue;
-        releaseThisandParentDOM();
-        if (newValue)
-            newValue->setParent(this);
-    }
-
-    return newValue;
-}
+    }\r
+    return NULL;\r
+}\r
+\r
+DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, const DateTime* newValue)\r
+{\r
+    if (!oldValue) {\r
+        if (newValue) {\r
+            releaseThisandParentDOM();\r
+            return new DateTime(*newValue);\r
+        }\r
+        return NULL;\r
+    }\r
+\r
+    delete oldValue;\r
+    releaseThisandParentDOM();\r
+    return newValue ? new DateTime(*newValue) : NULL;\r
+}\r
+\r
+DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, time_t newValue)\r
+{\r
+    delete oldValue;\r
+    releaseThisandParentDOM();\r
+    DateTime* ret = new DateTime(newValue);\r
+    ret->parseDateTime();\r
+    return ret;\r
+}\r
+\r
+DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, const XMLCh* newValue)\r
+{\r
+    delete oldValue;\r
+    releaseThisandParentDOM();\r
+    DateTime* ret = new DateTime(newValue);\r
+    ret->parseDateTime();\r
+    return ret;\r
+}\r
+\r
+XMLObject* AbstractXMLObject::prepareForAssignment(XMLObject* oldValue, XMLObject* newValue)\r
+{\r
+    if (newValue && newValue->hasParent())\r
+        throw XMLObjectException("child XMLObject cannot be added - it is already the child of another XMLObject");\r
+\r
+    if (!oldValue) {\r
+        if (newValue) {\r
+            releaseThisandParentDOM();\r
+            newValue->setParent(this);\r
+        }\r
+        return newValue;\r
+    }\r
+\r
+    if (oldValue != newValue) {\r
+        delete oldValue;\r
+        releaseThisandParentDOM();\r
+        if (newValue)\r
+            newValue->setParent(this);\r
+    }\r
+\r
+    return newValue;\r
+}\r
index c5126d9..963fa87 100644 (file)
@@ -49,8 +49,7 @@ ioinclude_HEADERS = \
 siginclude_HEADERS = \
     signature/KeyInfo.h \
     signature/Signature.h \
-    signature/SigningContext.h \
-    signature/VerifyingContext.h
+    signature/ContentReference.h
 
 utilinclude_HEADERS = \
     util/CredentialResolver.h \
index d32d155..ed750ce 100644 (file)
@@ -35,7 +35,6 @@ using namespace xercesc;
 #ifndef XMLTOOLING_NO_XMLSEC\r
 namespace xmlsignature {\r
     class XMLTOOL_API Signature;\r
-    class XMLTOOL_API SigningContext;\r
 };\r
 #endif\r
 \r
@@ -47,36 +46,6 @@ namespace xmlsignature {
 namespace xmltooling {\r
 \r
     /**\r
-     * Supplies additional information to the marshalling process.\r
-     * Currently this only consists of signature related information.\r
-     */\r
-    class XMLTOOL_API MarshallingContext\r
-    {\r
-        MAKE_NONCOPYABLE(MarshallingContext);\r
-    public:\r
-        /**\r
-         * Default constructor.\r
-         */\r
-        MarshallingContext() {}\r
-        ~MarshallingContext() {}\r
-\r
-#ifndef XMLTOOLING_NO_XMLSEC\r
-        /**\r
-         * Builds a marshalling context with an initial signature/context pair.\r
-         * \r
-         * @param sig   a signature object\r
-         * @param ctx   the signing context to associate with the signature \r
-         */\r
-        MarshallingContext(xmlsignature::Signature* sig, xmlsignature::SigningContext* ctx) {\r
-            m_signingContexts.push_back(std::make_pair(sig,ctx));\r
-        }\r
-        \r
-        /** Array of signing contexts, keyed off of the associated Signature */\r
-        std::vector< std::pair<xmlsignature::Signature*,xmlsignature::SigningContext*> > m_signingContexts;\r
-#endif\r
-    };\r
-\r
-    /**\r
      * Object that represents an XML Element that has been unmarshalled into this C++ object.\r
      */\r
     class XMLTOOL_API XMLObject\r
@@ -244,13 +213,18 @@ namespace xmltooling {
          * marshalled, unless an existing DOM can be reused without creating a new document. \r
          * \r
          * @param document  the DOM document the marshalled element will be placed in, or NULL\r
-         * @param ctx       optional marshalling context\r
+         * @param sigs      ordered array of signatures to create after marshalling is complete\r
          * @return the DOM element representing this XMLObject\r
          * \r
          * @throws MarshallingException thrown if there is a problem marshalling the given object\r
          * @throws SignatureException thrown if a problem occurs during signature creation \r
          */\r
-        virtual DOMElement* marshall(DOMDocument* document=NULL, MarshallingContext* ctx=NULL) const=0;\r
+        virtual DOMElement* marshall(\r
+            DOMDocument* document=NULL\r
+#ifndef XMLTOOLING_NO_XMLSEC\r
+            ,const std::vector<xmlsignature::Signature*>* sigs=NULL\r
+#endif\r
+            ) const=0;\r
         \r
         /**\r
          * Marshalls the XMLObject and appends it as a child of the given parent element.\r
@@ -259,13 +233,18 @@ namespace xmltooling {
          * the Document owning the given Element.\r
          * \r
          * @param parentElement the parent element to append the resulting DOM tree\r
-         * @param ctx       optional marshalling context\r
+         * @param sigs          ordered array of signatures to create after marshalling is complete\r
          * @return the marshalled element tree\r
 \r
          * @throws MarshallingException thrown if the given XMLObject can not be marshalled.\r
          * @throws SignatureException thrown if a problem occurs during signature creation \r
          */\r
-        virtual DOMElement* marshall(DOMElement* parentElement, MarshallingContext* ctx=NULL) const=0;\r
+        virtual DOMElement* marshall(\r
+            DOMElement* parentElement\r
+#ifndef XMLTOOLING_NO_XMLSEC\r
+            ,const std::vector<xmlsignature::Signature*>* sigs=NULL\r
+#endif\r
+            ) const=0;\r
 \r
         /**\r
          * Unmarshalls the given W3C DOM element into the XMLObject.\r
index 09dbbdd..27fcfd9 100644 (file)
@@ -70,7 +70,12 @@ void UnknownElementImpl::serialize(string& s) const
         XMLHelper::serialize(getDOM(),s);\r
 }\r
 \r
-DOMElement* UnknownElementImpl::marshall(DOMDocument* document, MarshallingContext* ctx) const\r
+DOMElement* UnknownElementImpl::marshall(\r
+    DOMDocument* document\r
+#ifndef XMLTOOLING_NO_XMLSEC\r
+    ,const std::vector<xmlsignature::Signature*>* sigs\r
+#endif\r
+    ) const\r
 {\r
 #ifdef _DEBUG\r
     xmltooling::NDC ndc("marshall");\r
@@ -131,7 +136,13 @@ DOMElement* UnknownElementImpl::marshall(DOMDocument* document, MarshallingConte
     return cachedDOM;\r
 }\r
 \r
-DOMElement* UnknownElementImpl::marshall(DOMElement* parentElement, MarshallingContext* ctx) const\r
+\r
+DOMElement* UnknownElementImpl::marshall(\r
+    DOMElement* parentElement\r
+#ifndef XMLTOOLING_NO_XMLSEC\r
+    ,const std::vector<xmlsignature::Signature*>* sigs\r
+#endif\r
+    ) const\r
 {\r
 #ifdef _DEBUG\r
     xmltooling::NDC ndc("marshall");\r
index ea2aafd..18e9cab 100644 (file)
@@ -49,15 +49,26 @@ namespace xmltooling {
 \r
         XMLObject* clone() const;\r
 \r
-        DOMElement* marshall(DOMDocument* document=NULL, MarshallingContext* ctx=NULL) const;\r
-        DOMElement* marshall(DOMElement* parentElement, MarshallingContext* ctx=NULL) const;\r
+        DOMElement* marshall(\r
+            DOMDocument* document=NULL\r
+#ifndef XMLTOOLING_NO_XMLSEC\r
+            ,const std::vector<xmlsignature::Signature*>* sigs=NULL\r
+#endif\r
+            ) const;\r
+\r
+        DOMElement* marshall(\r
+            DOMElement* parentElement\r
+#ifndef XMLTOOLING_NO_XMLSEC\r
+            ,const std::vector<xmlsignature::Signature*>* sigs=NULL\r
+#endif\r
+            ) const;\r
         XMLObject* unmarshall(DOMElement* element, bool bindDocument=false);\r
         \r
     protected:\r
         void setDocumentElement(DOMDocument* document, DOMElement* element) const {\r
             DOMElement* documentRoot = document->getDocumentElement();\r
             if (documentRoot)\r
-                document->replaceChild(documentRoot, element);\r
+                document->replaceChild(element, documentRoot);\r
             else\r
                 document->appendChild(element);\r
         }\r
index 8567d59..5d22362 100644 (file)
@@ -44,7 +44,12 @@ using namespace std;
 \r
 #define XT_log (*static_cast<Category*>(m_log))\r
 \r
-DOMElement* AbstractXMLObjectMarshaller::marshall(DOMDocument* document, MarshallingContext* ctx) const\r
+DOMElement* AbstractXMLObjectMarshaller::marshall(\r
+    DOMDocument* document\r
+#ifndef XMLTOOLING_NO_XMLSEC\r
+    ,const std::vector<xmlsignature::Signature*>* sigs\r
+#endif\r
+    ) const\r
 {\r
 #ifdef _DEBUG\r
     xmltooling::NDC ndc("marshall");\r
@@ -87,8 +92,11 @@ DOMElement* AbstractXMLObjectMarshaller::marshall(DOMDocument* document, Marshal
             getElementQName().getNamespaceURI(), getElementQName().getLocalPart()\r
             );\r
         setDocumentElement(document, domElement);\r
-        marshallInto(domElement, ctx);\r
-\r
+#ifndef XMLTOOLING_NO_XMLSEC\r
+        marshallInto(domElement, sigs);\r
+#else\r
+        marshallInto(domElement);\r
+#endif\r
         //Recache the DOM.\r
         XT_log.debug("caching DOM for XMLObject (document is %sbound)", bindDocument ? "" : "not ");\r
         setDOM(domElement, bindDocument);\r
@@ -105,7 +113,12 @@ DOMElement* AbstractXMLObjectMarshaller::marshall(DOMDocument* document, Marshal
     }\r
 }\r
 \r
-DOMElement* AbstractXMLObjectMarshaller::marshall(DOMElement* parentElement, MarshallingContext* ctx) const\r
+DOMElement* AbstractXMLObjectMarshaller::marshall(\r
+    DOMElement* parentElement\r
+#ifndef XMLTOOLING_NO_XMLSEC\r
+    ,const std::vector<xmlsignature::Signature*>* sigs\r
+#endif\r
+    ) const\r
 {\r
 #ifdef _DEBUG\r
     xmltooling::NDC ndc("marshall");\r
@@ -141,7 +154,11 @@ DOMElement* AbstractXMLObjectMarshaller::marshall(DOMElement* parentElement, Mar
         getElementQName().getNamespaceURI(), getElementQName().getLocalPart()\r
         );\r
     parentElement->appendChild(domElement);\r
-    marshallInto(domElement, ctx);\r
+#ifndef XMLTOOLING_NO_XMLSEC\r
+    marshallInto(domElement, sigs);\r
+#else\r
+    marshallInto(domElement);\r
+#endif\r
 \r
     //Recache the DOM.\r
     XT_log.debug("caching DOM for XMLObject");\r
@@ -151,16 +168,12 @@ DOMElement* AbstractXMLObjectMarshaller::marshall(DOMElement* parentElement, Mar
     return domElement;\r
 }\r
 \r
+void AbstractXMLObjectMarshaller::marshallInto(\r
+    DOMElement* targetElement\r
 #ifndef XMLTOOLING_NO_XMLSEC\r
-    class _signit : public unary_function<const pair<Signature*,SigningContext*>&, void> {\r
-    public:\r
-        void operator()(const pair<Signature*,SigningContext*>& p) const {\r
-            p.first->sign(*(p.second));\r
-        }\r
-    };\r
+    ,const std::vector<xmlsignature::Signature*>* sigs\r
 #endif\r
-\r
-void AbstractXMLObjectMarshaller::marshallInto(DOMElement* targetElement, MarshallingContext* ctx) const\r
+    ) const\r
 {\r
     if (getElementQName().hasPrefix())\r
         targetElement->setPrefix(getElementQName().getPrefix());\r
@@ -171,8 +184,8 @@ void AbstractXMLObjectMarshaller::marshallInto(DOMElement* targetElement, Marsha
     marshallElementContent(targetElement);\r
 \r
 #ifndef XMLTOOLING_NO_XMLSEC\r
-    if (ctx) {\r
-        for_each(ctx->m_signingContexts.begin(),ctx->m_signingContexts.end(),_signit());\r
+    if (sigs) {\r
+        for_each(sigs->begin(),sigs->end(),mem_fun<void,Signature>(&Signature::sign));\r
     }\r
 #endif\r
 }\r
index f52ae1c..18d9056 100644 (file)
@@ -40,9 +40,19 @@ namespace xmltooling {
     public:\r
         virtual ~AbstractXMLObjectMarshaller() {}\r
 \r
-        DOMElement* marshall(DOMDocument* document=NULL, MarshallingContext* ctx=NULL) const;\r
+        DOMElement* marshall(\r
+            DOMDocument* document=NULL\r
+#ifndef XMLTOOLING_NO_XMLSEC\r
+            ,const std::vector<xmlsignature::Signature*>* sigs=NULL\r
+#endif\r
+            ) const;\r
 \r
-        DOMElement* marshall(DOMElement* parentElement, MarshallingContext* ctx=NULL) const;\r
+        DOMElement* marshall(\r
+            DOMElement* parentElement\r
+#ifndef XMLTOOLING_NO_XMLSEC\r
+            ,const std::vector<xmlsignature::Signature*>* sigs=NULL\r
+#endif\r
+            ) const;\r
         \r
     protected:\r
         AbstractXMLObjectMarshaller() {}\r
@@ -57,7 +67,7 @@ namespace xmltooling {
         void setDocumentElement(DOMDocument* document, DOMElement* element) const {\r
             DOMElement* documentRoot = document->getDocumentElement();\r
             if (documentRoot)\r
-                document->replaceChild(documentRoot, element);\r
+                document->replaceChild(element, documentRoot);\r
             else\r
                 document->appendChild(element);\r
         }\r
@@ -72,7 +82,12 @@ namespace xmltooling {
          * @throws MarshallingException thrown if there is a problem marshalling the object\r
          * @throws SignatureException thrown if a problem occurs during signature creation \r
          */\r
-        void marshallInto(DOMElement* targetElement, MarshallingContext* ctx) const;\r
+        void marshallInto(\r
+            DOMElement* targetElement\r
+#ifndef XMLTOOLING_NO_XMLSEC\r
+            ,const std::vector<xmlsignature::Signature*>* sigs\r
+#endif\r
+            ) const;\r
     \r
         /**\r
          * Creates an xsi:type attribute, corresponding to the given type of the XMLObject, on the DOM element.\r
diff --git a/xmltooling/signature/ContentReference.h b/xmltooling/signature/ContentReference.h
new file mode 100644 (file)
index 0000000..7760de6
--- /dev/null
@@ -0,0 +1,69 @@
+/*\r
+ *  Copyright 2001-2006 Internet2\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * @file ContentReference.h\r
+ * \r
+ * Interface for creating signature references \r
+ */\r
+\r
+#if !defined(__xmltooling_sigref_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
+#define __xmltooling_sigref_h__\r
+\r
+#include <vector>\r
+#include <xsec/dsig/DSIGSignature.hpp>\r
+\r
+#if defined (_MSC_VER)\r
+    #pragma warning( push )\r
+    #pragma warning( disable : 4250 4251 )\r
+#endif\r
+\r
+namespace xmlsignature {\r
+\r
+    /**\r
+     * Interface for creating signature references based on application requirements.\r
+     */\r
+    class XMLTOOL_API ContentReference\r
+    {\r
+        MAKE_NONCOPYABLE(ContentReference);\r
+    public:\r
+        virtual ~ContentReference() {}\r
+\r
+        /**\r
+         * Given a native signature, asks the object to create the reference(s).\r
+         * \r
+         * @param sig   native signature interface\r
+         */\r
+        virtual void createReferences(DSIGSignature* sig)=0;\r
+        \r
+        /**\r
+         * Creates an independent copy of this object.\r
+         * \r
+         * @return  the cloned object\r
+         */\r
+        virtual ContentReference* clone() const=0;\r
+\r
+    protected:\r
+        ContentReference() {}\r
+    };\r
+\r
+};\r
+\r
+#if defined (_MSC_VER)\r
+    #pragma warning( pop )\r
+#endif\r
+\r
+#endif /* __xmltooling_sigref_h__ */\r
index 3dba1b4..14549ec 100644 (file)
 \r
 #include <xmltooling/exceptions.h>\r
 #include <xmltooling/XMLObjectBuilder.h>\r
-#include <xmltooling/signature/SigningContext.h>\r
-#include <xmltooling/signature/VerifyingContext.h>\r
+#include <xmltooling/signature/KeyInfo.h>\r
+#include <xmltooling/signature/ContentReference.h>\r
+#include <xmltooling/validation/ValidatingXMLObject.h>\r
 #include <xmltooling/util/XMLConstants.h>\r
 \r
+#include <xsec/dsig/DSIGSignature.hpp>\r
+\r
 /**\r
  * @namespace xmlsignature\r
  * Public namespace of XML Signature classes\r
@@ -40,7 +43,7 @@ namespace xmlsignature {
      * The default signature settings include Exclusive c14n w/o comments, SHA-1 digests,\r
      * and RSA-SHA1 signing. \r
      */\r
-    class XMLTOOL_API Signature : public virtual xmltooling::XMLObject\r
+    class XMLTOOL_API Signature : public virtual xmltooling::ValidatingXMLObject\r
     {\r
     public:\r
         virtual ~Signature() {}\r
@@ -61,24 +64,68 @@ namespace xmlsignature {
          * @param sm    the signature algorithm\r
          */\r
         virtual void setSignatureAlgorithm(const XMLCh* sm)=0;\r
-        \r
+\r
         /**\r
-         * Applies an XML signature based on the supplied context.\r
+         * Sets the signing key used to create the signature.\r
          * \r
-         * @param ctx   the signing context that determines the signature's content\r
-         * @throws SignatureException   thrown if the signing operation fails\r
+         * @param signingKey the secret/private key used to create the signature\r
          */\r
-        virtual void sign(SigningContext& ctx)=0;\r
-        \r
+        virtual void setSigningKey(XSECCryptoKey* signingKey)=0;\r
+\r
+        /**\r
+         * Sets a KeyInfo object to embed in the Signature.\r
+         * \r
+         * @param keyInfo   pointer to a KeyInfo object, or NULL\r
+         */\r
+        virtual void setKeyInfo(KeyInfo* keyInfo)=0;\r
+\r
+        /**\r
+         * Gets the KeyInfo object associated with the Signature.\r
+         * This is <strong>NOT</strong> provided for access to the\r
+         * data associated with an unmarshalled signature. It is\r
+         * used only in the creation of signatures. Access to data\r
+         * for validation purposes is provided through the native\r
+         * DSIGSignature object.\r
+         * \r
+         * @return  pointer to a KeyInfo object, or NULL\r
+         */\r
+        virtual KeyInfo* getKeyInfo() const=0;\r
+\r
         /**\r
-         * Verifies an XML signature based on the supplied context.\r
+         * Sets the ContentReference object to the Signature to be applied\r
+         * when the signature is created.\r
          * \r
-         * @param ctx   the verifying context that validates the signature's content\r
-         * @throws SignatureException   thrown if the verifying operation fails\r
+         * @param reference the reference to attach, or NULL \r
          */\r
-        virtual void verify(const VerifyingContext& ctx) const=0;\r
+        virtual void setContentReference(ContentReference* reference)=0;\r
+\r
+        /**\r
+         * Gets the ContentReference object associated with the Signature.\r
+         * This is <strong>NOT</strong> provided for access to the\r
+         * data associated with an unmarshalled signature. It is\r
+         * used only in the creation of signatures. Access to data\r
+         * for validation purposes is provided through the native\r
+         * DSIGSignature object.\r
+         * \r
+         * @return  pointer to a ContentReference object, or NULL\r
+         */\r
+        virtual ContentReference* getContentReference() const=0;\r
+\r
         \r
         /**\r
+         * Gets the native Apache signature object, if present.\r
+         * \r
+         * @return  the native Apache signature interface\r
+         */\r
+        virtual DSIGSignature* getXMLSignature() const=0;\r
+\r
+        /**\r
+         * Compute and append the signature based on the assigned\r
+         * ContentReference, KeyInfo, and signing key.\r
+         */\r
+        virtual void sign()=0;\r
+\r
+        /**\r
          * Type-safe clone operation.\r
          * \r
          * @return  copy of object\r
@@ -106,7 +153,7 @@ namespace xmlsignature {
          */\r
         virtual Signature* buildObject() const;\r
 \r
-        static Signature* newSignature() {\r
+        static Signature* buildSignature() {\r
             const SignatureBuilder* b = dynamic_cast<const SignatureBuilder*>(\r
                 xmltooling::XMLObjectBuilder::getBuilder(\r
                     xmltooling::QName(xmltooling::XMLConstants::XMLSIG_NS,Signature::LOCAL_NAME)\r
diff --git a/xmltooling/signature/SigningContext.h b/xmltooling/signature/SigningContext.h
deleted file mode 100644 (file)
index f04b724..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file SigningContext.h\r
- * \r
- * Interface to signing process supplied by a signing application \r
- */\r
-\r
-#if !defined(__xmltooling_signctx_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
-#define __xmltooling_signctx_h__\r
-\r
-#include <xmltooling/signature/KeyInfo.h>\r
-#include <xmltooling/util/CredentialResolver.h>\r
-\r
-#include <vector>\r
-#include <xsec/dsig/DSIGSignature.hpp>\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( push )\r
-    #pragma warning( disable : 4250 4251 )\r
-#endif\r
-\r
-namespace xmlsignature {\r
-\r
-    /**\r
-     * Interface to signing process supplied by a signing application\r
-     */\r
-    class XMLTOOL_API SigningContext\r
-    {\r
-        MAKE_NONCOPYABLE(SigningContext);\r
-    public:\r
-        virtual ~SigningContext() {}\r
-\r
-        /**\r
-         * Given a "blank" native signature, asks the context to define the\r
-         * appropriate signature transforms, references, etc. The context\r
-         * should return true iff the necessary ds:KeyInfo information was\r
-         * also attached.\r
-         * \r
-         * @param sig   native signature interface\r
-         * @return      indicator whether ds:KeyInfo was created by context\r
-         */\r
-        virtual bool createSignature(DSIGSignature* sig)=0;\r
-        \r
-        /**\r
-         * Gets a reference to a credential resolver.\r
-         * The resolver's certificates will be included in the signature only\r
-         * if the context returns false when creating the signature and returns\r
-         * NULL from the getKeyInfo() method.\r
-         * \r
-         * \r
-         * @return  a resolver to the credentials to sign with\r
-         */\r
-        virtual xmltooling::CredentialResolver& getCredentialResolver()=0;\r
-\r
-        /**\r
-         * Gets a KeyInfo structure to embed.\r
-         * Ownership of the object MUST be transferred to the caller.\r
-         * \r
-         * @return  pointer to a KeyInfo structure, will be freed by caller\r
-         */\r
-        virtual KeyInfo* getKeyInfo()=0;\r
-\r
-    protected:\r
-        SigningContext() {}\r
-    };\r
-\r
-};\r
-\r
-#if defined (_MSC_VER)\r
-    #pragma warning( pop )\r
-#endif\r
-\r
-#endif /* __xmltooling_signctx_h__ */\r
diff --git a/xmltooling/signature/VerifyingContext.h b/xmltooling/signature/VerifyingContext.h
deleted file mode 100644 (file)
index 7e0e436..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file VerifyingContext.h\r
- * \r
- * Interface to signature verification process supplied by a relying party \r
- */\r
-\r
-#if !defined(__xmltooling_verctx_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
-#define __xmltooling_verctx_h__\r
-\r
-#include <xsec/dsig/DSIGSignature.hpp>\r
-\r
-namespace xmlsignature {\r
-\r
-    /**\r
-     * Interface to signature verification process supplied by a relying party\r
-     */\r
-    class XMLTOOL_API VerifyingContext\r
-    {\r
-        MAKE_NONCOPYABLE(VerifyingContext);\r
-    public:\r
-        virtual ~VerifyingContext() {}\r
-\r
-        /**\r
-         * Given a native signature, asks the context to verify the signature\r
-         * in accordance with the relying party's requirements.\r
-         * \r
-         * @param sig   native signature object\r
-         * \r
-         * @throws SignatureException   raised if signature is invalid\r
-         */\r
-        virtual void verifySignature(DSIGSignature* sig) const=0;\r
-        \r
-    protected:\r
-        VerifyingContext() {}\r
-    };\r
-\r
-};\r
-\r
-#endif /* __xmltooling_verctx_h__ */\r
index cf3afd2..5218d57 100644 (file)
@@ -27,6 +27,7 @@
 #include "util/NDC.h"\r
 #include "util/XMLConstants.h"\r
 #include "util/XMLHelper.h"\r
+#include "validation/ValidatingXMLObject.h"\r
 \r
 #include <log4cpp/Category.hh>\r
 #include <xercesc/framework/MemBufInputSource.hpp>\r
@@ -48,36 +49,70 @@ using namespace std;
 \r
 namespace xmlsignature {\r
     \r
-    class XMLTOOL_DLLLOCAL XMLSecSignatureImpl : public UnknownElementImpl, public virtual Signature\r
+    class XMLTOOL_DLLLOCAL XMLSecSignatureImpl\r
+        : public UnknownElementImpl, public virtual Signature, public virtual ValidatingXMLObject\r
     {\r
     public:\r
         XMLSecSignatureImpl() : UnknownElementImpl(XMLConstants::XMLSIG_NS, Signature::LOCAL_NAME, XMLConstants::XMLSIG_PREFIX),\r
-            m_signature(NULL), m_c14n(NULL), m_sm(NULL) {}\r
+            m_signature(NULL), m_c14n(NULL), m_sm(NULL), m_key(NULL), m_keyInfo(NULL), m_reference(NULL) {}\r
         virtual ~XMLSecSignatureImpl();\r
         \r
         void releaseDOM();\r
+        void releaseChildrenDOM(bool propagateRelease=true) {\r
+            if (m_keyInfo) {\r
+                m_keyInfo->releaseDOM();\r
+                if (propagateRelease)\r
+                    m_keyInfo->releaseChildrenDOM();\r
+            }\r
+        }\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
+        DOMElement* marshall(DOMDocument* document=NULL, const vector<Signature*>* sigs=NULL) const;\r
+        DOMElement* marshall(DOMElement* parentElement, const vector<Signature*>* sigs=NULL) const;\r
         XMLObject* unmarshall(DOMElement* element, bool bindDocument=false);\r
         \r
         // Getters\r
         const XMLCh* getCanonicalizationMethod() const { return m_c14n ? m_c14n : DSIGConstants::s_unicodeStrURIEXC_C14N_NOC; }\r
         const XMLCh* getSignatureAlgorithm() const { return m_sm ? m_sm : DSIGConstants::s_unicodeStrURIRSA_SHA1; }\r
-\r
+        KeyInfo* getKeyInfo() const { return m_keyInfo; }\r
+        ContentReference* getContentReference() const { return m_reference; }\r
+        DSIGSignature* getXMLSignature() const { return m_signature; }\r
+        \r
         // Setters\r
         void setCanonicalizationMethod(const XMLCh* c14n) { m_c14n = prepareForAssignment(m_c14n,c14n); }\r
         void setSignatureAlgorithm(const XMLCh* sm) { m_sm = prepareForAssignment(m_sm,sm); }\r
+        void setSigningKey(XSECCryptoKey* signingKey) {\r
+            delete m_key;\r
+            m_key=signingKey;\r
+            if (m_key)\r
+                releaseThisandParentDOM();\r
+        }\r
+        void setKeyInfo(KeyInfo* keyInfo) {\r
+            prepareForAssignment(m_keyInfo, keyInfo);\r
+            m_keyInfo=keyInfo;\r
+        }\r
+        void setContentReference(ContentReference* reference) {\r
+            delete m_reference;\r
+            m_reference=reference;\r
+            releaseThisandParentDOM();\r
+        }\r
+        \r
+        void sign();\r
 \r
-        void sign(SigningContext& ctx);\r
-        void verify(const VerifyingContext& ctx) const;\r
+        void registerValidator(Validator* validator);\r
+        void deregisterValidator(Validator* validator);\r
+        void deregisterAll();\r
+        void validate(bool validateDescendants) const;\r
 \r
     private:\r
         mutable DSIGSignature* m_signature;\r
         XMLCh* m_c14n;\r
         XMLCh* m_sm;\r
+        XSECCryptoKey* m_key;\r
+        KeyInfo* m_keyInfo;\r
+        ContentReference* m_reference;\r
+        vector<Validator*> m_validators;\r
     };\r
     \r
 };\r
@@ -94,6 +129,10 @@ XMLSecSignatureImpl::~XMLSecSignatureImpl()
 \r
     XMLString::release(&m_c14n);\r
     XMLString::release(&m_sm);\r
+    delete m_key;\r
+    delete m_keyInfo;\r
+    delete m_reference;\r
+    for_each(m_validators.begin(),m_validators.end(),cleanup<Validator>());\r
 }\r
 \r
 void XMLSecSignatureImpl::releaseDOM()\r
@@ -119,6 +158,14 @@ Signature* XMLSecSignatureImpl::cloneSignature() const
 \r
     ret->m_c14n=XMLString::replicate(m_c14n);\r
     ret->m_sm=XMLString::replicate(m_sm);\r
+    if (m_key)\r
+        ret->m_key=m_key->clone();\r
+    if (m_keyInfo)\r
+        ret->m_keyInfo=m_keyInfo->cloneKeyInfo();\r
+    if (m_reference)\r
+        ret->m_reference=m_reference->clone();\r
+\r
+    xmltooling::clone(m_validators,ret->m_validators);\r
 \r
     // If there's no XML locally, serialize this object into the new one, otherwise just copy it over.\r
     if (m_xml.empty())\r
@@ -129,47 +176,27 @@ Signature* XMLSecSignatureImpl::cloneSignature() const
     return ret;\r
 }\r
 \r
-class _addcert : public std::binary_function<DSIGKeyInfoX509*,XSECCryptoX509*,void> {\r
-public:\r
-    void operator()(DSIGKeyInfoX509* bag, XSECCryptoX509* cert) const {\r
-        safeBuffer& buf=cert->getDEREncodingSB();\r
-        bag->appendX509Certificate(buf.sbStrToXMLCh());\r
-    }\r
-};\r
-\r
-void XMLSecSignatureImpl::sign(SigningContext& ctx)\r
+void XMLSecSignatureImpl::sign()\r
 {\r
     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature");\r
     log.debug("applying signature");\r
 \r
     if (!m_signature)\r
         throw SignatureException("Only a marshalled Signature object can be signed.");\r
+    else if (!m_key)\r
+        throw SignatureException("No signing key available for signature creation.");\r
+    else if (!m_reference)\r
+        throw SignatureException("No ContentReference object set for signature creation.");\r
 \r
     try {\r
-        log.debug("creating signature content");\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
+        log.debug("creating signature reference(s)");\r
+        m_reference->createReferences(m_signature);\r
+        if (m_keyInfo) {\r
+            m_keyInfo->marshall(getDOM());\r
         }\r
         \r
         log.debug("computing signature");\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->setSigningKey(m_key->clone());\r
         m_signature->sign();\r
     }\r
     catch(XSECException& e) {\r
@@ -181,27 +208,7 @@ void XMLSecSignatureImpl::sign(SigningContext& ctx)
     }\r
 }\r
 \r
-void XMLSecSignatureImpl::verify(const VerifyingContext& ctx) const\r
-{\r
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".Signature");\r
-    log.debug("verifying signature");\r
-\r
-    if (!m_signature)\r
-        throw SignatureException("Only a marshalled Signature object can be verified.");\r
-\r
-    try {\r
-        ctx.verifySignature(m_signature);\r
-    }\r
-    catch(XSECException& e) {\r
-        auto_ptr_char temp(e.getMsg());\r
-        throw SignatureException(string("Caught an XMLSecurity exception verifying signature: ") + temp.get());\r
-    }\r
-    catch(XSECCryptoException& e) {\r
-        throw SignatureException(string("Caught an XMLSecurity exception verifying signature: ") + e.getMsg());\r
-    }\r
-}\r
-\r
-DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, MarshallingContext* ctx) const\r
+DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, const vector<Signature*>* sigs) const\r
 {\r
 #ifdef _DEBUG\r
     xmltooling::NDC ndc("marshall");\r
@@ -310,7 +317,7 @@ DOMElement* XMLSecSignatureImpl::marshall(DOMDocument* document, MarshallingCont
     return cachedDOM;\r
 }\r
 \r
-DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, MarshallingContext* ctx) const\r
+DOMElement* XMLSecSignatureImpl::marshall(DOMElement* parentElement, const vector<Signature*>* sigs) const\r
 {\r
 #ifdef _DEBUG\r
     xmltooling::NDC ndc("marshall");\r
@@ -423,6 +430,49 @@ XMLObject* XMLSecSignatureImpl::unmarshall(DOMElement* element, bool bindDocumen
     return this;\r
 }\r
 \r
+void XMLSecSignatureImpl::registerValidator(Validator* validator)\r
+{\r
+    m_validators.push_back(validator);\r
+}\r
+\r
+void XMLSecSignatureImpl::deregisterValidator(Validator* validator)\r
+{\r
+    for (vector<Validator*>::iterator i=m_validators.begin(); i!=m_validators.end(); i++) {\r
+        if ((*i)==validator) {\r
+            m_validators.erase(i);\r
+            return;\r
+        }\r
+    }\r
+}\r
+\r
+void XMLSecSignatureImpl::deregisterAll()\r
+{\r
+    for_each(m_validators.begin(),m_validators.end(),cleanup<Validator>());\r
+    m_validators.clear();\r
+}\r
+\r
+class _validate : public binary_function<const XMLObject*,bool,void> {\r
+public:\r
+    void operator()(const XMLObject* obj, bool propagate) const {\r
+        const ValidatingXMLObject* val = dynamic_cast<const ValidatingXMLObject*>(obj);\r
+        if (val) {\r
+            val->validate(propagate);\r
+        }\r
+    }\r
+};\r
+\r
+void XMLSecSignatureImpl::validate(bool validateDescendants) const\r
+{\r
+    for_each(\r
+        m_validators.begin(),m_validators.end(),\r
+        bind2nd(mem_fun<void,Validator,const XMLObject*>(&Validator::validate),this)\r
+        );\r
+    \r
+    if (validateDescendants && m_keyInfo) {\r
+        m_keyInfo->validate(validateDescendants);\r
+    }\r
+}\r
+\r
 Signature* SignatureBuilder::buildObject(\r
     const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType\r
     ) const\r
diff --git a/xmltooling/util/CredentialResolver.h b/xmltooling/util/CredentialResolver.h
deleted file mode 100644 (file)
index f325b4c..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*\r
- *  Copyright 2001-2006 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/**\r
- * @file CredentialResolver.h\r
- * \r
- * Provides access to keys and certificates.\r
- */\r
-\r
-#if !defined(__xmltooling_credres_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
-#define __xmltooling_credres_h__\r
-\r
-#include <xmltooling/Lockable.h>\r
-\r
-#include <vector>\r
-#include <xsec/enc/XSECCryptoKey.hpp>\r
-#include <xsec/enc/XSECCryptoX509.hpp>\r
-\r
-namespace xmltooling {\r
-\r
-    /**\r
-     * An abstract interface to credential formats like files, keystores, hardware tokens, etc.\r
-     * All non-const methods require that the interface be locked.\r
-     */\r
-    class XMLTOOL_API CredentialResolver : public virtual Lockable\r
-    {\r
-    MAKE_NONCOPYABLE(CredentialResolver);\r
-    public:\r
-        virtual ~CredentialResolver() {}\r
-\r
-        /**\r
-         * Returns an identifier for the credential.\r
-         * \r
-         * @return      the identifier\r
-         */\r
-        virtual const char* getId() const=0;\r
-\r
-        /**\r
-         * Gets the public key associated with the credential.\r
-         * The caller <strong>MUST NOT</strong> modify the object.\r
-         * \r
-         * @return      the public key, or NULL\r
-         */\r
-        virtual XSECCryptoKey* getPublicKey()=0;\r
-\r
-        /**\r
-         * Gets the private key associated with the credential.\r
-         * The caller <strong>MUST NOT</strong> modify the object.\r
-         * \r
-         * @return      the private key, or NULL\r
-         */\r
-        virtual XSECCryptoKey* getPrivateKey()=0;\r
-\r
-        /**\r
-         * Gets the certificate chain associated with the credential.\r
-         * The caller <strong>MUST NOT</strong> modify the objects.\r
-         * The EE certificate <strong>MUST</strong> be first.\r
-         * \r
-         * @return      a chain of certificates, or NULL\r
-         */\r
-        virtual const std::vector<XSECCryptoX509*>* getX509Certificates()=0;\r
-    \r
-    protected:\r
-        CredentialResolver() {}\r
-    };\r
-\r
-};\r
-\r
-#endif /* __xmltooling_credres_h__ */\r
index 6df3ab4..5e50d3e 100644 (file)
@@ -49,24 +49,31 @@ AbstractValidatingXMLObject::~AbstractValidatingXMLObject()
     delete m_validators;\r
 }\r
 \r
-void AbstractValidatingXMLObject::registerValidator(Validator* validator) const\r
+void AbstractValidatingXMLObject::registerValidator(Validator* validator)\r
 {\r
     if (!m_validators)\r
         m_validators=new ValidatorWrapper();\r
     m_validators->v.push_back(validator);\r
 }\r
 \r
-void AbstractValidatingXMLObject::deregisterValidator(Validator* validator) const\r
+void AbstractValidatingXMLObject::deregisterValidator(Validator* validator)\r
 {\r
     if (m_validators) {\r
         for (std::vector<Validator*>::iterator i=m_validators->v.begin(); i!=m_validators->v.end(); i++) {\r
-            if ((*i)==validator)\r
+            if ((*i)==validator) {\r
                 m_validators->v.erase(i);\r
                 return;\r
+            }\r
         }\r
     }\r
 }\r
 \r
+void AbstractValidatingXMLObject::deregisterAll()\r
+{\r
+    delete m_validators;\r
+    m_validators=NULL;\r
+}\r
+\r
 class _validate : public binary_function<const XMLObject*,bool,void> {\r
 public:\r
     void operator()(const XMLObject* obj, bool propagate) const {\r
index 0eda2c6..5252e50 100644 (file)
@@ -44,12 +44,17 @@ namespace xmltooling {
         /**\r
          * @see ValidatingXMLObject::registerValidator()\r
          */\r
-        void registerValidator(Validator* validator) const;\r
+        void registerValidator(Validator* validator);\r
         \r
         /**\r
          * @see ValidatingXMLObject::deregisterValidator()\r
          */\r
-        void deregisterValidator(Validator* validator) const;\r
+        void deregisterValidator(Validator* validator);\r
+\r
+        /**\r
+         * @see ValidatingXMLObject::deregisterAll()\r
+         */\r
+        void deregisterAll();\r
         \r
         /**\r
          * @see ValidatingXMLObject::validate()\r
index 07d4a0e..0943be5 100644 (file)
@@ -51,14 +51,19 @@ namespace xmltooling {
          * \r
          * @param validator the validator\r
          */\r
-        virtual void registerValidator(Validator* validator) const=0;\r
+        virtual void registerValidator(Validator* validator)=0;\r
         \r
         /**\r
          * Deregisters a validator for this XMLObject.\r
          * \r
          * @param validator the validator\r
          */\r
-        virtual void deregisterValidator(Validator* validator) const=0;\r
+        virtual void deregisterValidator(Validator* validator)=0;\r
+\r
+        /**\r
+         * Deregisters all validators for this XMLObject.\r
+         */\r
+        virtual void deregisterAll()=0;\r
         \r
         /**\r
          * Validates this XMLObject against all registered validators.\r
index 525480e..146d950 100644 (file)
                                Name="signature"\r
                                >\r
                                <File\r
-                                       RelativePath=".\signature\KeyInfo.h"\r
+                                       RelativePath=".\signature\ContentReference.h"\r
                                        >\r
                                </File>\r
                                <File\r
-                                       RelativePath=".\signature\Signature.h"\r
+                                       RelativePath=".\signature\KeyInfo.h"\r
                                        >\r
                                </File>\r
                                <File\r
-                                       RelativePath=".\signature\SigningContext.h"\r
+                                       RelativePath=".\signature\Signature.h"\r
                                        >\r
                                </File>\r
                        </Filter>\r
index 62bd6a3..2312f8e 100644 (file)
 #include <xsec/enc/XSECKeyInfoResolverDefault.hpp>\r
 #include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>\r
 #include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>\r
+#include <xsec/enc/XSECCryptoException.hpp>\r
+#include <xsec/framework/XSECException.hpp>\r
 \r
-class TestContext : public SigningContext, public VerifyingContext, CredentialResolver\r
+class TestContext : public ContentReference\r
 {\r
-    XSECCryptoKey* m_key;\r
-    vector<XSECCryptoX509*> m_certs;\r
     XMLCh* m_uri;\r
     \r
 public:\r
     TestContext(const XMLCh* uri) {\r
-        string keypath=data_path + "key.pem";\r
-        BIO* in=BIO_new(BIO_s_file_internal());\r
-        if (in && BIO_read_filename(in,keypath.c_str())>0) {\r
-            EVP_PKEY* pkey=PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);\r
-            if (pkey) {\r
-                m_key=new OpenSSLCryptoKeyRSA(pkey);\r
-                EVP_PKEY_free(pkey);\r
-            }\r
-        }\r
-        if (in) BIO_free(in);\r
-        TS_ASSERT(m_key!=NULL);\r
-\r
-        string certpath=data_path + "cert.pem";\r
-        in=BIO_new(BIO_s_file_internal());\r
-        if (in && BIO_read_filename(in,certpath.c_str())>0) {\r
-            X509* x=NULL;\r
-            while (x=PEM_read_bio_X509(in,NULL,NULL,NULL)) {\r
-                m_certs.push_back(new OpenSSLCryptoX509(x));\r
-                X509_free(x);\r
-            }\r
-        }\r
-        if (in) BIO_free(in);\r
-        TS_ASSERT(m_certs.size()>0);\r
-        \r
         m_uri=XMLString::replicate(uri);\r
     }\r
     \r
     virtual ~TestContext() {\r
-        delete m_key;\r
-        for_each(m_certs.begin(),m_certs.end(),xmltooling::cleanup<XSECCryptoX509>());\r
         XMLString::release(&m_uri);\r
     }\r
 \r
-    bool createSignature(DSIGSignature* sig) {\r
+    ContentReference* clone() const {\r
+        return new TestContext(m_uri);\r
+    }\r
+\r
+    void createReferences(DSIGSignature* sig) {\r
         DSIGReference* ref=sig->createReference(m_uri);\r
         ref->appendEnvelopedSignatureTransform();\r
         ref->appendCanonicalizationTransform(CANON_C14NE_NOC);\r
-        return false;\r
+    }\r
+};\r
+\r
+class TestValidator : public Validator\r
+{\r
+    XMLCh* m_uri;\r
+    \r
+public:\r
+    TestValidator(const XMLCh* uri) {\r
+        m_uri=XMLString::replicate(uri);\r
+    }\r
+    \r
+    virtual ~TestValidator() {\r
+        XMLString::release(&m_uri);\r
+    }\r
+\r
+    Validator* clone() const {\r
+        return new TestValidator(m_uri);\r
     }\r
 \r
-    void verifySignature(DSIGSignature* sig) const {\r
+    void validate(const XMLObject* xmlObject) const {\r
+        DSIGSignature* sig=dynamic_cast<const Signature*>(xmlObject)->getXMLSignature();\r
+        if (!sig)\r
+            throw SignatureException("Only a marshalled Signature object can be verified.");\r
         const XMLCh* uri=sig->getReferenceList()->item(0)->getURI();\r
         TSM_ASSERT_SAME_DATA("Reference URI does not match.",uri,m_uri,XMLString::stringLen(uri));\r
         XSECKeyInfoResolverDefault resolver;\r
         sig->setKeyInfoResolver(&resolver); // It will clone the resolver for us.\r
-        sig->verify();\r
+        try {\r
+            if (!sig->verify())\r
+                throw SignatureException("Signature did not verify.");\r
+        }\r
+        catch(XSECException& e) {\r
+            auto_ptr_char temp(e.getMsg());\r
+            throw SignatureException(string("Caught an XMLSecurity exception verifying signature: ") + temp.get());\r
+        }\r
+        catch(XSECCryptoException& e) {\r
+            throw SignatureException(string("Caught an XMLSecurity exception verifying signature: ") + e.getMsg());\r
+        }\r
+    }\r
+};\r
+\r
+class _addcert : public std::binary_function<X509Data*,XSECCryptoX509*,void> {\r
+public:\r
+    void operator()(X509Data* bag, XSECCryptoX509* cert) const {\r
+        safeBuffer& buf=cert->getDEREncodingSB();\r
+        X509Certificate* x=X509CertificateBuilder::buildX509Certificate();\r
+        x->setValue(buf.sbStrToXMLCh());\r
+        bag->getX509Certificates().push_back(x);\r
     }\r
-    \r
-    KeyInfo* getKeyInfo() { return NULL; }\r
-    CredentialResolver& getCredentialResolver() { return *this; }\r
-    const char* getId() const { return "test"; }\r
-    const std::vector<XSECCryptoX509*>* getX509Certificates() { return &m_certs; }\r
-    XSECCryptoKey* getPublicKey() { return m_key; }\r
-    XSECCryptoKey* getPrivateKey() { return m_key; }\r
-    Lockable& lock() { return *this; }\r
-    void unlock() {}\r
 };\r
 \r
 class SignatureTest : public CxxTest::TestSuite {\r
+    XSECCryptoKey* m_key;\r
+    vector<XSECCryptoX509*> m_certs;\r
 public:\r
     void setUp() {\r
         QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);\r
         QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);\r
         XMLObjectBuilder::registerBuilder(qname, new SimpleXMLObjectBuilder());\r
         XMLObjectBuilder::registerBuilder(qtype, new SimpleXMLObjectBuilder());\r
+        string keypath=data_path + "key.pem";\r
+        BIO* in=BIO_new(BIO_s_file_internal());\r
+        if (in && BIO_read_filename(in,keypath.c_str())>0) {\r
+            EVP_PKEY* pkey=PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);\r
+            if (pkey) {\r
+                m_key=new OpenSSLCryptoKeyRSA(pkey);\r
+                EVP_PKEY_free(pkey);\r
+            }\r
+        }\r
+        if (in) BIO_free(in);\r
+        TS_ASSERT(m_key!=NULL);\r
+\r
+        string certpath=data_path + "cert.pem";\r
+        in=BIO_new(BIO_s_file_internal());\r
+        if (in && BIO_read_filename(in,certpath.c_str())>0) {\r
+            X509* x=NULL;\r
+            while (x=PEM_read_bio_X509(in,NULL,NULL,NULL)) {\r
+                m_certs.push_back(new OpenSSLCryptoX509(x));\r
+                X509_free(x);\r
+            }\r
+        }\r
+        if (in) BIO_free(in);\r
+        TS_ASSERT(m_certs.size()>0);\r
+        \r
     }\r
 \r
     void tearDown() {\r
@@ -104,6 +139,8 @@ public:
         QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);\r
         XMLObjectBuilder::deregisterBuilder(qname);\r
         XMLObjectBuilder::deregisterBuilder(qtype);\r
+        delete m_key;\r
+        for_each(m_certs.begin(),m_certs.end(),xmltooling::cleanup<XSECCryptoX509>());\r
     }\r
 \r
     void testSignature() {\r
@@ -126,13 +163,28 @@ public:
         kids[1]->setValue(bar.get());\r
         \r
         // Append a Signature.\r
-        Signature* sig=SignatureBuilder::newSignature();\r
+        Signature* sig=SignatureBuilder::buildSignature();\r
         sxObject->setSignature(sig);\r
+        sig->setContentReference(new TestContext(&chNull));\r
+        sig->setSigningKey(m_key->clone());\r
+        \r
+        // Build KeyInfo.\r
+        KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo();\r
+        X509Data* x509Data=X509DataBuilder::buildX509Data();\r
+        keyInfo->getX509Datas().push_back(x509Data);\r
+        for_each(m_certs.begin(),m_certs.end(),bind1st(_addcert(),x509Data));\r
+        sig->setKeyInfo(keyInfo);\r
         \r
         // Signing context for the whole document.\r
-        TestContext tc(&chNull);\r
-        MarshallingContext mctx(sig,&tc);\r
-        DOMElement* rootElement = sxObject->marshall((DOMDocument*)NULL,&mctx);\r
+        vector<Signature*> sigs(1,sig);\r
+        DOMElement* rootElement = NULL;\r
+        try {\r
+            rootElement=sxObject->marshall((DOMDocument*)NULL,&sigs);\r
+        }\r
+        catch (XMLToolingException& e) {\r
+            TS_TRACE(e.what());\r
+            throw;\r
+        }\r
         \r
         string buf;\r
         XMLHelper::serialize(rootElement, buf);\r
@@ -143,11 +195,12 @@ public:
         auto_ptr<SimpleXMLObject> sxObject2(dynamic_cast<SimpleXMLObject*>(b->buildFromDocument(doc)));\r
         TS_ASSERT(sxObject2.get()!=NULL);\r
         TS_ASSERT(sxObject2->getSignature()!=NULL);\r
+        sxObject2->getSignature()->registerValidator(new TestValidator(&chNull));\r
         \r
         try {\r
-            sxObject2->getSignature()->verify(tc);\r
+            sxObject2->getSignature()->validate(false);\r
         }\r
-        catch (SignatureException& e) {\r
+        catch (XMLToolingException& e) {\r
             TS_TRACE(e.what());\r
             throw;\r
         }\r