Skip to content

Commit

Permalink
updated tool, x509, x509_test files
Browse files Browse the repository at this point in the history
  • Loading branch information
ecdeye committed Jun 27, 2024
1 parent ce9b35f commit 21528ef
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 65 deletions.
2 changes: 2 additions & 0 deletions tool-openssl/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include "../tool/internal.h"

X509* CreateAndSignX509Certificate();

bool X509Tool(const args_list_t &args) ;

#endif //INTERNAL_H
Expand Down
81 changes: 46 additions & 35 deletions tool-openssl/tool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include <string>
#include <vector>
#include <array>
#include <iostream>

#include <openssl/crypto.h>
#include <openssl/err.h>
Expand All @@ -17,8 +19,7 @@
#endif

#include "../tool/internal.h"

extern bool X509Tool(const args_list_t &args);
#include "./internal.h"

typedef bool (*tool_func_t)(const std::vector<std::string> &args);

Expand All @@ -27,77 +28,87 @@ struct Tool {
tool_func_t func;
};

static const Tool kTools[] = {
static const std::array<Tool, 2> kTools = {{
{ "x509", X509Tool },
{ "", nullptr },
};
}};

static void usage(const char *name) {
printf("Usage: %s COMMAND\n", name);
printf("\n");
printf("Available commands:\n");
static void usage(const std::string &name) {
std::cout << "Usage: " << name << " COMMAND\n\n";
std::cout << "Available commands:\n";

for (size_t i = 0;; i++) {
const Tool &tool = kTools[i];
for (const auto& tool : kTools) {
if (tool.func == nullptr) {
break;
}
printf(" %s\n", tool.name);
}
}

static tool_func_t FindTool(const std::string &name) {
for (size_t i = 0;; i++) {
const Tool &tool = kTools[i];
if (tool.func == nullptr || name == tool.name) {
return tool.func;
}
std::cout << " " << tool.name << "\n";
}
}

int main(int argc, char **argv) {
static void initialize() {
#if defined(OPENSSL_WINDOWS)
// Read and write in binary mode. This makes bssl on Windows consistent with
// bssl on other platforms, and also makes it consistent with MSYS's commands
// like diff(1) and md5sum(1). This is especially important for the digest
// commands.
if (_setmode(_fileno(stdin), _O_BINARY) == -1) {
perror("_setmode(_fileno(stdin), O_BINARY)");
return 1;
exit(1);
}
if (_setmode(_fileno(stdout), _O_BINARY) == -1) {
perror("_setmode(_fileno(stdout), O_BINARY)");
return 1;
exit(1);
}
if (_setmode(_fileno(stderr), _O_BINARY) == -1) {
perror("_setmode(_fileno(stderr), O_BINARY)");
return 1;
exit(1);
}
#else
// Ignore SIGPIPE to prevent the process from terminating if it tries to
// write to a pipe that has been closed by the reading end. SIGPIPE can be
// received when writing to sockets or pipes that are no longer connected.
signal(SIGPIPE, SIG_IGN);
#endif
}

CRYPTO_library_init();
tool_func_t FindTool(const std::string &name) {
for (const auto& tool : kTools) {
if (tool.name == name) {
return tool.func;
}
}
return nullptr;
}

int starting_arg = 1;
tool_func_t tool = nullptr;
tool_func_t FindTool(int argc, char **argv, int &starting_arg) {
#if !defined(OPENSSL_WINDOWS)
tool = FindTool(basename(argv[0]));
tool_func_t tool = FindTool(basename(argv[0]));
if (tool != nullptr) {
return tool;
}
#endif
if (tool == nullptr) {
starting_arg++;
if (argc > 1) {
tool = FindTool(argv[1]);
}
starting_arg++;
if (argc > 1) {
return FindTool(argv[1]);
}
return nullptr;
}

int main(int argc, char **argv) {
initialize();
CRYPTO_library_init();

int starting_arg = 1;
tool_func_t tool = FindTool(argc, argv, starting_arg);

if (tool == nullptr) {
usage(argv[0]);
return 1;
}

args_list_t args;
for (int i = starting_arg; i < argc; i++) {
args.push_back(argv[i]);
args.emplace_back(argv[i]);
}

if (!tool(args)) {
Expand All @@ -106,4 +117,4 @@ int main(int argc, char **argv) {
}

return 0;
}
}
9 changes: 4 additions & 5 deletions tool-openssl/x509.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <stdio.h>
#include <string>
#include <vector>
#include <memory>
#include "../tool/internal.h"
#include "internal.h"

Expand Down Expand Up @@ -54,7 +55,8 @@ bool X509Tool(const args_list_t &args) {

// Parse x509 certificate from input file
const uint8_t *p = input_data.data();
X509 *x509 = d2i_X509(nullptr, &p, input_data.size());
auto x509Deleter = [](X509* x509) { X509_free(x509); };
std::unique_ptr<X509, decltype(x509Deleter)> x509(d2i_X509(nullptr, &p, input_data.size()), x509Deleter);
if (!x509) {
fprintf(stderr, "Failed to parse X509 certificate from '%s'.\n", in_path.c_str());
ERR_print_errors_fp(stderr);
Expand All @@ -63,23 +65,20 @@ bool X509Tool(const args_list_t &args) {

// Serialize certificate to DER format
uint8_t *out_data = nullptr;
int len = i2d_X509(x509, &out_data);
int len = i2d_X509(x509.get(), &out_data);
if (len < 0) {
fprintf(stderr, "Failed to serialize X509 certificate.\n");
ERR_print_errors_fp(stderr);
X509_free(x509);
return false;
}

// Write output file using WriteToFile function from tool/file.cc
if (!WriteToFile(out_path, out_data, len)) {
fprintf(stderr, "Failed to write X509 certificate to '%s'.\n", out_path.c_str());
OPENSSL_free(out_data);
X509_free(x509);
return false;
}

OPENSSL_free(out_data);
X509_free(x509);
return true;
}
74 changes: 49 additions & 25 deletions tool-openssl/x509_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,66 @@
#include <stdio.h>
#include <string>
#include <vector>
#include <memory>
#include "../tool/internal.h"
#include "internal.h"

X509* CreateAndSignX509Certificate() {
X509 *x509 = X509_new();
if (!x509) return nullptr;

// Set validity period
if (!X509_gmtime_adj(X509_getm_notBefore(x509), 0) ||
!X509_gmtime_adj(X509_getm_notAfter(x509), 31536000L)) {
X509_free(x509);
return nullptr;
}

// Generate and set the public key
EVP_PKEY *pkey = EVP_PKEY_new();
if (!pkey) {
X509_free(x509);
return nullptr;
}
RSA *rsa = RSA_new();
BIGNUM *bn = BN_new();
if (!bn || !BN_set_word(bn, RSA_F4) ||
!RSA_generate_key_ex(rsa, 2048, bn, nullptr) ||
!EVP_PKEY_assign_RSA(pkey, rsa)) {
BN_free(bn);
EVP_PKEY_free(pkey);
X509_free(x509);
return nullptr;
}
BN_free(bn);
if (!X509_set_pubkey(x509, pkey)) {
EVP_PKEY_free(pkey);
X509_free(x509);
return nullptr;
}

// Sign certificate
if (X509_sign(x509, pkey, EVP_sha256()) <= 0) {
EVP_PKEY_free(pkey);
X509_free(x509);
return nullptr;
}

EVP_PKEY_free(pkey);
return x509;
}

// Test x509 -in and -out
TEST(X509Test, X509ToolTest) {
std::string in_path = "test_input.der";
std::string out_path = "test_output.der";

X509 *x509 = X509_new();
std::unique_ptr<X509, decltype(&X509_free)> x509(CreateAndSignX509Certificate(), X509_free);
ASSERT_TRUE(x509 != nullptr);

// Set validity period
ASSERT_TRUE(X509_gmtime_adj(X509_getm_notBefore(x509), 0));
ASSERT_TRUE(X509_gmtime_adj(X509_getm_notAfter(x509), 31536000L));

// Generate and set the public key
EVP_PKEY *pkey = EVP_PKEY_new();
ASSERT_TRUE(pkey != nullptr);
RSA *rsa = RSA_new();
BIGNUM *bn = BN_new();
ASSERT_TRUE(bn != nullptr);
ASSERT_TRUE(BN_set_word(bn, RSA_F4));
ASSERT_TRUE(RSA_generate_key_ex(rsa, 2048, bn, nullptr));
ASSERT_TRUE(EVP_PKEY_assign_RSA(pkey, rsa));
BN_free(bn);
ASSERT_TRUE(X509_set_pubkey(x509, pkey));

// Sign certificate
ASSERT_TRUE(X509_sign(x509, pkey, EVP_sha256()) > 0);
EVP_PKEY_free(pkey);

// Serialize certificate to DER format
uint8_t *der_data = nullptr;
int len = i2d_X509(x509, &der_data);
int len = i2d_X509(x509.get(), &der_data);
if (len <= 0) {
ERR_print_errors_fp(stderr);
}
Expand Down Expand Up @@ -72,11 +98,9 @@ TEST(X509Test, X509ToolTest) {

// Parse x509 cert from output file
const uint8_t *p = output_data.data();
X509 *parsed_x509 = d2i_X509(nullptr, &p, output_data.size());
std::unique_ptr<X509, decltype(&X509_free)> parsed_x509(d2i_X509(nullptr, &p, output_data.size()), X509_free);
ASSERT_TRUE(parsed_x509 != nullptr);

X509_free(parsed_x509);
X509_free(x509);
remove(in_path.c_str());
remove(out_path.c_str());
}
Expand Down

0 comments on commit 21528ef

Please sign in to comment.