Skip to content
Snippets Groups Projects
Commit 423b25b2 authored by Amna Snene's avatar Amna Snene
Browse files

tools: add dhtnet-certmgr

Certificate manager: generate and load certificate/identity

Change-Id: I920834133b5f78985833ee4043b5aa4562211197
parent 4325f0ff
No related branches found
No related tags found
No related merge requests found
...@@ -247,7 +247,8 @@ if (BUILD_TOOLS AND NOT MSVC) ...@@ -247,7 +247,8 @@ if (BUILD_TOOLS AND NOT MSVC)
add_executable(dnc add_executable(dnc
tools/dnc/main.cpp tools/dnc/main.cpp
tools/dnc/dnc.cpp tools/dnc/dnc.cpp
tools/common.cpp) tools/common.cpp
tools/dhtnet_crtmgr/dhtnet_crtmgr.cpp)
target_link_libraries(dnc PRIVATE dhtnet fmt::fmt yaml-cpp) target_link_libraries(dnc PRIVATE dhtnet fmt::fmt yaml-cpp)
target_include_directories(dnc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools) target_include_directories(dnc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools)
install(TARGETS dnc RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS dnc RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
...@@ -255,7 +256,8 @@ if (BUILD_TOOLS AND NOT MSVC) ...@@ -255,7 +256,8 @@ if (BUILD_TOOLS AND NOT MSVC)
add_executable(dsh add_executable(dsh
tools/dsh/main.cpp tools/dsh/main.cpp
tools/dsh/dsh.cpp tools/dsh/dsh.cpp
tools/common.cpp) tools/common.cpp
tools/dhtnet_crtmgr/dhtnet_crtmgr.cpp)
target_link_libraries(dsh PRIVATE dhtnet fmt::fmt yaml-cpp) target_link_libraries(dsh PRIVATE dhtnet fmt::fmt yaml-cpp)
target_include_directories(dsh PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools) target_include_directories(dsh PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools)
install(TARGETS dsh RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS dsh RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
...@@ -263,7 +265,8 @@ if (BUILD_TOOLS AND NOT MSVC) ...@@ -263,7 +265,8 @@ if (BUILD_TOOLS AND NOT MSVC)
add_executable(dvpn add_executable(dvpn
tools/dvpn/main.cpp tools/dvpn/main.cpp
tools/dvpn/dvpn.cpp tools/dvpn/dvpn.cpp
tools/common.cpp) tools/common.cpp
tools/dhtnet_crtmgr/dhtnet_crtmgr.cpp)
target_link_libraries(dvpn PRIVATE dhtnet fmt::fmt yaml-cpp) target_link_libraries(dvpn PRIVATE dhtnet fmt::fmt yaml-cpp)
target_include_directories(dvpn PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools) target_include_directories(dvpn PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools)
install(TARGETS dvpn RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS dvpn RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
...@@ -280,6 +283,13 @@ if (BUILD_TOOLS AND NOT MSVC) ...@@ -280,6 +283,13 @@ if (BUILD_TOOLS AND NOT MSVC)
target_include_directories(upnpctrl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools) target_include_directories(upnpctrl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools)
install(TARGETS upnpctrl RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS upnpctrl RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
add_executable(dhtnet-crtmgr
tools/dhtnet_crtmgr/main.cpp
tools/dhtnet_crtmgr/dhtnet_crtmgr.cpp)
target_link_libraries(dhtnet-crtmgr PRIVATE dhtnet fmt::fmt)
target_include_directories(dhtnet-crtmgr PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools)
install(TARGETS dhtnet-crtmgr RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES install(FILES
tools/dnc/dnc.1 tools/dnc/dnc.1
tools/dsh/dsh.1 tools/dsh/dsh.1
......
...@@ -29,41 +29,6 @@ ...@@ -29,41 +29,6 @@
namespace dhtnet { namespace dhtnet {
dht::crypto::Identity
loadIdentity(const std::filesystem::path& path_id){
try {
for (const auto& path_id : std::filesystem::directory_iterator(path_id)) {
auto p = path_id.path();
if (p.extension() == ".pem") {
auto privateKey = std::make_unique<dht::crypto::PrivateKey>(fileutils::loadFile(p));
auto certificate = std::make_unique<dht::crypto::Certificate>(
fileutils::loadFile(p.replace_extension(".crt")));
return dht::crypto::Identity(std::move(privateKey), std::move(certificate));
}
}
} catch (const std::exception& e) {}
return {};
}
dht::crypto::Identity
loadIdentity(const std::filesystem::path& path_id, const std::filesystem::path& path_ca)
{
if (!std::filesystem::exists(path_id)) {
std::filesystem::create_directory(path_id);
}
// Load identity
auto id = loadIdentity(path_id);
if (!id.first or !id.second) {
// Load CA
auto ca_id = loadIdentity(path_ca);
if (!ca_id.first or !ca_id.second)
ca_id = dht::crypto::generateIdentity("dhtnet");
id = dht::crypto::generateIdentity("dhtnet", ca_id);
fmt::print("Generated new identity: {}\n", id.first->getPublicKey().getId());
dht::crypto::saveIdentity(id, path_id / "id");
}
return id;
}
std::unique_ptr<ConnectionManager::Config> std::unique_ptr<ConnectionManager::Config>
connectionManagerConfig(const std::filesystem::path& path, connectionManagerConfig(const std::filesystem::path& path,
dht::crypto::Identity identity, dht::crypto::Identity identity,
......
...@@ -25,13 +25,6 @@ namespace dhtnet { ...@@ -25,13 +25,6 @@ namespace dhtnet {
using Buffer = std::shared_ptr<std::vector<uint8_t>>; using Buffer = std::shared_ptr<std::vector<uint8_t>>;
constexpr size_t BUFFER_SIZE = 64 * 1024; constexpr size_t BUFFER_SIZE = 64 * 1024;
/**
* Attempt to retrieve the identity from the .ssh directory, and if none is found, generate a new
* certification.
* @return dht::crypto::Identity
*/
dht::crypto::Identity loadIdentity(const std::filesystem::path& path_id, const std::filesystem::path& path_ca);
// add certstore to the config
std::unique_ptr<ConnectionManager::Config> connectionManagerConfig( std::unique_ptr<ConnectionManager::Config> connectionManagerConfig(
const std::filesystem::path& path, const std::filesystem::path& path,
dht::crypto::Identity identity, dht::crypto::Identity identity,
......
/*
* 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 "fileutils.h"
#include <opendht/crypto.h>
namespace dhtnet {
dht::crypto::Identity
loadIdentity(const std::filesystem::path& privatekey, const std::filesystem::path& cert)
{
// check files exists
if (!std::filesystem::exists(privatekey) or !std::filesystem::exists(cert))
{
fmt::print(stderr, "Error: missing identity files\n");
return {};
}
// Load identity
auto privateKey = std::make_unique<dht::crypto::PrivateKey>(fileutils::loadFile(privatekey));
auto certificate = std::make_unique<dht::crypto::Certificate>(fileutils::loadFile(cert));
return dht::crypto::Identity(std::move(privateKey), std::move(certificate));
}
// generate a new identity
dht::crypto::Identity generateIdentity(const std::filesystem::path& path_id, const std::string& name, const dht::crypto::Identity& ca)
{
auto identity = dht::crypto::generateIdentity(name, ca);
if (!std::filesystem::exists(path_id))
std::filesystem::create_directories(path_id);
dht::crypto::saveIdentity(identity, path_id / name);
return identity;
}
} // namespace dhtnet
/*
* 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 <opendht/crypto.h>
#include "fileutils.h"
namespace dhtnet {
/**
* Get the private key and certificate from the given paths.
* @return dht::crypto::Identity
*/
dht::crypto::Identity loadIdentity(const std::filesystem::path& path_pkey, const std::filesystem::path& path_cert);
/**
* Generate a new identity.
*/
dht::crypto::Identity generateIdentity(const std::filesystem::path& path_id, const std::string& name, const dht::crypto::Identity& ca = {});
}
\ No newline at end of file
/*
* 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, 'i'},
{"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:i: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 'i':
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 identity is not provided.\n Please specify the path for saving the generated identity 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, --CA Provide the path to the Certificate Authority as an argument.\n"
" -i, --id Provide the path where the generated identity should be saved as an argument.\n"
" -g, --pkid Display the publickey id used by the server dnc.\n"
" -n, --name Provide the name of the identity to be generated.\n"
" -s, --setup Create an CA and an id.\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 Authority is not provided.\n Please specify the path for the private key and the Certificate Authority 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 identity 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 CA in {}: {} {}\n", params.id, "ca", ca.second->getId());
}else{
auto ca = dhtnet::generateIdentity(params.id, params.name);
fmt::print("Generated CA 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, "id", ca);
fmt::print("Generated identity in {}: {} {}\n", params.id, "id", id.second->getId());
}else{
auto id = dhtnet::generateIdentity(params.id, params.name, ca);
fmt::print("Generated identity in {}: {} {}\n", params.id, params.name, id.second->getId());
}
}
return EXIT_SUCCESS;
}
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
*/ */
#include "dnc.h" #include "dnc.h"
#include "common.h" #include "common.h"
#include "dhtnet_crtmgr/dhtnet_crtmgr.h"
#include <string> #include <string>
#include <vector> #include <vector>
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
*/ */
#include "dsh.h" #include "dsh.h"
#include "../common.h" #include "../common.h"
#include "dhtnet_crtmgr/dhtnet_crtmgr.h"
#include <string> #include <string>
#include <vector> #include <vector>
#include <iostream> #include <iostream>
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
*/ */
#include "dvpn.h" #include "dvpn.h"
#include "common.h" #include "common.h"
#include "dhtnet_crtmgr/dhtnet_crtmgr.h"
#include <string> #include <string>
#include <vector> #include <vector>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment