blob: f27d5bba70486a20b8b3929a972eaf91668095ea [file] [log] [blame]
Amna423b25b2024-02-06 13:21:19 -05001/*
2 * Copyright (C) 2023 Savoir-faire Linux Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17#include "dhtnet_crtmgr.h"
18
19
20#include <iostream>
21#include <unistd.h>
22#include <getopt.h>
23#if __has_include(<fmt/std.h>)
24#include <fmt/std.h>
25#else
26#include <fmt/ostream.h>
27#endif
28
29
30struct dhtnet_crtmgr_params
31{
32 bool help {false};
33 bool version {false};
34 std::filesystem::path ca {};
35 std::filesystem::path id {};
36 std::filesystem::path privatekey {};
37 bool pkid {false};
38 std::string name {};
39 bool setup {false};
40};
41static const constexpr struct option long_options[]
42 = {{"help", no_argument, nullptr, 'h'},
43 {"version", no_argument, nullptr, 'v'},
44 {"CA", required_argument, nullptr, 'c'},
45 {"id", required_argument, nullptr, 'i'},
46 {"privatekey", required_argument, nullptr, 'p'},
47 {"name", required_argument, nullptr, 'n'},
48 {"pkid", no_argument, nullptr, 'g'},
49 {"setup", no_argument, nullptr, 's'},
50 {nullptr, 0, nullptr, 0}};
51
52dhtnet_crtmgr_params
53parse_args(int argc, char** argv)
54{
55 dhtnet_crtmgr_params params;
56 int opt;
57 while ((opt = getopt_long(argc, argv, "hgsv:c:i:p:n:", long_options, nullptr)) != -1) {
58 switch (opt) {
59 case 'h':
60 params.help = true;
61 break;
62 case 'v':
63 params.version = true;
64 break;
65 case 'c':
66 params.ca = optarg;
67 break;
68 case 'i':
69 params.id = optarg;
70 break;
71 case 'p':
72 params.privatekey = optarg;
73 break;
74 case 'g':
75 params.pkid = true;
76 break;
77 case 'n':
78 params.name = optarg;
79 break;
80 case 's':
81 params.setup = true;
82 break;
83 default:
84 std::cerr << "Invalid option" << std::endl;
85 exit(EXIT_FAILURE);
86 }
87 }
88
89 if (params.id.empty() && !params.pkid) {
90 std::cerr << "Error: The path to save the generated identity is not provided.\n Please specify the path for saving the generated identity using the -i option.\n"; exit(EXIT_FAILURE);
91 }
92 return params;
93}
94
95
96int
97main(int argc, char** argv)
98{
99 auto params = parse_args(argc, argv);
100
101 if (params.help) {
102 fmt::print("Usage: dhtnet-crtmgr [options]\n"
103 "\nOptions:\n"
104 " -h, --help Display this help message and then exit.\n"
105 " -v, --version Show the version of the program.\n"
106 " -p, --privatekey Provide the path to the private key as an argument.\n"
107 " -c, --CA Provide the path to the Certificate Authority as an argument.\n"
108 " -i, --id Provide the path where the generated identity should be saved as an argument.\n"
109 " -g, --pkid Display the publickey id used by the server dnc.\n"
110 " -n, --name Provide the name of the identity to be generated.\n"
111 " -s, --setup Create an CA and an id.\n");
112 return EXIT_SUCCESS;
113 }
114
115 if (params.version) {
116 fmt::print("dhtnet-crtmgr v1.0\n");
117 return EXIT_SUCCESS;
118 }
119 // check if the public key id is requested
120 if (params.pkid) {
121 if (params.ca.empty() || params.privatekey.empty()) {
122 fmt::print(stderr, "Error: The path to the private key and the Certificate Authority is not provided.\n Please specify the path for the private key and the Certificate Authority using the -p and -c options.\n");
123 exit(EXIT_FAILURE);
124 }
125 auto identity = dhtnet::loadIdentity(params.privatekey, params.ca);
126 fmt::print("Public key id: {}\n", identity.second->getId());
127 return EXIT_SUCCESS;
128 }
129
130 // check if the setup is requested
131 if (params.setup) {
132 // create CA with name ca-server
133 std::filesystem::path path_ca = params.id / "CA";
134 auto ca = dhtnet::generateIdentity(path_ca, "ca-server");
135 fmt::print("Generated CA in {}: {} {}\n", path_ca, "ca-server", ca.second->getId());
136 // create identity with name id-server
137 std::filesystem::path path_id = params.id / "id";
138 auto identity = dhtnet::generateIdentity(path_id, "id-server", ca);
139 fmt::print("Generated identity in {}: {} {}\n", path_id,"id-server", identity.second->getId());
140 return EXIT_SUCCESS;
141 }
142
143 if (params.ca.empty() || params.privatekey.empty()) {
144 if (params.name.empty()) {
145 auto ca = dhtnet::generateIdentity(params.id, "ca");
146 fmt::print("Generated CA in {}: {} {}\n", params.id, "ca", ca.second->getId());
147 }else{
148 auto ca = dhtnet::generateIdentity(params.id, params.name);
149 fmt::print("Generated CA in {}: {} {}\n", params.id, params.name, ca.second->getId());
150 }
151 }else{
152 auto ca = dhtnet::loadIdentity(params.privatekey, params.ca);
153 if (params.name.empty()) {
154 auto id = dhtnet::generateIdentity(params.id, "id", ca);
155 fmt::print("Generated identity in {}: {} {}\n", params.id, "id", id.second->getId());
156 }else{
157 auto id = dhtnet::generateIdentity(params.id, params.name, ca);
158 fmt::print("Generated identity in {}: {} {}\n", params.id, params.name, id.second->getId());
159 }
160 }
161 return EXIT_SUCCESS;
162}