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();
+ }
}
}
diff --git a/src/endorse-certificate.h b/src/endorse-certificate.h
index 28202da..c4d160d 100644
--- a/src/endorse-certificate.h
+++ b/src/endorse-certificate.h
@@ -8,8 +8,8 @@
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
*/
-#ifndef LINKEDN_ENDORSE_CERTIFICATE_H
-#define LINKEDN_ENDORSE_CERTIFICATE_H
+#ifndef LINKNDN_ENDORSE_CERTIFICATE_H
+#define LINKNDN_ENDORSE_CERTIFICATE_H
#include <vector>
#include <ndn.cxx/data.h>
@@ -18,22 +18,54 @@
#include "profile-data.h"
+class ProfileExtension : public ndn::security::CertificateExtension
+{
+public:
+ ProfileExtension(const ProfileData& profileData);
+
+ ProfileExtension(const ProfileExtension& profileExtension);
+
+ ProfileExtension(const CertificateExtension& extension);
+
+ ~ProfileExtension() {}
+
+ ndn::Ptr<ProfileData>
+ getProfileData();
+};
+
class EndorseExtension : public ndn::security::CertificateExtension
{
public:
- EndorseExtension(const ndn::Blob & value);
+ EndorseExtension(const std::vector<std::string>& endorsedList);
- virtual
+ EndorseExtension(const EndorseExtension& endorseExtension);
+
+ EndorseExtension(const CertificateExtension& extension);
+
~EndorseExtension() {}
+
+ std::vector<std::string>
+ getEndorsedList();
+
+private:
+ static ndn::Ptr<ndn::Blob>
+ prepareValue(const std::vector<std::string>& endorsedList);
};
class EndorseCertificate : public ndn::security::Certificate
{
public:
EndorseCertificate(const ndn::security::IdentityCertificate& kskCertificate,
+ const ndn::Time& notBefore,
+ const ndn::Time& notAfter,
+ ndn::Ptr<ProfileData> profileData,
+ const std::vector<std::string>& endorseList);
+
+ EndorseCertificate(const EndorseCertificate& endorseCertificate,
const ndn::Name& signer,
const ndn::Time& notBefore,
- const ndn::Time& notAfter);
+ const ndn::Time& notAfter,
+ const std::vector<std::string>& endorseList);
EndorseCertificate(const EndorseCertificate& endorseCertificate);
@@ -43,32 +75,27 @@
~EndorseCertificate()
{}
- void
- addProfile(const ProfileData& profile);
-
- void
- encode();
-
inline const ndn::Name&
getSigner() const
{ return m_signer; }
- inline const std::vector<ProfileData>&
- getProfileList() const
- { return m_profileList; }
+ inline ndn::Ptr<ProfileData>
+ getProfileData() const
+ { return m_profileData; }
- inline ndn::Name
- getPublicKeyName ()
+ inline const std::vector<std::string>&
+ getEndorseList() const
+ { return m_endorseList; }
+
+ inline virtual ndn::Name
+ getPublicKeyName () const
{ return m_keyName; }
-private:
- void
- decode();
-
-private:
+protected:
ndn::Name m_keyName;
ndn::Name m_signer;
- std::vector<ProfileData> m_profileList;
+ ndn::Ptr<ProfileData> m_profileData;
+ std::vector<std::string> m_endorseList;
};
#endif
diff --git a/src/profile-data.cpp b/src/profile-data.cpp
index f4b6bde..b779adc 100644
--- a/src/profile-data.cpp
+++ b/src/profile-data.cpp
@@ -10,35 +10,51 @@
#include "profile-data.h"
#include "exception.h"
-
#include <ndn.cxx/fields/signature-sha256-with-rsa.h>
-using namespace std;
using namespace ndn;
+using namespace std;
-ProfileData::ProfileData (const Name& identityName,
- const string& profileType,
- const Blob& profileValue)
+ProfileData::ProfileData(const Name& identity,
+ const Profile& profile)
: Data()
- , m_identityName(identityName)
- , m_profileType(profileType)
+ , m_identity(identity)
+ , m_profile(profile)
{
- Name tmpName = identityName;
- setName(tmpName.append(profileType));
- setContent(Content(profileValue.buf(), profileValue.size()));
+ Name dataName = identity;
+ TimeInterval ti = time::NowUnixTimestamp();
+ ostringstream oss;
+ oss << ti.total_seconds();
+
+ dataName.append("PROFILE").append(oss.str());
+ setName(dataName);
+ Ptr<Blob> profileBlob = profile.toDerBlob();
+ setContent(Content(profileBlob->buf(), profileBlob->size()));
}
-
-ProfileData::ProfileData (const ProfileData& profile)
+ProfileData::ProfileData(const ProfileData& profileData)
: Data()
- , m_identityName(profile.m_identityName)
- , m_profileType(profile.m_profileType)
+ , m_identity(profileData.m_identity)
+ , m_profile(profileData.m_profile)
{
- setName(profile.getName());
- setContent(profile.getContent());
+ Ptr<const signature::Sha256WithRsa> dataSig = boost::dynamic_pointer_cast<const signature::Sha256WithRsa>(profileData.getSignature());
+ Ptr<signature::Sha256WithRsa> newSig = Ptr<signature::Sha256WithRsa>::Create();
+
+ Ptr<SignedBlob> newSignedBlob = NULL;
+ if(profileData.getSignedBlob() != NULL)
+ newSignedBlob = Ptr<SignedBlob>(new SignedBlob(*profileData.getSignedBlob()));
+
+ newSig->setKeyLocator(dataSig->getKeyLocator());
+ newSig->setPublisherKeyDigest(dataSig->getPublisherKeyDigest());
+ newSig->setSignatureBits(dataSig->getSignatureBits());
+
+ setName(profileData.getName());
+ setSignature(newSig);
+ setContent(profileData.getContent());
+ setSignedBlob(newSignedBlob);
}
-
-ProfileData::ProfileData (const Data& data)
+
+ProfileData::ProfileData(const Data& data)
: Data()
{
const Name& dataName = data.getName();
@@ -54,12 +70,14 @@
}
}
- if(profileIndex < 0 || profileIndex + 1 >= dataName.size())
+ if(profileIndex < 0)
throw LnException("No PROFILE component in data name!");
-
+
+ m_identity = dataName.getSubName(0, profileIndex);
+
Ptr<const signature::Sha256WithRsa> dataSig = boost::dynamic_pointer_cast<const signature::Sha256WithRsa>(data.getSignature());
Ptr<signature::Sha256WithRsa> newSig = Ptr<signature::Sha256WithRsa>::Create();
-
+
Ptr<SignedBlob> newSignedBlob = NULL;
if(data.getSignedBlob() != NULL)
newSignedBlob = Ptr<SignedBlob>(new SignedBlob(*data.getSignedBlob()));
@@ -73,7 +91,5 @@
setContent(data.getContent());
setSignedBlob(newSignedBlob);
- m_identityName = dataName.getSubName(0, profileIndex);
- m_profileType = dataName.get(profileIndex+1).toUri();
+ m_profile = *Profile::fromDerBlob(data.content());
}
-
diff --git a/src/profile-data.h b/src/profile-data.h
index c70f6fc..4c2ac71 100644
--- a/src/profile-data.h
+++ b/src/profile-data.h
@@ -8,36 +8,35 @@
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
*/
-#ifndef PROFILE_DATA_H
-#define PROFILE_DATA_H
+#ifndef LINKNDN_PROFILE_DATA_H
+#define LINKNDN_PROFILE_DATA_H
#include <ndn.cxx/data.h>
+#include "profile.h"
class ProfileData : public ndn::Data
{
public:
- ProfileData (const ndn::Name& identityName,
- const std::string& profileType,
- const ndn::Blob& profileValue);
+ ProfileData(const ndn::Name& identity,
+ const Profile& profile);
- ProfileData (const ProfileData& profile);
+ ProfileData(const ProfileData& profileData);
- ProfileData (const ndn::Data& data);
-
- virtual
- ~ProfileData () {}
+ ProfileData(const ndn::Data& data);
- inline const ndn::Name&
+ ~ProfileData() {}
+
+ inline const ndn::Name&
getIdentityName() const
- { return m_identityName; }
+ { return m_identity; }
- inline const std::string&
- getProfileType() const
- { return m_profileType; }
+ inline const Profile&
+ getProfile() const
+ { return m_profile; }
private:
- ndn::Name m_identityName;
- std::string m_profileType;
+ ndn::Name m_identity;
+ Profile m_profile;
};
#endif
diff --git a/src/profile.cpp b/src/profile.cpp
new file mode 100644
index 0000000..182fe77
--- /dev/null
+++ b/src/profile.cpp
@@ -0,0 +1,102 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "profile.h"
+#include <ndn.cxx/helpers/der/der.h>
+#include <ndn.cxx/helpers/der/visitor/simple-visitor.h>
+
+using namespace std;
+using namespace ndn;
+
+Profile::Profile(const Name& identityName)
+ : m_identityName(identityName)
+{}
+
+Profile::Profile(const Name& identityName,
+ const string& name,
+ const string& institution)
+ : m_identityName(identityName)
+{
+ Blob nameBlob (name.c_str(), name.size());
+ Blob institutionBlob (institution.c_str(), institution.size());
+
+ m_entries[string("name")] = nameBlob;
+ m_entries[string("institution")] = institutionBlob;
+}
+
+Profile::Profile(const Profile& profile)
+ : m_identityName(profile.m_identityName)
+ , m_entries(profile.m_entries)
+{}
+
+void
+Profile::setProfileEntry(const string& profileType,
+ const Blob& profileValue)
+{ m_entries[profileType] = profileValue; }
+
+Ptr<const Blob>
+Profile::getProfileEntry(const string& profileType)
+{
+ if(m_entries.find(profileType) != m_entries.end())
+ return Ptr<Blob>(new Blob(m_entries[profileType].buf(), m_entries[profileType].size()));
+
+ return NULL;
+}
+
+Ptr<Blob>
+Profile::toDerBlob() const
+{
+ Ptr<der::DerSequence> root = Ptr<der::DerSequence>::Create();
+
+ Ptr<der::DerPrintableString> identityName = Ptr<der::DerPrintableString>(new der::DerPrintableString(m_identityName.toUri()));
+ root->addChild(identityName);
+
+ map<string, Blob>::const_iterator it = m_entries.begin();
+ for(; it != m_entries.end(); it++)
+ {
+ Ptr<der::DerSequence> entry = Ptr<der::DerSequence>::Create();
+ Ptr<der::DerPrintableString> type = Ptr<der::DerPrintableString>(new der::DerPrintableString(it->first));
+ Ptr<der::DerOctetString> value = Ptr<der::DerOctetString>(new der::DerOctetString(it->second));
+ entry->addChild(type);
+ entry->addChild(value);
+ root->addChild(entry);
+ }
+
+ blob_stream blobStream;
+ OutputIterator & start = reinterpret_cast<OutputIterator &> (blobStream);
+ root->encode(start);
+
+ return blobStream.buf ();
+}
+
+Ptr<Profile>
+Profile::fromDerBlob(const Blob& derBlob)
+{
+ boost::iostreams::stream
+ <boost::iostreams::array_source> is (derBlob.buf(), derBlob.size());
+
+ Ptr<der::DerSequence> root = DynamicCast<der::DerSequence>(der::DerNode::parse(reinterpret_cast<InputIterator &>(is)));
+
+ const der::DerNodePtrList & children = root->getChildren();
+ der::SimpleVisitor simpleVisitor;
+ string identityName = boost::any_cast<string>(children[0]->accept(simpleVisitor));
+ Ptr<Profile> profile = Ptr<Profile>(new Profile(identityName));
+
+ for(int i = 1; i < children.size(); i++)
+ {
+ Ptr<der::DerSequence> entry = DynamicCast<der::DerSequence>(children[i]);
+ const der::DerNodePtrList & tuple = root->getChildren();
+ string type = boost::any_cast<string>(tuple[0]->accept(simpleVisitor));
+ Ptr<Blob> value = boost::any_cast<Ptr<Blob> >(tuple[1]->accept(simpleVisitor));
+ profile->setProfileEntry(type, *value);
+ }
+
+ return profile;
+}
diff --git a/src/profile.h b/src/profile.h
new file mode 100644
index 0000000..403b600
--- /dev/null
+++ b/src/profile.h
@@ -0,0 +1,75 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef LINKNDN_PROFILE_H
+#define LINKNDN_PROFILE_H
+
+#include <ndn.cxx/common.h>
+#include <ndn.cxx/fields/name.h>
+#include <ndn.cxx/fields/blob.h>
+#include <map>
+#include <string>
+
+class Profile
+{
+public:
+ typedef std::map<std::string, ndn::Blob>::iterator iterator;
+ typedef std::map<std::string, ndn::Blob>::const_iterator const_iterator;
+public:
+ Profile() {}
+
+ Profile(const ndn::Name& identityName);
+
+ Profile(const ndn::Name& identityName,
+ const std::string& name,
+ const std::string& institution);
+
+ Profile(const Profile& profile);
+
+ virtual
+ ~Profile() {}
+
+ void
+ setProfileEntry(const std::string& profileType,
+ const ndn::Blob& profileValue);
+
+ ndn::Ptr<const ndn::Blob>
+ getProfileEntry(const std::string& profileType);
+
+ inline Profile::iterator
+ begin()
+ { return m_entries.begin(); }
+
+ inline Profile::const_iterator
+ begin() const
+ { return m_entries.begin(); }
+
+ inline Profile::iterator
+ end()
+ { return m_entries.end(); }
+
+ inline Profile::const_iterator
+ end() const
+ { return m_entries.end(); }
+
+ ndn::Ptr<ndn::Blob>
+ toDerBlob() const;
+
+ static ndn::Ptr<Profile>
+ fromDerBlob(const ndn::Blob& derBlob);
+
+protected:
+ ndn::Name m_identityName;
+ std::map<std::string, ndn::Blob> m_entries;
+};
+
+
+
+#endif