blob: 98c2f5c835f6d61e09b69d676755f5d5cd397aba [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 }
42
43
44
45 /* Return Certificate Name */
46 ndn::Name
47 createIdentity(const ndn::Name identityName, const ndn::Name signee,
48 bool isUnSigned=false)
49 {
50 ndn::KeyChain::deleteIdentity(identityName);
51 ndn::KeyChain::addIdentity(identityName);
52 ndn::Name keyName;
53 try
54 {
55 keyName = ndn::KeyChain::getDefaultKeyNameForIdentity(identityName);
56 }
57 catch(InfoError& e)
58 {
59 keyName = ndn::KeyChain::generateRSAKeyPairAsDefault(identityName, true);
60 }
61
62 ndn::shared_ptr<ndn::PublicKey> pubKey;
63 try
64 {
65 pubKey = ndn::KeyChain::getPublicKey(keyName);
66 }
67 catch(InfoError& e)
68 {
69 return identityName;
70 }
71 ndn::Name certName;
72 try
73 {
74 certName = ndn::KeyChain::getDefaultCertificateNameForKey(keyName);
75 }
76 catch(InfoError& e)
77 {
78 ndn::shared_ptr<ndn::IdentityCertificate> certificate =
79 ndn::make_shared<ndn::IdentityCertificate>();
80 ndn::Name certificateName = keyName.getPrefix(-1);
81 certificateName.append("KEY").append(
82 keyName.get(-1)).append("ID-CERT").appendVersion();
83 certificate->setName(certificateName);
84 certificate->setNotBefore(ndn::getNow());
85 certificate->setNotAfter(ndn::getNow() + 63072000 /* 2 years*/);
86 certificate->setPublicKeyInfo(*pubKey);
87 certificate->addSubjectDescription(
88 ndn::CertificateSubjectDescription("2.5.4.41",
89 keyName.toUri()));
90 certificate->encode();
91 if ( !isUnSigned )
92 {
93 try
94 {
95 signByIdentity(*certificate,signee);
96 }
97 catch(InfoError& e)
98 {
99 try
100 {
101 ndn::KeyChain::deleteIdentity(identityName);
102 }
103 catch(InfoError& e)
104 {
105 }
106 return identityName;
107 }
108 ndn::KeyChain::addCertificate(*(certificate));
109 }
110
111 certName=certificate->getName();
112 }
113 return certName;
114 }
115
116 template<typename T>
117 void
118 signByIdentity(T& packet, const ndn::Name& identityName)
119 {
120 ndn::KeyChain::signByIdentity(packet,identityName);
121 }
122
123 bool
124 loadCertificate(std::string inputFile)
125 {
126 ndn::shared_ptr<ndn::IdentityCertificate> cert =
127 ndn::io::load<ndn::IdentityCertificate>(
128 inputFile.c_str(), ndn::io::BASE_64);
129
130 try
131 {
132 ndn::KeyChain::deleteCertificate(cert->getName());
133 ndn::KeyChain::addCertificate(*(cert));
134 return true;
135 }
136 catch(InfoError& e)
137 {
138 std::cout << e.what() <<std::endl;
139 return false;
140 }
141 }
142
143 };
144}
145
146
147void
148createCertificateAndDump(std::string identity, std::string signee,
149 std::string outputFile)
150{
151 ndn::Name certName;
152 CertTool ct;
153
154 if( boost::iequals(signee, "self") || boost::iequals(signee, "unsigned"))
155 {
156 certName=ct.createIdentity(ndn::Name(identity),ndn::Name(identity));
157 }
158 else
159 {
160 certName=ct.createIdentity(ndn::Name(identity),ndn::Name(signee));
161 }
162
163 std::pair<ndn::shared_ptr<ndn::IdentityCertificate> , bool> cert =
164 ct.getCertificate(certName);
165 if( cert.second )
166 {
167 std::cout<<*(cert.first)<<std::endl;
168 std::ofstream outFile(outputFile.c_str());
169 ndn::io::save(*(cert.first),outFile,ndn::io::BASE_64);
170 }
171 else
172 {
173 std::cerr<<"Certificate not created or signee not found"<<std::endl;
174 }
175
176}
177
178void
179signCertificateAndDump(std::string signee,
180 std::string inputFile, std::string outputFile)
181{
182 ndn::shared_ptr<ndn::IdentityCertificate> cert =
183 ndn::io::load<ndn::IdentityCertificate>(
184 inputFile.c_str(), ndn::io::BASE_64);
185 try
186 {
187 CertTool ct;
188 ct.signByIdentity(*(cert), ndn::Name(signee));
189 std::cout<<*(cert)<<std::endl;
190 std::ofstream outFile(outputFile.c_str());
191 ndn::io::save(*(cert),outFile,ndn::io::BASE_64);
192
193 }
194 catch(std::exception& e)
195 {
196 std::cout << e.what() <<std::endl;
197 }
198
199}
200
201void
202loadCertificate(std::string inputFile)
203{
204 try
205 {
206 CertTool ct;
207 if (ct.loadCertificate(inputFile) )
208 {
209 std::cout<<"Certificate Loaded in Key Chain"<<std::endl;
210 }
211 }
212 catch(std::exception& e)
213 {
214 std::cout << e.what() <<std::endl;
215 }
216}
217
218
219static int
220usage(const std::string& program)
221{
222 std::cout << "Usage: " << program << " [OPTIONS...]"<<std::endl;
223 std::cout << " Cert Tool options...." << std::endl;
224 std::cout << " -(c|s|l) , Create or Sign or Load identity's certificate" << std::endl;
225 std::cout << " -i , --identityName New/singing identity name" <<std::endl;
226 std::cout << " -I , --signeeIdentity Identity Name of signer or self for self signing or unsigned" <<std::endl;
227 std::cout << " -f , --inputFile Input file name for -s option"<<std::endl;
228 std::cout << " -o , --outputFile Output file name where certificate will be dumped"<<std::endl;
229 std::cout << " -h , Display this help message" << std::endl;
230 exit(EXIT_FAILURE);
231}
232
233int main(int argc, char **argv)
234{
235 bool isCreate=false;
236 bool isSign=false;
237 bool isLoad=false;
238 int operationCount=0;
239 std::string programName(argv[0]);
240 std::string inputFile;
241 std::string outputFile;
242 std::string identityName;
243 std::string signeeIdentityName;
244 int opt;
245 while ((opt = getopt(argc, argv, "cslf:I:i:f:o:h")) != -1)
246 {
247 switch (opt)
248 {
249 case 'c':
250 isCreate=true;
251 operationCount++;
252 break;
253 case 's':
254 isSign=true;
255 operationCount++;
256 break;
257 case 'l':
258 isLoad=true;
259 operationCount++;
260 break;
261 case 'f':
262 inputFile=optarg;
263 break;
264 case 'o':
265 outputFile=optarg;
266 break;
267 case 'i':
268 identityName=optarg;
269 case 'I':
270 signeeIdentityName=optarg;
271 break;
272 case 'h':
273 default:
274 usage(programName);
275 return EXIT_FAILURE;
276 }
277 }
278
279 if( operationCount > 1)
280 {
281 std::cerr<<"Can not perform more than one operation at once !"<<std::endl;
282 usage(programName);
283 }
284
285 if ( isCreate )
286 {
287 if ( identityName.empty() ||
288 signeeIdentityName.empty() || outputFile.empty())
289 {
290 usage(programName);
291 }
292
293 createCertificateAndDump(identityName,signeeIdentityName, outputFile);
294 }
295
296 if( isSign )
297 {
298 if ( signeeIdentityName.empty() ||
299 inputFile.empty() || outputFile.empty())
300 {
301 usage(programName);
302 }
303
304 signCertificateAndDump(signeeIdentityName, inputFile, outputFile);
305 }
306
307 if( isLoad )
308 {
309 if ( inputFile.empty() )
310 {
311 usage(programName);
312 }
313
314 loadCertificate(inputFile);
315
316 }
317
318 return EXIT_SUCCESS;
319}
320