Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
8141b56
feat(tool-openssl): Add barebones genrsa CLI implementation
kingstjo Jun 27, 2025
8729e51
feat(tool-openssl): Implement RSA key generation in genrsa CLI
kingstjo Jun 27, 2025
6a1f529
feat(tool-openssl): implement genrsa CLI tool with OpenSSL compatibility
kingstjo Jun 27, 2025
1e71013
refactor(genrsa): improve test efficiency with direct function calls
kingstjo Jun 30, 2025
9cf8ed0
fix(tool-openssl): resolve clang-tidy warnings for variable initializ…
kingstjo Jul 1, 2025
d513483
refactor(genrsa_test): consolidate test classes and improve parameter…
kingstjo Jul 2, 2025
7763c97
refactor(genrsa): Extract helper functions and add static constants
kingstjo Jul 3, 2025
eb8efc9
refactor(genrsa): Extract additional helper functions to reduce compl…
kingstjo Jul 8, 2025
4474866
refactor(genrsa_test): Implement hybrid approach with parameterized a…
kingstjo Jul 9, 2025
b3ada97
Merge upstream/main to get pkcs8 CLI tool
kingstjo Jul 10, 2025
c959ffd
refactor(genrsa): Improve help display and fix test segfaults
kingstjo Jul 10, 2025
da65427
Merge remote-tracking branch 'upstream/main' into openssl-genrsa-cli
kingstjo Jul 10, 2025
268d1f9
fix(genrsa): Add missing cstring include for strcmp
kingstjo Jul 10, 2025
ebb681a
fix: Initialize bits variable to fix clang-tidy warning
kingstjo Jul 11, 2025
59d8e9f
refactor(genrsa): Use constants for key sizes and simplify argument h…
kingstjo Jul 16, 2025
2378ac7
refactor(genrsa): Use local boolean variable with GetBoolArgument
kingstjo Jul 16, 2025
36800a2
fixed tool count
kingstjo Jul 17, 2025
8460d9b
Merge upstream/main into openssl-genrsa-cli
kingstjo Jul 17, 2025
3db1439
reverting 36800a2
kingstjo Jul 17, 2025
976f32e
fix(tool-openssl): restore kTools array size to 13
kingstjo Jul 17, 2025
8e0a88c
refactor(tool-openssl): Improve genrsa_test.cc organization and error…
kingstjo Jul 18, 2025
17e3a6e
fix: Remove redundant file handles in genrsa_test.cc to fix Windows a…
kingstjo Jul 18, 2025
9d62118
Merge remote-tracking branch 'upstream/main' into openssl-genrsa-cli
kingstjo Jul 18, 2025
ef8c109
fix: Improve file handling in genrsa.cc to fix Windows access violations
kingstjo Jul 19, 2025
f5c29b0
fix(genrsa): Change file opening mode from "w" to "wb" for Windows co…
kingstjo Jul 21, 2025
c748c9a
fix: Add null pointer checks to prevent potential dereferences
kingstjo Jul 28, 2025
4972f9e
fix(genrsa): Prevent BIO_flush on stdout to avoid Windows access viol…
kingstjo Jul 28, 2025
d5f580e
refactor(genrsa): Simplify BIO cleanup to match AWS-LC patterns
kingstjo Jul 28, 2025
490b1c5
refactor(genrsa_test): Use RSA_check_key() instead of manual componen…
kingstjo Jul 28, 2025
96e6224
refactor(genrsa_test): Focus CLI tests on CLI-specific concerns
kingstjo Jul 28, 2025
f70efcb
refactor(genrsa_test): Replace ScopedFILE with BIO-only approach
kingstjo Jul 29, 2025
91e1991
refactor(genrsa): use EVP_PKEY API for RSA key generation
kingstjo Jul 30, 2025
c5c739c
refactor(genrsa_test): improve test code quality and reduce noise
kingstjo Jul 30, 2025
0163df2
fix(genrsa_test): add FIPS-aware test skipping for weak key sizes
kingstjo Jul 30, 2025
37ac664
fix(genrsa_test): remove redundant file operations causing Windows ac…
kingstjo Jul 31, 2025
2658c59
fix: Address PR 2535 feedback for genrsa CLI tool
kingstjo Aug 17, 2025
4b128b0
Merge remote-tracking branch 'upstream/main' into openssl-genrsa-cli
kingstjo Aug 17, 2025
f4a6118
Fix FIPS mode detection in genrsa tests for macOS-ARM-FIPS
kingstjo Aug 20, 2025
0fbe9f0
Add kMinKeySize=1024 validation and rename bits to KeySizeBits
kingstjo Aug 21, 2025
ab39f95
Move output BIO validation before RSA key generation
kingstjo Aug 26, 2025
4f8b1d3
Simplify BIO flush logic in genrsa tool
kingstjo Aug 26, 2025
0c8fa35
Add warning for excessively large RSA key sizes
kingstjo Aug 26, 2025
29ccac3
Merge branch 'main' into openssl-genrsa-cli
kingstjo Aug 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions tool-openssl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_executable(

crl.cc
dgst.cc
genrsa.cc
pkcs8.cc
pkey.cc
rehash.cc
Expand Down Expand Up @@ -87,6 +88,8 @@ if(BUILD_TESTING)
crl_test.cc
dgst.cc
dgst_test.cc
genrsa.cc
genrsa_test.cc
pkcs8.cc
pkcs8_test.cc
pkey.cc
Expand Down
181 changes: 181 additions & 0 deletions tool-openssl/genrsa.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR ISC

#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <cstdlib>
#include <cstring>
#include "internal.h"

static const unsigned kDefaultKeySize = 2048;
static const unsigned kMinKeySize = 1024;
static const unsigned kRecommendedMaxKeySize = 16384;
static const char kKeyArgName[] = "key_size";

static const argument_t kArguments[] = {
{"-help", kBooleanArgument, "Display this summary"},
{"-out", kOptionalArgument, "Output file to write the key to"},
{"", kOptionalArgument, ""}};

static void DisplayHelp(BIO *bio) {
BIO_printf(bio, "Usage: genrsa [options] numbits\n\n");
BIO_printf(bio, "Options:\n");

for (size_t i = 0; kArguments[i].name[0] != '\0'; i++) {
BIO_printf(bio, " %-20s %s\n", kArguments[i].name,
kArguments[i].description);
}
BIO_printf(bio, "\n numbits Size of key in bits (default: %u)\n",
kDefaultKeySize);
}

static bool ParseKeySize(const args_list_t &extra_args, unsigned &KeySizeBits) {
KeySizeBits = kDefaultKeySize;

if (extra_args.empty()) {
return true;
}

if (extra_args.size() > 1) {
fprintf(stderr, "Error: Only one key size argument allowed\n");
return false;
}

ordered_args::ordered_args_map_t temp_args;
temp_args.push_back(std::make_pair(kKeyArgName, extra_args[0]));

if (!ordered_args::GetUnsigned(&KeySizeBits, kKeyArgName, 0, temp_args)) {
fprintf(stderr, "Error: Invalid key size '%s'\n", extra_args[0].c_str());
return false;
}

if (KeySizeBits < kMinKeySize) {
fprintf(stderr, "Error: Key size must be at least %u bits\n", kMinKeySize);
return false;
}

if (KeySizeBits > kRecommendedMaxKeySize) {
fprintf(stderr, "Warning: It is not recommended to use more than %u bits for RSA keys.\n", kRecommendedMaxKeySize);
fprintf(stderr, " Your key size is %u! Larger key sizes may not behave as expected.\n", KeySizeBits);
}

return true;
}

static bssl::UniquePtr<EVP_PKEY> GenerateRSAKey(unsigned bits) {
bssl::UniquePtr<EVP_PKEY> pkey;
EVP_PKEY *raw_pkey = nullptr;
bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, nullptr));
if (!ctx || !EVP_PKEY_keygen_init(ctx.get()) ||
!EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), bits)) {
return pkey;
}

if (!EVP_PKEY_keygen(ctx.get(), &raw_pkey)) {
return pkey;
}

pkey.reset(raw_pkey);
return pkey;
}

static bssl::UniquePtr<BIO> CreateOutputBIO(const std::string &out_path) {
bssl::UniquePtr<BIO> bio;
if (out_path.empty()) {
bio.reset(BIO_new_fp(stdout, BIO_NOCLOSE));
if (!bio) {
fprintf(stderr, "Error: Could not create BIO for stdout\n");
return nullptr;
}
} else {
bio.reset(BIO_new_file(out_path.c_str(), "wb"));
if (!bio) {
fprintf(stderr, "Error: Could not open output file '%s'\n",
out_path.c_str());
return nullptr;
}
}
return bio;
}

bool genrsaTool(const args_list_t &args) {
ordered_args::ordered_args_map_t parsed_args;
args_list_t extra_args{};
std::string out_path;
bool help = false;
bssl::UniquePtr<BIO> bio;
bssl::UniquePtr<EVP_PKEY> pkey;
unsigned KeySizeBits = 0;

// Parse command line arguments
if (!ordered_args::ParseOrderedKeyValueArguments(parsed_args, extra_args,
args, kArguments)) {
bio.reset(BIO_new_fp(stderr, BIO_NOCLOSE));
if (bio) {
DisplayHelp(bio.get());
}
goto err;
}

ordered_args::GetBoolArgument(&help, "-help", parsed_args);
ordered_args::GetString(&out_path, "-out", "", parsed_args);

// Parse and validate key size first (catches multiple key sizes)
if (!ParseKeySize(extra_args, KeySizeBits)) {
goto err;
}

// Simple validation that numbits is the last argument
if (!extra_args.empty() && args[args.size()-1] != extra_args[0]) {
fprintf(stderr,
"Error: Key size must be specified after all options\n");
fprintf(stderr, "Usage: genrsa [options] numbits\n");
goto err;
}

// Handle help request
if (help) {
bio.reset(BIO_new_fp(stdout, BIO_NOCLOSE));
if (!bio) {
goto err;
}
DisplayHelp(bio.get());
return true; // Help display is a successful exit
}

// Set up output BIO
bio = CreateOutputBIO(out_path);
if (!bio) {
goto err;
}

// Generate RSA key
pkey = GenerateRSAKey(KeySizeBits);
if (!pkey) {
fprintf(stderr, "Error: Failed to generate RSA key\n");
goto err;
}

// Write the key
if (!PEM_write_bio_PrivateKey(bio.get(), pkey.get(), NULL, NULL, 0, NULL,
NULL)) {
goto err;
}

// Flush output
if (!BIO_flush(bio.get())) {
goto err;
}

return true;

err:
ERR_print_errors_fp(stderr);
if (bio) {
BIO_flush(bio.get());
}
return false;
}
Loading
Loading