[rs-commit] r45 - in /redwax-tool/trunk: redwax-tool.c redwax-tool.h redwax_p11kit.c
rs-commit at redwax.eu
rs-commit at redwax.eu
Sat Nov 20 10:48:46 CET 2021
Author: minfrin at redwax.eu
Date: Sat Nov 20 10:48:45 2021
New Revision: 45
Log:
Add ability to read secrets for tokens from a secrets file.
Modified:
redwax-tool/trunk/redwax-tool.c
redwax-tool/trunk/redwax-tool.h
redwax-tool/trunk/redwax_p11kit.c
Modified: redwax-tool/trunk/redwax-tool.c
==============================================================================
--- redwax-tool/trunk/redwax-tool.c (original)
+++ redwax-tool/trunk/redwax-tool.c Sat Nov 20 10:48:45 2021
@@ -80,7 +80,7 @@
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(rt, REDWAX, int, process_pem_in,
(redwax_tool_t * r, const char *arg, const char *secret), (r, arg, secret), DECLINED);
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(rt, REDWAX, int, process_pkcs11_in,
- (redwax_tool_t * r, const char *arg), (r, arg), DECLINED);
+ (redwax_tool_t * r, const char *arg, apr_hash_t *secrets), (r, arg, secrets), DECLINED);
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(rt, REDWAX, int, complete_pkcs11_in,
(redwax_tool_t * r, const char *url, apr_hash_t *urls), (r, url, urls), DECLINED);
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(rt, REDWAX, int, process_pkcs11_module_in,
@@ -100,7 +100,7 @@
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(rt, REDWAX, int, process_pkcs12_out,
(redwax_tool_t * r, const char *arg, const char *secret), (r, arg, secret), DECLINED);
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(rt, REDWAX, int, process_pkcs11_out,
- (redwax_tool_t * r, const char *arg), (r, arg), DECLINED);
+ (redwax_tool_t * r, const char *arg, apr_hash_t *secrets), (r, arg, secrets), DECLINED);
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(rt, REDWAX, int, complete_pkcs11_out,
(redwax_tool_t * r, const char *url, apr_hash_t *urls), (r, url, urls), DECLINED);
APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(rt, REDWAX, int, process_pkcs11_module_out,
@@ -152,13 +152,15 @@
#define REDWAX_TOOL_VERIFY_PARAM 280
#define REDWAX_TOOL_SECRET_SUFFIX_IN 281
#define REDWAX_TOOL_SECRET_SUFFIX_OUT 282
-#define REDWAX_TOOL_LABEL_OUT 283
-#define REDWAX_TOOL_NSS_OUT 284
-#define REDWAX_TOOL_NSS_SLOT_OUT 285
-#define REDWAX_TOOL_PEM_OUT 286
-#define REDWAX_TOOL_PKCS12_OUT 287
-#define REDWAX_TOOL_PKCS11_OUT 288
-#define REDWAX_TOOL_PKCS11_MODULE_OUT 289
+#define REDWAX_TOOL_SECRET_TOKEN_IN 283
+#define REDWAX_TOOL_SECRET_TOKEN_OUT 284
+#define REDWAX_TOOL_LABEL_OUT 285
+#define REDWAX_TOOL_NSS_OUT 286
+#define REDWAX_TOOL_NSS_SLOT_OUT 287
+#define REDWAX_TOOL_PEM_OUT 288
+#define REDWAX_TOOL_PKCS12_OUT 289
+#define REDWAX_TOOL_PKCS11_OUT 290
+#define REDWAX_TOOL_PKCS11_MODULE_OUT 291
#define REDWAX_EXIT_OK 0
#define REDWAX_EXIT_INIT 1
@@ -166,6 +168,8 @@
#define REDWAX_EXIT_FILTER 3
#define REDWAX_PASSTHROUGH "passthrough"
+
+#define REDWAX_SECRET_MAX HUGE_STRING_LEN
static const apr_getopt_option_t
cmdline_opts[] =
@@ -180,6 +184,8 @@
" -t, --text\t\t\tInclude text in certificate output." },
{ "secret-suffix-in", REDWAX_TOOL_SECRET_SUFFIX_IN, 1, " --secret-suffix-in=suffix\tIf specified, secrets will be read from a file\n\t\t\t\twith the same name as the source file, and\n\t\t\t\tthe suffix specified. With value 'secret',\n\t\t\t\ta file 'key.pem' will have the secret loaded\n\t\t\t\tfrom 'key.secret' in the same directory." },
{ "secret-suffix-out", REDWAX_TOOL_SECRET_SUFFIX_OUT, 1, " --secret-suffix-out=suffix\tIf specified, secrets will be read from a file\n\t\t\t\twith the same name as the target file, and\n\t\t\t\tthe suffix specified. With value 'secret',\n\t\t\t\ta file 'key.pem' will have the secret loaded\n\t\t\t\tfrom 'key.secret' in the same directory." },
+ { "secret-token-in", REDWAX_TOOL_SECRET_TOKEN_IN, 1, " --secret-token-in=file\tIf specified, secrets needed to read\n\t\t\t\tcertificates and keys from tokens will be read\n\t\t\t\tfrom a file one secret per line. Each secret\n\t\t\t\tis preceded by the name of the token and a\n\t\t\t\tcolon, as per the NSS pwdfile.txt file." },
+ { "secret-token-out", REDWAX_TOOL_SECRET_TOKEN_OUT, 1, " --secret-token-out=file\tIf specified, secrets needed to write\n\t\t\t\tcertificates and keys to tokens (PKCS11 and\n\t\t\t\tNSS) will be read from a file one secret per\n\t\t\t\tline. Each secret is preceded by the name of\n\t\t\t\tthe token and a colon, as per the NSS\n\t\t\t\tpwdfile.txt file." },
{ "label-out", REDWAX_TOOL_LABEL_OUT, 1, " --label-out=label\t\tSet the name of the label to be applied to\n\t\t\t\tthe leaf certificates. If unspecified, the\n\t\t\t\tlabel is set to the subject of the certificate." },
{ "pem-in", REDWAX_TOOL_PEM_IN, 1, " --pem-in=wildcard\t\tRead pem files from here. Use '-' for stdin." },
{ "pkcs11-in", REDWAX_TOOL_PKCS11_IN, 1, " --pkcs11-in=url\t\tRead certificates, intermediate certificates,\n\t\t\t\troot certificates, crls, and keys from a PKCS11\n\t\t\t\ttoken identified by the given url." },
@@ -1027,6 +1033,98 @@
return NULL;
}
+apr_hash_t *redwax_secrets_path(redwax_tool_t *r, const char *secrets_path)
+{
+ if (secrets_path && secrets_path[0]) {
+
+ apr_file_t *sfile;
+ apr_status_t status;
+
+ apr_size_t max = REDWAX_SECRET_MAX;
+
+ apr_pool_t *pool;
+ apr_hash_t *hash;
+
+ apr_pool_create(&pool, r->pool);
+
+ hash = apr_hash_make(pool);
+
+ do {
+
+ char *buf;
+ char *lf;
+ char *cl;
+
+ if (!strcmp("-", secrets_path)) {
+ sfile = r->in;
+ }
+ else {
+ status = apr_file_open(&sfile, secrets_path, APR_FOPEN_READ,
+ APR_FPROT_OS_DEFAULT, pool);
+ if (APR_SUCCESS != status) {
+ break;
+ }
+ }
+
+ do {
+
+ buf = apr_pcalloc(pool, max);
+
+#if HAVE_APR_CRYPTO_CLEAR
+ apr_crypto_clear(pool, buf, max);
+#endif
+
+ status = apr_file_gets(buf, max - 1, sfile);
+
+ if (APR_EOF == status) {
+ break;
+ }
+ else if (APR_SUCCESS != status) {
+ redwax_print_error(r,
+ "Could not read '%s': %pm\n", secrets_path, &status);
+ apr_file_close(sfile);
+ apr_pool_destroy(pool);
+ return NULL;
+ }
+
+ /* string too long? */
+ if (strlen(buf) == max - 1) {
+ redwax_print_error(r,
+ "When reading '%s', line was too long (>%d)\n",
+ secrets_path, (int) (max - 1));
+ apr_file_close(sfile);
+ apr_pool_destroy(pool);
+ return NULL;
+ }
+
+ /* ignore comments */
+ if (buf[0] == '#') {
+ continue;
+ }
+
+ /* strip linefeed */
+ lf = strchr(buf, '\n');
+ if (lf) {
+ *lf = 0;
+ }
+
+ /* isolate the token */
+ cl = strchr(buf, ':');
+ if (cl) {
+ *cl = 0;
+ apr_hash_set(hash, buf, cl - buf, cl + 1);
+ }
+
+ } while (1);
+
+ } while (0);
+
+ return hash;
+ }
+
+ return NULL;
+}
+
apr_status_t redwax_complete_filter(redwax_tool_t *r, const char *arg,
redwax_token_quoted_e quoted)
{
@@ -1739,6 +1837,30 @@
return APR_SUCCESS;
}
+static apr_status_t redwax_set_secret_token_in(redwax_tool_t *r, const char *arg)
+{
+ if (arg && arg[0]) {
+ r->secret_token_in = arg;
+ }
+ else {
+ r->secret_token_in = NULL;
+ }
+
+ return APR_SUCCESS;
+}
+
+static apr_status_t redwax_set_secret_token_out(redwax_tool_t *r, const char *arg)
+{
+ if (arg && arg[0]) {
+ r->secret_token_out = arg;
+ }
+ else {
+ r->secret_token_out = NULL;
+ }
+
+ return APR_SUCCESS;
+}
+
static apr_status_t redwax_set_label_out(redwax_tool_t *r, const char *arg)
{
if (arg && arg[0]) {
@@ -1787,7 +1909,8 @@
static apr_status_t redwax_pkcs11_in(redwax_tool_t *r, const char *arg)
{
- apr_status_t status = rt_run_process_pkcs11_in(r, arg);
+ apr_status_t status = rt_run_process_pkcs11_in(r, arg,
+ redwax_secrets_path(r, r->secret_token_in));
apr_array_clear(r->pkcs11_in.pkcs11_modules);
@@ -1805,7 +1928,8 @@
static apr_status_t redwax_pkcs11_out(redwax_tool_t *r, const char *arg)
{
- apr_status_t status = rt_run_process_pkcs11_out(r, arg);
+ apr_status_t status = rt_run_process_pkcs11_out(r, arg,
+ redwax_secrets_path(r, r->secret_token_out));
apr_array_clear(r->pkcs11_out.pkcs11_modules);
@@ -1890,6 +2014,10 @@
redwax_set_secret_suffix_in(r, optarg);
break;
}
+ case REDWAX_TOOL_SECRET_TOKEN_IN: {
+ redwax_set_secret_token_in(r, optarg);
+ break;
+ }
case REDWAX_TOOL_PEM_IN: {
redwax_dir_walk(r, optarg, &rt_run_process_pem_in);
break;
@@ -2023,6 +2151,10 @@
}
case REDWAX_TOOL_SECRET_SUFFIX_OUT: {
redwax_set_secret_suffix_out(r, optarg);
+ break;
+ }
+ case REDWAX_TOOL_SECRET_TOKEN_OUT: {
+ redwax_set_secret_token_out(r, optarg);
break;
}
case REDWAX_TOOL_NSS_OUT: {
@@ -2126,6 +2258,10 @@
rt_run_complete_pkcs11_module_in(r, optarg, state.isquoted);
break;
}
+ case REDWAX_TOOL_SECRET_TOKEN_IN: {
+ redwax_complete_file(r, optarg, state.isquoted);
+ break;
+ }
case REDWAX_TOOL_FILTER: {
redwax_complete_filter(r, optarg, state.isquoted);
break;
@@ -2168,6 +2304,10 @@
}
case REDWAX_TOOL_PKCS11_MODULE_OUT: {
rt_run_complete_pkcs11_module_out(r, optarg, state.isquoted);
+ break;
+ }
+ case REDWAX_TOOL_SECRET_TOKEN_OUT: {
+ redwax_complete_file(r, optarg, state.isquoted);
break;
}
}
@@ -2190,6 +2330,10 @@
}
case REDWAX_TOOL_SECRET_SUFFIX_IN: {
redwax_set_secret_suffix_in(r, optarg);
+ break;
+ }
+ case REDWAX_TOOL_SECRET_TOKEN_IN: {
+ redwax_set_secret_token_in(r, optarg);
break;
}
case REDWAX_TOOL_PEM_IN: {
@@ -2298,6 +2442,10 @@
rt_run_complete_pkcs11_module_in(r, "", state.isquoted);
break;
}
+ case REDWAX_TOOL_SECRET_TOKEN_IN: {
+ redwax_complete_file(r, "", state.isquoted);
+ break;
+ }
case REDWAX_TOOL_FILTER: {
redwax_complete_filter(r, "", state.isquoted);
break;
@@ -2340,6 +2488,10 @@
}
case REDWAX_TOOL_PKCS11_MODULE_OUT: {
rt_run_complete_pkcs11_module_out(r, "", state.isquoted);
+ break;
+ }
+ case REDWAX_TOOL_SECRET_TOKEN_OUT: {
+ redwax_complete_file(r, "", state.isquoted);
break;
}
}
Modified: redwax-tool/trunk/redwax-tool.h
==============================================================================
--- redwax-tool/trunk/redwax-tool.h (original)
+++ redwax-tool/trunk/redwax-tool.h Sat Nov 20 10:48:45 2021
@@ -72,6 +72,8 @@
const char *verify_param;
const char *secret_suffix_in;
const char *secret_suffix_out;
+ const char *secret_token_in;
+ const char *secret_token_out;
const char *label_out;
redwax_nss_t nss_out;
redwax_pkcs11_t pkcs11_in;
@@ -339,7 +341,7 @@
* @param r The redwax-tool context.
*/
APR_DECLARE_EXTERNAL_HOOK(rt, REDWAX, apr_status_t, process_pkcs11_in,
- (redwax_tool_t *r, const char *arg));
+ (redwax_tool_t *r, const char *arg, apr_hash_t *secrets));
/**
* Hook to complete the module for the incoming PKCS11 URL.
@@ -423,7 +425,7 @@
* @param r The redwax-tool context.
*/
APR_DECLARE_EXTERNAL_HOOK(rt, REDWAX, apr_status_t, process_pkcs11_out,
- (redwax_tool_t *r, const char *arg));
+ (redwax_tool_t *r, const char *arg, apr_hash_t *secrets));
/**
* Hook to complete the module for the PKCS11 URL.
Modified: redwax-tool/trunk/redwax_p11kit.c
==============================================================================
--- redwax-tool/trunk/redwax_p11kit.c (original)
+++ redwax-tool/trunk/redwax_p11kit.c Sat Nov 20 10:48:45 2021
@@ -725,13 +725,12 @@
static apr_status_t redwax_p11kit_handle_token_login(redwax_tool_t *r,
apr_pool_t *pool, P11KitUri *parsed, CK_FUNCTION_LIST *module,
CK_TOKEN_INFO *tokenInfo, CK_SLOT_ID_PTR slot_id,
- CK_SESSION_HANDLE session, const char *direction)
+ CK_SESSION_HANDLE session, const char *direction, apr_hash_t *secrets)
{
redwax_pkcs11_session_t *s;
-// FIXME
-
const char *urlPIN = p11_kit_uri_get_pin_value(parsed);
+ const char *tokenPIN = NULL;
CK_UTF8CHAR *userPIN = NULL;
CK_RV ret;
apr_status_t status;
@@ -779,12 +778,15 @@
userPIN_len = strlen(urlPIN);
userPIN = apr_pmemdup(pool, urlPIN, userPIN_len);
+#if HAVE_APR_CRYPTO_CLEAR
+ apr_crypto_clear(pool, userPIN, userPIN_len);
+#endif
/* try once */
ret = module->C_Login(session, CKU_USER, userPIN, userPIN_len);
if (ret != CKR_OK) {
- redwax_print_error(r, "%s: login to '%s' with user PIN "
+ redwax_print_error(r, "%s: login to '%s' with URL PIN "
"failed, skipping: %s\n", direction,
redwax_pstrntrim(pool, (const char*) tokenInfo->label,
sizeof(tokenInfo->label)), pkcs11_errstr(ret));
@@ -796,9 +798,38 @@
}
/* otherwise see if there is a pinfile */
-#if 0
- // TODO - load the secret from a pinfile, compatible with 389ds.
-#endif
+ else if (secrets) {
+
+ /* if a pinfile exists, we try to log in to listed tokens, but we
+ * make no attempt to log in to anything not listed - the intention
+ * is we've been told explicitly which tokens to log in with, anything
+ * outside the list stays public.
+ */
+ if ((tokenPIN = apr_hash_get(secrets,
+ redwax_pstrntrim(pool, (const char*) tokenInfo->label,
+ sizeof(tokenInfo->label)), APR_HASH_KEY_STRING))) {
+
+ userPIN_len = strlen(tokenPIN);
+ userPIN = apr_pmemdup(pool, tokenPIN, userPIN_len);
+ #if HAVE_APR_CRYPTO_CLEAR
+ apr_crypto_clear(pool, userPIN, userPIN_len);
+ #endif
+
+ /* try once */
+ ret = module->C_Login(session, CKU_USER, userPIN, userPIN_len);
+ if (ret != CKR_OK) {
+
+ redwax_print_error(r, "%s: login to '%s' with token PIN "
+ "failed, skipping: %s\n", direction,
+ redwax_pstrntrim(pool, (const char*) tokenInfo->label,
+ sizeof(tokenInfo->label)), pkcs11_errstr(ret));
+
+ return APR_EGENERAL;
+
+ }
+
+ }
+ }
/* otherwise load from stdin */
else {
@@ -899,7 +930,7 @@
static apr_status_t redwax_p11kit_handle_slot_automatic(redwax_tool_t *r,
P11KitUri *parsed, CK_FUNCTION_LIST *module, CK_TOKEN_INFO *tokenInfo,
- CK_SLOT_ID_PTR slot_id)
+ CK_SLOT_ID_PTR slot_id, apr_hash_t *secrets)
{
return APR_ENOTIMPL;
@@ -907,7 +938,7 @@
static apr_status_t redwax_p11kit_handle_slot_manual(redwax_tool_t *r,
P11KitUri *parsed, CK_FUNCTION_LIST *module, CK_TOKEN_INFO *tokenInfo,
- CK_SLOT_ID_PTR slot_id)
+ CK_SLOT_ID_PTR slot_id, apr_hash_t *secrets)
{
apr_pool_t *pool;
CK_SESSION_HANDLE session;
@@ -944,7 +975,7 @@
apr_pool_cleanup_null);
status = redwax_p11kit_handle_token_login(r, pool, parsed,
- module, tokenInfo, slot_id, session, "pkcs11-out");
+ module, tokenInfo, slot_id, session, "pkcs11-out", secrets);
if (status != APR_SUCCESS) {
return status;
}
@@ -1061,7 +1092,7 @@
static apr_status_t redwax_p11kit_read_slot(redwax_tool_t *r,
P11KitUri *parsed, CK_FUNCTION_LIST *module, CK_TOKEN_INFO *tokenInfo,
- CK_SLOT_ID_PTR slot_id)
+ CK_SLOT_ID_PTR slot_id, apr_hash_t *secrets)
{
apr_pool_t *pool;
CK_SESSION_HANDLE session;
@@ -1101,7 +1132,7 @@
apr_status_t status;
status = redwax_p11kit_handle_token_login(r, pool, parsed,
- module, tokenInfo, slot_id, session, "pkcs11-in");
+ module, tokenInfo, slot_id, session, "pkcs11-in", secrets);
if (status != APR_SUCCESS) {
apr_pool_destroy(pool);
@@ -1440,8 +1471,8 @@
else {
redwax_print_error(r,
- "pkcs11-in: Object %d found on '%s', skipping\n",
- (int)clazz, redwax_pstrntrim(pool, (const char*) tokenInfo->label,
+ "pkcs11-in: Object %lu found on '%s', skipping\n",
+ clazz, redwax_pstrntrim(pool, (const char*) tokenInfo->label,
sizeof(tokenInfo->label)));
}
@@ -1459,7 +1490,7 @@
}
static apr_status_t redwax_p11kit_process_pkcs11_in(redwax_tool_t *r,
- const char *url)
+ const char *url, apr_hash_t *secrets)
{
apr_pool_t *pool;
P11KitUri *parsed;
@@ -1646,7 +1677,7 @@
}
status = redwax_p11kit_read_slot(r, parsed,
- modules[i], &tokenInfo, &pSlotList[j]);
+ modules[i], &tokenInfo, &pSlotList[j], secrets);
if (status != APR_SUCCESS) {
return status;
}
@@ -1664,7 +1695,7 @@
}
static apr_status_t redwax_p11kit_process_pkcs11_out(redwax_tool_t *r,
- const char *url)
+ const char *url, apr_hash_t *secrets)
{
apr_pool_t *pool;
P11KitUri *parsed;
@@ -1855,11 +1886,11 @@
/* automatic or manual? */
if (r->auto_out) {
status = redwax_p11kit_handle_slot_automatic(r, parsed,
- modules[i], &tokenInfo, &pSlotList[j]);
+ modules[i], &tokenInfo, &pSlotList[j], secrets);
}
else {
status = redwax_p11kit_handle_slot_manual(r, parsed,
- modules[i], &tokenInfo, &pSlotList[j]);
+ modules[i], &tokenInfo, &pSlotList[j], secrets);
}
if (status != APR_SUCCESS) {
return status;
More information about the rs-commit
mailing list