Skip to content

Commit 8f8fc1a

Browse files
committed
Order tool output by options provided - x509
1 parent 9ee8ec8 commit 8f8fc1a

File tree

5 files changed

+453
-173
lines changed

5 files changed

+453
-173
lines changed

tool-openssl/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ add_executable(
1111
dgst.cc
1212
rehash.cc
1313
req.cc
14+
ordered_args.cc
1415
rsa.cc
1516
s_client.cc
1617
tool.cc
@@ -92,6 +93,7 @@ if(BUILD_TESTING)
9293
rsa.cc
9394
rsa_test.cc
9495
s_client.cc
96+
ordered_args.cc
9597
verify.cc
9698
verify_test.cc
9799
x509.cc
@@ -114,5 +116,6 @@ if(BUILD_TESTING)
114116
target_link_libraries(tool_openssl_test boringssl_gtest_main ssl crypto)
115117
target_include_directories(tool_openssl_test BEFORE PRIVATE ${AWSLC_BINARY_DIR}/symbol_prefix_include)
116118
add_dependencies(all_tests tool_openssl_test)
119+
add_dependencies(tool_openssl_test openssl)
117120
set_test_location(tool_openssl_test)
118121
endif()

tool-openssl/internal.h

Lines changed: 76 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0 OR ISC
33

4-
#ifndef INTERNAL_H
5-
#define INTERNAL_H
4+
#ifndef TOOL_OPENSSL_INTERNAL_H
5+
#define TOOL_OPENSSL_INTERNAL_H
66

7-
#include "../tool/internal.h"
87
#include <openssl/digest.h>
8+
#include <algorithm>
99
#include <string>
10+
#include <utility>
1011
#include <vector>
12+
#include "../tool/internal.h"
1113

1214
#if !defined(O_BINARY)
1315
#define O_BINARY 0
@@ -20,12 +22,13 @@ struct Tool {
2022
tool_func_t func;
2123
};
2224

23-
bool IsNumeric(const std::string& str);
25+
bool IsNumeric(const std::string &str);
2426

25-
X509* CreateAndSignX509Certificate();
26-
X509_CRL* createTestCRL();
27+
X509 *CreateAndSignX509Certificate();
28+
X509_CRL *createTestCRL();
2729

28-
bool LoadPrivateKeyAndSignCertificate(X509 *x509, const std::string &signkey_path);
30+
bool LoadPrivateKeyAndSignCertificate(X509 *x509,
31+
const std::string &signkey_path);
2932

3033
tool_func_t FindTool(const std::string &name);
3134
tool_func_t FindTool(int argc, char **argv, int &starting_arg);
@@ -46,27 +49,76 @@ bssl::UniquePtr<X509_NAME> parse_subject_name(std::string &subject_string);
4649

4750

4851
// Rehash tool Utils
49-
typedef struct hash_entry_st { // Represents a single certificate/CRL file
50-
struct hash_entry_st *next; // Links to next entry in same bucket
51-
char *filename; // Actual filename
52-
uint8_t digest[EVP_MAX_MD_SIZE]; // File's cryptographic digest
52+
typedef struct hash_entry_st { // Represents a single certificate/CRL file
53+
struct hash_entry_st *next; // Links to next entry in same bucket
54+
char *filename; // Actual filename
55+
uint8_t digest[EVP_MAX_MD_SIZE]; // File's cryptographic digest
5356
} HASH_ENTRY;
5457

55-
typedef struct bucket_st { // Groups entries with same hash
56-
struct bucket_st *next; // Links to next bucket in hash table slot
57-
HASH_ENTRY *first_entry; // Start of entry list
58-
HASH_ENTRY *last_entry; // End of entry list
59-
uint32_t hash; // Hash value of the certificates/CRLs
60-
uint16_t type; // CERT or CRL Bucket
61-
uint16_t num_entries; // Count of entries
58+
typedef struct bucket_st { // Groups entries with same hash
59+
struct bucket_st *next; // Links to next bucket in hash table slot
60+
HASH_ENTRY *first_entry; // Start of entry list
61+
HASH_ENTRY *last_entry; // End of entry list
62+
uint32_t hash; // Hash value of the certificates/CRLs
63+
uint16_t type; // CERT or CRL Bucket
64+
uint16_t num_entries; // Count of entries
6265
} BUCKET;
6366

64-
enum Type {
65-
TYPE_CERT=0, TYPE_CRL=1
66-
};
67+
enum Type { TYPE_CERT = 0, TYPE_CRL = 1 };
6768
void add_entry(enum Type type, uint32_t hash, const char *filename,
68-
const uint8_t *digest);
69-
BUCKET** get_table();
69+
const uint8_t *digest);
70+
BUCKET **get_table();
7071
void cleanup_hash_table();
7172

72-
#endif //INTERNAL_H
73+
// Ordered argument processing (specific to tool-openssl)
74+
namespace ordered_args {
75+
typedef std::vector<std::pair<std::string, std::string>> ordered_args_map_t;
76+
77+
// Helper function to find an argument in the ordered args vector
78+
static inline bool HasArgument(const ordered_args_map_t &args,
79+
const std::string &arg_name) {
80+
return std::find_if(
81+
args.begin(), args.end(),
82+
[&arg_name](const std::pair<std::string, std::string> &pair) {
83+
return pair.first == arg_name;
84+
}) != args.end();
85+
}
86+
87+
// Helper function to count occurrences of an argument
88+
static inline size_t CountArgument(const ordered_args_map_t &args,
89+
const std::string &arg_name) {
90+
size_t count = 0;
91+
for (const auto &pair : args) {
92+
if (pair.first == arg_name) {
93+
count++;
94+
}
95+
}
96+
return count;
97+
}
98+
99+
// Helper function to find an argument in the ordered args vector
100+
static inline ordered_args_map_t::const_iterator FindArg(
101+
const ordered_args_map_t &args, const std::string &arg_name) {
102+
return std::find_if(
103+
args.begin(), args.end(),
104+
[&arg_name](const std::pair<std::string, std::string> &pair) {
105+
return pair.first == arg_name;
106+
});
107+
}
108+
109+
// Parse arguments in order of appearance
110+
bool ParseOrderedKeyValueArguments(ordered_args_map_t &out_args,
111+
args_list_t &extra_args,
112+
const args_list_t &args,
113+
const argument_t *templates);
114+
115+
// Get helpers for ordered arguments
116+
bool GetUnsigned(unsigned *out, const std::string &arg_name,
117+
unsigned default_value, const ordered_args_map_t &args);
118+
bool GetString(std::string *out, const std::string &arg_name,
119+
std::string default_value, const ordered_args_map_t &args);
120+
bool GetBoolArgument(bool *out, const std::string &arg_name,
121+
const ordered_args_map_t &args);
122+
} // namespace ordered_args
123+
124+
#endif // TOOL_OPENSSL_INTERNAL_H

tool-openssl/ordered_args.cc

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0 OR ISC
3+
4+
#include <algorithm>
5+
#include <string>
6+
#include <utility>
7+
#include <vector>
8+
9+
#include <errno.h>
10+
#include <limits.h>
11+
#include <stdio.h>
12+
#include <stdlib.h>
13+
#include <string.h>
14+
15+
#include "internal.h"
16+
17+
namespace ordered_args {
18+
19+
bool ParseOrderedKeyValueArguments(ordered_args_map_t &out_args,
20+
args_list_t &extra_args,
21+
const args_list_t &args,
22+
const argument_t *templates) {
23+
out_args.clear();
24+
extra_args.clear();
25+
26+
for (size_t i = 0; i < args.size(); i++) {
27+
const std::string &arg = args[i];
28+
const argument_t *templ = nullptr;
29+
for (size_t j = 0; templates[j].name[0] != 0; j++) {
30+
if (strcmp(arg.c_str(), templates[j].name) == 0) {
31+
templ = &templates[j];
32+
break;
33+
}
34+
}
35+
36+
if (templ == nullptr) {
37+
if (::IsFlag(arg)) {
38+
fprintf(stderr, "Unknown flag: %s\n", arg.c_str());
39+
return false;
40+
}
41+
extra_args.push_back(arg);
42+
continue;
43+
}
44+
45+
// Check for duplicate arguments - allowed for order preservation
46+
// but warn about it when debugging
47+
#ifndef NDEBUG
48+
if (HasArgument(out_args, arg)) {
49+
fprintf(stderr, "Warning: Duplicate argument: %s\n", arg.c_str());
50+
}
51+
#endif
52+
53+
if (templ->type == kBooleanArgument) {
54+
out_args.push_back(std::pair<std::string, std::string>(arg, ""));
55+
} else {
56+
if (i + 1 >= args.size()) {
57+
fprintf(stderr, "Missing argument for option: %s\n", arg.c_str());
58+
return false;
59+
}
60+
out_args.push_back(std::pair<std::string, std::string>(arg, args[++i]));
61+
}
62+
}
63+
64+
for (size_t j = 0; templates[j].name[0] != 0; j++) {
65+
const argument_t *templ = &templates[j];
66+
if (templ->type == kRequiredArgument &&
67+
!HasArgument(out_args, templ->name)) {
68+
fprintf(stderr, "Missing value for required argument: %s\n", templ->name);
69+
return false;
70+
}
71+
}
72+
73+
return true;
74+
}
75+
76+
bool GetUnsigned(unsigned *out, const std::string &arg_name,
77+
unsigned default_value, const ordered_args_map_t &args) {
78+
auto it = FindArg(args, arg_name);
79+
if (it == args.end()) {
80+
*out = default_value;
81+
return true;
82+
}
83+
84+
const std::string &value = it->second;
85+
if (value.empty()) {
86+
return false;
87+
}
88+
89+
errno = 0;
90+
char *endptr = nullptr;
91+
unsigned long int num = strtoul(value.c_str(), &endptr, 10);
92+
if (num == ULONG_MAX && errno == ERANGE) {
93+
return false;
94+
}
95+
if (endptr == nullptr || endptr == value.c_str()) {
96+
return false;
97+
}
98+
if (*endptr != 0 || num > UINT_MAX) {
99+
return false;
100+
}
101+
*out = static_cast<unsigned>(num);
102+
103+
return true;
104+
}
105+
106+
bool GetString(std::string *out, const std::string &arg_name,
107+
std::string default_value, const ordered_args_map_t &args) {
108+
auto it = FindArg(args, arg_name);
109+
if (it == args.end()) {
110+
*out = default_value;
111+
return true;
112+
}
113+
114+
const std::string &value = it->second;
115+
*out = value;
116+
117+
return true;
118+
}
119+
120+
bool GetBoolArgument(bool *out, const std::string &arg_name,
121+
const ordered_args_map_t &args) {
122+
auto it = FindArg(args, arg_name);
123+
if (it == args.end()) {
124+
// Boolean argument not found
125+
*out = false;
126+
} else {
127+
*out = true;
128+
}
129+
130+
// amazonq-ignore-next-line
131+
return true;
132+
}
133+
134+
} // namespace ordered_args

0 commit comments

Comments
 (0)