From: Scott Cantor Date: Thu, 1 Jun 2006 03:43:34 +0000 (+0000) Subject: Wrapped encryption schema, also block unknown attributes and handle schemaLocation. X-Git-Tag: 1.0-alpha1~234 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-xmltooling.git;a=commitdiff_plain;h=662e29b6668db409b0d81da58f3d68a9ab12c20b Wrapped encryption schema, also block unknown attributes and handle schemaLocation. --- diff --git a/xmltooling/AbstractXMLObject.cpp b/xmltooling/AbstractXMLObject.cpp index 3a47620..683fa09 100644 --- a/xmltooling/AbstractXMLObject.cpp +++ b/xmltooling/AbstractXMLObject.cpp @@ -30,7 +30,7 @@ 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_log(&log4cpp::Category::getInstance(XMLTOOLING_LOGCAT".XMLObject")), m_schemaLocation(NULL), m_parent(NULL), m_elementQname(nsURI, localName, prefix), m_typeQname(NULL) { addNamespace(Namespace(nsURI, prefix)); @@ -41,7 +41,8 @@ AbstractXMLObject::AbstractXMLObject(const XMLCh* nsURI, const XMLCh* localName, } 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) + : m_namespaces(src.m_namespaces), m_log(src.m_log), m_schemaLocation(XMLString::replicate(src.m_schemaLocation)), + m_parent(NULL), m_elementQname(src.m_elementQname), m_typeQname(NULL) { if (src.m_typeQname) m_typeQname=new QName(*src.m_typeQname); diff --git a/xmltooling/AbstractXMLObject.h b/xmltooling/AbstractXMLObject.h index ba34176..e159df1 100644 --- a/xmltooling/AbstractXMLObject.h +++ b/xmltooling/AbstractXMLObject.h @@ -45,6 +45,7 @@ namespace xmltooling { public: virtual ~AbstractXMLObject() { delete m_typeQname; + XMLString::release(&m_schemaLocation); } const QName& getElementQName() const { @@ -185,6 +186,11 @@ namespace xmltooling { */ void* m_log; + /** + * Stores off xsi:schemaLocation attribute. + */ + XMLCh* m_schemaLocation; + private: XMLObject* m_parent; QName m_elementQname; diff --git a/xmltooling/base.h b/xmltooling/base.h index 3375844..6a5ce17 100644 --- a/xmltooling/base.h +++ b/xmltooling/base.h @@ -469,6 +469,26 @@ } /** + * Implements get/set methods and a private list iterator member for + * a typed XML child object in a foreign namespace + * + * @param proper the proper name of the child type + * @param ns the C++ namespace for the type + */ +#define IMPL_TYPED_FOREIGN_CHILD(proper,ns) \ + protected: \ + ns::proper* m_##proper; \ + std::list::iterator m_pos_##proper; \ + public: \ + ns::proper* get##proper() const { \ + return m_##proper; \ + } \ + void set##proper(ns::proper* child) { \ + prepareForAssignment(m_##proper,child); \ + *m_pos_##proper = m_##proper = child; \ + } + +/** * Implements get/set methods and a private list iterator member for a generic XML child object. * * @param proper the proper name of the child @@ -541,6 +561,25 @@ } /** + * Implements get method and a private vector member for a typed XML child collection + * in a foreign namespace. + * + * @param proper the proper name of the child type + * @param ns the C++ namespace for the type + * @param fence insertion fence for new objects of the child collection in backing list + */ +#define IMPL_TYPED_FOREIGN_CHILDREN(proper,ns,fence) \ + protected: \ + std::vector m_##proper##s; \ + public: \ + VectorOf(ns::proper) get##proper##s() { \ + return VectorOf(ns::proper)(this, m_##proper##s, &m_children, fence); \ + } \ + const std::vector& get##proper##s() const { \ + return m_##proper##s; \ + } + +/** * Implements get method and a private vector member for a generic XML child collection. * * @param proper the proper name of the child @@ -732,6 +771,24 @@ } /** + * Implements unmarshalling process branch for typed child collection element + * in a foreign namespace. + * + * @param proper the proper name of the child type + * @param ns the C++ namespace for the type + * @param namespaceURI the XML namespace of the child element + * @param force bypass use of hint and just cast down to check child + */ +#define PROC_TYPED_FOREIGN_CHILDREN(proper,ns,namespaceURI,force) \ + if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,ns::proper::LOCAL_NAME)) { \ + ns::proper* typesafe=dynamic_cast(childXMLObject); \ + if (typesafe) { \ + get##proper##s().push_back(typesafe); \ + return; \ + } \ + } + +/** * Implements unmarshalling process branch for typed child singleton element * * @param proper the proper name of the child type @@ -748,6 +805,24 @@ } /** + * Implements unmarshalling process branch for typed child singleton element + * in a foreign namespace. + * + * @param proper the proper name of the child type + * @param ns the C++ namespace for the type + * @param namespaceURI the XML namespace of the child element + * @param force bypass use of hint and just cast down to check child + */ +#define PROC_TYPED_FOREIGN_CHILD(proper,ns,namespaceURI,force) \ + if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,ns::proper::LOCAL_NAME)) { \ + ns::proper* typesafe=dynamic_cast(childXMLObject); \ + if (typesafe) { \ + set##proper(typesafe); \ + return; \ + } \ + } + +/** * Implements unmarshalling process branch for a generic child singleton element * * @param proper the proper name of the child type @@ -954,6 +1029,26 @@ throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name())) /** + * Begins the declaration of a Schema Validator specialization subclass. + * + * @param linkage linkage specifier for the class + * @param cname the base name of the Validator specialization + * @param base base class for the validator + */ + #define BEGIN_XMLOBJECTVALIDATOR_SUB(linkage,cname,base) \ + class linkage cname##SchemaValidator : public base##SchemaValidator \ + { \ + public: \ + virtual ~cname##SchemaValidator() {} \ + virtual cname##SchemaValidator* clone() const { \ + return new cname##SchemaValidator(); \ + } \ + virtual void validate(const xmltooling::XMLObject* xmlObject) const { \ + const cname* ptr=dynamic_cast(xmlObject); \ + if (!ptr) \ + throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name())) + +/** * Ends the declaration of a Validator specialization. */ #define END_XMLOBJECTVALIDATOR } } diff --git a/xmltooling/encryption/Encryption.h b/xmltooling/encryption/Encryption.h index b25baba..53a94d9 100644 --- a/xmltooling/encryption/Encryption.h +++ b/xmltooling/encryption/Encryption.h @@ -23,11 +23,8 @@ #ifndef __xmltooling_encrypt_h__ #define __xmltooling_encrypt_h__ -#include -#include -#include -#include -#include +#include +#include #define DECL_XMLENCOBJECTBUILDER(cname) \ DECL_XMLOBJECTBUILDER(XMLTOOL_API,cname,xmltooling::XMLConstants::XMLENC_NS,xmltooling::XMLConstants::XMLENC_PREFIX) @@ -38,6 +35,8 @@ */ namespace xmlencryption { + DECL_XMLOBJECT_SIMPLE(XMLTOOL_API,CarriedKeyName,Name,XML Encryption CarriedKeyName element); + DECL_XMLOBJECT_SIMPLE(XMLTOOL_API,CipherValue,Value,XML Encryption CipherValue element); DECL_XMLOBJECT_SIMPLE(XMLTOOL_API,OAEPparams,Name,XML Encryption OAEPparams element); BEGIN_XMLOBJECT(XMLTOOL_API,KeySize,xmltooling::SimpleElement,XML Encryption KeySize element); @@ -53,9 +52,98 @@ namespace xmlencryption { static const XMLCh TYPE_NAME[]; END_XMLOBJECT; - DECL_XMLENCOBJECTBUILDER(OAEPparams); - DECL_XMLENCOBJECTBUILDER(KeySize); + BEGIN_XMLOBJECT(XMLTOOL_API,Transforms,xmltooling::XMLObject,XML Encryption Transforms element); + DECL_TYPED_FOREIGN_CHILDREN(Transform,xmlsignature); + /** TransformsType local name */ + static const XMLCh TYPE_NAME[]; + END_XMLOBJECT; + + BEGIN_XMLOBJECT(XMLTOOL_API,CipherReference,xmltooling::XMLObject,XML Encryption CipherReference element); + DECL_STRING_ATTRIB(URI,URI); + DECL_TYPED_CHILD(Transforms); + /** CipherReferenceType local name */ + static const XMLCh TYPE_NAME[]; + END_XMLOBJECT; + + BEGIN_XMLOBJECT(XMLTOOL_API,CipherData,xmltooling::XMLObject,XML Encryption CipherData element); + DECL_TYPED_CHILD(CipherValue); + DECL_TYPED_CHILD(CipherReference); + /** CipherDataType local name */ + static const XMLCh TYPE_NAME[]; + END_XMLOBJECT; + + BEGIN_XMLOBJECT2(XMLTOOL_API,EncryptionProperty,xmltooling::ElementProxy,xmltooling::AttributeExtensibleXMLObject,XML Encryption EncryptionProperty element); + DECL_STRING_ATTRIB(Target,TARGET); + DECL_STRING_ATTRIB(Id,ID); + /** EncryptionPropertyType local name */ + static const XMLCh TYPE_NAME[]; + END_XMLOBJECT; + + BEGIN_XMLOBJECT(XMLTOOL_API,EncryptionProperties,xmltooling::XMLObject,XML Encryption EncryptionProperties element); + DECL_STRING_ATTRIB(Id,ID); + DECL_TYPED_CHILDREN(EncryptionProperty); + /** EncryptionPropertiesType local name */ + static const XMLCh TYPE_NAME[]; + END_XMLOBJECT; + + BEGIN_XMLOBJECT(XMLTOOL_API,ReferenceType,xmltooling::ElementProxy,XML Encryption ReferenceType type); + DECL_STRING_ATTRIB(URI,URI); + /** ReferenceType local name */ + static const XMLCh TYPE_NAME[]; + END_XMLOBJECT; + + BEGIN_XMLOBJECT(XMLTOOL_API,DataReference,ReferenceType,XML Encryption DataReference element); + END_XMLOBJECT; + + BEGIN_XMLOBJECT(XMLTOOL_API,KeyReference,ReferenceType,XML Encryption KeyReference element); + END_XMLOBJECT; + + BEGIN_XMLOBJECT(XMLTOOL_API,ReferenceList,xmltooling::XMLObject,XML Encryption ReferenceList element); + DECL_TYPED_CHILDREN(DataReference); + DECL_TYPED_CHILDREN(KeyReference); + END_XMLOBJECT; + + BEGIN_XMLOBJECT(XMLTOOL_API,EncryptedType,xmltooling::XMLObject,XML Encryption EncryptedType abstract type); + DECL_STRING_ATTRIB(Id,ID); + DECL_STRING_ATTRIB(Type,TYPE); + DECL_STRING_ATTRIB(MimeType,MIMETYPE); + DECL_STRING_ATTRIB(Encoding,ENCODING); + DECL_TYPED_CHILD(EncryptionMethod); + DECL_TYPED_FOREIGN_CHILD(KeyInfo,xmlsignature); + DECL_TYPED_CHILD(CipherData); + DECL_TYPED_CHILD(EncryptionProperties); + /** EncryptedType local name */ + static const XMLCh TYPE_NAME[]; + END_XMLOBJECT; + + BEGIN_XMLOBJECT(XMLTOOL_API,EncryptedData,EncryptedType,XML Encryption EncryptedData element); + /** EncryptedDataType local name */ + static const XMLCh TYPE_NAME[]; + END_XMLOBJECT; + + BEGIN_XMLOBJECT(XMLTOOL_API,EncryptedKey,EncryptedType,XML Encryption EncryptedKey element); + DECL_STRING_ATTRIB(Recipient,RECIPIENT); + DECL_TYPED_CHILD(ReferenceList); + DECL_TYPED_CHILD(CarriedKeyName); + /** EncryptedKeyType local name */ + static const XMLCh TYPE_NAME[]; + END_XMLOBJECT; + + DECL_XMLENCOBJECTBUILDER(CarriedKeyName); + DECL_XMLENCOBJECTBUILDER(CipherData); + DECL_XMLENCOBJECTBUILDER(CipherReference); + DECL_XMLENCOBJECTBUILDER(CipherValue); + DECL_XMLENCOBJECTBUILDER(DataReference); + DECL_XMLENCOBJECTBUILDER(EncryptedData); + DECL_XMLENCOBJECTBUILDER(EncryptedKey); DECL_XMLENCOBJECTBUILDER(EncryptionMethod); + DECL_XMLENCOBJECTBUILDER(EncryptionProperties); + DECL_XMLENCOBJECTBUILDER(EncryptionProperty); + DECL_XMLENCOBJECTBUILDER(KeyReference); + DECL_XMLENCOBJECTBUILDER(KeySize); + DECL_XMLENCOBJECTBUILDER(OAEPparams); + DECL_XMLENCOBJECTBUILDER(ReferenceList); + DECL_XMLENCOBJECTBUILDER(Transforms); /** * Registers builders and validators for XML Encryption classes into the runtime. diff --git a/xmltooling/encryption/impl/EncryptionImpl.cpp b/xmltooling/encryption/impl/EncryptionImpl.cpp index 7b3cf21..324f8f6 100644 --- a/xmltooling/encryption/impl/EncryptionImpl.cpp +++ b/xmltooling/encryption/impl/EncryptionImpl.cpp @@ -21,9 +21,9 @@ */ #include "internal.h" +#include "AbstractAttributeExtensibleXMLObject.h" #include "AbstractChildlessElement.h" -#include "AbstractComplexElement.h" -#include "AbstractSimpleElement.h" +#include "AbstractElementProxy.h" #include "exceptions.h" #include "encryption/Encryption.h" #include "io/AbstractXMLObjectMarshaller.h" @@ -44,6 +44,8 @@ using namespace std; namespace xmlencryption { + DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,CarriedKeyName); + DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,CipherValue); DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,KeySize); DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,OAEPparams); @@ -115,6 +117,569 @@ namespace xmlencryption { void processAttribute(const DOMAttr* attribute) { PROC_STRING_ATTRIB(Algorithm,ALGORITHM,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); + } + }; + + class XMLTOOL_DLLLOCAL TransformsImpl : public virtual Transforms, + public AbstractComplexElement, + public AbstractDOMCachingXMLObject, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller + { + public: + virtual ~TransformsImpl() {} + + TransformsImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + } + + TransformsImpl(const TransformsImpl& src) + : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) { + VectorOf(xmlsignature::Transform) v=getTransforms(); + for (vector::const_iterator i=src.m_Transforms.begin(); i!=src.m_Transforms.end(); i++) { + if (*i) { + v.push_back((*i)->cloneTransform()); + } + } + } + + IMPL_XMLOBJECT_CLONE(Transforms); + IMPL_TYPED_FOREIGN_CHILDREN(Transform,xmlsignature,m_children.end()); + + protected: + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + PROC_TYPED_FOREIGN_CHILDREN(Transform,xmlsignature,XMLConstants::XMLSIG_NS,false); + AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root); + } + }; + + class XMLTOOL_DLLLOCAL CipherReferenceImpl : public virtual CipherReference, + public AbstractComplexElement, + public AbstractDOMCachingXMLObject, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller + { + void init() { + m_URI=NULL; + m_Transforms=NULL; + m_children.push_back(NULL); + m_pos_Transforms=m_children.begin(); + } + public: + virtual ~CipherReferenceImpl() { + XMLString::release(&m_URI); + } + + CipherReferenceImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + init(); + } + + CipherReferenceImpl(const CipherReferenceImpl& src) + : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) { + init(); + setURI(src.getURI()); + if (src.getTransforms()) + setTransforms(src.getTransforms()->cloneTransforms()); + } + + IMPL_XMLOBJECT_CLONE(CipherReference); + IMPL_STRING_ATTRIB(URI); + IMPL_TYPED_CHILD(Transforms); + + protected: + void marshallAttributes(DOMElement* domElement) const { + MARSHALL_STRING_ATTRIB(URI,URI,NULL); + } + + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + PROC_TYPED_CHILD(Transforms,XMLConstants::XMLENC_NS,false); + AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root); + } + + void processAttribute(const DOMAttr* attribute) { + PROC_STRING_ATTRIB(URI,URI,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); + } + }; + + class XMLTOOL_DLLLOCAL CipherDataImpl : public virtual CipherData, + public AbstractComplexElement, + public AbstractDOMCachingXMLObject, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller + { + void init() { + m_CipherValue=NULL; + m_CipherReference=NULL; + m_children.push_back(NULL); + m_children.push_back(NULL); + m_pos_CipherValue=m_children.begin(); + m_pos_CipherReference=m_pos_CipherValue; + ++m_pos_CipherReference; + } + public: + virtual ~CipherDataImpl() {} + + CipherDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + init(); + } + + CipherDataImpl(const CipherDataImpl& src) + : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) { + init(); + if (src.getCipherValue()) + setCipherValue(src.getCipherValue()->cloneCipherValue()); + if (src.getCipherReference()) + setCipherReference(src.getCipherReference()->cloneCipherReference()); + } + + IMPL_XMLOBJECT_CLONE(CipherData); + IMPL_TYPED_CHILD(CipherValue); + IMPL_TYPED_CHILD(CipherReference); + + protected: + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + PROC_TYPED_CHILD(CipherValue,XMLConstants::XMLENC_NS,false); + PROC_TYPED_CHILD(CipherReference,XMLConstants::XMLENC_NS,false); + AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root); + } + }; + + class XMLTOOL_DLLLOCAL EncryptionPropertyImpl : public virtual EncryptionProperty, + public AbstractElementProxy, + public AbstractAttributeExtensibleXMLObject, + public AbstractDOMCachingXMLObject, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller + { + void init() { + m_Id=m_Target=NULL; + } + public: + virtual ~EncryptionPropertyImpl() { + XMLString::release(&m_Id); + XMLString::release(&m_Target); + } + + EncryptionPropertyImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + init(); + } + + EncryptionPropertyImpl(const EncryptionPropertyImpl& src) + : AbstractXMLObject(src), + AbstractElementProxy(src), + AbstractAttributeExtensibleXMLObject(src), + AbstractDOMCachingXMLObject(src), + AbstractValidatingXMLObject(src) { + init(); + setId(src.getId()); + setTarget(src.getTarget()); + for (list::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) { + if (*i) { + getXMLObjects().push_back((*i)->clone()); + } + } + } + + IMPL_XMLOBJECT_CLONE(EncryptionProperty); + IMPL_STRING_ATTRIB(Id); + IMPL_STRING_ATTRIB(Target); + + void setAttribute(QName& qualifiedName, const XMLCh* value) { + if (!qualifiedName.hasNamespaceURI()) { + if (XMLString::equals(qualifiedName.getLocalPart(),ID_ATTRIB_NAME)) + setId(value); + else if (XMLString::equals(qualifiedName.getLocalPart(),TARGET_ATTRIB_NAME)) + setTarget(value); + } + AbstractAttributeExtensibleXMLObject::setAttribute(qualifiedName, value); + } + + protected: + void marshallAttributes(DOMElement* domElement) const { + MARSHALL_ID_ATTRIB(Id,ID,NULL); + MARSHALL_STRING_ATTRIB(Target,TARGET,NULL); + + // Take care of wildcard. + for (map::const_iterator i=m_attributeMap.begin(); i!=m_attributeMap.end(); i++) { + DOMAttr* attr=domElement->getOwnerDocument()->createAttributeNS(i->first.getNamespaceURI(),i->first.getLocalPart()); + if (i->first.hasPrefix()) + attr->setPrefix(i->first.getPrefix()); + attr->setNodeValue(i->second); + domElement->setAttributeNode(attr); + } + } + + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + getXMLObjects().push_back(childXMLObject); + } + + void processAttribute(const DOMAttr* attribute) { + PROC_ID_ATTRIB(Id,ID,NULL); + QName q(attribute->getNamespaceURI(),attribute->getLocalName(),attribute->getPrefix()); + setAttribute(q,attribute->getNodeValue()); + } + }; + + class XMLTOOL_DLLLOCAL EncryptionPropertiesImpl : public virtual EncryptionProperties, + public AbstractComplexElement, + public AbstractDOMCachingXMLObject, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller + { + void init() { + m_Id=NULL; + } + public: + virtual ~EncryptionPropertiesImpl() { + XMLString::release(&m_Id); + } + + EncryptionPropertiesImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + init(); + } + + EncryptionPropertiesImpl(const EncryptionPropertiesImpl& src) + : AbstractXMLObject(src), + AbstractDOMCachingXMLObject(src), + AbstractValidatingXMLObject(src) { + init(); + setId(src.getId()); + VectorOf(EncryptionProperty) v=getEncryptionPropertys(); + for (vector::const_iterator i=src.m_EncryptionPropertys.begin(); i!=src.m_EncryptionPropertys.end(); i++) { + if (*i) { + v.push_back((*i)->cloneEncryptionProperty()); + } + } + } + + IMPL_XMLOBJECT_CLONE(EncryptionProperties); + IMPL_STRING_ATTRIB(Id); + IMPL_TYPED_CHILDREN(EncryptionProperty,m_children.end()); + + protected: + void marshallAttributes(DOMElement* domElement) const { + MARSHALL_ID_ATTRIB(Id,ID,NULL); + } + + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + PROC_TYPED_CHILDREN(EncryptionProperty,XMLConstants::XMLENC_NS,false); + AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root); + } + + void processAttribute(const DOMAttr* attribute) { + PROC_ID_ATTRIB(Id,ID,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); + } + }; + + class XMLTOOL_DLLLOCAL ReferenceTypeImpl : public virtual ReferenceType, + public AbstractElementProxy, + public AbstractDOMCachingXMLObject, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller + { + void init() { + m_URI=NULL; + } + + protected: + ReferenceTypeImpl() { + init(); + } + + public: + virtual ~ReferenceTypeImpl() { + XMLString::release(&m_URI); + } + + ReferenceTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + init(); + } + + ReferenceTypeImpl(const ReferenceTypeImpl& src) + : AbstractXMLObject(src), + AbstractElementProxy(src), + AbstractDOMCachingXMLObject(src), + AbstractValidatingXMLObject(src) { + init(); + setURI(src.getURI()); + for (list::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) { + if (*i) { + getXMLObjects().push_back((*i)->clone()); + } + } + } + + IMPL_XMLOBJECT_CLONE(ReferenceType); + IMPL_STRING_ATTRIB(URI); + + protected: + void marshallAttributes(DOMElement* domElement) const { + MARSHALL_STRING_ATTRIB(URI,URI,NULL); + } + + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + getXMLObjects().push_back(childXMLObject); + } + + void processAttribute(const DOMAttr* attribute) { + PROC_STRING_ATTRIB(URI,URI,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); + } + }; + + class XMLTOOL_DLLLOCAL DataReferenceImpl : public virtual DataReference, public ReferenceTypeImpl + { + public: + virtual ~DataReferenceImpl() {} + + DataReferenceImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) {} + + DataReferenceImpl(const DataReferenceImpl& src) : AbstractXMLObject(src), ReferenceTypeImpl(src) {} + + IMPL_XMLOBJECT_CLONE(DataReference); + ReferenceType* cloneReferenceType() const { + return new DataReferenceImpl(*this); + } + }; + + class XMLTOOL_DLLLOCAL KeyReferenceImpl : public virtual KeyReference, public ReferenceTypeImpl + { + public: + virtual ~KeyReferenceImpl() {} + + KeyReferenceImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) {} + + KeyReferenceImpl(const KeyReferenceImpl& src) : AbstractXMLObject(src), ReferenceTypeImpl(src) {} + + IMPL_XMLOBJECT_CLONE(KeyReference); + ReferenceType* cloneReferenceType() const { + return new KeyReferenceImpl(*this); + } + }; + + class XMLTOOL_DLLLOCAL ReferenceListImpl : public virtual ReferenceList, + public AbstractComplexElement, + public AbstractDOMCachingXMLObject, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller + { + public: + virtual ~ReferenceListImpl() {} + + ReferenceListImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + } + + ReferenceListImpl(const ReferenceListImpl& src) + : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) { + for (list::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) { + if (*i) { + DataReference* data=dynamic_cast(*i); + if (data) { + getDataReferences().push_back(data->cloneDataReference()); + continue; + } + + KeyReference* key=dynamic_cast(*i); + if (key) { + getKeyReferences().push_back(key->cloneKeyReference()); + continue; + } + } + } + } + + IMPL_XMLOBJECT_CLONE(ReferenceList); + IMPL_TYPED_CHILDREN(DataReference,m_children.end()); + IMPL_TYPED_CHILDREN(KeyReference,m_children.end()); + + protected: + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + PROC_TYPED_CHILDREN(DataReference,XMLConstants::XMLENC_NS,false); + PROC_TYPED_CHILDREN(KeyReference,XMLConstants::XMLENC_NS,false); + AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root); + } + }; + + class XMLTOOL_DLLLOCAL EncryptedTypeImpl : public virtual EncryptedType, + public AbstractComplexElement, + public AbstractDOMCachingXMLObject, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller + { + void init() { + m_Id=m_Type=m_MimeType=m_Encoding=NULL; + m_EncryptionMethod=NULL; + m_KeyInfo=NULL; + m_CipherData=NULL; + m_EncryptionProperties=NULL; + m_children.push_back(NULL); + m_children.push_back(NULL); + m_children.push_back(NULL); + m_children.push_back(NULL); + m_pos_EncryptionMethod=m_children.begin(); + m_pos_KeyInfo=m_pos_EncryptionMethod; + ++m_pos_KeyInfo; + m_pos_CipherData=m_pos_KeyInfo; + ++m_pos_CipherData; + m_pos_EncryptionProperties=m_pos_CipherData; + ++m_pos_EncryptionProperties; + } + protected: + EncryptedTypeImpl() { + init(); + } + + public: + virtual ~EncryptedTypeImpl() { + XMLString::release(&m_Id); + XMLString::release(&m_Type); + XMLString::release(&m_MimeType); + XMLString::release(&m_Encoding); + } + + EncryptedTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + init(); + } + + EncryptedTypeImpl(const EncryptedTypeImpl& src) + : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) { + init(); + setId(src.getId()); + setType(src.getType()); + setMimeType(src.getMimeType()); + setEncoding(src.getEncoding()); + if (src.getEncryptionMethod()) + setEncryptionMethod(src.getEncryptionMethod()->cloneEncryptionMethod()); + if (src.getKeyInfo()) + setKeyInfo(src.getKeyInfo()->cloneKeyInfo()); + if (src.getCipherData()) + setCipherData(src.getCipherData()->cloneCipherData()); + if (src.getEncryptionProperties()) + setEncryptionProperties(src.getEncryptionProperties()->cloneEncryptionProperties()); + } + + IMPL_XMLOBJECT_CLONE(EncryptedType); + IMPL_STRING_ATTRIB(Id); + IMPL_STRING_ATTRIB(Type); + IMPL_STRING_ATTRIB(MimeType); + IMPL_STRING_ATTRIB(Encoding); + IMPL_TYPED_CHILD(EncryptionMethod); + IMPL_TYPED_FOREIGN_CHILD(KeyInfo,xmlsignature); + IMPL_TYPED_CHILD(CipherData); + IMPL_TYPED_CHILD(EncryptionProperties); + + protected: + void marshallAttributes(DOMElement* domElement) const { + MARSHALL_ID_ATTRIB(Id,ID,NULL); + MARSHALL_STRING_ATTRIB(Type,TYPE,NULL); + MARSHALL_STRING_ATTRIB(MimeType,MIMETYPE,NULL); + MARSHALL_STRING_ATTRIB(Encoding,ENCODING,NULL); + } + + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + PROC_TYPED_CHILD(EncryptionMethod,XMLConstants::XMLENC_NS,false); + PROC_TYPED_FOREIGN_CHILD(KeyInfo,xmlsignature,XMLConstants::XMLSIG_NS,false); + PROC_TYPED_CHILD(CipherData,XMLConstants::XMLENC_NS,false); + PROC_TYPED_CHILD(EncryptionProperties,XMLConstants::XMLENC_NS,false); + AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root); + } + + void processAttribute(const DOMAttr* attribute) { + PROC_ID_ATTRIB(Id,ID,NULL); + PROC_STRING_ATTRIB(Type,TYPE,NULL); + PROC_STRING_ATTRIB(MimeType,MIMETYPE,NULL); + PROC_STRING_ATTRIB(Encoding,ENCODING,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); + } + }; + + class XMLTOOL_DLLLOCAL EncryptedDataImpl : public virtual EncryptedData, public EncryptedTypeImpl + { + public: + virtual ~EncryptedDataImpl() {} + + EncryptedDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) {} + + EncryptedDataImpl(const EncryptedDataImpl& src) : AbstractXMLObject(src), EncryptedTypeImpl(src) {} + + IMPL_XMLOBJECT_CLONE(EncryptedData); + EncryptedType* cloneEncryptedType() const { + return new EncryptedDataImpl(*this); + } + }; + + class XMLTOOL_DLLLOCAL EncryptedKeyImpl : public virtual EncryptedKey, public EncryptedTypeImpl + { + void init() { + m_Recipient=NULL; + m_ReferenceList=NULL; + m_CarriedKeyName=NULL; + m_children.push_back(NULL); + m_children.push_back(NULL); + m_pos_ReferenceList=m_pos_EncryptionProperties; + ++m_pos_ReferenceList; + m_pos_CarriedKeyName=m_pos_ReferenceList; + ++m_pos_CarriedKeyName; + } + + public: + virtual ~EncryptedKeyImpl() { + XMLString::release(&m_Recipient); + } + + EncryptedKeyImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + init(); + } + + EncryptedKeyImpl(const EncryptedKeyImpl& src) : AbstractXMLObject(src), EncryptedTypeImpl(src) { + init(); + } + + IMPL_XMLOBJECT_CLONE(EncryptedKey); + EncryptedType* cloneEncryptedType() const { + return new EncryptedKeyImpl(*this); + } + IMPL_STRING_ATTRIB(Recipient); + IMPL_TYPED_CHILD(ReferenceList); + IMPL_TYPED_CHILD(CarriedKeyName); + + protected: + void marshallAttributes(DOMElement* domElement) const { + MARSHALL_STRING_ATTRIB(Recipient,RECIPIENT,NULL); + EncryptedTypeImpl::marshallAttributes(domElement); + } + + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + PROC_TYPED_CHILD(ReferenceList,XMLConstants::XMLENC_NS,false); + PROC_TYPED_CHILD(CarriedKeyName,XMLConstants::XMLENC_NS,false); + EncryptedTypeImpl::processChildElement(childXMLObject,root); + } + + void processAttribute(const DOMAttr* attribute) { + PROC_STRING_ATTRIB(Recipient,RECIPIENT,NULL); + EncryptedTypeImpl::processAttribute(attribute); } }; @@ -126,14 +691,59 @@ namespace xmlencryption { // Builder Implementations +IMPL_XMLOBJECTBUILDER(CarriedKeyName); +IMPL_XMLOBJECTBUILDER(CipherData); +IMPL_XMLOBJECTBUILDER(CipherReference); +IMPL_XMLOBJECTBUILDER(CipherValue); +IMPL_XMLOBJECTBUILDER(DataReference); +IMPL_XMLOBJECTBUILDER(EncryptedData); +IMPL_XMLOBJECTBUILDER(EncryptedKey); +IMPL_XMLOBJECTBUILDER(EncryptionMethod); +IMPL_XMLOBJECTBUILDER(EncryptionProperties); +IMPL_XMLOBJECTBUILDER(EncryptionProperty); +IMPL_XMLOBJECTBUILDER(KeyReference); IMPL_XMLOBJECTBUILDER(KeySize); IMPL_XMLOBJECTBUILDER(OAEPparams); -IMPL_XMLOBJECTBUILDER(EncryptionMethod); +IMPL_XMLOBJECTBUILDER(ReferenceList); +IMPL_XMLOBJECTBUILDER(Transforms); // Unicode literals -const XMLCh KeySize::LOCAL_NAME[] = UNICODE_LITERAL_7(K,e,y,S,i,z,e); -const XMLCh OAEPparams::LOCAL_NAME[] = UNICODE_LITERAL_10(O,A,E,P,p,a,r,a,m,s); +const XMLCh CarriedKeyName::LOCAL_NAME[] = UNICODE_LITERAL_14(C,a,r,r,i,e,d,K,e,y,N,a,m,e); +const XMLCh CipherData::LOCAL_NAME[] = UNICODE_LITERAL_10(C,i,p,h,e,r,D,a,t,a); +const XMLCh CipherData::TYPE_NAME[] = UNICODE_LITERAL_14(C,i,p,h,e,r,D,a,t,a,T,y,p,e); +const XMLCh CipherReference::LOCAL_NAME[] = UNICODE_LITERAL_15(C,i,p,h,e,r,R,e,f,e,r,e,n,c,e); +const XMLCh CipherReference::TYPE_NAME[] = UNICODE_LITERAL_19(C,i,p,h,e,r,R,e,f,e,r,e,n,c,e,T,y,p,e); +const XMLCh CipherReference::URI_ATTRIB_NAME[] = UNICODE_LITERAL_3(U,R,I); +const XMLCh CipherValue::LOCAL_NAME[] = UNICODE_LITERAL_11(C,i,p,h,e,r,V,a,l,u,e); +const XMLCh DataReference::LOCAL_NAME[] = UNICODE_LITERAL_13(D,a,t,a,R,e,f,e,r,e,n,c,e); +const XMLCh EncryptedData::LOCAL_NAME[] = UNICODE_LITERAL_13(E,n,c,r,y,p,t,e,d,D,a,t,a); +const XMLCh EncryptedData::TYPE_NAME[] = UNICODE_LITERAL_17(E,n,c,r,y,p,t,e,d,D,a,t,a,T,y,p,e); +const XMLCh EncryptedKey::LOCAL_NAME[] = UNICODE_LITERAL_12(E,n,c,r,y,p,t,e,d,K,e,y); +const XMLCh EncryptedKey::TYPE_NAME[] = UNICODE_LITERAL_16(E,n,c,r,y,p,t,e,d,K,e,y,T,y,p,e); +const XMLCh EncryptedKey::RECIPIENT_ATTRIB_NAME[] = UNICODE_LITERAL_9(R,e,c,i,p,i,e,n,t); +const XMLCh EncryptedType::LOCAL_NAME[] = {chNull}; +const XMLCh EncryptedType::TYPE_NAME[] = UNICODE_LITERAL_13(E,n,c,r,y,p,t,e,d,T,y,p,e); +const XMLCh EncryptedType::ID_ATTRIB_NAME[] = UNICODE_LITERAL_2(I,d); +const XMLCh EncryptedType::TYPE_ATTRIB_NAME[] = UNICODE_LITERAL_4(T,y,p,e); +const XMLCh EncryptedType::MIMETYPE_ATTRIB_NAME[] = UNICODE_LITERAL_8(M,i,m,e,T,y,p,e); +const XMLCh EncryptedType::ENCODING_ATTRIB_NAME[] = UNICODE_LITERAL_8(E,n,c,o,d,i,n,g); const XMLCh EncryptionMethod::LOCAL_NAME[] = UNICODE_LITERAL_16(E,n,c,r,y,p,t,i,o,n,M,e,t,h,o,d); const XMLCh EncryptionMethod::TYPE_NAME[] = UNICODE_LITERAL_20(E,n,c,r,y,p,t,i,o,n,M,e,t,h,o,d,T,y,p,e); const XMLCh EncryptionMethod::ALGORITHM_ATTRIB_NAME[] = UNICODE_LITERAL_9(A,l,g,o,r,i,t,h,m); +const XMLCh EncryptionProperties::LOCAL_NAME[] = UNICODE_LITERAL_20(E,n,c,r,y,p,t,i,o,n,P,r,o,p,e,r,t,i,e,s); +const XMLCh EncryptionProperties::TYPE_NAME[] = UNICODE_LITERAL_24(E,n,c,r,y,p,t,i,o,n,P,r,o,p,e,r,t,i,e,s,T,y,p,e); +const XMLCh EncryptionProperties::ID_ATTRIB_NAME[] = UNICODE_LITERAL_2(I,d); +const XMLCh EncryptionProperty::LOCAL_NAME[] = UNICODE_LITERAL_18(E,n,c,r,y,p,t,i,o,n,P,r,o,p,e,r,t,y); +const XMLCh EncryptionProperty::TYPE_NAME[] = UNICODE_LITERAL_22(E,n,c,r,y,p,t,i,o,n,P,r,o,p,e,r,t,y,T,y,p,e); +const XMLCh EncryptionProperty::ID_ATTRIB_NAME[] = UNICODE_LITERAL_2(I,d); +const XMLCh EncryptionProperty::TARGET_ATTRIB_NAME[] = UNICODE_LITERAL_6(T,a,r,g,e,t); +const XMLCh KeyReference::LOCAL_NAME[] = UNICODE_LITERAL_12(K,e,y,R,e,f,e,r,e,n,c,e); +const XMLCh KeySize::LOCAL_NAME[] = UNICODE_LITERAL_7(K,e,y,S,i,z,e); +const XMLCh OAEPparams::LOCAL_NAME[] = UNICODE_LITERAL_10(O,A,E,P,p,a,r,a,m,s); +const XMLCh ReferenceList::LOCAL_NAME[] = UNICODE_LITERAL_13(R,e,f,e,r,e,n,c,e,L,i,s,t); +const XMLCh ReferenceType::LOCAL_NAME[] = {chNull}; +const XMLCh ReferenceType::TYPE_NAME[] = UNICODE_LITERAL_13(R,e,f,e,r,e,n,c,e,T,y,p,e); +const XMLCh ReferenceType::URI_ATTRIB_NAME[] = UNICODE_LITERAL_3(U,R,I); +const XMLCh Transforms::LOCAL_NAME[] = UNICODE_LITERAL_10(T,r,a,n,s,f,o,r,m,s); +const XMLCh Transforms::TYPE_NAME[] = UNICODE_LITERAL_14(T,r,a,n,s,f,o,r,m,s,T,y,p,e); diff --git a/xmltooling/encryption/impl/EncryptionSchemaValidators.cpp b/xmltooling/encryption/impl/EncryptionSchemaValidators.cpp index aab35b5..90407b8 100644 --- a/xmltooling/encryption/impl/EncryptionSchemaValidators.cpp +++ b/xmltooling/encryption/impl/EncryptionSchemaValidators.cpp @@ -30,6 +30,8 @@ using namespace std; namespace xmlencryption { + XMLOBJECTVALIDATOR_SIMPLE(XMLTOOL_DLLLOCAL,CarriedKeyName); + XMLOBJECTVALIDATOR_SIMPLE(XMLTOOL_DLLLOCAL,CipherValue); XMLOBJECTVALIDATOR_SIMPLE(XMLTOOL_DLLLOCAL,KeySize); XMLOBJECTVALIDATOR_SIMPLE(XMLTOOL_DLLLOCAL,OAEPparams); @@ -37,6 +39,73 @@ namespace xmlencryption { XMLOBJECTVALIDATOR_REQUIRE(EncryptionMethod,Algorithm); END_XMLOBJECTVALIDATOR; + BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,Transforms); + XMLOBJECTVALIDATOR_NONEMPTY(Transforms,Transform); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,CipherReference); + XMLOBJECTVALIDATOR_REQUIRE(CipherReference,URI); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,CipherData); + XMLOBJECTVALIDATOR_ONLYONEOF(CipherData,CipherValue,CipherReference); + END_XMLOBJECTVALIDATOR; + + class XMLTOOL_DLLLOCAL checkWildcardNS { + public: + void operator()(const XMLObject* xmlObject) const { + const XMLCh* ns=xmlObject->getElementQName().getNamespaceURI(); + if (XMLString::equals(ns,XMLConstants::XMLENC_NS) || !ns || !*ns) { + throw ValidationException( + "Object contains an illegal extension child element ($1).", + params(1,xmlObject->getElementQName().toString().c_str()) + ); + } + } + }; + + BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,EncryptionProperty); + if (!ptr->hasChildren()) + throw ValidationException("EncryptionProperty must have at least one child element."); + const list& anys=ptr->getXMLObjects(); + for_each(anys.begin(),anys.end(),checkWildcardNS()); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,EncryptionProperties); + XMLOBJECTVALIDATOR_NONEMPTY(EncryptionProperties,EncryptionProperty); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,ReferenceType); + XMLOBJECTVALIDATOR_REQUIRE(DataReference,URI); + const list& anys=ptr->getXMLObjects(); + for_each(anys.begin(),anys.end(),checkWildcardNS()); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR_SUB(XMLTOOL_DLLLOCAL,DataReference,ReferenceType); + ReferenceTypeSchemaValidator::validate(xmlObject); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR_SUB(XMLTOOL_DLLLOCAL,KeyReference,ReferenceType); + ReferenceTypeSchemaValidator::validate(xmlObject); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,ReferenceList); + if (!ptr->hasChildren()) + throw ValidationException("ReferenceList must have at least one child element."); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,EncryptedType); + XMLOBJECTVALIDATOR_REQUIRE(EncryptedType,CipherData); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR_SUB(XMLTOOL_DLLLOCAL,EncryptedData,EncryptedType); + EncryptedTypeSchemaValidator::validate(xmlObject); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR_SUB(XMLTOOL_DLLLOCAL,EncryptedKey,EncryptedType); + EncryptedTypeSchemaValidator::validate(xmlObject); + END_XMLOBJECTVALIDATOR; + }; #define REGISTER_ELEMENT(namespaceURI,cname) \ @@ -52,8 +121,25 @@ namespace xmlencryption { void xmlencryption::registerEncryptionClasses() { QName q; + REGISTER_ELEMENT(XMLConstants::XMLENC_NS,CarriedKeyName); + REGISTER_ELEMENT(XMLConstants::XMLENC_NS,CipherData); + REGISTER_ELEMENT(XMLConstants::XMLENC_NS,CipherReference); + REGISTER_ELEMENT(XMLConstants::XMLENC_NS,CipherValue); + REGISTER_ELEMENT(XMLConstants::XMLENC_NS,DataReference); + REGISTER_ELEMENT(XMLConstants::XMLENC_NS,EncryptedData); + REGISTER_ELEMENT(XMLConstants::XMLENC_NS,EncryptedKey); + REGISTER_ELEMENT(XMLConstants::XMLENC_NS,EncryptionMethod); + REGISTER_ELEMENT(XMLConstants::XMLENC_NS,EncryptionProperties); + REGISTER_ELEMENT(XMLConstants::XMLENC_NS,EncryptionProperty); + REGISTER_ELEMENT(XMLConstants::XMLENC_NS,KeyReference); REGISTER_ELEMENT(XMLConstants::XMLENC_NS,KeySize); REGISTER_ELEMENT(XMLConstants::XMLENC_NS,OAEPparams); - REGISTER_ELEMENT(XMLConstants::XMLENC_NS,EncryptionMethod); + REGISTER_ELEMENT(XMLConstants::XMLENC_NS,ReferenceList); + REGISTER_ELEMENT(XMLConstants::XMLENC_NS,Transforms); + REGISTER_TYPE(XMLConstants::XMLENC_NS,CipherData); + REGISTER_TYPE(XMLConstants::XMLENC_NS,CipherReference); REGISTER_TYPE(XMLConstants::XMLENC_NS,EncryptionMethod); + REGISTER_TYPE(XMLConstants::XMLENC_NS,EncryptionProperties); + REGISTER_TYPE(XMLConstants::XMLENC_NS,EncryptionProperty); + REGISTER_TYPE(XMLConstants::XMLENC_NS,Transforms); } diff --git a/xmltooling/io/AbstractXMLObjectUnmarshaller.cpp b/xmltooling/io/AbstractXMLObjectUnmarshaller.cpp index e44e37d..6532d53 100644 --- a/xmltooling/io/AbstractXMLObjectUnmarshaller.cpp +++ b/xmltooling/io/AbstractXMLObjectUnmarshaller.cpp @@ -62,12 +62,6 @@ XMLObject* AbstractXMLObjectUnmarshaller::unmarshall(DOMElement* element, bool b unmarshallChildElements(element); - /* TODO: Signing - if (xmlObject instanceof SignableXMLObject) { - verifySignature(domElement, xmlObject); - } - */ - setDOM(element,bindDocument); return this; } @@ -77,7 +71,6 @@ void AbstractXMLObjectUnmarshaller::unmarshallAttributes(const DOMElement* domEl #ifdef _DEBUG xmltooling::NDC ndc("unmarshallAttributes"); #endif - static const XMLCh type[]={chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull}; if (XT_log.isDebugEnabled()) { auto_ptr_char dname(domElement->getNodeName()); @@ -116,9 +109,20 @@ void AbstractXMLObjectUnmarshaller::unmarshallAttributes(const DOMElement* domEl continue; } } - else if (XMLString::equals(nsuri,XMLConstants::XSI_NS) && XMLString::equals(attribute->getLocalName(),type)) { - XT_log.debug("skipping xsi:type declaration"); - continue; + else if (XMLString::equals(nsuri,XMLConstants::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); + if (XMLString::equals(attribute->getLocalName(),type)) { + XT_log.debug("skipping xsi:type declaration"); + continue; + } + else if (XMLString::equals(attribute->getLocalName(),schemaLocation)) { + XT_log.debug("storing off xsi:schemaLocation attribute"); + if (m_schemaLocation) + XMLString::release(&m_schemaLocation); + m_schemaLocation=XMLString::replicate(attribute->getValue()); + continue; + } } else if (nsuri && !XMLString::equals(nsuri,XMLConstants::XML_NS)) { XT_log.debug("found namespace-qualified attribute, adding prefix to the list of namespaces on the XMLObject"); @@ -168,7 +172,7 @@ void AbstractXMLObjectUnmarshaller::unmarshallChildElements(const DOMElement* do processChildElement(childObject.get(), static_cast(childNode)); childObject.release(); } - else if (childNode->getNodeType() == DOMNode::TEXT_NODE) { + else if (childNode->getNodeType() == DOMNode::TEXT_NODE && !XMLString::isAllWhiteSpace(childNode->getNodeValue())) { XT_log.debug("processing element content"); processElementContent(childNode->getNodeValue()); } @@ -179,3 +183,14 @@ void AbstractXMLObjectUnmarshaller::processChildElement(XMLObject* child, const { throw UnmarshallingException("Invalid child element: $1",params(1,child->getElementQName().toString().c_str())); } + +void AbstractXMLObjectUnmarshaller::processAttribute(const DOMAttr* attribute) +{ + auto_ptr q(XMLHelper::getNodeQName(attribute)); + throw UnmarshallingException("Invalid attribute: $1",params(1,q->toString().c_str())); +} + +void AbstractXMLObjectUnmarshaller::processElementContent(const XMLCh* elementContent) +{ + throw UnmarshallingException("Invalid text content in element."); +} diff --git a/xmltooling/io/AbstractXMLObjectUnmarshaller.h b/xmltooling/io/AbstractXMLObjectUnmarshaller.h index 7d75827..9ed78bd 100644 --- a/xmltooling/io/AbstractXMLObjectUnmarshaller.h +++ b/xmltooling/io/AbstractXMLObjectUnmarshaller.h @@ -84,14 +84,14 @@ namespace xmltooling { * * @throws UnmarshallingException thrown if there is a problem adding the attribute to the XMLObject */ - virtual void processAttribute(const DOMAttr* attribute) {} + virtual void processAttribute(const DOMAttr* attribute); /** * Called if the element being unmarshalled contained textual content so that it can be added to the XMLObject. * * @param elementContent the Element's text content */ - virtual void processElementContent(const XMLCh* elementContent) {} + virtual void processElementContent(const XMLCh* elementContent); }; }; diff --git a/xmltooling/signature/impl/KeyInfoImpl.cpp b/xmltooling/signature/impl/KeyInfoImpl.cpp index 4643bf7..587591d 100644 --- a/xmltooling/signature/impl/KeyInfoImpl.cpp +++ b/xmltooling/signature/impl/KeyInfoImpl.cpp @@ -293,6 +293,7 @@ namespace xmlsignature { void processAttribute(const DOMAttr* attribute) { PROC_STRING_ATTRIB(Algorithm,ALGORITHM,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); } }; @@ -383,6 +384,7 @@ namespace xmlsignature { void processAttribute(const DOMAttr* attribute) { PROC_STRING_ATTRIB(URI,URI,NULL); PROC_STRING_ATTRIB(Type,TYPE,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); } }; @@ -743,6 +745,7 @@ namespace xmlsignature { void processAttribute(const DOMAttr* attribute) { PROC_ID_ATTRIB(Id,ID,NULL); + AbstractXMLObjectUnmarshaller::processAttribute(attribute); } };