| /* |
| * Copyright (C) 2023 Savoir-faire Linux Inc. |
| * |
| * This program is free software: you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation, either version 3 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program. If not, see <https://www.gnu.org/licenses/>. |
| */ |
| #include "dhtnet_crtmgr.h" |
| |
| |
| #include <iostream> |
| #include <unistd.h> |
| #include <getopt.h> |
| #if __has_include(<fmt/std.h>) |
| #include <fmt/std.h> |
| #else |
| #include <fmt/ostream.h> |
| #endif |
| |
| |
| struct dhtnet_crtmgr_params |
| { |
| bool help {false}; |
| bool version {false}; |
| std::filesystem::path ca {}; |
| std::filesystem::path id {}; |
| std::filesystem::path privatekey {}; |
| bool pkid {false}; |
| std::string name {}; |
| bool setup {false}; |
| }; |
| static const constexpr struct option long_options[] |
| = {{"help", no_argument, nullptr, 'h'}, |
| {"version", no_argument, nullptr, 'v'}, |
| {"CA", required_argument, nullptr, 'c'}, |
| {"id", required_argument, nullptr, 'o'}, |
| {"privatekey", required_argument, nullptr, 'p'}, |
| {"name", required_argument, nullptr, 'n'}, |
| {"pkid", no_argument, nullptr, 'g'}, |
| {"setup", no_argument, nullptr, 's'}, |
| {nullptr, 0, nullptr, 0}}; |
| |
| dhtnet_crtmgr_params |
| parse_args(int argc, char** argv) |
| { |
| dhtnet_crtmgr_params params; |
| int opt; |
| while ((opt = getopt_long(argc, argv, "hgsv:c:o:p:n:", long_options, nullptr)) != -1) { |
| switch (opt) { |
| case 'h': |
| params.help = true; |
| break; |
| case 'v': |
| params.version = true; |
| break; |
| case 'c': |
| params.ca = optarg; |
| break; |
| case 'o': |
| params.id = optarg; |
| break; |
| case 'p': |
| params.privatekey = optarg; |
| break; |
| case 'g': |
| params.pkid = true; |
| break; |
| case 'n': |
| params.name = optarg; |
| break; |
| case 's': |
| params.setup = true; |
| break; |
| default: |
| std::cerr << "Invalid option" << std::endl; |
| exit(EXIT_FAILURE); |
| } |
| } |
| |
| if (params.id.empty() && !params.pkid) { |
| std::cerr << "Error: The path to save the generated certificate is not provided.\n Please specify the path using the -i option.\n"; |
| exit(EXIT_FAILURE); |
| } |
| return params; |
| } |
| |
| |
| int |
| main(int argc, char** argv) |
| { |
| auto params = parse_args(argc, argv); |
| |
| if (params.help) { |
| fmt::print("Usage: dhtnet-crtmgr [options]\n" |
| "\nOptions:\n" |
| " -h, --help Display this help message and then exit.\n" |
| " -v, --version Show the version of the program.\n" |
| " -p, --privatekey Provide the path to the private key as an argument.\n" |
| " -c, --certificate Provide the path to the certificate as an argument.\n" |
| " -o, --output Provide the path where the generated certificate should be saved as an argument.\n" |
| " -g, --identifier Display the user identifier.\n" |
| " -n, --name Provide the name of the certificate to be generated.\n" |
| " -s, --setup Create an CA and a certificate.\n"); |
| return EXIT_SUCCESS; |
| } |
| |
| if (params.version) { |
| fmt::print("dhtnet-crtmgr v1.0\n"); |
| return EXIT_SUCCESS; |
| } |
| // check if the public key id is requested |
| if (params.pkid) { |
| if (params.ca.empty() || params.privatekey.empty()) { |
| 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"); |
| exit(EXIT_FAILURE); |
| } |
| auto identity = dhtnet::loadIdentity(params.privatekey, params.ca); |
| fmt::print("Public key id: {}\n", identity.second->getId()); |
| return EXIT_SUCCESS; |
| } |
| |
| // check if the setup is requested |
| if (params.setup) { |
| // create CA with name ca-server |
| std::filesystem::path path_ca = params.id / "CA"; |
| auto ca = dhtnet::generateIdentity(path_ca, "ca-server"); |
| fmt::print("Generated CA in {}: {} {}\n", path_ca, "ca-server", ca.second->getId()); |
| // create identity with name id-server |
| std::filesystem::path path_id = params.id / "id"; |
| auto identity = dhtnet::generateIdentity(path_id, "id-server", ca); |
| fmt::print("Generated certificate in {}: {} {}\n", path_id,"id-server", identity.second->getId()); |
| return EXIT_SUCCESS; |
| } |
| |
| if (params.ca.empty() || params.privatekey.empty()) { |
| if (params.name.empty()) { |
| auto ca = dhtnet::generateIdentity(params.id, "ca"); |
| fmt::print("Generated certificate in {}: {} {}\n", params.id, "ca", ca.second->getId()); |
| }else{ |
| auto ca = dhtnet::generateIdentity(params.id, params.name); |
| fmt::print("Generated certificate in {}: {} {}\n", params.id, params.name, ca.second->getId()); |
| } |
| }else{ |
| auto ca = dhtnet::loadIdentity(params.privatekey, params.ca); |
| if (params.name.empty()) { |
| auto id = dhtnet::generateIdentity(params.id, "certificate", ca); |
| fmt::print("Generated certificate in {}: {} {}\n", params.id, "certificate", id.second->getId()); |
| }else{ |
| auto id = dhtnet::generateIdentity(params.id, params.name, ca); |
| fmt::print("Generated certificate in {}: {} {}\n", params.id, params.name, id.second->getId()); |
| } |
| } |
| return EXIT_SUCCESS; |
| } |