[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