[rs-commit] r95 - in /redwax-tool/trunk: redwax-tool.c redwax-tool.h redwax_p11kit.c
rs-commit at redwax.eu
rs-commit at redwax.eu
Mon Nov 29 19:00:18 CET 2021
Author: minfrin at redwax.eu
Date: Mon Nov 29 19:00:17 2021
New Revision: 95
Log:
Enable the --auto-out option, providing sensible behaviour
where keys and certificates already exist.
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 Mon Nov 29 19:00:17 2021
@@ -248,12 +248,10 @@
" --key-out\t\t\tInclude keys in the output." },
{ "no-key-out", REDWAX_TOOL_NO_KEY_OUT, 0,
" --no-key-out\t\t\tExclude keys from the output." },
-#if 0
{ "auto-out", REDWAX_TOOL_AUTO_OUT, 0,
- " --auto-out\t\t\tOutput selectively. If a key already exists in a\n\t\t\t\ttoken, skip the key. Write leaf certificates where\n\t\t\t\tthe corresponding key is already present. Write\n\t\t\t\tintermediate and root certificates where a\n\t\t\t\tcorresponding leaf or intermediate certificate is\n\t\t\t\talready present." },
+ " --auto-out\t\t\tOutput selectively. If a key or a certificate already\n\t\t\t\texists in a PKCS11 token, skip writing the key or\n\t\t\t\tcertificate. A key is considered to already exist if\n\t\t\t\tthe Subject Key Info of the incoming key matches the\n\t\t\t\tSubject Key Info field of an existing key on the\n\t\t\t\ttoken. A certificate is considered to already exist\n\t\t\t\tif another certificate with the same value is present\n\t\t\t\ton the token. When adding a certificate, look up the\n\t\t\t\tID of any corresponding key and use that ID for the\n\t\t\t\tcertificate (unless an ID is explicitly specified in\n\t\t\t\ta target URL)." },
{ "no-auto-out", REDWAX_TOOL_NO_AUTO_OUT, 0,
" --no-auto-out\t\t\tOutput everything as specified." },
-#endif
{ "verify-parameters", REDWAX_TOOL_VERIFY_PARAM, 1,
" --verify-parameters=name\tSpecify the name of the set of parameters used\n\t\t\t\tfor verification. If unspecified, set to\n\t\t\t\t'default'." },
{ "nss-out", REDWAX_TOOL_NSS_OUT, 1, " --nss-out=directory\t\tWrite certificates, intermediate certificates,\n\t\t\t\troot certificates, crls, and keys to an NSS\n\t\t\t\tdatabase." },
Modified: redwax-tool/trunk/redwax-tool.h
==============================================================================
--- redwax-tool/trunk/redwax-tool.h (original)
+++ redwax-tool/trunk/redwax-tool.h Mon Nov 29 19:00:17 2021
@@ -134,6 +134,8 @@
apr_size_t subject_len;
const unsigned char *id_der;
apr_size_t id_len;
+ const unsigned char *kid_der;
+ apr_size_t kid_len;
const unsigned char *skid_der;
apr_size_t skid_len;
const unsigned char *gid_der;
@@ -185,6 +187,8 @@
redwax_key_type_e type;
const unsigned char *id_der;
apr_size_t id_len;
+ const unsigned char *kid_der;
+ apr_size_t kid_len;
const unsigned char *gid_der;
apr_size_t gid_len;
const unsigned char *subject_der;
Modified: redwax-tool/trunk/redwax_p11kit.c
==============================================================================
--- redwax-tool/trunk/redwax_p11kit.c (original)
+++ redwax-tool/trunk/redwax_p11kit.c Mon Nov 29 19:00:17 2021
@@ -433,6 +433,13 @@
if (attr) {
redwax_pkcs11_add_attribute(template, CKA_ID,
attr->pValue, attr->ulValueLen);
+// fixme add debug statements
+ }
+
+ /* otherwise use the ID that matches the key */
+ else if (x509->kid_len) {
+ redwax_pkcs11_add_attribute(template, CKA_ID,
+ (void *)x509->kid_der, x509->kid_len);
}
/* otherwise keep the original ID */
@@ -641,6 +648,12 @@
redwax_pkcs11_add_attribute(privateTemplate, CKA_ID,
attr->pValue, attr->ulValueLen);
}
+ else if (key->common.kid_len) {
+ redwax_pkcs11_add_attribute(publicTemplate, CKA_ID,
+ (void *)key->common.kid_der, key->common.kid_len);
+ redwax_pkcs11_add_attribute(privateTemplate, CKA_ID,
+ (void *)key->common.kid_der, key->common.kid_len);
+ }
else if (key->common.id_len) {
redwax_pkcs11_add_attribute(publicTemplate, CKA_ID,
(void *)key->common.id_der, key->common.id_len);
@@ -1027,15 +1040,157 @@
return APR_SUCCESS;
}
-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, apr_hash_t *secrets)
+static CK_RV redwax_p11kit_read_attributes(apr_pool_t *pool,
+ CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR template,
+ CK_ULONG template_len)
{
-
- return APR_ENOTIMPL;
+ CK_ULONG i;
+ int ret;
+
+ ret = module->C_GetAttributeValue(session, object,
+ template, template_len);
+ if (ret == CKR_OK || ret == CKR_ATTRIBUTE_SENSITIVE
+ || ret == CKR_ATTRIBUTE_TYPE_INVALID) {
+
+ for (i = 0; i < template_len; i++) {
+ if (CK_UNAVAILABLE_INFORMATION != template[i].ulValueLen) {
+ template[i].pValue = apr_palloc(pool, template[i].ulValueLen);
+ }
+ }
+
+ ret = module->C_GetAttributeValue(session,
+ object, &template[0], template_len);
+
+ }
+
+ return ret;
}
-static apr_status_t redwax_p11kit_handle_slot_manual(redwax_tool_t *r,
+static int redwax_pk11_key_exists(redwax_tool_t *r, CK_FUNCTION_LIST *module,
+ CK_SESSION_HANDLE session, const unsigned char *subjectpublickeyinfo_der,
+ apr_size_t subjectpublickeyinfo_len, const unsigned char **id_der,
+ apr_size_t *id_len, apr_pool_t *pool)
+{
+ int ret;
+
+ /*
+ * For each key, check if the key already exists at the target
+ * location.
+ *
+ * If the key exists, read the ID off the card. We will use the
+ * existing ID for any matching certificates.
+ */
+ CK_OBJECT_CLASS clazz = CKO_PRIVATE_KEY;
+
+ CK_ATTRIBUTE template[] = {
+ { CKA_CLASS, &clazz, sizeof(clazz) },
+ { CKA_PUBLIC_KEY_INFO,
+ (void*) subjectpublickeyinfo_der,
+ subjectpublickeyinfo_len
+ }
+ };
+
+ int template_len = 2;
+
+ ret = module->C_FindObjectsInit(session, template, template_len);
+ if (ret == CKR_OK) {
+
+ CK_OBJECT_HANDLE object;
+ CK_ULONG object_count;
+
+ CK_ATTRIBUTE id_template[] = {
+ {CKA_ID, NULL_PTR, 0}
+ };
+
+ int id_template_len = 1;
+
+ ret = module->C_FindObjects(session, &object, 1,
+ &object_count);
+ if (ret == CKR_OK && object_count == 1) {
+
+ ret = redwax_p11kit_read_attributes(pool, module, session, object,
+ id_template, id_template_len);
+ if (ret == CKR_OK) {
+
+ /* overwrite our ID (if present) with the ID already present */
+ *id_der = id_template[0].pValue;
+ *id_len = id_template[0].ulValueLen;
+
+ }
+
+ module->C_FindObjectsFinal (session);
+
+ return 1;
+ }
+
+ module->C_FindObjectsFinal (session);
+ }
+
+ return 0;
+}
+
+static int redwax_pk11_cert_exists(redwax_tool_t *r, CK_FUNCTION_LIST *module,
+ CK_SESSION_HANDLE session, const unsigned char *der,
+ apr_size_t len, const unsigned char **id_der,
+ apr_size_t *id_len, apr_pool_t *pool)
+{
+ int ret;
+
+ /*
+ * For each certificate, check if the certificate already exists at the target
+ * location.
+ *
+ * If the certificate exists, read the ID off the card. We will use the
+ * existing ID for any matching certificates.
+ */
+ CK_OBJECT_CLASS clazz = CKO_CERTIFICATE;
+
+ CK_ATTRIBUTE template[] = {
+ { CKA_CLASS, &clazz, sizeof(clazz) },
+ { CKA_VALUE, (void*) der, len }
+ };
+
+ int template_len = 2;
+
+ ret = module->C_FindObjectsInit(session, template, template_len);
+ if (ret == CKR_OK) {
+
+ CK_OBJECT_HANDLE object;
+ CK_ULONG object_count;
+
+ CK_ATTRIBUTE id_template[] = {
+ {CKA_ID, NULL_PTR, 0}
+ };
+
+ int id_template_len = 1;
+
+ ret = module->C_FindObjects(session, &object, 1,
+ &object_count);
+ if (ret == CKR_OK && object_count == 1) {
+
+ ret = redwax_p11kit_read_attributes(pool, module, session, object,
+ id_template, id_template_len);
+ if (ret == CKR_OK) {
+
+ /* overwrite our ID (if present) with the ID already present */
+ *id_der = id_template[0].pValue;
+ *id_len = id_template[0].ulValueLen;
+
+ }
+
+ module->C_FindObjectsFinal (session);
+
+ return 1;
+ }
+
+ module->C_FindObjectsFinal (session);
+ }
+
+ return 0;
+}
+
+static apr_status_t redwax_p11kit_handle_slot(redwax_tool_t *r,
P11KitUri *parsed, CK_FUNCTION_LIST *module, CK_TOKEN_INFO *tokenInfo,
CK_SLOT_ID_PTR slot_id, apr_hash_t *secrets)
{
@@ -1086,8 +1241,23 @@
if (r->key_out) {
for (i = 0; i < r->keys_out->nelts; i++)
{
- const redwax_key_t
- *key = &APR_ARRAY_IDX(r->keys_out, i, const redwax_key_t);
+ redwax_key_t
+ *key = &APR_ARRAY_IDX(r->keys_out, i, redwax_key_t);
+
+ if (r->auto_out
+ && redwax_pk11_key_exists(r, module, session,
+ key->common.subjectpublickeyinfo_der,
+ key->common.subjectpublickeyinfo_len,
+ &key->common.kid_der, &key->common.kid_len, pool)) {
+
+ redwax_print_error(r,
+ "pkcs11-out: key with id '%s' already exists, skipping.\n",
+ redwax_pencode_base16_binary(pool, key->common.kid_der,
+ key->common.kid_len,
+ REDWAX_ENCODE_LOWER, NULL));
+
+ continue;
+ }
redwax_print_error(r, "pkcs11-out: key\n");
@@ -1109,6 +1279,29 @@
*cert = &APR_ARRAY_IDX(r->certs_out, i,
const redwax_certificate_t);
+ if (r->auto_out && cert->x509) {
+
+ const unsigned char *id_der = NULL;
+ apr_size_t id_len = 0;
+
+ redwax_pk11_key_exists(r, module, session,
+ cert->common.subjectpublickeyinfo_der,
+ cert->common.subjectpublickeyinfo_len,
+ &cert->x509->kid_der, &cert->x509->kid_len, cert->pool);
+
+ if (redwax_pk11_cert_exists(r, module, session, cert->der,
+ cert->len, &id_der, &id_len, pool)) {
+
+ redwax_print_error(r,
+ "pkcs11-out: certificate '%s' with id '%s' already exists, skipping.\n",
+ cert->common.subject,
+ redwax_pencode_base16_binary(pool, id_der, id_len,
+ REDWAX_ENCODE_LOWER, NULL));
+
+ continue;
+ }
+ }
+
redwax_print_error(r, "pkcs11-out: certificate: %s\n",
cert->common.subject);
@@ -1131,6 +1324,29 @@
*cert = &APR_ARRAY_IDX(r->intermediates_out, i,
const redwax_certificate_t);
+ if (r->auto_out && cert->x509) {
+
+ const unsigned char *id_der = NULL;
+ apr_size_t id_len = 0;
+
+ redwax_pk11_key_exists(r, module, session,
+ cert->common.subjectpublickeyinfo_der,
+ cert->common.subjectpublickeyinfo_len,
+ &cert->x509->kid_der, &cert->x509->kid_len, cert->pool);
+
+ if (redwax_pk11_cert_exists(r, module, session, cert->der,
+ cert->len, &id_der, &id_len, pool)) {
+
+ redwax_print_error(r,
+ "pkcs11-out: intermediate '%s' with id '%s' already exists, skipping.\n",
+ cert->common.subject,
+ redwax_pencode_base16_binary(pool, id_der, id_len,
+ REDWAX_ENCODE_LOWER, NULL));
+
+ continue;
+ }
+ }
+
redwax_print_error(r, "pkcs11-out: intermediate: %s\n",
cert->common.subject);
@@ -1149,6 +1365,29 @@
const redwax_certificate_t *cert =
&APR_ARRAY_IDX(r->trusted_out, i, const redwax_certificate_t);
+ if (r->auto_out && cert->x509) {
+
+ const unsigned char *id_der = NULL;
+ apr_size_t id_len = 0;
+
+ redwax_pk11_key_exists(r, module, session,
+ cert->common.subjectpublickeyinfo_der,
+ cert->common.subjectpublickeyinfo_len,
+ &cert->x509->kid_der, &cert->x509->kid_len, cert->pool);
+
+ if (redwax_pk11_cert_exists(r, module, session, cert->der,
+ cert->len, &id_der, &id_len, pool)) {
+
+ redwax_print_error(r,
+ "pkcs11-out: trusted '%s' with id '%s' already exists, skipping.\n",
+ cert->common.subject,
+ redwax_pencode_base16_binary(pool, id_der, id_len,
+ REDWAX_ENCODE_LOWER, NULL));
+
+ continue;
+ }
+ }
+
redwax_print_error(r, "pkcs11-out: trusted: %s\n",
cert->common.subject);
@@ -1164,33 +1403,6 @@
apr_pool_destroy(pool);
return APR_SUCCESS;
-}
-
-static CK_RV redwax_p11kit_read_attributes(apr_pool_t *pool,
- CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session,
- CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR template,
- CK_ULONG template_len)
-{
- CK_ULONG i;
- int ret;
-
- ret = module->C_GetAttributeValue(session, object,
- template, template_len);
- if (ret == CKR_OK || ret == CKR_ATTRIBUTE_SENSITIVE
- || ret == CKR_ATTRIBUTE_TYPE_INVALID) {
-
- for (i = 0; i < template_len; i++) {
- if (CK_UNAVAILABLE_INFORMATION != template[i].ulValueLen) {
- template[i].pValue = apr_palloc(pool, template[i].ulValueLen);
- }
- }
-
- ret = module->C_GetAttributeValue(session,
- object, &template[0], template_len);
-
- }
-
- return ret;
}
static const char *redwax_p11kit_origin(redwax_tool_t *r, apr_pool_t *pool,
@@ -1289,8 +1501,8 @@
"Identifier '%s' present, and is therefore unlikely to be found by "
"most software. Reading certificate anyway.\n",
cert->token,
- redwax_pstrntrim(pool, (const char*) x509->id_der,
- x509->id_len));
+ redwax_pencode_base16_binary(pool, x509->id_der,
+ x509->id_len, REDWAX_ENCODE_LOWER, NULL));
}
@@ -1304,10 +1516,10 @@
"Subject Key Identifier '%s', and is therefore unlikely to be found "
"by most software. Reading certificate anyway.\n",
cert->token,
- redwax_pstrntrim(pool, (const char*) x509->id_der,
- x509->id_len),
- redwax_pstrntrim(pool, (const char*) x509->skid_der,
- x509->skid_len));
+ redwax_pencode_base16_binary(pool, x509->id_der,
+ x509->id_len, REDWAX_ENCODE_LOWER, NULL),
+ redwax_pencode_base16_binary(pool, x509->skid_der,
+ x509->skid_len, REDWAX_ENCODE_LOWER, NULL));
}
@@ -2139,20 +2351,12 @@
}
- /* automatic or manual? */
- if (r->auto_out) {
- status = redwax_p11kit_handle_slot_automatic(r, parsed,
- modules[i], &tokenInfo, &pSlotList[j], secrets);
- }
- else {
- status = redwax_p11kit_handle_slot_manual(r, parsed,
- modules[i], &tokenInfo, &pSlotList[j], secrets);
- }
+ /* handle the slot */
+ status = redwax_p11kit_handle_slot(r, parsed,
+ modules[i], &tokenInfo, &pSlotList[j], secrets);
if (status != APR_SUCCESS) {
return status;
}
-
-
}
More information about the rs-commit
mailing list