1 | // |
2 | // genrsakey.cpp |
3 | // |
4 | // This sample demonstrates the XYZ class. |
5 | // |
6 | // Copyright (c) 2007, Applied Informatics Software Engineering GmbH. |
7 | // and Contributors. |
8 | // |
9 | // SPDX-License-Identifier: BSL-1.0 |
10 | // |
11 | |
12 | |
13 | #include "Poco/Util/Application.h" |
14 | #include "Poco/Util/Option.h" |
15 | #include "Poco/Util/OptionException.h" |
16 | #include "Poco/Util/OptionSet.h" |
17 | #include "Poco/Util/HelpFormatter.h" |
18 | #include "Poco/Util/AbstractConfiguration.h" |
19 | #include "Poco/AutoPtr.h" |
20 | #include "Poco/NumberFormatter.h" |
21 | #include "Poco/NumberParser.h" |
22 | #include "Poco/String.h" |
23 | #include "Poco/Crypto/RSAKey.h" |
24 | #include <iostream> |
25 | |
26 | |
27 | using Poco::Util::Application; |
28 | using Poco::Util::Option; |
29 | using Poco::Util::OptionSet; |
30 | using Poco::Util::HelpFormatter; |
31 | using Poco::Util::AbstractConfiguration; |
32 | using Poco::Util::OptionCallback; |
33 | using Poco::AutoPtr; |
34 | using Poco::NumberParser; |
35 | using Poco::Crypto::RSAKey; |
36 | |
37 | |
38 | class RSAApp: public Application |
39 | /// This sample demonstrates some of the features of the Util::Application class, |
40 | /// such as configuration file handling and command line arguments processing. |
41 | /// |
42 | /// Try genrsakey --help (on Unix platforms) or genrsakey /help (elsewhere) for |
43 | /// more information. |
44 | { |
45 | public: |
46 | RSAApp(): |
47 | _helpRequested(false), |
48 | _length(RSAKey::KL_1024), |
49 | _exp(RSAKey::EXP_LARGE), |
50 | _name(), |
51 | _pwd() |
52 | { |
53 | Poco::Crypto::initializeCrypto(); |
54 | } |
55 | |
56 | ~RSAApp() |
57 | { |
58 | Poco::Crypto::uninitializeCrypto(); |
59 | } |
60 | |
61 | protected: |
62 | void initialize(Application& self) |
63 | { |
64 | loadConfiguration(); // load default configuration files, if present |
65 | Application::initialize(self); |
66 | } |
67 | |
68 | void uninitialize() |
69 | { |
70 | Application::uninitialize(); |
71 | } |
72 | |
73 | void reinitialize(Application& self) |
74 | { |
75 | Application::reinitialize(self); |
76 | } |
77 | |
78 | void defineOptions(OptionSet& options) |
79 | { |
80 | Application::defineOptions(options); |
81 | |
82 | options.addOption( |
83 | Option("help" , "h" , "display help information on command line arguments" ) |
84 | .required(false) |
85 | .repeatable(false) |
86 | .callback(OptionCallback<RSAApp>(this, &RSAApp::handleHelp))); |
87 | |
88 | options.addOption( |
89 | Option("?" , "?" , "display help information on command line arguments" ) |
90 | .required(false) |
91 | .repeatable(false) |
92 | .callback(OptionCallback<RSAApp>(this, &RSAApp::handleHelp))); |
93 | |
94 | options.addOption( |
95 | Option("key" , "k" , "define the key length" ) |
96 | .required(false) |
97 | .repeatable(false) |
98 | .argument("512|1024|2048|4096" ) |
99 | .callback(OptionCallback<RSAApp>(this, &RSAApp::handleKeyLength))); |
100 | |
101 | options.addOption( |
102 | Option("exponent" , "e" , "defines the exponent of the key" ) |
103 | .required(false) |
104 | .repeatable(false) |
105 | .argument("small|large" ) |
106 | .callback(OptionCallback<RSAApp>(this, &RSAApp::handleExponent))); |
107 | |
108 | options.addOption( |
109 | Option("file" , "f" , "defines the file base name. creates a file.pub and a file.priv" ) |
110 | .required(true) |
111 | .repeatable(false) |
112 | .argument("filebasename" ) |
113 | .callback(OptionCallback<RSAApp>(this, &RSAApp::handleFilePrefix))); |
114 | |
115 | options.addOption( |
116 | Option("password" , "p" , "defines the password used to encrypt the private key file. If not defined user will be asked via stdin to provide in" ) |
117 | .required(false) |
118 | .repeatable(false) |
119 | .argument("pwd" ) |
120 | .callback(OptionCallback<RSAApp>(this, &RSAApp::handlePassword))); |
121 | } |
122 | |
123 | void handleHelp(const std::string& name, const std::string& value) |
124 | { |
125 | _helpRequested = true; |
126 | displayHelp(); |
127 | stopOptionsProcessing(); |
128 | } |
129 | |
130 | void handleKeyLength(const std::string& name, const std::string& value) |
131 | { |
132 | int keyLen = Poco::NumberParser::parse(value); |
133 | if (keyLen == 512 || keyLen == 1024 || keyLen == 2048 || keyLen == 4096) |
134 | _length = (RSAKey::KeyLength)keyLen; |
135 | else |
136 | throw Poco::Util::IncompatibleOptionsException("Illegal key length value" ); |
137 | } |
138 | |
139 | void handleExponent(const std::string& name, const std::string& value) |
140 | { |
141 | if (Poco::icompare(value, "small" ) == 0) |
142 | _exp = RSAKey::EXP_SMALL; |
143 | else |
144 | _exp = RSAKey::EXP_LARGE; |
145 | } |
146 | |
147 | void handleFilePrefix(const std::string& name, const std::string& value) |
148 | { |
149 | if (value.empty()) |
150 | throw Poco::Util::IncompatibleOptionsException("Empty file prefix forbidden" ); |
151 | _name = value; |
152 | } |
153 | |
154 | void handlePassword(const std::string& name, const std::string& value) |
155 | { |
156 | _pwd = value; |
157 | } |
158 | |
159 | void displayHelp() |
160 | { |
161 | HelpFormatter helpFormatter(options()); |
162 | helpFormatter.setCommand(commandName()); |
163 | helpFormatter.setUsage("OPTIONS" ); |
164 | helpFormatter.setHeader("Application for generating RSA public/private key pairs." ); |
165 | helpFormatter.format(std::cout); |
166 | } |
167 | |
168 | int main(const std::vector<std::string>& args) |
169 | { |
170 | if (!_helpRequested) |
171 | { |
172 | logger().information("Generating key with length " + Poco::NumberFormatter::format((int)_length)); |
173 | logger().information(std::string("Exponent is " ) + ((_exp == RSAKey::EXP_SMALL)?"small" :"large" )); |
174 | logger().information("Generating key" ); |
175 | RSAKey key(_length, _exp); |
176 | logger().information("Generating key: DONE" ); |
177 | std::string pubFile(_name + ".pub" ); |
178 | std::string privFile(_name + ".priv" ); |
179 | |
180 | logger().information("Saving key to " + pubFile + " and " + privFile); |
181 | key.save(pubFile, privFile, _pwd); |
182 | logger().information("Key saved" ); |
183 | } |
184 | return Application::EXIT_OK; |
185 | } |
186 | |
187 | private: |
188 | bool _helpRequested; |
189 | RSAKey::KeyLength _length; |
190 | RSAKey::Exponent _exp; |
191 | std::string _name; |
192 | std::string _pwd; |
193 | }; |
194 | |
195 | |
196 | POCO_APP_MAIN(RSAApp) |
197 | |