blob: f43cddb996e3e000fc58b119d50594dca953107a [file] [log] [blame]
Yingdi Yud59b5932013-10-16 13:16:49 -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>
9 */
10
Yingdi Yua4898752013-10-15 20:31:37 -070011#include "addcontactpanel.h"
12#include "ui_addcontactpanel.h"
Yingdi Yueb98f7d2013-11-10 01:34:57 -080013#include <QMessageBox>
Yingdi Yua4898752013-10-15 20:31:37 -070014
Yingdi Yuc29fb982013-10-20 19:43:10 -070015#ifndef Q_MOC_RUN
Yingdi Yu64206112013-12-24 11:16:32 +080016#include <ndn-cpp/security/signature/sha256-with-rsa-handler.hpp>
17#include <boost/iostreams/stream.hpp>
18#include "null-ptrs.h"
19#include "endorse-collection.pb.h"
Yingdi Yuc29fb982013-10-20 19:43:10 -070020#include "logging.h"
21#endif
22
Yingdi Yuaa8d7692013-10-18 17:05:02 -070023using namespace ndn;
Yingdi Yu64206112013-12-24 11:16:32 +080024using namespace ndn::ptr_lib;
Yingdi Yuaa8d7692013-10-18 17:05:02 -070025using namespace std;
26
Yingdi Yuc29fb982013-10-20 19:43:10 -070027INIT_LOGGER("AddContactPanel");
28
Yingdi Yu64206112013-12-24 11:16:32 +080029AddContactPanel::AddContactPanel(shared_ptr<ContactManager> contactManager,
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070030 QWidget *parent)
Yingdi Yud59b5932013-10-16 13:16:49 -070031 : QDialog(parent)
32 , ui(new Ui::AddContactPanel)
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070033 , m_contactManager(contactManager)
Yingdi Yuc29fb982013-10-20 19:43:10 -070034 , m_warningDialog(new WarningDialog())
Yingdi Yua4898752013-10-15 20:31:37 -070035{
Yingdi Yud59b5932013-10-16 13:16:49 -070036 ui->setupUi(this);
Yingdi Yuc29fb982013-10-20 19:43:10 -070037
38 qRegisterMetaType<ndn::Name>("NdnName");
39 qRegisterMetaType<EndorseCertificate>("EndorseCertificate");
Yingdi Yu8dacdf22013-11-05 23:06:43 -080040 qRegisterMetaType<ndn::Data>("NdnData");
Yingdi Yud59b5932013-10-16 13:16:49 -070041
42 connect(ui->cancelButton, SIGNAL(clicked()),
43 this, SLOT(onCancelClicked()));
44 connect(ui->searchButton, SIGNAL(clicked()),
45 this, SLOT(onSearchClicked()));
Yingdi Yu79c25a22013-10-21 13:38:38 -070046 connect(ui->addButton, SIGNAL(clicked()),
47 this, SLOT(onAddClicked()));
48 connect(&*m_contactManager, SIGNAL(contactFetched(const EndorseCertificate&)),
49 this, SLOT(selfEndorseCertificateFetched(const EndorseCertificate&)));
Yingdi Yuc29fb982013-10-20 19:43:10 -070050 connect(&*m_contactManager, SIGNAL(contactFetchFailed(const ndn::Name&)),
51 this, SLOT(selfEndorseCertificateFetchFailed(const ndn::Name&)));
Yingdi Yu8dacdf22013-11-05 23:06:43 -080052 connect(&*m_contactManager, SIGNAL(collectEndorseFetched(const ndn::Data&)),
53 this, SLOT(onCollectEndorseFetched(const ndn::Data&)));
54 connect(&*m_contactManager, SIGNAL(collectEndorseFetchFailed(const ndn::Name&)),
55 this, SLOT(onCollectEndorseFetchFailed(const ndn::Name&)));
56 connect(&*m_contactManager, SIGNAL(contactKeyFetched(const EndorseCertificate&)),
57 this, SLOT(onContactKeyFetched(const EndorseCertificate&)));
58 connect(&*m_contactManager, SIGNAL(contactKeyFetchFailed(const ndn::Name&)),
59 this, SLOT(onContactKeyFetchFailed(const ndn::Name&)));
60
61
Yingdi Yua4898752013-10-15 20:31:37 -070062}
63
64AddContactPanel::~AddContactPanel()
65{
66 delete ui;
Yingdi Yuc29fb982013-10-20 19:43:10 -070067 delete m_warningDialog;
Yingdi Yua4898752013-10-15 20:31:37 -070068}
Yingdi Yud59b5932013-10-16 13:16:49 -070069
70void
71AddContactPanel::onCancelClicked()
72{ this->close(); }
73
74void
75AddContactPanel::onSearchClicked()
76{
Yingdi Yu8dacdf22013-11-05 23:06:43 -080077 m_currentEndorseCertificateReady = false;
78 m_currentCollectEndorseReady = false;
Yingdi Yu79c25a22013-10-21 13:38:38 -070079 ui->infoView->clear();
80 for(int i = ui->infoView->rowCount() - 1; i >= 0 ; i--)
81 ui->infoView->removeRow(i);
Yingdi Yuaa8d7692013-10-18 17:05:02 -070082 QString inputIdentity = ui->contactInput->text();
Yingdi Yu64206112013-12-24 11:16:32 +080083 m_searchIdentity = Name(inputIdentity.toStdString());
Yingdi Yuc29fb982013-10-20 19:43:10 -070084
Yingdi Yu8dacdf22013-11-05 23:06:43 -080085 if(Qt::Checked == ui->fetchBox->checkState())
86 {
87 m_contactManager->fetchSelfEndorseCertificate(m_searchIdentity);
88 m_contactManager->fetchCollectEndorse(m_searchIdentity);
89 }
90 else
91 {
92 if(isCorrectName(m_searchIdentity))
93 m_contactManager->fetchKey(m_searchIdentity);
94 else
95 {
Yingdi Yueb98f7d2013-11-10 01:34:57 -080096 QMessageBox::information(this, tr("Chronos"), QString::fromStdString("Wrong key certificate name!"));
Yingdi Yu8dacdf22013-11-05 23:06:43 -080097 }
98 }
99}
100
101bool
102AddContactPanel::isCorrectName(const Name& name)
103{
104 string key("KEY");
105 string idCert("ID-CERT");
106
Yingdi Yu64206112013-12-24 11:16:32 +0800107 if(name.get(-1).toEscapedString() != idCert)
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800108 return false;
109
110 int keyIndex = -1;
111 for(int i = 0; i < name.size(); i++)
112 {
Yingdi Yu64206112013-12-24 11:16:32 +0800113 if(name.get(i).toEscapedString() == key)
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800114 {
115 keyIndex = i;
116 break;
117 }
118 }
119
120 if(keyIndex < 0)
121 return false;
122 else
123 return true;
Yingdi Yud59b5932013-10-16 13:16:49 -0700124}
125
126void
127AddContactPanel::onAddClicked()
128{
Yingdi Yu79c25a22013-10-21 13:38:38 -0700129 ContactItem contactItem(*m_currentEndorseCertificate);
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800130 try{
131 m_contactManager->getContactStorage()->addContact(contactItem);
Yingdi Yu64206112013-12-24 11:16:32 +0800132 }catch(std::exception& e){
Yingdi Yueb98f7d2013-11-10 01:34:57 -0800133 QMessageBox::information(this, tr("Chronos"), QString::fromStdString(e.what()));
Yingdi Yub35b8652013-11-07 11:32:40 -0800134 _LOG_ERROR("Exception: " << e.what());
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800135 return;
136 }
Yingdi Yu79c25a22013-10-21 13:38:38 -0700137 emit newContactAdded();
138 this->close();
Yingdi Yud59b5932013-10-16 13:16:49 -0700139}
140
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700141void
Yingdi Yuc29fb982013-10-20 19:43:10 -0700142AddContactPanel::selfEndorseCertificateFetched(const EndorseCertificate& endorseCertificate)
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700143{
Yingdi Yub35b8652013-11-07 11:32:40 -0800144 try{
Yingdi Yu64206112013-12-24 11:16:32 +0800145 m_currentEndorseCertificate = make_shared<EndorseCertificate>(endorseCertificate);
146 }catch(std::exception& e){
Yingdi Yueb98f7d2013-11-10 01:34:57 -0800147 QMessageBox::information(this, tr("Chronos"), QString::fromStdString(e.what()));
Yingdi Yub35b8652013-11-07 11:32:40 -0800148 _LOG_ERROR("Exception: " << e.what());
149 return;
150 }
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800151 m_currentEndorseCertificateReady = true;
152
153 if(m_currentCollectEndorseReady == true)
154 displayContactInfo();
Yingdi Yuc29fb982013-10-20 19:43:10 -0700155}
156
157void
158AddContactPanel::selfEndorseCertificateFetchFailed(const Name& identity)
159{
Yingdi Yueb98f7d2013-11-10 01:34:57 -0800160 QMessageBox::information(this, tr("Chronos"), QString::fromStdString("Cannot fetch contact profile"));
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700161}
162
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800163void
164AddContactPanel::onContactKeyFetched(const EndorseCertificate& endorseCertificate)
165{
Yingdi Yub35b8652013-11-07 11:32:40 -0800166 try{
Yingdi Yu64206112013-12-24 11:16:32 +0800167 m_currentEndorseCertificate = make_shared<EndorseCertificate>(endorseCertificate);
168 }catch(std::exception& e){
Yingdi Yueb98f7d2013-11-10 01:34:57 -0800169 QMessageBox::information(this, tr("Chronos"), QString::fromStdString(e.what()));
Yingdi Yub35b8652013-11-07 11:32:40 -0800170 _LOG_ERROR("Exception: " << e.what());
171 return;
172 }
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800173
Alexander Afanasyev4f04c552013-11-07 15:30:05 -0800174 m_currentCollectEndorseReady = false;
Yingdi Yue9ea5c92013-11-06 18:42:34 -0800175
176 displayContactInfo();
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800177}
178
179void
180AddContactPanel::onContactKeyFetchFailed(const Name& identity)
181{
Yingdi Yueb98f7d2013-11-10 01:34:57 -0800182 QMessageBox::information(this, tr("Chronos"), QString::fromStdString("Cannot fetch contact ksk certificate"));
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800183}
184
185void
186AddContactPanel::onCollectEndorseFetched(const Data& data)
187{
Yingdi Yu64206112013-12-24 11:16:32 +0800188 m_currentCollectEndorse = make_shared<Data>(data);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800189 m_currentCollectEndorseReady = true;
190
191 if(m_currentEndorseCertificateReady == true)
192 displayContactInfo();
193}
194
195void
196AddContactPanel::onCollectEndorseFetchFailed(const Name& identity)
197{
Yingdi Yu64206112013-12-24 11:16:32 +0800198 m_currentCollectEndorse = CHRONOCHAT_NULL_DATA_PTR;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800199 m_currentCollectEndorseReady = true;
200
201 if(m_currentEndorseCertificateReady == true)
202 displayContactInfo();
203}
204
205void
206AddContactPanel::displayContactInfo()
207{
Yingdi Yub35b8652013-11-07 11:32:40 -0800208 // _LOG_TRACE("displayContactInfo");
Yingdi Yu64206112013-12-24 11:16:32 +0800209 const Profile& profile = m_currentEndorseCertificate->getProfileData().getProfile();
210 const Blob& profileBlob = m_currentEndorseCertificate->getProfileData().getContent();
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800211
212 map<string, int> endorseCount;
213
Yingdi Yu64206112013-12-24 11:16:32 +0800214 if(m_currentCollectEndorse != CHRONOCHAT_NULL_DATA_PTR)
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800215 {
Yingdi Yu64206112013-12-24 11:16:32 +0800216 Chronos::EndorseCollection endorseCollection;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800217
Yingdi Yu64206112013-12-24 11:16:32 +0800218 boost::iostreams::stream
219 <boost::iostreams::array_source> is ((const char*)m_currentCollectEndorse->getContent().buf(), m_currentCollectEndorse->getContent().size());
220
221 endorseCollection.ParseFromIstream(&is);
222
223 for(int i = 0; i < endorseCollection.endorsement_size(); i ++)
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800224 {
Yingdi Yub35b8652013-11-07 11:32:40 -0800225 try{
Yingdi Yu64206112013-12-24 11:16:32 +0800226 Data data;
227 data.wireDecode((const uint8_t*)endorseCollection.endorsement(i).blob().c_str(), endorseCollection.endorsement(i).blob().size());
228 EndorseCertificate endorseCert(data);
229
230 Name signerKeyName = endorseCert.getSigner();
231 Name signerName = signerKeyName.getPrefix(-1);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800232
Yingdi Yu64206112013-12-24 11:16:32 +0800233 shared_ptr<ContactItem> contact = m_contactManager->getContact(signerName);
234 if(contact == CHRONOCHAT_NULL_CONTACTITEM_PTR)
235 continue;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800236
Yingdi Yu64206112013-12-24 11:16:32 +0800237 if(!contact->isIntroducer() || !contact->canBeTrustedFor(m_currentEndorseCertificate->getProfileData().getIdentityName()))
238 continue;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800239
Yingdi Yu64206112013-12-24 11:16:32 +0800240 if(!Sha256WithRsaHandler::verifySignature(data, contact->getSelfEndorseCertificate().getPublicKeyInfo()))
241 continue;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800242
Yingdi Yu64206112013-12-24 11:16:32 +0800243 const Blob& tmpProfileBlob = endorseCert.getProfileData().getContent();
244 if(!isSameBlob(profileBlob, tmpProfileBlob))
245 continue;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800246
Yingdi Yu64206112013-12-24 11:16:32 +0800247 const vector<string>& endorseList = endorseCert.getEndorseList();
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800248 vector<string>::const_iterator it = endorseList.begin();
249 for(; it != endorseList.end(); it++)
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800250 endorseCount[*it] += 1;
Yingdi Yu64206112013-12-24 11:16:32 +0800251 }catch(std::exception& e){
252 continue;
253 }
254 }
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800255 }
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800256
257 ui->infoView->setColumnCount(3);
258 Profile::const_iterator it = profile.begin();
259 int rowCount = 0;
260
261 QTableWidgetItem *typeHeader = new QTableWidgetItem(QString::fromUtf8("Type"));
262 ui->infoView->setHorizontalHeaderItem(0, typeHeader);
263 QTableWidgetItem *valueHeader = new QTableWidgetItem(QString::fromUtf8("Value"));
264 ui->infoView->setHorizontalHeaderItem(1, valueHeader);
265 QTableWidgetItem *endorseHeader = new QTableWidgetItem(QString::fromUtf8("Endorse"));
266 ui->infoView->setHorizontalHeaderItem(2, endorseHeader);
267
268 for(; it != profile.end(); it++)
269 {
270 ui->infoView->insertRow(rowCount);
Yingdi Yu64206112013-12-24 11:16:32 +0800271 QTableWidgetItem *type = new QTableWidgetItem(QString::fromStdString(it->first));
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800272 ui->infoView->setItem(rowCount, 0, type);
273
Yingdi Yu64206112013-12-24 11:16:32 +0800274 QTableWidgetItem *value = new QTableWidgetItem(QString::fromStdString(it->second));
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800275 ui->infoView->setItem(rowCount, 1, value);
276
277 map<string, int>::iterator map_it = endorseCount.find(it->first);
278 QTableWidgetItem *endorse = NULL;
279 if(map_it == endorseCount.end())
280 endorse = new QTableWidgetItem(QString::number(0));
281 else
282 endorse = new QTableWidgetItem(QString::number(map_it->second));
283 ui->infoView->setItem(rowCount, 2, endorse);
284
285 rowCount++;
286 }
287}
288
Yingdi Yu64206112013-12-24 11:16:32 +0800289bool
290AddContactPanel::isSameBlob(const ndn::Blob& blobA, const ndn::Blob& blobB)
291{
292 size_t size = blobA.size();
293
294 if(size != blobB.size())
295 return false;
296
297 const uint8_t* ap = blobA.buf();
298 const uint8_t* bp = blobB.buf();
299
300 for(int i = 0; i < size; i++)
301 {
302 if(ap[i] != bp[i])
303 return false;
304 }
305
306 return true;
307
308}
309
310
Yingdi Yud59b5932013-10-16 13:16:49 -0700311#if WAF
312#include "addcontactpanel.moc"
313#include "addcontactpanel.cpp.moc"
314#endif