generated from amazon-archives/__template_Apache-2.0
-
Notifications
You must be signed in to change notification settings - Fork 142
Implement ecparam CLI tool #2718
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
19
commits into
aws:main
Choose a base branch
from
kingstjo:implement-ecparam-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.
+542
−1
Open
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
ae63347
Implement ecparam CLI tool with proper memory management and high-lev…
kingstjo ec8b2d6
refactor: Replace ScopedFILE with BIO in ecparam_test.cc
kingstjo c5aa4f0
refactor: Replace manual system() calls with RunCommandsAndCompareOut…
kingstjo 48e266e
refactor: Replace defines with type-safe enums in ecparam
kingstjo 621f805
improve: Add comprehensive error handling to ecparam
kingstjo b9e9ea5
refactor: Simplify EC key generation using higher-level APIs
kingstjo fd9655e
feat(ecparam): improve curve validation and error messages
kingstjo 2ae38dd
Fix ecparam_test.cc compilation and improve cross-compatibility testing
kingstjo e23e245
Refactor ecparam tests to use Google Test parameterization
kingstjo 2b0a395
Enhance EcparamTest with cryptographic content validation
kingstjo 120b750
Implement dynamic curve detection for parameterized tests
kingstjo 30e6faf
Refactor ecparam_test.cc for better maintainability and code quality
kingstjo 22b765d
Reorganize ecparam_test.cc structure and eliminate duplicates
kingstjo 4c50e45
Address PR review feedback: simplify format validation and enum usage
kingstjo 46844aa
Address PR review feedback: simplify function parameters and code str…
kingstjo 634bbb5
Address PR review feedback: simplify test class hierarchy
kingstjo 5906718
Address PR review feedback: improve curve validation with group creation
kingstjo 517dfa3
Fix valgrind error: initialize char arrays in test classes
kingstjo 36f6537
Merge branch 'main' into implement-ecparam-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
Some comments aren't visible on the classic Files Changed page.
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,189 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 OR ISC | ||
|
||
#include <openssl/ec.h> | ||
#include <openssl/pem.h> | ||
#include <openssl/err.h> | ||
#include <openssl/obj.h> | ||
#include "../tool/internal.h" | ||
#include "internal.h" | ||
|
||
enum OutputFormat { | ||
FORMAT_PEM = 1, | ||
FORMAT_DER = 2 | ||
}; | ||
|
||
static bssl::UniquePtr<EC_GROUP> ValidateAndCreateECGroup(const std::string& curve_name) { | ||
int nid = OBJ_sn2nid(curve_name.c_str()); | ||
if (nid == NID_undef) { | ||
nid = EC_curve_nist2nid(curve_name.c_str()); | ||
} | ||
|
||
bssl::UniquePtr<EC_GROUP> group; | ||
if (nid != NID_undef) { | ||
group.reset(EC_GROUP_new_by_curve_name(nid)); | ||
} | ||
|
||
if (!group) { | ||
fprintf(stderr, "unknown curve name (%s)\n", curve_name.c_str()); | ||
|
||
size_t num_curves = EC_get_builtin_curves(nullptr, 0); | ||
std::vector<EC_builtin_curve> curves(num_curves); | ||
EC_get_builtin_curves(curves.data(), num_curves); | ||
|
||
fprintf(stderr, "Supported curves:\n"); | ||
for (const auto& curve : curves) { | ||
const char* nist_name = EC_curve_nid2nist(curve.nid); | ||
const char* sn = OBJ_nid2sn(curve.nid); | ||
|
||
if (nist_name) { | ||
fprintf(stderr, " %s (%s) - %s\n", sn, nist_name, curve.comment); | ||
} else { | ||
fprintf(stderr, " %s - %s\n", sn, curve.comment); | ||
} | ||
} | ||
return nullptr; | ||
} | ||
|
||
return group; | ||
} | ||
|
||
static const argument_t kArguments[] = { | ||
{ "-help", kBooleanArgument, "Display option summary" }, | ||
{ "-name", kOptionalArgument, "Use the ec parameters with specified 'short name'" }, | ||
{ "-out", kOptionalArgument, "Output file, default stdout" }, | ||
{ "-outform", kOptionalArgument, "Output format (PEM or DER), default PEM" }, | ||
{ "-conv_form", kOptionalArgument, "Point conversion form (compressed or uncompressed)" }, | ||
{ "-noout", kBooleanArgument, "Do not print the ec parameter" }, | ||
{ "-genkey", kBooleanArgument, "Generate ec key" }, | ||
{ "", kOptionalArgument, "" } | ||
}; | ||
|
||
bool ecparamTool(const args_list_t &args) { | ||
using namespace ordered_args; | ||
ordered_args_map_t parsed_args; | ||
args_list_t extra_args; | ||
|
||
if (!ParseOrderedKeyValueArguments(parsed_args, extra_args, args, kArguments) || | ||
extra_args.size() > 0) { | ||
PrintUsage(kArguments); | ||
return false; | ||
} | ||
|
||
if (HasArgument(parsed_args, "-help")) { | ||
PrintUsage(kArguments); | ||
return true; | ||
} | ||
|
||
bool ret = false; | ||
std::string curve_name, out_path, outform, conv_form; | ||
bool noout = false, genkey = false; | ||
point_conversion_form_t point_form = POINT_CONVERSION_UNCOMPRESSED; | ||
OutputFormat output_format = FORMAT_PEM; | ||
bssl::UniquePtr<EC_GROUP> group; | ||
bssl::UniquePtr<EC_KEY> eckey; | ||
bssl::UniquePtr<BIO> out_bio; | ||
|
||
GetString(&curve_name, "-name", "", parsed_args); | ||
GetString(&out_path, "-out", "", parsed_args); | ||
GetString(&outform, "-outform", "", parsed_args); | ||
GetString(&conv_form, "-conv_form", "", parsed_args); | ||
GetBoolArgument(&noout, "-noout", parsed_args); | ||
GetBoolArgument(&genkey, "-genkey", parsed_args); | ||
|
||
if (curve_name.empty()) { | ||
fprintf(stderr, "No curve specified\n"); | ||
goto err; | ||
} | ||
|
||
// Parse output format | ||
if (!outform.empty()) { | ||
if (isStringUpperCaseEqual(outform, "DER")) { | ||
output_format = FORMAT_DER; | ||
} else if (isStringUpperCaseEqual(outform, "PEM")) { | ||
output_format = FORMAT_PEM; | ||
} else { | ||
fprintf(stderr, "Invalid output format: %s\n", outform.c_str()); | ||
goto err; | ||
} | ||
} | ||
|
||
// Parse point conversion form | ||
if (!conv_form.empty()) { | ||
if (conv_form == "compressed") { | ||
point_form = POINT_CONVERSION_COMPRESSED; | ||
} else if (conv_form == "uncompressed") { | ||
point_form = POINT_CONVERSION_UNCOMPRESSED; | ||
} else { | ||
fprintf(stderr, "Invalid point conversion form: %s\n", conv_form.c_str()); | ||
goto err; | ||
} | ||
} | ||
|
||
// Validate curve and create group | ||
group = ValidateAndCreateECGroup(curve_name); | ||
if (!group) { | ||
goto err; | ||
} | ||
|
||
// Set up output BIO | ||
if (out_path.empty()) { | ||
out_bio.reset(BIO_new_fp(stdout, BIO_NOCLOSE)); | ||
} else { | ||
out_bio.reset(BIO_new_file(out_path.c_str(), output_format == FORMAT_DER ? "wb" : "w")); | ||
} | ||
if (!out_bio) { | ||
fprintf(stderr, "Error opening output\n"); | ||
goto err; | ||
} | ||
|
||
if (genkey) { | ||
// Generate EC key using existing group | ||
eckey.reset(EC_KEY_new()); | ||
if (!eckey || !EC_KEY_set_group(eckey.get(), group.get())) { | ||
fprintf(stderr, "Failed to create EC key for curve\n"); | ||
goto err; | ||
} | ||
|
||
if (!EC_KEY_generate_key(eckey.get())) { | ||
fprintf(stderr, "Failed to generate EC key\n"); | ||
goto err; | ||
} | ||
|
||
// Set point conversion form on the key | ||
EC_KEY_set_conv_form(eckey.get(), point_form); | ||
|
||
if (!noout) { | ||
if (output_format == FORMAT_PEM) { | ||
if (!PEM_write_bio_ECPrivateKey(out_bio.get(), eckey.get(), nullptr, nullptr, 0, nullptr, nullptr)) { | ||
fprintf(stderr, "Failed to write private key in PEM format\n"); | ||
goto err; | ||
} | ||
} else { | ||
if (!i2d_ECPrivateKey_bio(out_bio.get(), eckey.get())) { | ||
fprintf(stderr, "Failed to write private key in DER format\n"); | ||
goto err; | ||
} | ||
} | ||
} | ||
} else if (!noout) { | ||
// Output parameters | ||
if (output_format == FORMAT_PEM) { | ||
if (!PEM_write_bio_ECPKParameters(out_bio.get(), group.get())) { | ||
fprintf(stderr, "Failed to write EC parameters in PEM format\n"); | ||
goto err; | ||
} | ||
} else { | ||
if (!i2d_ECPKParameters_bio(out_bio.get(), group.get())) { | ||
fprintf(stderr, "Failed to write EC parameters in DER format\n"); | ||
goto err; | ||
} | ||
} | ||
} | ||
|
||
ret = true; | ||
|
||
err: | ||
ERR_print_errors_fp(stderr); | ||
return ret; | ||
} |
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.