blob: c4b88c7379129aada21d60f7a10d3fe6e9f3f74c [file] [log] [blame]
akmhoque099495b2014-03-11 16:01:19 -05001#include <ndn-cpp-dev/data.hpp>
2#include <ndn-cpp-dev/security/key-chain.hpp>
3#include <ndn-cpp-dev/util/random.hpp>
4#include <ndn-cpp-dev/security/identity-certificate.hpp>
5#include <ndn-cpp-dev/security/certificate-subject-description.hpp>
6#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
7#include <ndn-cpp-dev/util/io.hpp>
8#include <boost/algorithm/string.hpp>
9#include <exception>
10
11
12
13
14namespace
15{
16
17 class CertTool: public ndn::KeyChain
18 {
19 typedef SecPublicInfo::Error InfoError;
20 typedef SecTpm::Error TpmError;
21 public:
22 CertTool()
23 {
24 }
25
26 std::pair<ndn::shared_ptr<ndn::IdentityCertificate> , bool>
27 getCertificate(ndn::Name certificateName)
28 {
29 try
30 {
31 ndn::shared_ptr<ndn::IdentityCertificate> cert=
32 ndn::KeyChain::getCertificate(certificateName);
33 return std::make_pair(cert , true);
34 }
35 catch(TpmError& e)
36 {
37 std::cerr<<"Certificate Not Found"<<std::endl;
38 return std::make_pair(
39 ndn::make_shared<ndn::IdentityCertificate>() , false);
40 }
41 }
akmhoquee14bc492014-04-03 13:14:50 -050042
43 void
44 deleteIdentity(const ndn::Name identityName)
45 {
46 ndn::KeyChain::deleteIdentity(identityName);
47 }
akmhoque099495b2014-03-11 16:01:19 -050048
49
50 /* Return Certificate Name */
51 ndn::Name
52 createIdentity(const ndn::Name identityName, const ndn::Name signee,
53 bool isUnSigned=false)
54 {
55 ndn::KeyChain::deleteIdentity(identityName);
56 ndn::KeyChain::addIdentity(identityName);
57 ndn::Name keyName;
58 try
59 {
60 keyName = ndn::KeyChain::getDefaultKeyNameForIdentity(identityName);
61 }
62 catch(InfoError& e)
63 {
64 keyName = ndn::KeyChain::generateRSAKeyPairAsDefault(identityName, true);
65 }
66
67 ndn::shared_ptr<ndn::PublicKey> pubKey;
68 try
69 {
70 pubKey = ndn::KeyChain::getPublicKey(keyName);
71 }
72 catch(InfoError& e)
73 {
74 return identityName;
75 }
76 ndn::Name certName;
77 try
78 {
79 certName = ndn::KeyChain::getDefaultCertificateNameForKey(keyName);
80 }
81 catch(InfoError& e)
82 {
83 ndn::shared_ptr<ndn::IdentityCertificate> certificate =
84 ndn::make_shared<ndn::IdentityCertificate>();
85 ndn::Name certificateName = keyName.getPrefix(-1);
86 certificateName.append("KEY").append(
87 keyName.get(-1)).append("ID-CERT").appendVersion();
88 certificate->setName(certificateName);
89 certificate->setNotBefore(ndn::getNow());
90 certificate->setNotAfter(ndn::getNow() + 63072000 /* 2 years*/);
91 certificate->setPublicKeyInfo(*pubKey);
92 certificate->addSubjectDescription(
93 ndn::CertificateSubjectDescription("2.5.4.41",
94 keyName.toUri()));
95 certificate->encode();
96 if ( !isUnSigned )
97 {
98 try
99 {
100 signByIdentity(*certificate,signee);
101 }
102 catch(InfoError& e)
103 {
104 try
105 {
106 ndn::KeyChain::deleteIdentity(identityName);
107 }
108 catch(InfoError& e)
109 {
110 }
111 return identityName;
112 }
A K M Mahmudul Hoque6e6b7fc2014-04-03 13:25:08 -0500113 ndn::KeyChain::addCertificateAsIdentityDefault(*(certificate));
akmhoque099495b2014-03-11 16:01:19 -0500114 }
115
116 certName=certificate->getName();
117 }
118 return certName;
119 }
120
121 template<typename T>
122 void
123 signByIdentity(T& packet, const ndn::Name& identityName)
124 {
125 ndn::KeyChain::signByIdentity(packet,identityName);
126 }
127
128 bool
129 loadCertificate(std::string inputFile)
130 {
131 ndn::shared_ptr<ndn::IdentityCertificate> cert =
132 ndn::io::load<ndn::IdentityCertificate>(
133 inputFile.c_str(), ndn::io::BASE_64);
134
135 try
136 {
137 ndn::KeyChain::deleteCertificate(cert->getName());
A K M Mahmudul Hoque6e6b7fc2014-04-03 13:25:08 -0500138 ndn::KeyChain::addCertificateAsIdentityDefault(*(cert));
akmhoque099495b2014-03-11 16:01:19 -0500139 return true;
140 }
141 catch(InfoError& e)
142 {
143 std::cout << e.what() <<std::endl;
144 return false;
145 }
146 }
147
148 };
149}
150
151
152void
153createCertificateAndDump(std::string identity, std::string signee,
154 std::string outputFile)
155{
156 ndn::Name certName;
157 CertTool ct;
158
159 if( boost::iequals(signee, "self") || boost::iequals(signee, "unsigned"))
160 {
161 certName=ct.createIdentity(ndn::Name(identity),ndn::Name(identity));
162 }
163 else
164 {
165 certName=ct.createIdentity(ndn::Name(identity),ndn::Name(signee));
166 }
167
168 std::pair<ndn::shared_ptr<ndn::IdentityCertificate> , bool> cert =
169 ct.getCertificate(certName);
170 if( cert.second )
171 {
172 std::cout<<*(cert.first)<<std::endl;
173 std::ofstream outFile(outputFile.c_str());
174 ndn::io::save(*(cert.first),outFile,ndn::io::BASE_64);
175 }
176 else
177 {
178 std::cerr<<"Certificate not created or signee not found"<<std::endl;
179 }
180
181}
182
183void
184signCertificateAndDump(std::string signee,
185 std::string inputFile, std::string outputFile)
186{
187 ndn::shared_ptr<ndn::IdentityCertificate> cert =
188 ndn::io::load<ndn::IdentityCertificate>(
189 inputFile.c_str(), ndn::io::BASE_64);
190 try
191 {
192 CertTool ct;
193 ct.signByIdentity(*(cert), ndn::Name(signee));
194 std::cout<<*(cert)<<std::endl;
195 std::ofstream outFile(outputFile.c_str());
196 ndn::io::save(*(cert),outFile,ndn::io::BASE_64);
197
198 }
199 catch(std::exception& e)
200 {
201 std::cout << e.what() <<std::endl;
202 }
203
204}
205
206void
207loadCertificate(std::string inputFile)
208{
209 try
210 {
211 CertTool ct;
212 if (ct.loadCertificate(inputFile) )
213 {
214 std::cout<<"Certificate Loaded in Key Chain"<<std::endl;
215 }
216 }
217 catch(std::exception& e)
218 {
219 std::cout << e.what() <<std::endl;
220 }
221}
222
akmhoquee14bc492014-04-03 13:14:50 -0500223void
224deleteIdentity(std::string identityName)
225{
226 ndn::Name idName(identityName);
227 try
228 {
229 CertTool ct;
230 ct.deleteIdentity(idName);
231
232 std::cout<<"Identity Deleted"<<std::endl;
233
234 }
235 catch(std::exception& e)
236 {
237 std::cout << e.what() <<std::endl;
238 }
239
240}
241
akmhoque099495b2014-03-11 16:01:19 -0500242
243static int
244usage(const std::string& program)
245{
246 std::cout << "Usage: " << program << " [OPTIONS...]"<<std::endl;
247 std::cout << " Cert Tool options...." << std::endl;
248 std::cout << " -(c|s|l) , Create or Sign or Load identity's certificate" << std::endl;
249 std::cout << " -i , --identityName New/singing identity name" <<std::endl;
250 std::cout << " -I , --signeeIdentity Identity Name of signer or self for self signing or unsigned" <<std::endl;
251 std::cout << " -f , --inputFile Input file name for -s option"<<std::endl;
252 std::cout << " -o , --outputFile Output file name where certificate will be dumped"<<std::endl;
253 std::cout << " -h , Display this help message" << std::endl;
254 exit(EXIT_FAILURE);
255}
256
257int main(int argc, char **argv)
258{
259 bool isCreate=false;
260 bool isSign=false;
261 bool isLoad=false;
akmhoquee14bc492014-04-03 13:14:50 -0500262 bool isDelete=false;
akmhoque099495b2014-03-11 16:01:19 -0500263 int operationCount=0;
264 std::string programName(argv[0]);
265 std::string inputFile;
266 std::string outputFile;
267 std::string identityName;
268 std::string signeeIdentityName;
269 int opt;
akmhoquee14bc492014-04-03 13:14:50 -0500270 while ((opt = getopt(argc, argv, "dcslf:I:i:f:o:h")) != -1)
akmhoque099495b2014-03-11 16:01:19 -0500271 {
272 switch (opt)
273 {
274 case 'c':
275 isCreate=true;
276 operationCount++;
277 break;
278 case 's':
279 isSign=true;
280 operationCount++;
281 break;
282 case 'l':
283 isLoad=true;
284 operationCount++;
285 break;
akmhoquee14bc492014-04-03 13:14:50 -0500286 case 'd':
287 isDelete=true;
288 operationCount++;
289 break;
akmhoque099495b2014-03-11 16:01:19 -0500290 case 'f':
291 inputFile=optarg;
292 break;
293 case 'o':
294 outputFile=optarg;
295 break;
296 case 'i':
297 identityName=optarg;
298 case 'I':
299 signeeIdentityName=optarg;
300 break;
301 case 'h':
302 default:
303 usage(programName);
304 return EXIT_FAILURE;
305 }
306 }
307
308 if( operationCount > 1)
309 {
310 std::cerr<<"Can not perform more than one operation at once !"<<std::endl;
311 usage(programName);
312 }
313
314 if ( isCreate )
315 {
316 if ( identityName.empty() ||
317 signeeIdentityName.empty() || outputFile.empty())
318 {
319 usage(programName);
320 }
321
322 createCertificateAndDump(identityName,signeeIdentityName, outputFile);
323 }
324
325 if( isSign )
326 {
327 if ( signeeIdentityName.empty() ||
328 inputFile.empty() || outputFile.empty())
329 {
330 usage(programName);
331 }
332
333 signCertificateAndDump(signeeIdentityName, inputFile, outputFile);
334 }
335
336 if( isLoad )
337 {
338 if ( inputFile.empty() )
339 {
340 usage(programName);
341 }
342
343 loadCertificate(inputFile);
344
345 }
346
akmhoquee14bc492014-04-03 13:14:50 -0500347 if( isDelete )
348 {
349 if ( identityName.empty() )
350 {
351 usage(programName);
352 }
353 deleteIdentity(identityName);
354 }
355
akmhoque099495b2014-03-11 16:01:19 -0500356 return EXIT_SUCCESS;
357}
358