Wrap rest of KeyInfo, add support for exposing object pairs.
authorScott Cantor <cantor.2@osu.edu>
Mon, 3 Apr 2006 05:00:18 +0000 (05:00 +0000)
committerScott Cantor <cantor.2@osu.edu>
Mon, 3 Apr 2006 05:00:18 +0000 (05:00 +0000)
xmltooling/XMLToolingConfig.cpp
xmltooling/exceptions.h
xmltooling/signature/KeyInfo.h
xmltooling/signature/Signature.h
xmltooling/signature/impl/KeyInfoImpl.cpp
xmltooling/util/XMLObjectChildrenList.h

index 6cd8826..80f844e 100644 (file)
@@ -62,14 +62,14 @@ using namespace std;
     Validator::registerValidator(q,new cname##SchemaValidator())
 
 
-DECL_EXCEPTION_FACTORY(XMLParserException);
-DECL_EXCEPTION_FACTORY(XMLObjectException);
-DECL_EXCEPTION_FACTORY(MarshallingException);
-DECL_EXCEPTION_FACTORY(UnmarshallingException);
-DECL_EXCEPTION_FACTORY(UnknownElementException);
-DECL_EXCEPTION_FACTORY(UnknownAttributeException);
-DECL_EXCEPTION_FACTORY(ValidationException);
-DECL_EXCEPTION_FACTORY(SignatureException);
+DECL_EXCEPTION_FACTORY(XMLParserException,xmltooling);
+DECL_EXCEPTION_FACTORY(XMLObjectException,xmltooling);
+DECL_EXCEPTION_FACTORY(MarshallingException,xmltooling);
+DECL_EXCEPTION_FACTORY(UnmarshallingException,xmltooling);
+DECL_EXCEPTION_FACTORY(UnknownElementException,xmltooling);
+DECL_EXCEPTION_FACTORY(UnknownAttributeException,xmltooling);
+DECL_EXCEPTION_FACTORY(ValidationException,xmltooling);
+DECL_EXCEPTION_FACTORY(SignatureException,xmlsignature);
 
 namespace xmltooling {
    XMLToolingInternalConfig g_config;
@@ -187,25 +187,44 @@ bool XMLToolingInternalConfig::init()
         REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,XPath);
         REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,Transform);
         REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,Transforms);
+        REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,RetrievalMethod);
+        REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,X509IssuerSerial);
+        REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,X509IssuerName);
+        REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,X509SerialNumber);
+        REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,X509SKI);
+        REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,X509SubjectName);
+        REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,X509Certificate);
+        REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,X509CRL);
+        REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,X509Data);
+        REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,SPKISexp);
+        REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,SPKIData);
+        REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,PGPKeyID);
+        REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,PGPKeyPacket);
+        REGISTER_ELEMENT(XMLConstants::XMLSIG_NS,PGPData);
         REGISTER_TYPE(XMLConstants::XMLSIG_NS,KeyInfo);
         REGISTER_TYPE(XMLConstants::XMLSIG_NS,KeyValue);
         REGISTER_TYPE(XMLConstants::XMLSIG_NS,DSAKeyValue);
         REGISTER_TYPE(XMLConstants::XMLSIG_NS,RSAKeyValue);
         REGISTER_TYPE(XMLConstants::XMLSIG_NS,Transform);
         REGISTER_TYPE(XMLConstants::XMLSIG_NS,Transforms);
+        REGISTER_TYPE(XMLConstants::XMLSIG_NS,RetrievalMethod);
+        REGISTER_TYPE(XMLConstants::XMLSIG_NS,X509IssuerSerial);
+        REGISTER_TYPE(XMLConstants::XMLSIG_NS,X509Data);
+        REGISTER_TYPE(XMLConstants::XMLSIG_NS,SPKIData);
+        REGISTER_TYPE(XMLConstants::XMLSIG_NS,PGPData);
 
 #ifndef XMLTOOLING_NO_XMLSEC
         XMLObjectBuilder::registerBuilder(QName(XMLConstants::XMLSIG_NS,Signature::LOCAL_NAME),new SignatureBuilder());
 #endif
 
-        REGISTER_EXCEPTION_FACTORY(XMLParserException);
-        REGISTER_EXCEPTION_FACTORY(XMLObjectException);
-        REGISTER_EXCEPTION_FACTORY(MarshallingException);
-        REGISTER_EXCEPTION_FACTORY(UnmarshallingException);
-        REGISTER_EXCEPTION_FACTORY(UnknownElementException);
-        REGISTER_EXCEPTION_FACTORY(UnknownAttributeException);
-        REGISTER_EXCEPTION_FACTORY(ValidationException);
-        REGISTER_EXCEPTION_FACTORY(SignatureException);
+        REGISTER_EXCEPTION_FACTORY(XMLParserException,xmltooling);
+        REGISTER_EXCEPTION_FACTORY(XMLObjectException,xmltooling);
+        REGISTER_EXCEPTION_FACTORY(MarshallingException,xmltooling);
+        REGISTER_EXCEPTION_FACTORY(UnmarshallingException,xmltooling);
+        REGISTER_EXCEPTION_FACTORY(UnknownElementException,xmltooling);
+        REGISTER_EXCEPTION_FACTORY(UnknownAttributeException,xmltooling);
+        REGISTER_EXCEPTION_FACTORY(ValidationException,xmltooling);
+        REGISTER_EXCEPTION_FACTORY(SignatureException,xmlsignature);
     }
     catch (const xercesc::XMLException&) {
         log.fatal("caught exception while initializing Xerces");
index a10db9b..3ed1d6d 100644 (file)
 /**
  * Declares a derived exception class
  * 
- * @param name  the exception class
- * @param base  the base class
- * @param desc
+ * @param name      the exception class
+ * @param ns        the exception class C++ namespace
+ * @param base      the base class
+ * @param desc      documentation comment for class
  */
-#define DECL_XMLTOOLING_EXCEPTION(name,base,desc) \
+#define DECL_XMLTOOLING_EXCEPTION(name,ns,base,desc) \
     XMLTOOLING_DOXYGEN(desc) \
-    class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) name : public xmltooling::base { \
+    class XMLTOOL_EXCEPTIONAPI(XMLTOOL_API) name : public base { \
     public: \
         XMLTOOLING_DOXYGEN(Constructor) \
-        name(const char* msg=NULL, const xmltooling::params& p=xmltooling::params()) \
-            : xmltooling::base(msg,p) {} \
+        name(const char* msg=NULL, const xmltooling::params& p=xmltooling::params()) : base(msg,p) {} \
         XMLTOOLING_DOXYGEN(Constructor) \
-        name(const char* msg, const xmltooling::namedparams& p) \
-            : xmltooling::base(msg,p) {} \
+        name(const char* msg, const xmltooling::namedparams& p) : base(msg,p) {} \
         XMLTOOLING_DOXYGEN(Constructor) \
-        name(const std::string& msg, const xmltooling::params& p=xmltooling::params()) \
-            : xmltooling::base(msg,p) {} \
+        name(const std::string& msg, const xmltooling::params& p=xmltooling::params()) : base(msg,p) {} \
         XMLTOOLING_DOXYGEN(Constructor) \
-        name(const std::string& msg, const xmltooling::namedparams& p) \
-            : xmltooling::base(msg,p) {} \
+        name(const std::string& msg, const xmltooling::namedparams& p) : base(msg,p) {} \
         virtual ~name() {} \
-        virtual const char* getClassName() const { return "xmltooling::"#name; } \
+        virtual const char* getClassName() const { return #ns"::"#name; } \
         void raise() const {throw *this;} \
     }
 
  * Declares a factory function for an exception class.
  * 
  * @param name  the exception class name
+ * @param ns    the exception class C++ namespace
  */
-#define DECL_EXCEPTION_FACTORY(name) \
+#define DECL_EXCEPTION_FACTORY(name,ns) \
     xmltooling::XMLToolingException* name##Factory() \
     { \
-        return new xmltooling::name(); \
+        return new ns::name(); \
     }
 
 /**
  * Registers a factory for an exception class.
  * 
- * @param name  the exception class name
+ * @param name      the exception class name
+ * @param ns        the exception class C++ namespace
  */
-#define REGISTER_EXCEPTION_FACTORY(name) XMLToolingException::registerFactory("xmltooling::"#name,name##Factory)
+#define REGISTER_EXCEPTION_FACTORY(name,ns) XMLToolingException::registerFactory(#ns".."#name,name##Factory)
 
 #if defined (_MSC_VER)
     #pragma warning( push )
@@ -335,14 +334,13 @@ namespace xmltooling {
         static ExceptionFactoryMap m_factoryMap;
     };
 
-    DECL_XMLTOOLING_EXCEPTION(XMLParserException,XMLToolingException,Exceptions related to XML parsing);
-    DECL_XMLTOOLING_EXCEPTION(XMLObjectException,XMLToolingException,Exceptions in basic object usage);
-    DECL_XMLTOOLING_EXCEPTION(MarshallingException,XMLToolingException,Exceptions during object marshalling);
-    DECL_XMLTOOLING_EXCEPTION(UnmarshallingException,XMLToolingException,Exceptions during object unmarshalling);
-    DECL_XMLTOOLING_EXCEPTION(UnknownElementException,XMLToolingException,Exceptions due to processing of unknown element content);
-    DECL_XMLTOOLING_EXCEPTION(UnknownAttributeException,XMLToolingException,Exceptions due to processing of unknown attributes);
-    DECL_XMLTOOLING_EXCEPTION(ValidationException,XMLToolingException,Exceptions during object validation);
-    DECL_XMLTOOLING_EXCEPTION(SignatureException,XMLToolingException,Exceptions in signature processing);
+    DECL_XMLTOOLING_EXCEPTION(XMLParserException,xmltooling,XMLToolingException,Exceptions related to XML parsing);
+    DECL_XMLTOOLING_EXCEPTION(XMLObjectException,xmltooling,XMLToolingException,Exceptions in basic object usage);
+    DECL_XMLTOOLING_EXCEPTION(MarshallingException,xmltooling,XMLToolingException,Exceptions during object marshalling);
+    DECL_XMLTOOLING_EXCEPTION(UnmarshallingException,xmltooling,XMLToolingException,Exceptions during object unmarshalling);
+    DECL_XMLTOOLING_EXCEPTION(UnknownElementException,xmltooling,XMLToolingException,Exceptions due to processing of unknown element content);
+    DECL_XMLTOOLING_EXCEPTION(UnknownAttributeException,xmltooling,XMLToolingException,Exceptions due to processing of unknown attributes);
+    DECL_XMLTOOLING_EXCEPTION(ValidationException,xmltooling,XMLToolingException,Exceptions during object validation);
 
 };
 
index a3b21f0..f4280fd 100644 (file)
@@ -49,6 +49,15 @@ namespace xmlsignature {
     DECL_XMLOBJECT_SIMPLE(XMLTOOL_API,Y,Value,XML Digital Signature version 20020212 Y element);
     DECL_XMLOBJECT_SIMPLE(XMLTOOL_API,J,Value,XML Digital Signature version 20020212 J element);
     DECL_XMLOBJECT_SIMPLE(XMLTOOL_API,XPath,Expression,XML Digital Signature version 20020212 XPath element);
+    DECL_XMLOBJECT_SIMPLE(XMLTOOL_API,X509IssuerName,Name,XML Digital Signature version 20020212 X509IssuerName element);
+    DECL_XMLOBJECT_SIMPLE(XMLTOOL_API,X509SerialNumber,SerialNumber,XML Digital Signature version 20020212 X509SerialNumber element);
+    DECL_XMLOBJECT_SIMPLE(XMLTOOL_API,X509SKI,Value,XML Digital Signature version 20020212 X509SKI element);
+    DECL_XMLOBJECT_SIMPLE(XMLTOOL_API,X509SubjectName,Name,XML Digital Signature version 20020212 X509SubjectName element);
+    DECL_XMLOBJECT_SIMPLE(XMLTOOL_API,X509Certificate,Value,XML Digital Signature version 20020212 X509Certificate element);
+    DECL_XMLOBJECT_SIMPLE(XMLTOOL_API,X509CRL,Value,XML Digital Signature version 20020212 X509CRL element);
+    DECL_XMLOBJECT_SIMPLE(XMLTOOL_API,SPKISexp,Value,XML Digital Signature version 20020212 SPKISexp element);
+    DECL_XMLOBJECT_SIMPLE(XMLTOOL_API,PGPKeyID,ID,XML Digital Signature version 20020212 PGPKeyID element);
+    DECL_XMLOBJECT_SIMPLE(XMLTOOL_API,PGPKeyPacket,Packet,XML Digital Signature version 20020212 PGPKeyPacket element);
 
     BEGIN_XMLOBJECT(XMLTOOL_API,DSAKeyValue,xmltooling::XMLObject,XML Digital Signature version 20020212 DSAKeyValue element);
         DECL_XMLOBJECT_CHILD(P);
@@ -91,17 +100,81 @@ namespace xmlsignature {
         static const XMLCh TYPE_NAME[];
     END_XMLOBJECT;
 
+    BEGIN_XMLOBJECT(XMLTOOL_API,RetrievalMethod,xmltooling::XMLObject,XML Digital Signature version 20020212 RetrievalMethod element);
+        DECL_XMLOBJECT_ATTRIB(URI,URI);
+        DECL_XMLOBJECT_ATTRIB(Type,TYPE);
+        DECL_XMLOBJECT_CHILD(Transforms);
+        /** RetrievalMethodType local name */
+        static const XMLCh TYPE_NAME[];
+    END_XMLOBJECT;
+
+    BEGIN_XMLOBJECT(XMLTOOL_API,X509IssuerSerial,xmltooling::XMLObject,XML Digital Signature version 20020212 X509IssuerSerial element);
+        DECL_XMLOBJECT_CHILD(X509IssuerName);
+        DECL_XMLOBJECT_CHILD(X509SerialNumber);
+        /** X509IssuerSerialType local name */
+        static const XMLCh TYPE_NAME[];
+    END_XMLOBJECT;
+
+    BEGIN_XMLOBJECT(XMLTOOL_API,X509Data,xmltooling::XMLObject,XML Digital Signature version 20020212 X509Data element);
+        DECL_XMLOBJECT_CHILDREN(X509IssuerSerial);
+        DECL_XMLOBJECT_CHILDREN(X509SKI);
+        DECL_XMLOBJECT_CHILDREN(X509SubjectName);
+        DECL_XMLOBJECT_CHILDREN(X509Certificate);
+        DECL_XMLOBJECT_CHILDREN(X509CRL);
+        DECL_XMLOBJECT_CHILDREN(XMLObject);
+        /** X509DataType local name */
+        static const XMLCh TYPE_NAME[];
+    END_XMLOBJECT;
+
+    BEGIN_XMLOBJECT(XMLTOOL_API,SPKIData,xmltooling::XMLObject,XML Digital Signature version 20020212 SPKIData element);
+        /** SPKIDataType local name */
+        static const XMLCh TYPE_NAME[];
+        
+        /** Returns modifiable collection of SPKIsexp/XMLObject pairs. */
+        virtual VectorOfPairs(SPKISexp,xmltooling::XMLObject) getSPKISexps()=0;
+        
+        /** Returns reference to immutable collection of SPKIsexp/XMLObject pairs. */
+        virtual const std::vector< std::pair<SPKISexp*,xmltooling::XMLObject*> >& getSPKISexps() const=0;
+    END_XMLOBJECT;
+
+    BEGIN_XMLOBJECT(XMLTOOL_API,PGPData,xmltooling::XMLObject,XML Digital Signature version 20020212 PGPData element);
+        DECL_XMLOBJECT_CHILD(PGPKeyID);
+        DECL_XMLOBJECT_CHILD(PGPKeyPacket);
+        DECL_XMLOBJECT_CHILDREN(XMLObject);
+        /** PGPDataType local name */
+        static const XMLCh TYPE_NAME[];
+    END_XMLOBJECT;
+
     BEGIN_XMLOBJECT(XMLTOOL_API,KeyInfo,xmltooling::ElementProxy,XML Digital Signature version 20020212 KeyInfo element);
         DECL_XMLOBJECT_ATTRIB(Id,ID);
+        DECL_XMLOBJECT_CHILDREN(X509Data);
         DECL_XMLOBJECT_CHILDREN(KeyName);
+        DECL_XMLOBJECT_CHILDREN(KeyValue);
+        DECL_XMLOBJECT_CHILDREN(RetrievalMethod);
         DECL_XMLOBJECT_CHILDREN(MgmtData);
+        DECL_XMLOBJECT_CHILDREN(PGPData);
+        DECL_XMLOBJECT_CHILDREN(SPKIData);
         /** KeyInfoType local name */
         static const XMLCh TYPE_NAME[];
     END_XMLOBJECT;
 
+    DECL_XMLSIGOBJECTBUILDER(PGPData);
+    DECL_XMLSIGOBJECTBUILDER(PGPKeyID);
+    DECL_XMLSIGOBJECTBUILDER(PGPKeyPacket);
+    DECL_XMLSIGOBJECTBUILDER(SPKIData);
+    DECL_XMLSIGOBJECTBUILDER(SPKISexp);
+    DECL_XMLSIGOBJECTBUILDER(X509IssuerSerial);
+    DECL_XMLSIGOBJECTBUILDER(X509IssuerName);
+    DECL_XMLSIGOBJECTBUILDER(X509SerialNumber);
+    DECL_XMLSIGOBJECTBUILDER(X509SKI);
+    DECL_XMLSIGOBJECTBUILDER(X509SubjectName);
+    DECL_XMLSIGOBJECTBUILDER(X509Certificate);
+    DECL_XMLSIGOBJECTBUILDER(X509CRL);
+    DECL_XMLSIGOBJECTBUILDER(X509Data);
     DECL_XMLSIGOBJECTBUILDER(XPath);
     DECL_XMLSIGOBJECTBUILDER(Transform);
     DECL_XMLSIGOBJECTBUILDER(Transforms);
+    DECL_XMLSIGOBJECTBUILDER(RetrievalMethod);
     DECL_XMLSIGOBJECTBUILDER(KeyName);
     DECL_XMLSIGOBJECTBUILDER(MgmtData);
     DECL_XMLSIGOBJECTBUILDER(Modulus);
@@ -131,7 +204,16 @@ namespace xmlsignature {
     XMLOBJECTVALIDATOR_SIMPLE(XMLTOOL_DLLLOCAL,Y,Value);
     XMLOBJECTVALIDATOR_SIMPLE(XMLTOOL_DLLLOCAL,J,Value);
     XMLOBJECTVALIDATOR_SIMPLE(XMLTOOL_DLLLOCAL,XPath,Expression);
-
+    XMLOBJECTVALIDATOR_SIMPLE(XMLTOOL_DLLLOCAL,X509IssuerName,Name);
+    XMLOBJECTVALIDATOR_SIMPLE(XMLTOOL_DLLLOCAL,X509SerialNumber,SerialNumber);
+    XMLOBJECTVALIDATOR_SIMPLE(XMLTOOL_DLLLOCAL,X509SKI,Value);
+    XMLOBJECTVALIDATOR_SIMPLE(XMLTOOL_DLLLOCAL,X509SubjectName,Name);
+    XMLOBJECTVALIDATOR_SIMPLE(XMLTOOL_DLLLOCAL,X509Certificate,Value);
+    XMLOBJECTVALIDATOR_SIMPLE(XMLTOOL_DLLLOCAL,X509CRL,Value);
+    XMLOBJECTVALIDATOR_SIMPLE(XMLTOOL_DLLLOCAL,SPKISexp,Value);
+    XMLOBJECTVALIDATOR_SIMPLE(XMLTOOL_DLLLOCAL,PGPKeyID,ID);
+    XMLOBJECTVALIDATOR_SIMPLE(XMLTOOL_DLLLOCAL,PGPKeyPacket,Packet);
+    
     BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,RSAKeyValue);
         XMLOBJECTVALIDATOR_REQUIRE(RSAKeyValue,Modulus);
         XMLOBJECTVALIDATOR_REQUIRE(RSAKeyValue,Exponent);
@@ -155,6 +237,28 @@ namespace xmlsignature {
         XMLOBJECTVALIDATOR_NONEMPTY(Transforms,Transform);
     END_XMLOBJECTVALIDATOR;
 
+    BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,RetrievalMethod);
+        XMLOBJECTVALIDATOR_REQUIRE(RetrievalMethod,URI);
+    END_XMLOBJECTVALIDATOR;
+
+    BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,X509IssuerSerial);
+        XMLOBJECTVALIDATOR_REQUIRE(X509IssuerSerial,X509IssuerName);
+        XMLOBJECTVALIDATOR_REQUIRE(X509IssuerSerial,X509SerialNumber);
+    END_XMLOBJECTVALIDATOR;
+
+    BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,X509Data);
+        if (!ptr->hasChildren())
+            throw xmltooling::ValidationException("X509Data must have at least one child element.");
+    END_XMLOBJECTVALIDATOR;
+
+    BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,SPKIData);
+        XMLOBJECTVALIDATOR_NONEMPTY(SPKIData,SPKISexp);
+    END_XMLOBJECTVALIDATOR;
+
+    BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,PGPData);
+        XMLOBJECTVALIDATOR_ONEOF(PGPData,PGPKeyID,PGPKeyPacket);
+    END_XMLOBJECTVALIDATOR;
+
     BEGIN_XMLOBJECTVALIDATOR(XMLTOOL_DLLLOCAL,KeyInfo);
         XMLOBJECTVALIDATOR_NONEMPTY(KeyInfo,XMLObject);
     END_XMLOBJECTVALIDATOR;
index 717fa74..53bb10a 100644 (file)
@@ -23,6 +23,7 @@
 #if !defined(__xmltooling_sig_h__) && !defined(XMLTOOLING_NO_XMLSEC)\r
 #define __xmltooling_sig_h__\r
 \r
+#include <xmltooling/exceptions.h>\r
 #include <xmltooling/XMLObjectBuilder.h>\r
 #include <xmltooling/signature/SigningContext.h>\r
 #include <xmltooling/signature/VerifyingContext.h>\r
@@ -98,6 +99,8 @@ namespace xmlsignature {
         virtual Signature* buildObject() const;\r
     };\r
 \r
+    DECL_XMLTOOLING_EXCEPTION(SignatureException,xmlsignature,xmltooling::XMLToolingException,Exceptions in signature processing);\r
+\r
 };\r
 \r
 #endif /* __xmltooling_sig_h__ */\r
index 746cd0a..eac57ad 100644 (file)
@@ -59,13 +59,20 @@ namespace xmlsignature {
         DSAKeyValueImpl(const DSAKeyValueImpl& src)
                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
             init();
-            setP(src.getP());
-            setQ(src.getQ());
-            setG(src.getG());
-            setY(src.getY());
-            setJ(src.getJ());
-            setSeed(src.getSeed());
-            setPgenCounter(src.getPgenCounter());
+            if (src.getP())
+                setP(src.getP()->cloneP());
+            if (src.getQ())
+                setQ(src.getQ()->cloneQ());
+            if (src.getG())
+                setG(src.getG()->cloneG());
+            if (src.getY())
+                setY(src.getY()->cloneY());
+            if (src.getJ())
+                setJ(src.getJ()->cloneJ());
+            if (src.getSeed())
+                setSeed(src.getSeed()->cloneSeed());
+            if (src.getPgenCounter())
+                setPgenCounter(src.getPgenCounter()->clonePgenCounter());
         }
         
         void init() {
@@ -137,8 +144,10 @@ namespace xmlsignature {
         RSAKeyValueImpl(const RSAKeyValueImpl& src)
                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
             init();
-            setModulus(src.getModulus());
-            setExponent(src.getExponent());
+            if (src.getModulus())
+                setModulus(src.getModulus()->cloneModulus());
+            if (src.getExponent())
+                setExponent(src.getExponent()->cloneExponent());
         }
         
         void init() {
@@ -180,9 +189,12 @@ namespace xmlsignature {
         KeyValueImpl(const KeyValueImpl& src)
                 : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
             init();
-            setDSAKeyValue(src.getDSAKeyValue());
-            setRSAKeyValue(src.getRSAKeyValue());
-            setXMLObject(src.getXMLObject());
+            if (src.getDSAKeyValue())
+                setDSAKeyValue(src.getDSAKeyValue()->cloneDSAKeyValue());
+            if (src.getRSAKeyValue())
+                setRSAKeyValue(src.getRSAKeyValue()->cloneRSAKeyValue());
+            if (src.getXMLObject())
+                setXMLObject(src.getXMLObject()->clone());
             setTextContent(src.getTextContent());
         }
         
@@ -318,6 +330,301 @@ namespace xmlsignature {
         }
     };
 
+    class XMLTOOL_DLLLOCAL RetrievalMethodImpl : public RetrievalMethod,
+        public AbstractDOMCachingXMLObject,
+        public AbstractValidatingXMLObject,
+        public AbstractXMLObjectMarshaller,
+        public AbstractXMLObjectUnmarshaller
+    {
+    public:
+        virtual ~RetrievalMethodImpl() {}
+
+        RetrievalMethodImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+            : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
+            init();
+        }
+            
+        RetrievalMethodImpl(const RetrievalMethodImpl& src)
+                : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
+            init();
+            setURI(getURI());
+            setType(getType());
+            if (src.getTransforms())
+                setTransforms(src.getTransforms()->cloneTransforms());
+        }
+        
+        void init() {
+            m_URI=m_Type=NULL;
+            m_Transforms=NULL;
+            m_children.push_back(NULL);
+            m_pos_Transforms=m_children.begin();
+        }
+        
+        IMPL_XMLOBJECT_CLONE(RetrievalMethod);
+        IMPL_XMLOBJECT_ATTRIB(URI);
+        IMPL_XMLOBJECT_ATTRIB(Type);
+        IMPL_XMLOBJECT_CHILD(Transforms);
+
+    protected:
+        void marshallAttributes(DOMElement* domElement) const {
+            MARSHALL_XMLOBJECT_ATTRIB(URI,URI,NULL);
+            MARSHALL_XMLOBJECT_ATTRIB(Type,TYPE,NULL);
+        }
+
+        void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
+            PROC_XMLOBJECT_CHILD(Transforms,XMLConstants::XMLSIG_NS);
+            throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
+        }
+
+        void processAttribute(const DOMAttr* attribute) {
+            PROC_XMLOBJECT_ATTRIB(URI,URI,NULL);
+            PROC_XMLOBJECT_ATTRIB(Type,TYPE,NULL);
+        }
+    };
+
+    class XMLTOOL_DLLLOCAL X509IssuerSerialImpl : public X509IssuerSerial,
+        public AbstractDOMCachingXMLObject,
+        public AbstractValidatingXMLObject,
+        public AbstractXMLObjectMarshaller,
+        public AbstractXMLObjectUnmarshaller
+    {
+    public:
+        virtual ~X509IssuerSerialImpl() {}
+
+        X509IssuerSerialImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
+            init();
+        }
+            
+        X509IssuerSerialImpl(const X509IssuerSerialImpl& src)
+                : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
+            init();
+            if (src.getX509IssuerName())
+                setX509IssuerName(src.getX509IssuerName()->cloneX509IssuerName());
+            if (src.getX509SerialNumber())
+                setX509SerialNumber(src.getX509SerialNumber()->cloneX509SerialNumber());
+        }
+        
+        void init() {
+            m_X509IssuerName=NULL;
+            m_X509SerialNumber=NULL;
+            m_children.push_back(NULL);
+            m_children.push_back(NULL);
+            m_pos_X509IssuerName=m_children.begin();
+            m_pos_X509SerialNumber=m_pos_X509IssuerName;
+            ++m_pos_X509SerialNumber;
+        }
+        
+        IMPL_XMLOBJECT_CLONE(X509IssuerSerial);
+        IMPL_XMLOBJECT_CHILD(X509IssuerName);
+        IMPL_XMLOBJECT_CHILD(X509SerialNumber);
+
+    protected:
+        void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
+            PROC_XMLOBJECT_CHILD(X509IssuerName,XMLConstants::XMLSIG_NS);
+            PROC_XMLOBJECT_CHILD(X509SerialNumber,XMLConstants::XMLSIG_NS);
+            throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
+        }
+    };
+
+    class XMLTOOL_DLLLOCAL X509DataImpl : public X509Data,
+        public AbstractDOMCachingXMLObject,
+        public AbstractValidatingXMLObject,
+        public AbstractXMLObjectMarshaller,
+        public AbstractXMLObjectUnmarshaller
+    {
+    public:
+        virtual ~X509DataImpl() {}
+
+        X509DataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+            : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
+        }
+            
+        X509DataImpl(const X509DataImpl& src)
+                : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
+            for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
+                if (*i) {
+                    X509Certificate* xcert=dynamic_cast<X509Certificate*>(*i);
+                    if (xcert) {
+                        getX509Certificates().push_back(xcert->cloneX509Certificate());
+                        continue;
+                    }
+
+                    X509CRL* xcrl=dynamic_cast<X509CRL*>(*i);
+                    if (xcrl) {
+                        getX509CRLs().push_back(xcrl->cloneX509CRL());
+                        continue;
+                    }
+
+                    X509SubjectName* xsn=dynamic_cast<X509SubjectName*>(*i);
+                    if (xsn) {
+                        getX509SubjectNames().push_back(xsn->cloneX509SubjectName());
+                        continue;
+                    }
+
+                    X509IssuerSerial* xis=dynamic_cast<X509IssuerSerial*>(*i);
+                    if (xis) {
+                        getX509IssuerSerials().push_back(xis->cloneX509IssuerSerial());
+                        continue;
+                    }
+
+                    X509SKI* xski=dynamic_cast<X509SKI*>(*i);
+                    if (xski) {
+                        getX509SKIs().push_back(xski->cloneX509SKI());
+                        continue;
+                    }
+
+                    getXMLObjects().push_back((*i)->clone());
+                }
+            }
+        }
+        
+        IMPL_XMLOBJECT_CLONE(X509Data);
+        IMPL_XMLOBJECT_CHILDREN(X509IssuerSerial,m_children.end());
+        IMPL_XMLOBJECT_CHILDREN(X509SKI,m_children.end());
+        IMPL_XMLOBJECT_CHILDREN(X509SubjectName,m_children.end());
+        IMPL_XMLOBJECT_CHILDREN(X509Certificate,m_children.end());
+        IMPL_XMLOBJECT_CHILDREN(X509CRL,m_children.end());
+        IMPL_XMLOBJECT_CHILDREN(XMLObject,m_children.end());
+
+    protected:
+        void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
+            PROC_XMLOBJECT_CHILDREN(X509IssuerSerial,XMLConstants::XMLSIG_NS);
+            PROC_XMLOBJECT_CHILDREN(X509SKI,XMLConstants::XMLSIG_NS);
+            PROC_XMLOBJECT_CHILDREN(X509SubjectName,XMLConstants::XMLSIG_NS);
+            PROC_XMLOBJECT_CHILDREN(X509Certificate,XMLConstants::XMLSIG_NS);
+            PROC_XMLOBJECT_CHILDREN(X509CRL,XMLConstants::XMLSIG_NS);
+            
+            // Unknown child.
+            const XMLCh* nsURI=root->getNamespaceURI();
+            if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
+                getXMLObjects().push_back(childXMLObject);
+            
+            throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
+        }
+    };
+
+    class XMLTOOL_DLLLOCAL SPKIDataImpl : public SPKIData,
+        public AbstractDOMCachingXMLObject,
+        public AbstractValidatingXMLObject,
+        public AbstractXMLObjectMarshaller,
+        public AbstractXMLObjectUnmarshaller
+    {
+    public:
+        virtual ~SPKIDataImpl() {}
+
+        SPKIDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+            : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
+        }
+            
+        SPKIDataImpl(const SPKIDataImpl& src)
+                : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
+            VectorOfPairs(SPKISexp,XMLObject) v=getSPKISexps();
+            for (vector< pair<SPKISexp*,XMLObject*> >::const_iterator i=src.m_SPKISexps.begin(); i!=src.m_SPKISexps.end(); i++) {
+                if (i->first) {
+                    v.push_back(make_pair(i->first->cloneSPKISexp(),(i->second ? i->second->clone() : (XMLObject*)NULL)));
+                }
+            }
+        }
+        
+        IMPL_XMLOBJECT_CLONE(SPKIData);
+
+    private:
+        vector< pair<SPKISexp*,XMLObject*> > m_SPKISexps;
+
+    public:
+        VectorOfPairs(SPKISexp,XMLObject) getSPKISexps() {
+            return VectorOfPairs(SPKISexp,XMLObject)(this, m_SPKISexps, &m_children, m_children.end());
+        }
+        
+        const vector< pair<SPKISexp*,XMLObject*> >& getSPKISexps() const {
+            return m_SPKISexps;
+        }
+        
+    protected:
+        void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
+            if (XMLHelper::isNodeNamed(root,XMLConstants::XMLSIG_NS,SPKISexp::LOCAL_NAME)) {
+                SPKISexp* typesafe=dynamic_cast<SPKISexp*>(childXMLObject);
+                if (typesafe) {
+                    getSPKISexps().push_back(make_pair(typesafe,(XMLObject*)NULL));
+                    return;
+                }
+            }
+
+            // Unknown child (has to be paired with the last SPKISexp processed.
+            const XMLCh* nsURI=root->getNamespaceURI();
+            if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI) {
+                // Update second half of pair in vector, then add to master list.
+                if (m_SPKISexps.back().second==NULL) {
+                    m_SPKISexps.back().second=childXMLObject;
+                    m_children.push_back(childXMLObject);
+                }
+                else
+                    throw UnmarshallingException("Extension element must follow ds:SPKISexp element.");
+            }
+            
+            throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
+        }
+    };
+
+    class XMLTOOL_DLLLOCAL PGPDataImpl : public PGPData,
+        public AbstractDOMCachingXMLObject,
+        public AbstractValidatingXMLObject,
+        public AbstractXMLObjectMarshaller,
+        public AbstractXMLObjectUnmarshaller
+    {
+    public:
+        virtual ~PGPDataImpl() {}
+
+        PGPDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
+            init();
+        }
+            
+        PGPDataImpl(const PGPDataImpl& src)
+                : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) {
+            init();
+            if (src.getPGPKeyID())
+                setPGPKeyID(src.getPGPKeyID()->clonePGPKeyID());
+            if (src.getPGPKeyPacket())
+                setPGPKeyPacket(src.getPGPKeyPacket()->clonePGPKeyPacket());
+            VectorOf(XMLObject) v=getXMLObjects();
+            for (vector<XMLObject*>::const_iterator i=src.m_XMLObjects.begin(); i!=src.m_XMLObjects.end(); i++) {
+                if (*i) {
+                    v.push_back((*i)->clone());
+                }
+            }
+        }
+        
+        void init() {
+            m_PGPKeyID=NULL;
+            m_PGPKeyPacket=NULL;
+            m_children.push_back(NULL);
+            m_children.push_back(NULL);
+            m_pos_PGPKeyID=m_children.begin();
+            m_pos_PGPKeyPacket=m_pos_PGPKeyID;
+            ++m_pos_PGPKeyPacket;
+        }
+        
+        IMPL_XMLOBJECT_CLONE(PGPData);
+        IMPL_XMLOBJECT_CHILD(PGPKeyID);
+        IMPL_XMLOBJECT_CHILD(PGPKeyPacket);
+        IMPL_XMLOBJECT_CHILDREN(XMLObject,m_children.end());
+
+    protected:
+        void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
+            PROC_XMLOBJECT_CHILD(PGPKeyID,XMLConstants::XMLSIG_NS);
+            PROC_XMLOBJECT_CHILD(PGPKeyPacket,XMLConstants::XMLSIG_NS);
+
+            // Unknown child.
+            const XMLCh* nsURI=root->getNamespaceURI();
+            if (!XMLString::equals(nsURI,XMLConstants::XMLSIG_NS) && nsURI && *nsURI)
+                getXMLObjects().push_back(childXMLObject);
+
+            throw UnmarshallingException("Invalid child element: $1",params(1,childXMLObject->getElementQName().toString().c_str()));
+        }
+    };
+
     class XMLTOOL_DLLLOCAL KeyInfoImpl : public KeyInfo,
         public AbstractDOMCachingXMLObject,
         public AbstractElementProxy,
@@ -337,21 +644,48 @@ namespace xmlsignature {
                     AbstractValidatingXMLObject(src), m_Id(XMLString::replicate(src.m_Id)) {
             for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
                 if (*i) {
+                    X509Data* xd=dynamic_cast<X509Data*>(*i);
+                    if (xd) {
+                        getX509Datas().push_back(xd->cloneX509Data());
+                        continue;
+                    }
+
                     KeyName* kn=dynamic_cast<KeyName*>(*i);
                     if (kn) {
                         getKeyNames().push_back(kn->cloneKeyName());
                         continue;
                     }
+
                     KeyValue* kv=dynamic_cast<KeyValue*>(*i);
                     if (kv) {
                         getKeyValues().push_back(kv->cloneKeyValue());
                         continue;
                     }
+
+                    RetrievalMethod* rm=dynamic_cast<RetrievalMethod*>(*i);
+                    if (rm) {
+                        getRetrievalMethods().push_back(rm->cloneRetrievalMethod());
+                        continue;
+                    }
+
                     MgmtData* md=dynamic_cast<MgmtData*>(*i);
                     if (md) {
                         getMgmtDatas().push_back(md->cloneMgmtData());
                         continue;
                     }
+
+                    SPKIData* sd=dynamic_cast<SPKIData*>(*i);
+                    if (sd) {
+                        getSPKIDatas().push_back(sd->cloneSPKIData());
+                        continue;
+                    }
+
+                    PGPData* pd=dynamic_cast<PGPData*>(*i);
+                    if (pd) {
+                        getPGPDatas().push_back(pd->clonePGPData());
+                        continue;
+                    }
+
                     getXMLObjects().push_back((*i)->clone());
                 }
             }
@@ -361,7 +695,11 @@ namespace xmlsignature {
         IMPL_XMLOBJECT_ATTRIB(Id);
         IMPL_XMLOBJECT_CHILDREN(KeyName,m_children.end());
         IMPL_XMLOBJECT_CHILDREN(KeyValue,m_children.end());
+        IMPL_XMLOBJECT_CHILDREN(RetrievalMethod,m_children.end());
+        IMPL_XMLOBJECT_CHILDREN(X509Data,m_children.end());
         IMPL_XMLOBJECT_CHILDREN(MgmtData,m_children.end());
+        IMPL_XMLOBJECT_CHILDREN(SPKIData,m_children.end());
+        IMPL_XMLOBJECT_CHILDREN(PGPData,m_children.end());
 
     protected:
         void marshallAttributes(DOMElement* domElement) const {
@@ -379,9 +717,13 @@ namespace xmlsignature {
         }
 
         void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
+            PROC_XMLOBJECT_CHILDREN(X509Data,XMLConstants::XMLSIG_NS);
             PROC_XMLOBJECT_CHILDREN(KeyName,XMLConstants::XMLSIG_NS);
             PROC_XMLOBJECT_CHILDREN(KeyValue,XMLConstants::XMLSIG_NS);
+            PROC_XMLOBJECT_CHILDREN(RetrievalMethod,XMLConstants::XMLSIG_NS);
             PROC_XMLOBJECT_CHILDREN(MgmtData,XMLConstants::XMLSIG_NS);
+            PROC_XMLOBJECT_CHILDREN(SPKIData,XMLConstants::XMLSIG_NS);
+            PROC_XMLOBJECT_CHILDREN(PGPData,XMLConstants::XMLSIG_NS);
             
             // Unknown child.
             const XMLCh* nsURI=root->getNamespaceURI();
@@ -408,6 +750,15 @@ namespace xmlsignature {
     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,Y,Value);
     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,J,Value);
     DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,XPath,Expression);
+    DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,X509IssuerName,Name);
+    DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,X509SerialNumber,SerialNumber);
+    DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,X509SKI,Value);
+    DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,X509SubjectName,Name);
+    DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,X509Certificate,Value);
+    DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,X509CRL,Value);
+    DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,SPKISexp,Value);
+    DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,PGPKeyID,ID);
+    DECL_XMLOBJECTIMPL_SIMPLE(XMLTOOL_DLLLOCAL,PGPKeyPacket,Packet);
 };
 
 #if defined (_MSC_VER)
@@ -416,9 +767,18 @@ namespace xmlsignature {
 
 // Builder Implementations
 
+IMPL_XMLOBJECTBUILDER(X509IssuerSerial);
+IMPL_XMLOBJECTBUILDER(X509IssuerName);
+IMPL_XMLOBJECTBUILDER(X509SerialNumber);
+IMPL_XMLOBJECTBUILDER(X509SKI);
+IMPL_XMLOBJECTBUILDER(X509SubjectName);
+IMPL_XMLOBJECTBUILDER(X509Certificate);
+IMPL_XMLOBJECTBUILDER(X509CRL);
+IMPL_XMLOBJECTBUILDER(X509Data);
 IMPL_XMLOBJECTBUILDER(XPath);
 IMPL_XMLOBJECTBUILDER(Transform);
 IMPL_XMLOBJECTBUILDER(Transforms);
+IMPL_XMLOBJECTBUILDER(RetrievalMethod);
 IMPL_XMLOBJECTBUILDER(KeyName);
 IMPL_XMLOBJECTBUILDER(MgmtData);
 IMPL_XMLOBJECTBUILDER(Modulus);
@@ -434,30 +794,85 @@ IMPL_XMLOBJECTBUILDER(DSAKeyValue);
 IMPL_XMLOBJECTBUILDER(RSAKeyValue);
 IMPL_XMLOBJECTBUILDER(KeyValue);
 IMPL_XMLOBJECTBUILDER(KeyInfo);
-
-const XMLCh KeyInfo::LOCAL_NAME[] =         UNICODE_LITERAL_7(K,e,y,I,n,f,o);
-const XMLCh KeyInfo::TYPE_NAME[] =          UNICODE_LITERAL_11(K,e,y,I,n,f,o,T,y,p,e);
-const XMLCh KeyInfo::ID_ATTRIB_NAME[] =     UNICODE_LITERAL_2(I,d);
-const XMLCh KeyValue::LOCAL_NAME[] =        UNICODE_LITERAL_8(K,e,y,V,a,l,u,e);
-const XMLCh KeyValue::TYPE_NAME[] =         UNICODE_LITERAL_12(K,e,y,V,a,l,u,e,T,y,p,e);
-const XMLCh DSAKeyValue::LOCAL_NAME[] =     UNICODE_LITERAL_11(D,S,A,K,e,y,V,a,l,u,e);
-const XMLCh DSAKeyValue::TYPE_NAME[] =      UNICODE_LITERAL_15(D,S,A,K,e,y,V,a,l,u,e,T,y,p,e);
-const XMLCh RSAKeyValue::LOCAL_NAME[] =     UNICODE_LITERAL_11(R,S,A,K,e,y,V,a,l,u,e);
-const XMLCh RSAKeyValue::TYPE_NAME[] =      UNICODE_LITERAL_15(R,S,A,K,e,y,V,a,l,u,e,T,y,p,e);
-const XMLCh MgmtData::LOCAL_NAME[] =        UNICODE_LITERAL_8(M,g,m,t,D,a,t,a);
-const XMLCh KeyName::LOCAL_NAME[] =         UNICODE_LITERAL_7(K,e,y,N,a,m,e);
-const XMLCh Modulus::LOCAL_NAME[] =         UNICODE_LITERAL_7(M,o,d,u,l,u,s);
-const XMLCh Exponent::LOCAL_NAME[] =        UNICODE_LITERAL_8(E,x,p,o,n,e,n,t);
-const XMLCh Seed::LOCAL_NAME[] =            UNICODE_LITERAL_4(S,e,e,d);
-const XMLCh PgenCounter::LOCAL_NAME[] =     UNICODE_LITERAL_11(P,g,e,n,C,o,u,n,t,e,r);
-const XMLCh P::LOCAL_NAME[] =               UNICODE_LITERAL_1(P);
-const XMLCh Q::LOCAL_NAME[] =               UNICODE_LITERAL_1(Q);
-const XMLCh G::LOCAL_NAME[] =               UNICODE_LITERAL_1(G);
-const XMLCh Y::LOCAL_NAME[] =               UNICODE_LITERAL_1(Y);
-const XMLCh J::LOCAL_NAME[] =               UNICODE_LITERAL_1(J);
-const XMLCh XPath::LOCAL_NAME[] =           UNICODE_LITERAL_5(X,P,a,t,h);
-const XMLCh Transform::LOCAL_NAME[] =       UNICODE_LITERAL_9(T,r,a,n,s,f,o,r,m);
-const XMLCh Transform::TYPE_NAME[] =        UNICODE_LITERAL_13(T,r,a,n,s,f,o,r,m,T,y,p,e);
+IMPL_XMLOBJECTBUILDER(SPKISexp);
+IMPL_XMLOBJECTBUILDER(SPKIData);
+IMPL_XMLOBJECTBUILDER(PGPKeyID);
+IMPL_XMLOBJECTBUILDER(PGPKeyPacket);
+IMPL_XMLOBJECTBUILDER(PGPData);
+
+// Unicode literals
+
+const XMLCh KeyInfo::LOCAL_NAME[] =             UNICODE_LITERAL_7(K,e,y,I,n,f,o);
+const XMLCh KeyInfo::TYPE_NAME[] =              UNICODE_LITERAL_11(K,e,y,I,n,f,o,T,y,p,e);
+const XMLCh KeyInfo::ID_ATTRIB_NAME[] =         UNICODE_LITERAL_2(I,d);
+const XMLCh KeyValue::LOCAL_NAME[] =            UNICODE_LITERAL_8(K,e,y,V,a,l,u,e);
+const XMLCh KeyValue::TYPE_NAME[] =             UNICODE_LITERAL_12(K,e,y,V,a,l,u,e,T,y,p,e);
+const XMLCh DSAKeyValue::LOCAL_NAME[] =         UNICODE_LITERAL_11(D,S,A,K,e,y,V,a,l,u,e);
+const XMLCh DSAKeyValue::TYPE_NAME[] =          UNICODE_LITERAL_15(D,S,A,K,e,y,V,a,l,u,e,T,y,p,e);
+const XMLCh RSAKeyValue::LOCAL_NAME[] =         UNICODE_LITERAL_11(R,S,A,K,e,y,V,a,l,u,e);
+const XMLCh RSAKeyValue::TYPE_NAME[] =          UNICODE_LITERAL_15(R,S,A,K,e,y,V,a,l,u,e,T,y,p,e);
+const XMLCh MgmtData::LOCAL_NAME[] =            UNICODE_LITERAL_8(M,g,m,t,D,a,t,a);
+const XMLCh KeyName::LOCAL_NAME[] =             UNICODE_LITERAL_7(K,e,y,N,a,m,e);
+const XMLCh Modulus::LOCAL_NAME[] =             UNICODE_LITERAL_7(M,o,d,u,l,u,s);
+const XMLCh Exponent::LOCAL_NAME[] =            UNICODE_LITERAL_8(E,x,p,o,n,e,n,t);
+const XMLCh Seed::LOCAL_NAME[] =                UNICODE_LITERAL_4(S,e,e,d);
+const XMLCh PgenCounter::LOCAL_NAME[] =         UNICODE_LITERAL_11(P,g,e,n,C,o,u,n,t,e,r);
+const XMLCh P::LOCAL_NAME[] =                   UNICODE_LITERAL_1(P);
+const XMLCh Q::LOCAL_NAME[] =                   UNICODE_LITERAL_1(Q);
+const XMLCh G::LOCAL_NAME[] =                   UNICODE_LITERAL_1(G);
+const XMLCh Y::LOCAL_NAME[] =                   UNICODE_LITERAL_1(Y);
+const XMLCh J::LOCAL_NAME[] =                   UNICODE_LITERAL_1(J);
+const XMLCh XPath::LOCAL_NAME[] =               UNICODE_LITERAL_5(X,P,a,t,h);
+const XMLCh Transform::LOCAL_NAME[] =           UNICODE_LITERAL_9(T,r,a,n,s,f,o,r,m);
+const XMLCh Transform::TYPE_NAME[] =            UNICODE_LITERAL_13(T,r,a,n,s,f,o,r,m,T,y,p,e);
 const XMLCh Transform::ALGORITHM_ATTRIB_NAME[] = UNICODE_LITERAL_9(A,l,g,o,r,i,t,h,m);
-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);
+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);
+const XMLCh RetrievalMethod::LOCAL_NAME[] =     UNICODE_LITERAL_15(R,e,t,r,i,e,v,a,l,M,e,t,h,o,d);
+const XMLCh RetrievalMethod::TYPE_NAME[] =      UNICODE_LITERAL_19(R,e,t,r,i,e,v,a,l,M,e,t,h,o,d,T,y,p,e);
+const XMLCh RetrievalMethod::URI_ATTRIB_NAME[] = UNICODE_LITERAL_3(U,R,I);
+const XMLCh RetrievalMethod::TYPE_ATTRIB_NAME[] = UNICODE_LITERAL_4(T,y,p,e);
+const XMLCh SPKISexp::LOCAL_NAME[] =            UNICODE_LITERAL_8(S,P,K,I,S,e,x,p);
+const XMLCh SPKIData::LOCAL_NAME[] =            UNICODE_LITERAL_8(S,P,K,I,D,a,t,a);
+const XMLCh SPKIData::TYPE_NAME[] =             UNICODE_LITERAL_12(S,P,K,I,D,a,t,a,T,y,p,e);
+const XMLCh PGPKeyID::LOCAL_NAME[] =            UNICODE_LITERAL_8(P,G,P,K,e,y,I,D);
+const XMLCh PGPKeyPacket::LOCAL_NAME[] =        UNICODE_LITERAL_12(P,G,P,K,e,y,P,a,c,k,e,t);
+const XMLCh PGPData::LOCAL_NAME[] =             UNICODE_LITERAL_7(P,G,P,D,a,t,a);
+const XMLCh PGPData::TYPE_NAME[] =              UNICODE_LITERAL_11(P,G,P,D,a,t,a,T,y,p,e);
+
+#define XCH(ch) chLatin_##ch
+#define XNUM(d) chDigit_##d
+
+const XMLCh X509Data::LOCAL_NAME[] = {
+    XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(D), XCH(a), XCH(t), XCH(a), chNull
+    };
+const XMLCh X509Data::TYPE_NAME[] = {
+    XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(D), XCH(a), XCH(t), XCH(a), XCH(T), XCH(y), XCH(p), XCH(e), chNull
+    };
+const XMLCh X509IssuerSerial::LOCAL_NAME[] = {
+    XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(I), XCH(s), XCH(s), XCH(u), XCH(e), XCH(r),
+    XCH(S), XCH(e), XCH(r), XCH(i), XCH(a), XCH(l), chNull
+    };
+const XMLCh X509IssuerSerial::TYPE_NAME[] = {
+    XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(I), XCH(s), XCH(s), XCH(u), XCH(e), XCH(r),
+    XCH(S), XCH(e), XCH(r), XCH(i), XCH(a), XCH(l), XCH(T), XCH(y), XCH(p), XCH(e), chNull
+    };
+const XMLCh X509IssuerName::LOCAL_NAME[] = {
+    XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(I), XCH(s), XCH(s), XCH(u), XCH(e), XCH(r),
+    XCH(N), XCH(a), XCH(m), XCH(e), chNull
+    };
+const XMLCh X509SerialNumber::LOCAL_NAME[] = {
+    XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(S), XCH(e), XCH(r), XCH(i), XCH(a), XCH(l),
+    XCH(N), XCH(u), XCH(m), XCH(b), XCH(e), XCH(r), chNull
+    };
+const XMLCh X509SKI::LOCAL_NAME[] = { XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(S), XCH(K), XCH(I), chNull };
+const XMLCh X509SubjectName::LOCAL_NAME[] = {
+    XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(S), XCH(u), XCH(b), XCH(j), XCH(e), XCH(c), XCH(t),
+    XCH(N), XCH(a), XCH(m), XCH(e), chNull
+    };
+const XMLCh X509Certificate::LOCAL_NAME[] = {
+    XCH(X), XNUM(5), XNUM(0), XNUM(9),
+    XCH(C), XCH(e), XCH(r), XCH(t), XCH(i), XCH(f), XCH(i), XCH(c), XCH(a), XCH(t), XCH(e), chNull
+    };
+const XMLCh X509CRL::LOCAL_NAME[] = { XCH(X), XNUM(5), XNUM(0), XNUM(9), XCH(C), XCH(R), XCH(L), chNull };
+    
\ No newline at end of file
index 1890f97..3844346 100644 (file)
  */
 #define DequeOf(type) xmltooling::XMLObjectChildrenList< std::deque<type*> >
 
+/**
+ * Shorthand for an XMLObjectPairList wrapped around a vector
+ * 
+ * @param type1  the first type of object in the vector
+ * @param type2  the second type of object in the vector
+ */
+#define VectorOfPairs(type1,type2) xmltooling::XMLObjectPairList< std::vector< std::pair<type1*,type2*> > >
+
+/**
+ * Shorthand for an XMLObjectPairList wrapped around a list
+ * 
+ * @param type1  the first type of object in the vector
+ * @param type2  the second type of object in the vector
+ */
+#define ListOfPairs(type1,type2) xmltooling::XMLObjectPairList< std::list< std::pair<type1*,type2*> > >
+
+/**
+ * Shorthand for an XMLObjectPairList wrapped around a deque
+ * 
+ * @param type1  the first type of object in the vector
+ * @param type2  the second type of object in the vector
+ */
+#define DequeOfPairs(type1,type2) xmltooling::XMLObjectPairList< std::deque< std::pair<type1*,type2*> > >
+
 namespace xmltooling {
 
     // Forward reference
     template <class _Tx, class _Ty=XMLObject> class XMLObjectChildrenList;
+    template <class _Tx, class _Ty=XMLObject> class XMLObjectPairList;
 
     /**
      * STL iterator that mediates access to an iterator over typed XML children.
@@ -61,6 +86,7 @@ namespace xmltooling {
         /// @cond OFF
         typename _Ty::iterator m_iter;
         template <class _Tx, class _Tz> friend class XMLObjectChildrenList;
+        template <class _Tx, class _Tz> friend class XMLObjectPairList;
     public:
         typedef typename _Ty::iterator::iterator_category iterator_category;
         typedef typename _Ty::iterator::value_type value_type;
@@ -307,6 +333,174 @@ namespace xmltooling {
         /// @endcond
     };
 
+    /**
+     * STL-compatible container that mediates access to underlying lists of typed XML children
+     * that come in pairs.
+     * 
+     * @param _Tx   the subtype container to encapsulate
+     * @param _Ty   the base type in the underlying list (defaults to XMLObject)
+     */
+    template <class Container, class _Ty>
+    class XMLObjectPairList
+    {
+        Container& m_container;
+        typename std::list<_Ty*>* m_list;
+        typename std::list<_Ty*>::iterator m_fence;
+        XMLObject* m_parent;
+
+    public:
+        /// @cond OFF
+        typedef typename Container::value_type value_type;
+        typedef typename Container::reference reference;
+        typedef typename Container::const_reference const_reference;
+        typedef typename Container::difference_type difference_type;
+        typedef typename Container::size_type size_type;
+
+        // We override the iterator types with our constrained wrapper.
+        typedef XMLObjectChildrenIterator<Container> iterator;
+        typedef XMLObjectChildrenIterator<Container> const_iterator;
+        /// @endcond
+
+        /**
+         * Constructor to expose a typed collection of pairs backed by a list of a base type.
+         *
+         * @param parent    parent object of the collection
+         * @param sublist   underlying container to expose
+         * @param backing   pointer to backing list for children, if any
+         * @param ins_fence a marker designating where new children of this type should be added
+         */
+        XMLObjectPairList(
+            XMLObject* parent,
+            Container& sublist,
+            typename std::list<_Ty*>* backing,
+            typename std::list<_Ty*>::iterator ins_fence
+            ) : m_container(sublist), m_list(backing), m_fence(ins_fence), m_parent(parent) {
+        }
+
+        /// @cond OFF
+
+        size_type size() const {
+            // return length of sequence
+            return m_container.size();
+        }
+
+        bool empty() const {
+            // test if sequence is empty
+            return m_container.empty();
+        }
+
+        iterator begin() {
+            // return iterator for beginning of mutable sequence
+            return m_container.begin();
+        }
+
+        iterator end() {
+            // return iterator for end of mutable sequence
+            return m_container.end();
+        }
+
+        const_iterator begin() const {
+            // return iterator for beginning of const sequence
+            return m_container.begin();
+        }
+
+        const_iterator end() const {
+            // return iterator for end of const sequence
+            return m_container.end();
+        }
+
+        const_reference at(size_type _Pos) const {
+            // subscript nonmutable sequence with checking
+            return m_container.at(_Pos);
+        }
+
+        const_reference operator[](size_type _Pos) const {
+            // subscript nonmutable sequence
+            return m_container[_Pos];
+        }
+
+        const_reference front() const {
+            // return first element of nonmutable sequence
+            return m_container.front();
+        }
+
+        const_reference back() const {
+            // return last element of nonmutable sequence
+            return m_container.back();
+        }
+
+        void push_back(const_reference _Val) {
+            setParent(_Val);
+            if (m_list) {
+                m_list->insert(m_fence,_Val.first);
+                m_list->insert(m_fence,_Val.second);
+            }
+            m_container.push_back(_Val);
+        }
+
+        iterator erase(iterator _Where) {
+            removeParent(*_Where);
+            if (m_list)
+                removeChild(*_Where);
+            else {
+                delete _Where.m_iter->first;
+                delete _Where.m_iter->second;
+            }
+            return m_container.erase(_Where.m_iter);
+        }
+
+        iterator erase(iterator _First, iterator _Last) {
+            for (iterator i=_First; i!=_Last; i++) {
+                removeParent(*i);
+                if (m_list)
+                    removeChild(*i);
+                else {
+                    delete i.m_iter->first;
+                    delete i.m_iter->second;
+                }
+            }
+            return m_container.erase(_First,_Last);
+        }
+
+        void clear() {
+            erase(begin(),end());
+        }
+
+    private:
+        void setParent(const_reference _Val) {
+            if (_Val.first->getParent() || (_Val.second && _Val.second->getParent()))
+                throw XMLObjectException("One of the child objects already has a parent.");
+            _Val.first->setParent(m_parent);
+            if (_Val.second)
+                _Val.second->setParent(m_parent);
+            _Val.first->releaseParentDOM(true);
+        }
+
+        void removeParent(const_reference _Val) {
+            if (_Val.first->getParent()!=m_parent || (_Val.second && _Val.second->getParent()!=m_parent))
+                throw XMLObjectException("One of the child objects not owned by this parent.");
+            _Val.first->setParent(NULL);
+            if (_Val.second)
+                _Val.second->setParent(NULL);
+            m_parent->releaseParentDOM(true);
+        }
+
+        void removeChild(const_reference _Val) {
+            for (typename std::list<_Ty*>::iterator i=m_list->begin(); i!=m_list->end(); i++) {
+                if ((*i)==_Val.first) {
+                    typename std::list<_Ty*>::iterator j=i++;
+                    m_list->erase(j);
+                    m_list->erase(i);
+                    delete _Val.first;
+                    delete _Val.second;
+                    return;
+                }
+                i++;
+            }
+        }
+        /// @endcond
+    };
+
 };
 
 #endif /* __xmltooling_list_h__ */