[rt-commit] r228 - in /redwax-tool/trunk: ChangeLog configure.ac redwax-tool.c redwax-tool.h redwax_openssl.c
rt-commit at redwax.eu
rt-commit at redwax.eu
Wed Jul 22 13:58:00 CEST 2026
Author: minfrin at redwax.eu
Date: Wed Jul 22 13:57:58 2026
New Revision: 228
Log:
Add --filter-signature to limit certificates by
key type.
Modified:
redwax-tool/trunk/ChangeLog
redwax-tool/trunk/configure.ac
redwax-tool/trunk/redwax-tool.c
redwax-tool/trunk/redwax-tool.h
redwax-tool/trunk/redwax_openssl.c
Modified: redwax-tool/trunk/ChangeLog
==============================================================================
--- redwax-tool/trunk/ChangeLog (original)
+++ redwax-tool/trunk/ChangeLog Wed Jul 22 13:57:58 2026
@@ -1,7 +1,12 @@
+
+Changes with v1.1.0
+
+ *) Add --filter-signature to limit certificates by
+ key type. [Graham Leggett]
Changes with v1.0.1
- *) Add --pems-out to output certificates as seperate
+ *) Add --pems-out to output certificates as separate
files. [Graham Leggett]
*) Implement the generation of the secret file when
Modified: redwax-tool/trunk/configure.ac
==============================================================================
--- redwax-tool/trunk/configure.ac (original)
+++ redwax-tool/trunk/configure.ac Wed Jul 22 13:57:58 2026
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
-AC_INIT(redwax-tool, 1.0.1, minfrin at sharp.fm)
+AC_INIT(redwax-tool, 1.1.0, minfrin at sharp.fm)
AC_CONFIG_AUX_DIR(build-aux)
AC_CONFIG_MACRO_DIRS([m4])
AM_INIT_AUTOMAKE([dist-bzip2])
Modified: redwax-tool/trunk/redwax-tool.c
==============================================================================
--- redwax-tool/trunk/redwax-tool.c (original)
+++ redwax-tool/trunk/redwax-tool.c Wed Jul 22 13:57:58 2026
@@ -85,6 +85,8 @@
APR_HOOK_LINK(complete_verify_dane)
APR_HOOK_LINK(set_purpose)
APR_HOOK_LINK(complete_purpose)
+ APR_HOOK_LINK(set_signature)
+ APR_HOOK_LINK(complete_signature)
APR_HOOK_LINK(set_tlsa)
APR_HOOK_LINK(process_tlsa)
APR_HOOK_LINK(set_smimea)
@@ -161,6 +163,10 @@
(redwax_tool_t * r, const char *arg), (r, arg), DECLINED)
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(rt, REDWAX, int, complete_purpose,
(redwax_tool_t * r, apr_hash_t *purposes), (r, purposes), OK, DECLINED)
+APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(rt, REDWAX, apr_status_t, set_signature,
+ (redwax_tool_t * r, const char *arg), (r, arg), DECLINED)
+APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(rt, REDWAX, int, complete_signature,
+ (redwax_tool_t * r, apr_hash_t *signatures), (r, signatures), OK, DECLINED)
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(rt, REDWAX, apr_status_t, set_tlsa,
(redwax_tool_t * r, const char *arg), (r, arg), DECLINED)
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(rt, REDWAX, int, process_tlsa,
@@ -277,61 +283,62 @@
#define REDWAX_TOOL_FILTER_EXPIRY 270
#define REDWAX_TOOL_FILTER_DANE 271
#define REDWAX_TOOL_FILTER_PURPOSE 272
-#define REDWAX_TOOL_FILTER_VERIFY_PARAM 273
-#define REDWAX_TOOL_FILTER_VERIFY_TLSA 274
-#define REDWAX_TOOL_FILTER_VERIFY_SMIMEA 275
-#define REDWAX_TOOL_CERT_OUT 276
-#define REDWAX_TOOL_NO_CERT_OUT 277
-#define REDWAX_TOOL_CHAIN_OUT 278
-#define REDWAX_TOOL_NO_CHAIN_OUT 279
-#define REDWAX_TOOL_ROOT_OUT 280
-#define REDWAX_TOOL_NO_ROOT_OUT 281
-#define REDWAX_TOOL_TRUST_OUT 282
-#define REDWAX_TOOL_NO_TRUST_OUT 283
-#define REDWAX_TOOL_CRL_OUT 284
-#define REDWAX_TOOL_NO_CRL_OUT 285
-#define REDWAX_TOOL_PARAM_OUT 286
-#define REDWAX_TOOL_NO_PARAM_OUT 287
-#define REDWAX_TOOL_KEY_IN 288
-#define REDWAX_TOOL_NO_KEY_IN 289
-#define REDWAX_TOOL_KEY_OUT 290
-#define REDWAX_TOOL_NO_KEY_OUT 291
-#define REDWAX_TOOL_AUTO_OUT 292
-#define REDWAX_TOOL_NO_AUTO_OUT 293
-#define REDWAX_TOOL_SECRET_SUFFIX_IN 294
-#define REDWAX_TOOL_SECRET_SUFFIX_OUT 295
-#define REDWAX_TOOL_SECRET_TOKEN_IN 296
-#define REDWAX_TOOL_SECRET_TOKEN_OUT 297
-#define REDWAX_TOOL_LABEL_OUT 298
-#define REDWAX_TOOL_NSS_OUT 299
-#define REDWAX_TOOL_NSS_SLOT_OUT 300
-#define REDWAX_TOOL_DER_OUT 301
-#define REDWAX_TOOL_PEMS_OUT 302
-#define REDWAX_TOOL_PEM_OUT 303
-#define REDWAX_TOOL_PKCS12_OUT 304
-#define REDWAX_TOOL_PKCS11_OUT 305
-#define REDWAX_TOOL_PKCS11_MODULE_OUT 306
-#define REDWAX_TOOL_METADATA_OUT 307
-#define REDWAX_TOOL_METADATA_THRESHOLD 308
-#define REDWAX_TOOL_FORMAT_OUT 309
-#define REDWAX_TOOL_CALENDAR_OUT 310
-#define REDWAX_TOOL_CALENDAR_ALARM 311
-#define REDWAX_TOOL_REMINDER_OUT 312
-#define REDWAX_TOOL_JWKS_OUT 313
-#define REDWAX_TOOL_TEXT_OUT 314
-#define REDWAX_TOOL_NO_TEXT_OUT 315
-#define REDWAX_TOOL_SSH_PRIVATE_OUT 316
-#define REDWAX_TOOL_SSH_PUBLIC_OUT 317
-#define REDWAX_TOOL_SMIMEA_OUT 318
-#define REDWAX_TOOL_SSHFP_OUT 319
-#define REDWAX_TOOL_TLSA_OUT 320
-#define REDWAX_TOOL_USER_IN 321
-#define REDWAX_TOOL_USER_OUT 322
-#define REDWAX_TOOL_GROUP_IN 323
-#define REDWAX_TOOL_GROUP_OUT 324
-#define REDWAX_TOOL_ORDER_OUT 325
-#define REDWAX_TOOL_DNS_SERVER 326
-#define REDWAX_TOOL_DNS_TRUST_ANCHOR 327
+#define REDWAX_TOOL_FILTER_SIGNATURE 273
+#define REDWAX_TOOL_FILTER_VERIFY_PARAM 274
+#define REDWAX_TOOL_FILTER_VERIFY_TLSA 275
+#define REDWAX_TOOL_FILTER_VERIFY_SMIMEA 276
+#define REDWAX_TOOL_CERT_OUT 277
+#define REDWAX_TOOL_NO_CERT_OUT 278
+#define REDWAX_TOOL_CHAIN_OUT 279
+#define REDWAX_TOOL_NO_CHAIN_OUT 280
+#define REDWAX_TOOL_ROOT_OUT 281
+#define REDWAX_TOOL_NO_ROOT_OUT 282
+#define REDWAX_TOOL_TRUST_OUT 283
+#define REDWAX_TOOL_NO_TRUST_OUT 284
+#define REDWAX_TOOL_CRL_OUT 285
+#define REDWAX_TOOL_NO_CRL_OUT 286
+#define REDWAX_TOOL_PARAM_OUT 287
+#define REDWAX_TOOL_NO_PARAM_OUT 288
+#define REDWAX_TOOL_KEY_IN 289
+#define REDWAX_TOOL_NO_KEY_IN 290
+#define REDWAX_TOOL_KEY_OUT 291
+#define REDWAX_TOOL_NO_KEY_OUT 292
+#define REDWAX_TOOL_AUTO_OUT 293
+#define REDWAX_TOOL_NO_AUTO_OUT 294
+#define REDWAX_TOOL_SECRET_SUFFIX_IN 295
+#define REDWAX_TOOL_SECRET_SUFFIX_OUT 296
+#define REDWAX_TOOL_SECRET_TOKEN_IN 297
+#define REDWAX_TOOL_SECRET_TOKEN_OUT 298
+#define REDWAX_TOOL_LABEL_OUT 299
+#define REDWAX_TOOL_NSS_OUT 300
+#define REDWAX_TOOL_NSS_SLOT_OUT 301
+#define REDWAX_TOOL_DER_OUT 302
+#define REDWAX_TOOL_PEMS_OUT 303
+#define REDWAX_TOOL_PEM_OUT 304
+#define REDWAX_TOOL_PKCS12_OUT 305
+#define REDWAX_TOOL_PKCS11_OUT 306
+#define REDWAX_TOOL_PKCS11_MODULE_OUT 307
+#define REDWAX_TOOL_METADATA_OUT 308
+#define REDWAX_TOOL_METADATA_THRESHOLD 309
+#define REDWAX_TOOL_FORMAT_OUT 310
+#define REDWAX_TOOL_CALENDAR_OUT 311
+#define REDWAX_TOOL_CALENDAR_ALARM 312
+#define REDWAX_TOOL_REMINDER_OUT 313
+#define REDWAX_TOOL_JWKS_OUT 314
+#define REDWAX_TOOL_TEXT_OUT 315
+#define REDWAX_TOOL_NO_TEXT_OUT 316
+#define REDWAX_TOOL_SSH_PRIVATE_OUT 317
+#define REDWAX_TOOL_SSH_PUBLIC_OUT 318
+#define REDWAX_TOOL_SMIMEA_OUT 319
+#define REDWAX_TOOL_SSHFP_OUT 320
+#define REDWAX_TOOL_TLSA_OUT 321
+#define REDWAX_TOOL_USER_IN 322
+#define REDWAX_TOOL_USER_OUT 323
+#define REDWAX_TOOL_GROUP_IN 324
+#define REDWAX_TOOL_GROUP_OUT 325
+#define REDWAX_TOOL_ORDER_OUT 326
+#define REDWAX_TOOL_DNS_SERVER 327
+#define REDWAX_TOOL_DNS_TRUST_ANCHOR 328
#define REDWAX_EXIT_OK 0
#define REDWAX_EXIT_INIT 1
@@ -490,6 +497,9 @@
{ "filter-purpose", REDWAX_TOOL_FILTER_PURPOSE, 1,
" --filter-purpose=purpose\tSet the purpose of the certificate to verify.\n"
"\t\t\t\tIf unset, it will default to any purpose." },
+ { "filter-signature", REDWAX_TOOL_FILTER_SIGNATURE, 1,
+ " --filter-signature=algorithm\tSet the signature algorithm of the certificate to verify.\n"
+ "\t\t\t\tIf unset, it will default to any algorithm." },
{ "text-out", REDWAX_TOOL_TEXT_OUT, 0,
" --text-out\t\t\tInclude additional text in certificate PEM and\n"
"\t\t\t\tmetadata output." },
@@ -796,7 +806,7 @@
(*cp >= '0' && *cp <= '9') ? *cp - '0' : \
(*cp >= 'A' && *cp <= 'F') ? *cp - 'A' + 10 : \
(*cp >= 'a' && *cp <= 'f') ? *cp - 'a' + 10 : \
- (!(error = cp)) /* last line of macro... */
+ ((error = cp) ? 0 : 0) /* last line of macro... */
/*
* OCTAL_TO_3BITS:
@@ -805,7 +815,7 @@
*/
#define OCTAL_TO_3BITS(cp,error) \
(*cp >= '0' && *cp <= '7') ? *cp - '0' : \
- (!(error = cp)) /* last line of macro... */
+ ((error = cp) ? 0 : 0) /* last line of macro... */
if (state_out) {
@@ -1224,10 +1234,10 @@
case 'N': /* shift out */ \
case 'O': /* shift in */ \
case 'P': /* data line escape */ \
- case 'Q': /* redwax control 1 */ \
- case 'R': /* redwax control 2 */ \
- case 'S': /* redwax control 3 */ \
- case 'T': /* redwax control 4 */ \
+ case 'Q': /* device control 1 */ \
+ case 'R': /* device control 2 */ \
+ case 'S': /* device control 3 */ \
+ case 'T': /* device control 4 */ \
case 'U': /* nack */ \
case 'V': /* sync idel */ \
case 'W': /* end of transmit block */ \
@@ -1292,50 +1302,50 @@
case 'P': /* data line escape */ \
*cc++ = '\x10'; \
break; \
- case 'Q': /* redwax control 1 */ \
+ case 'Q': /* device control 1 */ \
*cc++ = '\x11'; \
break; \
- case 'R': /* redwax control 2 */ \
+ case 'R': /* device control 2 */ \
*cc++ = '\x12'; \
break; \
- case 'S': /* redwax control 3 */ \
+ case 'S': /* device control 3 */ \
*cc++ = '\x13'; \
break; \
- case 'T': /* redwax control 4 */ \
- *cc++ = '\x24'; \
+ case 'T': /* device control 4 */ \
+ *cc++ = '\x14'; \
break; \
case 'U': /* nack */ \
- *cc++ = '\x25'; \
+ *cc++ = '\x15'; \
break; \
case 'V': /* sync idel */ \
- *cc++ = '\x26'; \
+ *cc++ = '\x16'; \
break; \
case 'W': /* end of transmit block */ \
- *cc++ = '\x27'; \
+ *cc++ = '\x17'; \
break; \
case 'X': /* cancel */ \
- *cc++ = '\x28'; \
+ *cc++ = '\x18'; \
break; \
case 'Y': /* end of medium */ \
- *cc++ = '\x29'; \
+ *cc++ = '\x19'; \
break; \
case 'Z': /* substitute */ \
- *cc++ = '\x2A'; \
+ *cc++ = '\x1A'; \
break; \
case '[': /* escape */ \
- *cc++ = '\x2B'; \
+ *cc++ = '\x1B'; \
break; \
case '\\': /* file separator */ \
- *cc++ = '\x2C'; \
+ *cc++ = '\x1C'; \
break; \
case ']': /* group separator */ \
- *cc++ = '\x2D'; \
+ *cc++ = '\x1D'; \
break; \
case '^': /* record separator */ \
- *cc++ = '\x2E'; \
+ *cc++ = '\x1E'; \
break; \
case '_': /* unit separator */ \
- *cc++ = '\x2F'; \
+ *cc++ = '\x1F'; \
break; \
} \
if (offset) *offset++ = (cp - arg_str); \
@@ -2909,6 +2919,13 @@
}
break;
}
+ case REDWAX_TOOL_FILTER_SIGNATURE: {
+ if (redwax_set_option(r, optarg, &rt_run_set_signature,
+ "filter-signature")) {
+ return r->rc;
+ }
+ break;
+ }
case REDWAX_TOOL_FILTER_VERIFY_TLSA: {
if (redwax_set_option(r, optarg, &rt_run_set_tlsa,
"filter-verify-tlsa")) {
@@ -3334,6 +3351,10 @@
redwax_complete_hash(r, optarg, &rt_run_complete_purpose, state.isquoted);
break;
}
+ case REDWAX_TOOL_FILTER_SIGNATURE: {
+ redwax_complete_hash(r, optarg, &rt_run_complete_signature, state.isquoted);
+ break;
+ }
case REDWAX_TOOL_NSS_OUT: {
redwax_complete_directory(r, optarg, state.isquoted);
break;
@@ -3560,6 +3581,10 @@
}
case REDWAX_TOOL_FILTER_PURPOSE: {
redwax_complete_hash(r, "", &rt_run_complete_purpose, state.isquoted);
+ break;
+ }
+ case REDWAX_TOOL_FILTER_SIGNATURE: {
+ redwax_complete_hash(r, "", &rt_run_complete_signature, state.isquoted);
break;
}
case REDWAX_TOOL_NSS_OUT: {
Modified: redwax-tool/trunk/redwax-tool.h
==============================================================================
--- redwax-tool/trunk/redwax-tool.h (original)
+++ redwax-tool/trunk/redwax-tool.h Wed Jul 22 13:57:58 2026
@@ -143,6 +143,7 @@
const char *verify_param;
const char *verify_date;
const char *purpose;
+ const char *signature;
const char *secret_suffix_in;
const char *secret_suffix_out;
const char *secret_token_in;
@@ -884,6 +885,22 @@
(redwax_tool_t *r, const char *arg))
/**
+ * Hook to complete signatures.
+ *
+ * @param r The redwax-tool context.
+ */
+APR_DECLARE_EXTERNAL_HOOK(rt, REDWAX, apr_status_t, complete_signature,
+ (redwax_tool_t *r, apr_hash_t *signatures))
+
+/**
+ * Hook to set the signature.
+ *
+ * @param r The redwax-tool context.
+ */
+APR_DECLARE_EXTERNAL_HOOK(rt, REDWAX, apr_status_t, set_signature,
+ (redwax_tool_t *r, const char *arg))
+
+/**
* Hook to set the tlsa.
*
* @param r The redwax-tool context.
Modified: redwax-tool/trunk/redwax_openssl.c
==============================================================================
--- redwax-tool/trunk/redwax_openssl.c (original)
+++ redwax-tool/trunk/redwax_openssl.c Wed Jul 22 13:57:58 2026
@@ -1853,6 +1853,64 @@
return APR_SUCCESS;
}
+static apr_status_t redwax_openssl_set_signature(redwax_tool_t *r, const char *arg)
+{
+ int nid = OBJ_txt2nid(arg);
+
+ if (nid == NID_undef) {
+
+ redwax_print_error(r,
+ "--filter-signature: signature '%s' not found\n", arg);
+
+ return APR_ENOENT;
+ }
+
+ r->signature = arg;
+
+ return APR_SUCCESS;
+}
+
+static void complete_signature_name_cb(const char *name, void *data)
+{
+ apr_hash_t *params = data;
+
+ if (OBJ_txt2obj(name, 1)) {
+ return;
+ }
+
+ EVP_SIGNATURE *sig = EVP_SIGNATURE_fetch(NULL, name, NULL);
+
+ if (sig) {
+ apr_hash_set(params, name, APR_HASH_KEY_STRING, name);
+ EVP_SIGNATURE_free(sig);
+ }
+}
+
+static void complete_signature_cb(EVP_KEYMGMT *km, void *data)
+{
+ const OSSL_PARAM *params = EVP_KEYMGMT_gettable_params(km);
+
+ if (params) {
+ for (; params->key; params++) {
+ if (strcmp(params->key, OSSL_PKEY_PARAM_BITS) == 0 ||
+ strcmp(params->key, OSSL_PKEY_PARAM_MAX_SIZE) == 0) {
+
+ EVP_KEYMGMT_names_do_all(km, complete_signature_name_cb, data);
+
+ break;
+ }
+ }
+ }
+}
+
+static apr_status_t redwax_openssl_complete_signature(redwax_tool_t *r,
+ apr_hash_t *params)
+{
+ EVP_KEYMGMT_do_all_provided(NULL, complete_signature_cb, params);
+
+ return APR_SUCCESS;
+}
+
static apr_status_t redwax_openssl_complete_filter_search(redwax_tool_t *r,
apr_hash_t *filters)
{
@@ -1882,7 +1940,7 @@
if (purpose == -1) {
redwax_print_error(r,
- "When searchinging, purpose was not recognised: %s\n", r->purpose);
+ "search-filter: purpose was not recognised: %s\n", r->purpose);
return APR_EINVAL;
}
@@ -1893,6 +1951,16 @@
purpose = X509_PURPOSE_get_id(xptmp);
if (!X509_check_purpose(x, purpose, 0)) {
+ X509_free(x);
+ return 0;
+ }
+ }
+
+ if (r->signature) {
+
+ EVP_PKEY *pkey = X509_get0_pubkey(x);
+
+ if (pkey && !EVP_PKEY_is_a(pkey, r->signature)) {
X509_free(x);
return 0;
}
@@ -2200,6 +2268,24 @@
if (!config) {
config = apr_pcalloc(cert->pool, sizeof(openssl_certificate_config_t));
redwax_set_module_config(cert->per_module, &openssl_module, config);
+ }
+
+ /* signature check */
+ if (r->signature && current_cert) {
+
+ EVP_PKEY *pkey = X509_get0_pubkey(current_cert);
+
+ int nid;
+
+ X509_get_signature_info(current_cert, NULL, &nid, NULL, NULL);
+
+ if (!EVP_PKEY_is_a(pkey, r->signature)) {
+ redwax_print_error(r,
+ "verify-filter: %d: %.*s: %s != %s, skipping\n",
+ X509_STORE_CTX_get_error_depth(ctx), len, buf,
+ r->signature, OBJ_nid2sn(nid));
+ return 0;
+ }
}
/* set verification result */
@@ -3620,7 +3706,7 @@
status = apr_file_puts(buf, sfile);
if (APR_SUCCESS != status) {
- apr_file_remove(template, pool);
+ apr_file_remove(template, pool);
redwax_print_error(r,
"Could not write to '%s': %pm\n", secret, &status);
return NULL;
@@ -3629,7 +3715,7 @@
status = apr_file_close(sfile);
if (APR_SUCCESS != status) {
- apr_file_remove(template, pool);
+ apr_file_remove(template, pool);
redwax_print_error(r,
"Could not close '%s': %pm\n", secret, &status);
return NULL;
@@ -3638,7 +3724,7 @@
status = apr_file_rename(template, secret, pool);
if (APR_SUCCESS != status) {
- apr_file_remove(template, pool);
+ apr_file_remove(template, pool);
redwax_print_error(r,
"Could not rename '%s': %pm\n", secret, &status);
return NULL;
@@ -7258,6 +7344,8 @@
rt_hook_set_verify_dane(redwax_openssl_set_verify_dane, NULL, NULL, APR_HOOK_MIDDLE);
rt_hook_complete_purpose(redwax_openssl_complete_purpose, NULL, NULL, APR_HOOK_MIDDLE);
rt_hook_set_purpose(redwax_openssl_set_purpose, NULL, NULL, APR_HOOK_MIDDLE);
+ rt_hook_complete_signature(redwax_openssl_complete_signature, NULL, NULL, APR_HOOK_MIDDLE);
+ rt_hook_set_signature(redwax_openssl_set_signature, NULL, NULL, APR_HOOK_MIDDLE);
rt_hook_process_pem_in(redwax_openssl_process_pem_in, NULL, NULL, APR_HOOK_MIDDLE);
rt_hook_process_trust_pem_in(redwax_openssl_process_trust_pem_in, NULL, NULL, APR_HOOK_MIDDLE);
rt_hook_process_pkcs12_in(redwax_openssl_process_pkcs12_in, NULL, NULL, APR_HOOK_MIDDLE);
More information about the rt-commit
mailing list