Add ProfileData
diff --git a/src/endorse-certificate.cpp b/src/endorse-certificate.cpp
index a565ebc..c6d338a 100644
--- a/src/endorse-certificate.cpp
+++ b/src/endorse-certificate.cpp
@@ -10,6 +10,8 @@
 
 #include "endorse-certificate.h"
 #include "exception.h"
+#include <ndn.cxx/helpers/der/der.h>
+#include <ndn.cxx/helpers/der/visitor/simple-visitor.h>
 #include <ndn.cxx/security/certificate/certificate-subdescrpt.h>
 
 
@@ -17,29 +19,143 @@
 using namespace ndn;
 using namespace ndn::security;
 
-EndorseExtension::EndorseExtension(const Blob & value)
-  : CertificateExtension("1.3.6.1.5.32.2", true, value)
+ProfileExtension::ProfileExtension(const ProfileData & profileData)
+  : CertificateExtension("1.3.6.1.5.32.2.1", true, *profileData.encodeToWire())
 {}
 
+ProfileExtension::ProfileExtension(const ProfileExtension& profileExtension)
+  : CertificateExtension("1.3.6.1.5.32.2.1", true, profileExtension.m_extnValue)
+{}
+
+ProfileExtension::ProfileExtension(const CertificateExtension& extension)
+  : CertificateExtension(extension.getOID(), extension.getCritical(), extension.getValue())
+{
+  if(m_extnID != OID("1.3.6.1.5.32.2.1"))
+    throw LnException("Wrong ProfileExtension Number!");
+}
+
+Ptr<ProfileData>
+ProfileExtension::getProfileData()
+{
+  boost::iostreams::stream
+    <boost::iostreams::array_source> is (m_extnValue.buf (), m_extnValue.size ());
+  return Ptr<ProfileData>(new ProfileData(*Data::decodeFromWire(is)));
+}
+
+EndorseExtension::EndorseExtension(const vector<string>& endorsedList)
+  : CertificateExtension("1.3.6.1.5.32.2.2", true, *EndorseExtension::prepareValue(endorsedList))
+{}
+
+EndorseExtension::EndorseExtension(const EndorseExtension& endorseExtension)
+  : CertificateExtension("1.3.6.1.5.32.2.2", true, endorseExtension.m_extnValue)
+{}
+
+EndorseExtension::EndorseExtension(const CertificateExtension& extension)
+  : CertificateExtension(extension.getOID(), extension.getCritical(), extension.getValue())
+{
+  if(m_extnID != OID("1.3.6.1.5.32.2.2"))
+    throw LnException("Wrong EndorseExtension Number!");
+}
+
+vector<string>
+EndorseExtension::getEndorsedList()
+{
+  vector<string> endorsedList;
+
+  boost::iostreams::stream
+    <boost::iostreams::array_source> is (m_extnValue.buf(), m_extnValue.size());
+  
+  Ptr<der::DerSequence> root = DynamicCast<der::DerSequence>(der::DerNode::parse(reinterpret_cast<InputIterator &>(is)));
+  const der::DerNodePtrList & children = root->getChildren();
+  der::SimpleVisitor simpleVisitor;
+
+  for(int i = 0; i < children.size(); i++)
+      endorsedList.push_back(boost::any_cast<string>(children[i]->accept(simpleVisitor)));
+
+  return endorsedList;
+}
+
+Ptr<Blob>
+EndorseExtension::prepareValue(const vector<string>& endorsedList)
+{
+  Ptr<der::DerSequence> root = Ptr<der::DerSequence>::Create();
+  
+  vector<string>::const_iterator it = endorsedList.begin();
+  for(; it != endorsedList.end(); it++)
+    {
+      Ptr<der::DerPrintableString> entry = Ptr<der::DerPrintableString>(new der::DerPrintableString(*it));
+      root->addChild(entry);
+    }
+  
+  blob_stream blobStream;
+  OutputIterator & start = reinterpret_cast<OutputIterator &> (blobStream);
+  root->encode(start);
+
+  return blobStream.buf ();
+}
+
 EndorseCertificate::EndorseCertificate(const IdentityCertificate& kskCertificate,
-				       const Name& signer,
-				       const Time& notBefore,
-				       const Time& notAfter)
+                                       const Time& notBefore,
+                                       const Time& notAfter,
+                                       Ptr<ProfileData> profileData,
+                                       const vector<string>& endorseList)
   : Certificate()
   , m_keyName(kskCertificate.getPublicKeyName())
-  , m_signer(signer)
+  , m_signer(kskCertificate.getPublicKeyName())
+  , m_profileData(profileData)
+  , m_endorseList(endorseList)
 {
+  Name dataName = m_keyName;
+  TimeInterval ti = time::NowUnixTimestamp();
+  ostringstream oss;
+  oss << ti.total_seconds();
+  dataName.append("PROFILE-CERT").append(m_signer).append(oss.str());
+  setName(dataName);
+
   setNotBefore(notBefore);
   setNotAfter(notAfter);
   addSubjectDescription(CertificateSubDescrypt("2.5.4.41", m_keyName.toUri()));
   setPublicKeyInfo(kskCertificate.getPublicKeyInfo());
+  addExtension(ProfileExtension(*m_profileData));
+  addExtension(EndorseExtension(m_endorseList));
+  
+  encode();
+}
+
+EndorseCertificate::EndorseCertificate(const EndorseCertificate& endorseCertificate,
+                                       const Name& signer,
+                                       const Time& notBefore,
+                                       const Time& notAfter,
+                                       const vector<string>& endorseList)
+  : Certificate()
+  , m_keyName(endorseCertificate.m_keyName)
+  , m_signer(signer)
+  , m_profileData(endorseCertificate.m_profileData)
+  , m_endorseList(endorseList)
+{
+  Name dataName = m_keyName;
+  TimeInterval ti = time::NowUnixTimestamp();
+  ostringstream oss;
+  oss << ti.total_seconds();
+  dataName.append("PROFILE-CERT").append(m_signer).append(oss.str());
+  setName(dataName);
+  
+  setNotBefore(notBefore);
+  setNotAfter(notAfter);
+  addSubjectDescription(CertificateSubDescrypt("2.5.4.41", m_keyName.toUri()));
+  setPublicKeyInfo(endorseCertificate.getPublicKeyInfo());
+  addExtension(ProfileExtension(*m_profileData));
+  addExtension(EndorseExtension(m_endorseList));
+
+  encode();
 }
 
 EndorseCertificate::EndorseCertificate(const EndorseCertificate& endorseCertificate)
   : Certificate(endorseCertificate)
   , m_keyName(endorseCertificate.m_keyName)
   , m_signer(endorseCertificate.m_signer)
-  , m_profileList(endorseCertificate.m_profileList)
+  , m_profileData(endorseCertificate.m_profileData)
+  , m_endorseList(endorseCertificate.m_endorseList)
 {}
 
 EndorseCertificate::EndorseCertificate(const Data& data)
@@ -64,14 +180,21 @@
   m_keyName = dataName.getSubName(0, profileIndex);
   m_signer = dataName.getSubName(profileIndex + 1, dataName.size() - profileIndex - 2);
 
-  OID profileExtenstionOID("1.3.6.1.5.32.2");
+  OID profileExtensionOID("1.3.6.1.5.32.2.1");
+  OID endorseExtensionOID("1.3.6.1.5.32.2.2");
+
   ExtensionList::iterator it = m_extnList.begin();
   for(; it != m_extnList.end(); it++)
     {
-      if(profileExtenstionOID == it->getOID())
+      if(profileExtensionOID == it->getOID())
 	{
-	  Ptr<Blob> valueBlob = Ptr<Blob>(new Blob(it->getValue().buf(), it->getValue().size()));
-	  m_profileList.push_back(ProfileData(*(Data::decodeFromWire(valueBlob))));
+          ProfileExtension profileExtension(*it);
+	  m_profileData = profileExtension.getProfileData();
 	}
+      if(endorseExtensionOID == it->getOID())
+        {
+          EndorseExtension endorseExtension(*it);
+          m_endorseList = endorseExtension.getEndorsedList();
+        }
     }
 }