-
Notifications
You must be signed in to change notification settings - Fork 140
Implement genrsa command #2535
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
kingstjo
wants to merge
43
commits into
aws:main
Choose a base branch
from
kingstjo:openssl-genrsa-cli
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+414
−2
Open
Implement genrsa command #2535
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 8729e51
feat(tool-openssl): Implement RSA key generation in genrsa CLI
kingstjo 6a1f529
feat(tool-openssl): implement genrsa CLI tool with OpenSSL compatibility
kingstjo 1e71013
refactor(genrsa): improve test efficiency with direct function calls
kingstjo 9cf8ed0
fix(tool-openssl): resolve clang-tidy warnings for variable initializ…
kingstjo d513483
refactor(genrsa_test): consolidate test classes and improve parameter…
kingstjo 7763c97
refactor(genrsa): Extract helper functions and add static constants
kingstjo eb8efc9
refactor(genrsa): Extract additional helper functions to reduce compl…
kingstjo 4474866
refactor(genrsa_test): Implement hybrid approach with parameterized a…
kingstjo b3ada97
Merge upstream/main to get pkcs8 CLI tool
kingstjo c959ffd
refactor(genrsa): Improve help display and fix test segfaults
kingstjo da65427
Merge remote-tracking branch 'upstream/main' into openssl-genrsa-cli
kingstjo 268d1f9
fix(genrsa): Add missing cstring include for strcmp
kingstjo ebb681a
fix: Initialize bits variable to fix clang-tidy warning
kingstjo 59d8e9f
refactor(genrsa): Use constants for key sizes and simplify argument h…
kingstjo 2378ac7
refactor(genrsa): Use local boolean variable with GetBoolArgument
kingstjo 36800a2
fixed tool count
kingstjo 8460d9b
Merge upstream/main into openssl-genrsa-cli
kingstjo 3db1439
reverting 36800a2
kingstjo 976f32e
fix(tool-openssl): restore kTools array size to 13
kingstjo 8e0a88c
refactor(tool-openssl): Improve genrsa_test.cc organization and error…
kingstjo 17e3a6e
fix: Remove redundant file handles in genrsa_test.cc to fix Windows a…
kingstjo 9d62118
Merge remote-tracking branch 'upstream/main' into openssl-genrsa-cli
kingstjo ef8c109
fix: Improve file handling in genrsa.cc to fix Windows access violations
kingstjo f5c29b0
fix(genrsa): Change file opening mode from "w" to "wb" for Windows co…
kingstjo c748c9a
fix: Add null pointer checks to prevent potential dereferences
kingstjo 4972f9e
fix(genrsa): Prevent BIO_flush on stdout to avoid Windows access viol…
kingstjo d5f580e
refactor(genrsa): Simplify BIO cleanup to match AWS-LC patterns
kingstjo 490b1c5
refactor(genrsa_test): Use RSA_check_key() instead of manual componen…
kingstjo 96e6224
refactor(genrsa_test): Focus CLI tests on CLI-specific concerns
kingstjo f70efcb
refactor(genrsa_test): Replace ScopedFILE with BIO-only approach
kingstjo 91e1991
refactor(genrsa): use EVP_PKEY API for RSA key generation
kingstjo c5c739c
refactor(genrsa_test): improve test code quality and reduce noise
kingstjo 0163df2
fix(genrsa_test): add FIPS-aware test skipping for weak key sizes
kingstjo 37ac664
fix(genrsa_test): remove redundant file operations causing Windows ac…
kingstjo 2658c59
fix: Address PR 2535 feedback for genrsa CLI tool
kingstjo 4b128b0
Merge remote-tracking branch 'upstream/main' into openssl-genrsa-cli
kingstjo f4a6118
Fix FIPS mode detection in genrsa tests for macOS-ARM-FIPS
kingstjo 0fbe9f0
Add kMinKeySize=1024 validation and rename bits to KeySizeBits
kingstjo ab39f95
Move output BIO validation before RSA key generation
kingstjo 4f8b1d3
Simplify BIO flush logic in genrsa tool
kingstjo 0c8fa35
Add warning for excessively large RSA key sizes
kingstjo 29ccac3
Merge branch 'main' into openssl-genrsa-cli
kingstjo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) { | ||
kingstjo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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; | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.