blob: 95687cc800928adac9ca8ccdaeca6f51d5103e16 [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'},
Amnab5f0a682024-02-08 16:21:12 -050045 {"id", required_argument, nullptr, 'o'},
Amna423b25b2024-02-06 13:21:19 -050046 {"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;
Amnab5f0a682024-02-08 16:21:12 -050057 while ((opt = getopt_long(argc, argv, "hgsv:c:o:p:n:", long_options, nullptr)) != -1) {
Amna423b25b2024-02-06 13:21:19 -050058 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;
Amnab5f0a682024-02-08 16:21:12 -050068 case 'o':
Amna423b25b2024-02-06 13:21:19 -050069 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) {
Amnab5f0a682024-02-08 16:21:12 -050090 std::cerr << "Error: The path to save the generated certificate is not provided.\n Please specify the path using the -i option.\n";
91 exit(EXIT_FAILURE);
Amna423b25b2024-02-06 13:21:19 -050092 }
93 return params;
94}
95
96
97int
98main(int argc, char** argv)
99{
100 auto params = parse_args(argc, argv);
101
102 if (params.help) {
103 fmt::print("Usage: dhtnet-crtmgr [options]\n"
104 "\nOptions:\n"
105 " -h, --help Display this help message and then exit.\n"
106 " -v, --version Show the version of the program.\n"
107 " -p, --privatekey Provide the path to the private key as an argument.\n"
Amnab5f0a682024-02-08 16:21:12 -0500108 " -c, --certificate Provide the path to the certificate as an argument.\n"
109 " -o, --output Provide the path where the generated certificate should be saved as an argument.\n"
110 " -g, --identifier Display the user identifier.\n"
111 " -n, --name Provide the name of the certificate to be generated.\n"
112 " -s, --setup Create an CA and a certificate.\n");
Amna423b25b2024-02-06 13:21:19 -0500113 return EXIT_SUCCESS;
114 }
115
116 if (params.version) {
117 fmt::print("dhtnet-crtmgr v1.0\n");
118 return EXIT_SUCCESS;
119 }
120 // check if the public key id is requested
121 if (params.pkid) {
122 if (params.ca.empty() || params.privatekey.empty()) {
Amnab5f0a682024-02-08 16:21:12 -0500123 fmt::print(stderr, "Error: The path to the private key and the certificate is not provided.\n Please specify the path for the private key and the certificate using the -p and -c options.\n");
Amna423b25b2024-02-06 13:21:19 -0500124 exit(EXIT_FAILURE);
125 }
126 auto identity = dhtnet::loadIdentity(params.privatekey, params.ca);
127 fmt::print("Public key id: {}\n", identity.second->getId());
128 return EXIT_SUCCESS;
129 }
130
131 // check if the setup is requested
132 if (params.setup) {
133 // create CA with name ca-server
134 std::filesystem::path path_ca = params.id / "CA";
135 auto ca = dhtnet::generateIdentity(path_ca, "ca-server");
136 fmt::print("Generated CA in {}: {} {}\n", path_ca, "ca-server", ca.second->getId());
137 // create identity with name id-server
138 std::filesystem::path path_id = params.id / "id";
139 auto identity = dhtnet::generateIdentity(path_id, "id-server", ca);
Amnab5f0a682024-02-08 16:21:12 -0500140 fmt::print("Generated certificate in {}: {} {}\n", path_id,"id-server", identity.second->getId());
Amna423b25b2024-02-06 13:21:19 -0500141 return EXIT_SUCCESS;
142 }
143
144 if (params.ca.empty() || params.privatekey.empty()) {
145 if (params.name.empty()) {
146 auto ca = dhtnet::generateIdentity(params.id, "ca");
Amnab5f0a682024-02-08 16:21:12 -0500147 fmt::print("Generated certificate in {}: {} {}\n", params.id, "ca", ca.second->getId());
Amna423b25b2024-02-06 13:21:19 -0500148 }else{
149 auto ca = dhtnet::generateIdentity(params.id, params.name);
Amnab5f0a682024-02-08 16:21:12 -0500150 fmt::print("Generated certificate in {}: {} {}\n", params.id, params.name, ca.second->getId());
Amna423b25b2024-02-06 13:21:19 -0500151 }
152 }else{
153 auto ca = dhtnet::loadIdentity(params.privatekey, params.ca);
154 if (params.name.empty()) {
Amnab5f0a682024-02-08 16:21:12 -0500155 auto id = dhtnet::generateIdentity(params.id, "certificate", ca);
156 fmt::print("Generated certificate in {}: {} {}\n", params.id, "certificate", id.second->getId());
Amna423b25b2024-02-06 13:21:19 -0500157 }else{
158 auto id = dhtnet::generateIdentity(params.id, params.name, ca);
Amnab5f0a682024-02-08 16:21:12 -0500159 fmt::print("Generated certificate in {}: {} {}\n", params.id, params.name, id.second->getId());
Amna423b25b2024-02-06 13:21:19 -0500160 }
161 }
162 return EXIT_SUCCESS;
163}