blob: 38f7b634b705e2cab1fa528709eea3b8087fa2d4 [file] [log] [blame]
Yingdi Yub4be64a2013-10-13 17:24:50 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * Yingdi Yu
5 *
6 * BSD license, See the LICENSE file for more information
7 *
8 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
Qiuhan Ding0cfc1512015-02-17 17:44:11 -08009 * Qiuhan Ding <qiuhanding@cs.ucla.edu>
Yingdi Yub4be64a2013-10-13 17:24:50 -070010 */
11
Yingdi Yu0b0a7362014-08-05 16:31:30 -070012#include "profile.hpp"
Yingdi Yu92e8e482013-10-17 21:13:03 -070013#include "logging.h"
Yingdi Yub4be64a2013-10-13 17:24:50 -070014
Yingdi Yueb692ac2015-02-10 18:46:18 -080015namespace chronochat {
Yingdi Yu2e3199c2013-11-06 18:42:34 -080016
Yingdi Yu0b0a7362014-08-05 16:31:30 -070017using std::vector;
18using std::string;
19using std::map;
20
21using ndn::IdentityCertificate;
22using ndn::CertificateSubjectDescription;
23
Yingdi Yu17032f82014-03-25 15:48:23 -070024const std::string Profile::OID_NAME("2.5.4.41");
25const std::string Profile::OID_ORG("2.5.4.11");
26const std::string Profile::OID_GROUP("2.5.4.1");
27const std::string Profile::OID_HOMEPAGE("2.5.4.3");
28const std::string Profile::OID_ADVISOR("2.5.4.80");
29const std::string Profile::OID_EMAIL("1.2.840.113549.1.9.1");
Yingdi Yufa4ce792014-02-06 18:09:22 -080030
31Profile::Profile(const IdentityCertificate& identityCertificate)
Yingdi Yu2e3199c2013-11-06 18:42:34 -080032{
Yingdi Yufa4ce792014-02-06 18:09:22 -080033 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(identityCertificate.getName());
Yingdi Yu2e3199c2013-11-06 18:42:34 -080034
Yingdi Yu0b0a7362014-08-05 16:31:30 -070035 m_entries[string("IDENTITY")] = keyName.getPrefix(-1).toUri();
Yingdi Yufa0b6a02014-04-30 14:26:42 -070036
Yingdi Yu0b0a7362014-08-05 16:31:30 -070037 const vector<CertificateSubjectDescription>& subList =
38 identityCertificate.getSubjectDescriptionList();
39
40 for (vector<CertificateSubjectDescription>::const_iterator it = subList.begin();
41 it != subList.end(); it++) {
42 const string oidStr = it->getOidString();
43 string valueStr = it->getValue();
44 if (oidStr == OID_NAME)
45 m_entries["name"] = valueStr;
46 else if (oidStr == OID_ORG)
47 m_entries["institution"] = valueStr;
48 else if (oidStr == OID_GROUP)
49 m_entries["group"] = valueStr;
50 else if (oidStr == OID_HOMEPAGE)
51 m_entries["homepage"] = valueStr;
52 else if (oidStr == OID_ADVISOR)
53 m_entries["advisor"] = valueStr;
54 else if (oidStr == OID_EMAIL)
55 m_entries["email"] = valueStr;
56 else
57 m_entries[oidStr] = valueStr;
58 }
Yingdi Yu2e3199c2013-11-06 18:42:34 -080059}
60
Yingdi Yub4be64a2013-10-13 17:24:50 -070061Profile::Profile(const Name& identityName)
Yingdi Yu3b318c12013-10-15 17:54:00 -070062{
Yingdi Yufa4ce792014-02-06 18:09:22 -080063 m_entries["IDENTITY"] = identityName.toUri();
Yingdi Yu3b318c12013-10-15 17:54:00 -070064}
Yingdi Yub4be64a2013-10-13 17:24:50 -070065
66Profile::Profile(const Name& identityName,
Yingdi Yu0b0a7362014-08-05 16:31:30 -070067 const string& name,
68 const string& institution)
Yingdi Yub4be64a2013-10-13 17:24:50 -070069{
Yingdi Yufa4ce792014-02-06 18:09:22 -080070 m_entries["IDENTITY"] = identityName.toUri();
71 m_entries["name"] = name;
72 m_entries["institution"] = institution;
Yingdi Yub4be64a2013-10-13 17:24:50 -070073}
74
75Profile::Profile(const Profile& profile)
Yingdi Yufa4ce792014-02-06 18:09:22 -080076 : m_entries(profile.m_entries)
Yingdi Yu0b0a7362014-08-05 16:31:30 -070077{
78}
Yingdi Yub4be64a2013-10-13 17:24:50 -070079
Qiuhan Ding0cfc1512015-02-17 17:44:11 -080080template<bool T>
81size_t
82Profile::wireEncode(ndn::EncodingImpl<T>& block) const
Yingdi Yub4be64a2013-10-13 17:24:50 -070083{
Qiuhan Ding0cfc1512015-02-17 17:44:11 -080084 size_t totalLength = 0;
85
86 // Profile := PROFILE-TYPE TLV-LENGTH
87 // ProfileEntry+
88 //
89 // ProfileEntry := PROFILEENTRY-TYPE TLV-LENGTH
90 // Oid
91 // EntryData
92 //
93 // Oid := OID-TYPE TLV-LENGTH
94 // String
95 //
96 // EntryData := ENTRYDATA-TYPE TLV-LENGTH
97 // String
98
99 // Entries
100 size_t entryLength = 0;
101 for (map<string, string>::const_reverse_iterator it = m_entries.rbegin();
102 it != m_entries.rend(); it++) {
103 // Entry Data
104 const uint8_t* dataWire = reinterpret_cast<const uint8_t*>(it->second.c_str());
105 entryLength += block.prependByteArrayBlock(tlv::EntryData, dataWire, it->second.length());
106 // Oid
107 const uint8_t* oidWire = reinterpret_cast<const uint8_t*>(it->first.c_str());
108 entryLength += block.prependByteArrayBlock(tlv::Oid, oidWire, it->first.length());
109 entryLength += block.prependVarNumber(entryLength);
110 entryLength += block.prependVarNumber(tlv::ProfileEntry);
111 totalLength += entryLength;
112 entryLength = 0;
113 }
114
115 // Profile
116 totalLength += block.prependVarNumber(totalLength);
117 totalLength += block.prependVarNumber(tlv::Profile);
118
119 return totalLength;
120}
121
122
123
124const Block&
125Profile::wireEncode() const
126{
127 ndn::EncodingEstimator estimator;
128 size_t estimatedSize = wireEncode(estimator);
129
130 ndn::EncodingBuffer buffer(estimatedSize, 0);
131 wireEncode(buffer);
132
133 m_wire = buffer.block();
134 m_wire.parse();
135
136 return m_wire;
Yingdi Yub4be64a2013-10-13 17:24:50 -0700137}
138
Yingdi Yu76dd8002013-12-24 11:16:32 +0800139void
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800140Profile::wireDecode(const Block& profileWire)
Yingdi Yub4be64a2013-10-13 17:24:50 -0700141{
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800142 m_wire = profileWire;
143 m_wire.parse();
144
145 if (m_wire.type() != tlv::Profile)
146 throw Error("Unexpected TLV number when decoding profile packet");
147
148 Block::element_const_iterator i = m_wire.elements_begin();
149 if (i == m_wire.elements_end())
150 throw Error("Missing Profile Entry");
151 if (i->type() != tlv::ProfileEntry)
152 throw Error("Expect Profile Entry but get TLV Type " + std::to_string(i->type()));
153
154 while (i != m_wire.elements_end() && i->type() == tlv::ProfileEntry) {
155 Block temp = *i;
156 temp.parse();
157 Block::element_const_iterator j = temp.elements_begin();
158 if (j == temp.elements_end())
159 throw Error("Missing Oid");
160 if (j->type() != tlv::Oid)
161 throw Error("Expect Oid but get TLV Type" + std::to_string(j->type()));
162
163 string Oid = std::string(reinterpret_cast<const char* >(j->value()),
164 j->value_size());
165 ++j;
166 if (j == temp.elements_end())
167 throw Error("Missing EntryData");
168 if (j->type() != tlv::EntryData)
169 throw Error("Expect EntryData but get TLV Type " + std::to_string(j->type()));
170
171 string EntryData = std::string(reinterpret_cast<const char* >(j->value()),
172 j->value_size());
173 ++j;
174 if (j != temp.elements_end()) {
175 throw Error("Unexpected element");
176 }
177 m_entries[Oid] = EntryData;
178 ++i;
179 }
180
181 if (i != m_wire.elements_end()) {
182 throw Error("Unexpected element");
183 }
184
Yingdi Yufa4ce792014-02-06 18:09:22 -0800185}
Yingdi Yub4be64a2013-10-13 17:24:50 -0700186
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700187bool
188Profile::operator==(const Profile& profile) const
Yingdi Yufa4ce792014-02-06 18:09:22 -0800189{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700190 if (m_entries.size() != profile.m_entries.size())
191 return false;
192
193 for(map<string, string>::const_iterator it = m_entries.begin(); it != m_entries.end(); it++) {
194 map<string, string>::const_iterator found = profile.m_entries.find(it->first);
195 if (found == profile.m_entries.end())
196 return false;
197 if (found->second != it->second)
198 return false;
199 }
200
201 return true;
202}
203
204bool
205Profile::operator!=(const Profile& profile) const
206{
207 return !(*this == profile);
208}
209
Yingdi Yueb692ac2015-02-10 18:46:18 -0800210} // namespace chronochat