blob: 08332eea1194e3905df3fa5dc8a6958d5669dfaa [file] [log] [blame]
Yingdi Yu8d7468f2014-02-21 14:49:45 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * BSD license, See the LICENSE file for more information
5 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
6 */
7
8#ifndef NDNSEC_DSK_GEN_HPP
9#define NDNSEC_DSK_GEN_HPP
10
11#include "ndnsec-util.hpp"
12
Yingdi Yub61f5402014-02-26 17:46:11 -080013int
Yingdi Yu8d7468f2014-02-21 14:49:45 -080014ndnsec_dsk_gen(int argc, char** argv)
15{
16 using namespace ndn;
17 namespace po = boost::program_options;
18
19 std::string identityName;
20 char keyType = 'r';
21 int keySize = 2048;
22
Yingdi Yub61f5402014-02-26 17:46:11 -080023 po::options_description description("General Usage\n ndnsec dsk-gen [-h] identity\nGeneral options");
24 description.add_options()
Yingdi Yu8d7468f2014-02-21 14:49:45 -080025 ("help,h", "produce help message")
26 ("identity,i", po::value<std::string>(&identityName), "identity name, for example, /ndn/ucla.edu/alice")
27 // ("type,t", po::value<char>(&keyType)->default_value('r'), "optional, key type, r for RSA key (default)")
28 // ("size,s", po::value<int>(&keySize)->default_value(2048), "optional, key size, 2048 (default)")
29 ;
30
31 po::positional_options_description p;
32 p.add("identity", 1);
33
34 po::variables_map vm;
Yingdi Yub61f5402014-02-26 17:46:11 -080035 try
Yingdi Yu8d7468f2014-02-21 14:49:45 -080036 {
Yingdi Yub61f5402014-02-26 17:46:11 -080037 po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(),
38 vm);
39 po::notify(vm);
40 }
41 catch (const std::exception& e)
42 {
43 std::cerr << "ERROR: " << e.what() << std::endl;
44 std::cerr << description << std::endl;
45 return 1;
46 }
47
48 if (vm.count("help") != 0)
49 {
50 std::cerr << description << std::endl;
Yingdi Yu8d7468f2014-02-21 14:49:45 -080051 return 0;
52 }
53
Yingdi Yub61f5402014-02-26 17:46:11 -080054 if (vm.count("identity") == 0)
Yingdi Yu8d7468f2014-02-21 14:49:45 -080055 {
56 std::cerr << "identity must be specified" << std::endl;
Yingdi Yub61f5402014-02-26 17:46:11 -080057 std::cerr << description << std::endl;
Yingdi Yu8d7468f2014-02-21 14:49:45 -080058 return 1;
59 }
60
61 shared_ptr<IdentityCertificate> kskCert;
62 Name signingCertName;
Yingdi Yub61f5402014-02-26 17:46:11 -080063
64 KeyChain keyChain;
65
66 Name defaultCertName = keyChain.getDefaultCertificateNameForIdentity(identityName);
67 bool isDefaultDsk = false;
68 if (defaultCertName.get(-3).toEscapedString().substr(0,4) == "dsk-")
69 isDefaultDsk = true;
70
71 if (isDefaultDsk)
Yingdi Yu8d7468f2014-02-21 14:49:45 -080072 {
Yingdi Yub61f5402014-02-26 17:46:11 -080073 shared_ptr<IdentityCertificate> dskCert = keyChain.getCertificate(defaultCertName);
74 SignatureSha256WithRsa sha256sig(dskCert->getSignature());
Yingdi Yu8d7468f2014-02-21 14:49:45 -080075
Yingdi Yub61f5402014-02-26 17:46:11 -080076 Name keyLocatorName = sha256sig.getKeyLocator().getName(); // will throw exception if keylocator is absent or it is not a name
Yingdi Yu8d7468f2014-02-21 14:49:45 -080077
Yingdi Yub61f5402014-02-26 17:46:11 -080078 Name kskName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
79 Name kskCertName = keyChain.getDefaultCertificateNameForKey(kskName);
80 signingCertName = kskCertName;
81 kskCert = keyChain.getCertificate(kskCertName);
Yingdi Yu8d7468f2014-02-21 14:49:45 -080082 }
Yingdi Yub61f5402014-02-26 17:46:11 -080083 else
Yingdi Yu8d7468f2014-02-21 14:49:45 -080084 {
Yingdi Yub61f5402014-02-26 17:46:11 -080085 signingCertName = defaultCertName;
86 kskCert = keyChain.getCertificate(defaultCertName);
Yingdi Yu8d7468f2014-02-21 14:49:45 -080087 }
88
Yingdi Yub61f5402014-02-26 17:46:11 -080089 if (!static_cast<bool>(kskCert))
Yingdi Yu8d7468f2014-02-21 14:49:45 -080090 {
91 std::cerr << "ERROR: no KSK certificate." << std::endl;
92 return 1;
93 }
94
Yingdi Yub61f5402014-02-26 17:46:11 -080095 Name newKeyName;
96 switch (keyType)
Yingdi Yu8d7468f2014-02-21 14:49:45 -080097 {
Yingdi Yub61f5402014-02-26 17:46:11 -080098 case 'r':
99 {
100 newKeyName = keyChain.generateRSAKeyPair(Name(identityName), false, keySize);
101 if (0 == newKeyName.size())
Yingdi Yu8d7468f2014-02-21 14:49:45 -0800102 {
Yingdi Yub61f5402014-02-26 17:46:11 -0800103 std::cerr << "fail to generate key!" << std::endl;
104 return 1;
Yingdi Yu8d7468f2014-02-21 14:49:45 -0800105 }
Yingdi Yub61f5402014-02-26 17:46:11 -0800106 break;
107 }
108 default:
109 std::cerr << "Unrecongized key type" << "\n";
110 std::cerr << description << std::endl;
Yingdi Yu8d7468f2014-02-21 14:49:45 -0800111 return 1;
112 }
Yingdi Yub61f5402014-02-26 17:46:11 -0800113
114 Name certName = newKeyName.getPrefix(-1);
115 certName.append("KEY")
116 .append(newKeyName.get(-1))
117 .append("ID-CERT")
118 .appendVersion();
119
120 shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
121 certificate->setName(certName);
122 certificate->setNotBefore(kskCert->getNotBefore());
123 certificate->setNotAfter(kskCert->getNotAfter());
124
125 certificate->setPublicKeyInfo(*keyChain.getPublicKey(newKeyName));
126
127 const std::vector<CertificateSubjectDescription>& subList =
128 kskCert->getSubjectDescriptionList();
129
130 for (std::vector<CertificateSubjectDescription>::const_iterator it = subList.begin();
131 it != subList.end(); it++)
132 certificate->addSubjectDescription(*it);
133
134 certificate->encode();
135
136 keyChain.sign(*certificate, signingCertName);
137
138 keyChain.addCertificateAsIdentityDefault(*certificate);
139
140 return 0;
Yingdi Yu8d7468f2014-02-21 14:49:45 -0800141}
142
143#endif //NDNSEC_DSK_GEN_HPP