https://issues.shibboleth.net/jira/browse/CPPXT-90
[shibboleth/cpp-xmltooling.git] / xmltooling / signature / impl / KeyInfoImpl.cpp
index 0613940..910267c 100644 (file)
 #include "signature/KeyInfo.h"
 #include "util/XMLHelper.h"
 
+#include <boost/lambda/bind.hpp>
+#include <boost/lambda/casts.hpp>
+#include <boost/lambda/if.hpp>
+#include <boost/lambda/lambda.hpp>
 #include <xercesc/util/XMLUniDefs.hpp>
 
 using namespace xmlsignature;
@@ -55,33 +59,6 @@ namespace xmlsignature {
         public AbstractXMLObjectMarshaller,
         public AbstractXMLObjectUnmarshaller
     {
-    public:
-        virtual ~DSAKeyValueImpl() {}
-
-        DSAKeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-            : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            init();
-        }
-            
-        DSAKeyValueImpl(const DSAKeyValueImpl& src)
-                : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
-            init();
-            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() {
             m_P=nullptr;
             m_Q=nullptr;
@@ -111,7 +88,27 @@ namespace xmlsignature {
             m_pos_PgenCounter=m_pos_Seed;
             ++m_pos_PgenCounter;
         }
-        
+
+    public:
+        virtual ~DSAKeyValueImpl() {}
+
+        DSAKeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
+            : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
+            init();
+        }
+            
+        DSAKeyValueImpl(const DSAKeyValueImpl& src)
+                : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
+            init();
+            IMPL_CLONE_TYPED_CHILD(P);
+            IMPL_CLONE_TYPED_CHILD(Q);
+            IMPL_CLONE_TYPED_CHILD(G);
+            IMPL_CLONE_TYPED_CHILD(Y);
+            IMPL_CLONE_TYPED_CHILD(J);
+            IMPL_CLONE_TYPED_CHILD(Seed);
+            IMPL_CLONE_TYPED_CHILD(PgenCounter);
+        }
+                
         IMPL_XMLOBJECT_CLONE(DSAKeyValue);
         IMPL_TYPED_CHILD(P);
         IMPL_TYPED_CHILD(Q);
@@ -140,6 +137,16 @@ namespace xmlsignature {
         public AbstractXMLObjectMarshaller,
         public AbstractXMLObjectUnmarshaller
     {
+        void init() {
+            m_Modulus=nullptr;
+            m_Exponent=nullptr;
+            m_children.push_back(nullptr);
+            m_children.push_back(nullptr);
+            m_pos_Modulus=m_children.begin();
+            m_pos_Exponent=m_pos_Modulus;
+            ++m_pos_Exponent;
+        }
+        
     public:
         virtual ~RSAKeyValueImpl() {}
 
@@ -151,20 +158,8 @@ namespace xmlsignature {
         RSAKeyValueImpl(const RSAKeyValueImpl& src)
                 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
             init();
-            if (src.getModulus())
-                setModulus(src.getModulus()->cloneModulus());
-            if (src.getExponent())
-                setExponent(src.getExponent()->cloneExponent());
-        }
-        
-        void init() {
-            m_Modulus=nullptr;
-            m_Exponent=nullptr;
-            m_children.push_back(nullptr);
-            m_children.push_back(nullptr);
-            m_pos_Modulus=m_children.begin();
-            m_pos_Exponent=m_pos_Modulus;
-            ++m_pos_Exponent;
+            IMPL_CLONE_TYPED_CHILD(Modulus);
+            IMPL_CLONE_TYPED_CHILD(Exponent);
         }
         
         IMPL_XMLOBJECT_CLONE(RSAKeyValue);
@@ -191,14 +186,12 @@ namespace xmlsignature {
         }
 
         NamedCurveImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-            : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            m_URI=nullptr;
+            : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_URI(nullptr) {
         }
 
         NamedCurveImpl(const NamedCurveImpl& src)
-                : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
-            m_URI=nullptr;
-            setURI(getURI());
+                : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src), m_URI(nullptr) {
+            IMPL_CLONE_ATTRIB(URI);
         }
 
         IMPL_XMLOBJECT_CLONE(NamedCurve);
@@ -221,28 +214,6 @@ namespace xmlsignature {
         public AbstractXMLObjectMarshaller,
         public AbstractXMLObjectUnmarshaller
     {
-    public:
-        virtual ~ECKeyValueImpl() {
-            XMLString::release(&m_Id);
-        }
-
-        ECKeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            init();
-        }
-            
-        ECKeyValueImpl(const ECKeyValueImpl& src)
-                : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
-            init();
-            m_Id=XMLString::replicate(src.m_Id);
-            if (src.getECParameters())
-                setECParameters(src.getECParameters()->clone());
-            if (src.getNamedCurve())
-                setNamedCurve(src.getNamedCurve()->cloneNamedCurve());
-            if (src.getPublicKey())
-                setPublicKey(src.getPublicKey()->clonePublicKey());
-        }
-        
         void init() {
             m_Id=nullptr;
             m_ECParameters=nullptr;
@@ -258,6 +229,25 @@ namespace xmlsignature {
             ++m_pos_PublicKey;
         }
         
+    public:
+        virtual ~ECKeyValueImpl() {
+            XMLString::release(&m_Id);
+        }
+
+        ECKeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
+            init();
+        }
+            
+        ECKeyValueImpl(const ECKeyValueImpl& src)
+                : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
+            init();
+            IMPL_CLONE_ATTRIB(Id);
+            IMPL_CLONE_XMLOBJECT_CHILD(ECParameters);
+            IMPL_CLONE_TYPED_CHILD(NamedCurve);
+            IMPL_CLONE_TYPED_CHILD(PublicKey);
+        }
+        
         IMPL_XMLOBJECT_CLONE(ECKeyValue);
         IMPL_ID_ATTRIB_EX(Id,ID,nullptr);
         IMPL_XMLOBJECT_CHILD(ECParameters);
@@ -295,27 +285,6 @@ namespace xmlsignature {
         public AbstractXMLObjectMarshaller,
         public AbstractXMLObjectUnmarshaller
     {
-    public:
-        virtual ~KeyValueImpl() {}
-
-        KeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            init();
-        }
-            
-        KeyValueImpl(const KeyValueImpl& src)
-                : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
-            init();
-            if (src.getDSAKeyValue())
-                setDSAKeyValue(src.getDSAKeyValue()->cloneDSAKeyValue());
-            if (src.getRSAKeyValue())
-                setRSAKeyValue(src.getRSAKeyValue()->cloneRSAKeyValue());
-            if (src.getECKeyValue())
-                setECKeyValue(src.getECKeyValue()->cloneECKeyValue());
-            if (src.getUnknownXMLObject())
-                setUnknownXMLObject(src.getUnknownXMLObject()->clone());
-        }
-        
         void init() {
             m_DSAKeyValue=nullptr;
             m_RSAKeyValue=nullptr;
@@ -333,7 +302,24 @@ namespace xmlsignature {
             m_pos_UnknownXMLObject=m_pos_ECKeyValue;
             ++m_pos_UnknownXMLObject;
         }
-        
+
+    public:
+        virtual ~KeyValueImpl() {}
+
+        KeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
+            init();
+        }
+            
+        KeyValueImpl(const KeyValueImpl& src)
+                : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
+            init();
+            IMPL_CLONE_TYPED_CHILD(DSAKeyValue);
+            IMPL_CLONE_TYPED_CHILD(RSAKeyValue);
+            IMPL_CLONE_TYPED_CHILD(ECKeyValue);
+            IMPL_CLONE_XMLOBJECT_CHILD(UnknownXMLObject);
+        }
+                
         IMPL_XMLOBJECT_CLONE(KeyValue);
         IMPL_TYPED_CHILD(DSAKeyValue);
         IMPL_TYPED_CHILD(RSAKeyValue);
@@ -374,7 +360,7 @@ namespace xmlsignature {
 
         DEREncodedKeyValueImpl(const DEREncodedKeyValueImpl& src)
                 : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src), m_Id(nullptr) {
-            setId(src.getId());
+            IMPL_CLONE_ATTRIB(Id);
         }
 
         IMPL_XMLOBJECT_CLONE(DEREncodedKeyValue);
@@ -407,18 +393,12 @@ namespace xmlsignature {
         }
             
         TransformImpl(const TransformImpl& src)
-                : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src),
-                    m_Algorithm(XMLString::replicate(src.m_Algorithm)) {
-            for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
-                if (*i) {
-                    XPath* x=dynamic_cast<XPath*>(*i);
-                    if (x) {
-                        getXPaths().push_back(x->cloneXPath());
-                        continue;
-                    }
-                    getUnknownXMLObjects().push_back((*i)->clone());
-                }
-            }
+                : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src), m_Algorithm(nullptr) {
+            IMPL_CLONE_ATTRIB(Algorithm);
+            IMPL_CLONE_CHILDBAG_BEGIN;
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(XPath);
+                IMPL_CLONE_XMLOBJECT_CHILD_IN_BAG(UnknownXMLObject);
+            IMPL_CLONE_CHILDBAG_END;
         }
         
         IMPL_XMLOBJECT_CLONE(Transform);
@@ -465,12 +445,7 @@ namespace xmlsignature {
             
         TransformsImpl(const TransformsImpl& src)
                 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
-            VectorOf(Transform) v=getTransforms();
-            for (vector<Transform*>::const_iterator i=src.m_Transforms.begin(); i!=src.m_Transforms.end(); i++) {
-                if (*i) {
-                    v.push_back((*i)->cloneTransform());
-                }
-            }
+            IMPL_CLONE_TYPED_CHILDREN(Transform);
         }
         
         IMPL_XMLOBJECT_CLONE(Transforms);
@@ -489,6 +464,13 @@ namespace xmlsignature {
         public AbstractXMLObjectMarshaller,
         public AbstractXMLObjectUnmarshaller
     {
+        void init() {
+            m_URI=m_Type=nullptr;
+            m_Transforms=nullptr;
+            m_children.push_back(nullptr);
+            m_pos_Transforms=m_children.begin();
+        }
+        
     public:
         virtual ~RetrievalMethodImpl() {
             XMLString::release(&m_URI);
@@ -503,17 +485,9 @@ namespace xmlsignature {
         RetrievalMethodImpl(const RetrievalMethodImpl& src)
                 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
             init();
-            setURI(getURI());
-            setType(getType());
-            if (src.getTransforms())
-                setTransforms(src.getTransforms()->cloneTransforms());
-        }
-        
-        void init() {
-            m_URI=m_Type=nullptr;
-            m_Transforms=nullptr;
-            m_children.push_back(nullptr);
-            m_pos_Transforms=m_children.begin();
+            IMPL_CLONE_ATTRIB(URI);
+            IMPL_CLONE_ATTRIB(Type);
+            IMPL_CLONE_TYPED_CHILD(Transforms);
         }
         
         IMPL_XMLOBJECT_CLONE(RetrievalMethod);
@@ -545,6 +519,16 @@ namespace xmlsignature {
         public AbstractXMLObjectMarshaller,
         public AbstractXMLObjectUnmarshaller
     {
+        void init() {
+            m_X509IssuerName=nullptr;
+            m_X509SerialNumber=nullptr;
+            m_children.push_back(nullptr);
+            m_children.push_back(nullptr);
+            m_pos_X509IssuerName=m_children.begin();
+            m_pos_X509SerialNumber=m_pos_X509IssuerName;
+            ++m_pos_X509SerialNumber;
+        }
+        
     public:
         virtual ~X509IssuerSerialImpl() {}
 
@@ -556,20 +540,8 @@ namespace xmlsignature {
         X509IssuerSerialImpl(const X509IssuerSerialImpl& src)
                 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
             init();
-            if (src.getX509IssuerName())
-                setX509IssuerName(src.getX509IssuerName()->cloneX509IssuerName());
-            if (src.getX509SerialNumber())
-                setX509SerialNumber(src.getX509SerialNumber()->cloneX509SerialNumber());
-        }
-        
-        void init() {
-            m_X509IssuerName=nullptr;
-            m_X509SerialNumber=nullptr;
-            m_children.push_back(nullptr);
-            m_children.push_back(nullptr);
-            m_pos_X509IssuerName=m_children.begin();
-            m_pos_X509SerialNumber=m_pos_X509IssuerName;
-            ++m_pos_X509SerialNumber;
+            IMPL_CLONE_TYPED_CHILD(X509IssuerName);
+            IMPL_CLONE_TYPED_CHILD(X509SerialNumber);
         }
         
         IMPL_XMLOBJECT_CLONE(X509IssuerSerial);
@@ -585,7 +557,7 @@ namespace xmlsignature {
     };
 
     class XMLTOOL_DLLLOCAL X509DigestImpl : public virtual X509Digest,
-        public AbstractComplexElement,
+        public AbstractSimpleElement,
         public AbstractDOMCachingXMLObject,
         public AbstractXMLObjectMarshaller,
         public AbstractXMLObjectUnmarshaller
@@ -600,8 +572,8 @@ namespace xmlsignature {
         }
 
         X509DigestImpl(const X509DigestImpl& src)
-                : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src), m_Algorithm(nullptr) {
-            setAlgorithm(src.getAlgorithm());
+                : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src), m_Algorithm(nullptr) {
+            IMPL_CLONE_ATTRIB(Algorithm);
         }
 
         IMPL_XMLOBJECT_CLONE(X509Digest);
@@ -634,53 +606,16 @@ namespace xmlsignature {
             
         X509DataImpl(const X509DataImpl& src)
                 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(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;
-                    }
-
-                    X509Digest* xdig=dynamic_cast<X509Digest*>(*i);
-                    if (xdig) {
-                        getX509Digests().push_back(xdig->cloneX509Digest());
-                        continue;
-                    }
-
-                    OCSPResponse* ocsp=dynamic_cast<OCSPResponse*>(*i);
-                    if (ocsp) {
-                        getOCSPResponses().push_back(ocsp->cloneOCSPResponse());
-                        continue;
-                    }
-
-                    getUnknownXMLObjects().push_back((*i)->clone());
-                }
-            }
+            IMPL_CLONE_CHILDBAG_BEGIN;
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(X509Certificate);
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(X509CRL);
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(X509SubjectName);
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(X509IssuerSerial);
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(X509SKI);
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(X509Digest);
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(OCSPResponse);
+                IMPL_CLONE_XMLOBJECT_CHILD_IN_BAG(UnknownXMLObject);
+            IMPL_CLONE_CHILDBAG_END;
         }
         
         IMPL_XMLOBJECT_CLONE(X509Data);
@@ -720,6 +655,8 @@ namespace xmlsignature {
         public AbstractXMLObjectMarshaller,
         public AbstractXMLObjectUnmarshaller
     {
+        vector< pair<SPKISexp*,XMLObject*> > m_SPKISexps;
+
     public:
         virtual ~SPKIDataImpl() {}
 
@@ -729,19 +666,15 @@ namespace xmlsignature {
             
         SPKIDataImpl(const SPKIDataImpl& src)
                 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
-            VectorOfPairs(SPKISexp,XMLObject) v=getSPKISexps();
-            for (vector< pair<SPKISexp*,XMLObject*> >::const_iterator i=src.m_SPKISexps.begin(); i!=src.m_SPKISexps.end(); i++) {
+            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*)nullptr)));
+                    getSPKISexps().push_back(make_pair(i->first->cloneSPKISexp(),(i->second ? i->second->clone() : (XMLObject*)nullptr)));
                 }
             }
         }
         
         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());
@@ -784,6 +717,16 @@ namespace xmlsignature {
         public AbstractXMLObjectMarshaller,
         public AbstractXMLObjectUnmarshaller
     {
+        void init() {
+            m_PGPKeyID=nullptr;
+            m_PGPKeyPacket=nullptr;
+            m_children.push_back(nullptr);
+            m_children.push_back(nullptr);
+            m_pos_PGPKeyID=m_children.begin();
+            m_pos_PGPKeyPacket=m_pos_PGPKeyID;
+            ++m_pos_PGPKeyPacket;
+        }
+        
     public:
         virtual ~PGPDataImpl() {}
 
@@ -795,23 +738,9 @@ namespace xmlsignature {
         PGPDataImpl(const PGPDataImpl& src)
                 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
             init();
-            if (src.getPGPKeyID())
-                setPGPKeyID(src.getPGPKeyID()->clonePGPKeyID());
-            if (src.getPGPKeyPacket())
-                setPGPKeyPacket(src.getPGPKeyPacket()->clonePGPKeyPacket());
-            VectorOf(XMLObject) v=getUnknownXMLObjects();
-            for (vector<XMLObject*>::const_iterator i=src.m_UnknownXMLObjects.begin(); i!=src.m_UnknownXMLObjects.end(); ++i)
-                v.push_back((*i)->clone());
-        }
-        
-        void init() {
-            m_PGPKeyID=nullptr;
-            m_PGPKeyPacket=nullptr;
-            m_children.push_back(nullptr);
-            m_children.push_back(nullptr);
-            m_pos_PGPKeyID=m_children.begin();
-            m_pos_PGPKeyPacket=m_pos_PGPKeyID;
-            ++m_pos_PGPKeyPacket;
+            IMPL_CLONE_TYPED_CHILD(PGPKeyID);
+            IMPL_CLONE_TYPED_CHILD(PGPKeyPacket);
+            IMPL_CLONE_XMLOBJECT_CHILDREN(UnknownXMLObject);
         }
         
         IMPL_XMLOBJECT_CLONE(PGPData);
@@ -841,6 +770,10 @@ namespace xmlsignature {
         public AbstractXMLObjectMarshaller,
         public AbstractXMLObjectUnmarshaller
     {
+        void init() {
+            m_Id=m_URI=nullptr;
+        }
+
     public:
         virtual ~KeyInfoReferenceImpl() {
             XMLString::release(&m_Id);
@@ -855,12 +788,8 @@ namespace xmlsignature {
         KeyInfoReferenceImpl(const KeyInfoReferenceImpl& src)
                 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
             init();
-            setId(getId());
-            setURI(getURI());
-        }
-
-        void init() {
-            m_Id=m_URI=nullptr;
+            IMPL_CLONE_ATTRIB(Id);
+            IMPL_CLONE_ATTRIB(URI);
         }
 
         IMPL_XMLOBJECT_CLONE(KeyInfoReference);
@@ -896,68 +825,20 @@ namespace xmlsignature {
         }
             
         KeyInfoImpl(const KeyInfoImpl& src)
-                : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(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;
-                    }
-
-                    DEREncodedKeyValue* ekv=dynamic_cast<DEREncodedKeyValue*>(*i);
-                    if (ekv) {
-                        getDEREncodedKeyValues().push_back(ekv->cloneDEREncodedKeyValue());
-                        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;
-                    }
-
-                    KeyInfoReference* kref=dynamic_cast<KeyInfoReference*>(*i);
-                    if (kref) {
-                        getKeyInfoReferences().push_back(kref->cloneKeyInfoReference());
-                        continue;
-                    }
-
-                    getUnknownXMLObjects().push_back((*i)->clone());
-                }
-            }
+                : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src), m_Id(nullptr) {
+            IMPL_CLONE_ATTRIB(Id);
+            IMPL_CLONE_CHILDBAG_BEGIN;
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(X509Data);
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(KeyName);
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(KeyValue);
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(DEREncodedKeyValue);
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(RetrievalMethod);
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(MgmtData);
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(SPKIData);
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(PGPData);
+                IMPL_CLONE_TYPED_CHILD_IN_BAG(KeyInfoReference);
+                IMPL_CLONE_XMLOBJECT_CHILD_IN_BAG(UnknownXMLObject);
+            IMPL_CLONE_CHILDBAG_END;
         }
         
         IMPL_XMLOBJECT_CLONE(KeyInfo);