[rt-commit] r122 - in /redwax-tool/trunk: ChangeLog redwax-tool.h redwax_openssl.c redwax_p11kit.c

rt-commit at redwax.eu rt-commit at redwax.eu
Fri Dec 10 00:20:05 CET 2021


Author: minfrin at redwax.eu
Date: Fri Dec 10 00:20:04 2021
New Revision: 122

Log:
Decide on and write the label on certificates and keys when 
writing to pkcs11.

Modified:
    redwax-tool/trunk/ChangeLog
    redwax-tool/trunk/redwax-tool.h
    redwax-tool/trunk/redwax_openssl.c
    redwax-tool/trunk/redwax_p11kit.c

Modified: redwax-tool/trunk/ChangeLog
==============================================================================
--- redwax-tool/trunk/ChangeLog	(original)
+++ redwax-tool/trunk/ChangeLog	Fri Dec 10 00:20:04 2021
@@ -1,5 +1,8 @@
 
 Changes with v0.9.1
+
+ *) Decide on and write the label on certificates and keys when
+    writing to pkcs11. [Graham Leggett]
 
  *) Check if certificates already exist before attempting write to
     NSS if --auto-out has been set. [Graham Leggett]

Modified: redwax-tool/trunk/redwax-tool.h
==============================================================================
--- redwax-tool/trunk/redwax-tool.h	(original)
+++ redwax-tool/trunk/redwax-tool.h	Fri Dec 10 00:20:04 2021
@@ -127,15 +127,24 @@
     const unsigned char *subjectpublickeyinfo_der;
     apr_size_t subjectpublickeyinfo_len;
     const char *subject;
+    /* LABEL generated from the CN of the certificate subject */
+    const char *glabel;
+    apr_size_t glabel_len;
+    /* LABEL synced from a key */
+    const unsigned char *klabel_der;
+    apr_size_t klabel_len;
 } redwax_certificate_common_t;
 
 typedef struct redwax_certificate_x509_t {
     const unsigned char *subject_der;
     apr_size_t subject_len;
+    /* ID synced from a key */
     const unsigned char *kid_der;
     apr_size_t kid_len;
+    /* ID from the certificate SubjectKeyIdentifier */
     const unsigned char *skid_der;
     apr_size_t skid_len;
+    /* ID generated from public key */
     const unsigned char *gid_der;
     apr_size_t gid_len;
     const unsigned char *issuer_der;
@@ -151,8 +160,10 @@
     const unsigned char *der;
     apr_size_t len;
     const char *origin;
+    /* ID from the input certificate */
     const unsigned char *id_der;
     apr_size_t id_len;
+    /* LABEL from the input certificate */
     const char *label;
     apr_size_t label_len;
     const char *token;
@@ -185,12 +196,18 @@
 
 typedef struct redwax_key_common_t {
     redwax_key_type_e type;
+    /* ID read from the input key */
     const unsigned char *id_der;
     apr_size_t id_len;
-    const unsigned char *kid_der;
-    apr_size_t kid_len;
+    /* ID read from a certificate */
+    const unsigned char *cid_der;
+    apr_size_t cid_len;
+    /* ID generated from the public key */
     const unsigned char *gid_der;
     apr_size_t gid_len;
+    /* label read from a certificate */
+    const unsigned char *clabel_der;
+    apr_size_t clabel_len;
     const unsigned char *subject_der;
     apr_size_t subject_len;
     const unsigned char *subjectpublickeyinfo_der;
@@ -223,6 +240,7 @@
     const unsigned char *der;
     apr_size_t len;
     const char *origin;
+    /* label read from the input key */
     const char *label;
     apr_size_t label_len;
     const char *token;

Modified: redwax-tool/trunk/redwax_openssl.c
==============================================================================
--- redwax-tool/trunk/redwax_openssl.c	(original)
+++ redwax-tool/trunk/redwax_openssl.c	Fri Dec 10 00:20:04 2021
@@ -4811,6 +4811,30 @@
 
             unsigned char *der;
 
+            int index = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
+            X509_NAME_ENTRY *cnEntry = X509_NAME_get_entry(name, index);
+
+            if (cnEntry) {
+
+                ASN1_STRING *cnASN1 = X509_NAME_ENTRY_get_data(cnEntry);
+
+                if (cnASN1) {
+
+                    unsigned char *astr;
+
+                    cert->common.glabel_len = ASN1_STRING_to_UTF8(&astr, cnASN1);
+                    if (astr) {
+
+                        cert->common.glabel = apr_pmemdup(cert->pool, astr,
+                                cert->common.glabel_len);
+
+                        apr_pool_cleanup_register(cert->pool, astr, cleanup_alloc,
+                                apr_pool_cleanup_null);
+                    }
+                }
+
+            }
+
             x509->subject_len = i2d_X509_NAME(name, NULL);
             x509->subject_der = der = apr_palloc(r->pool, x509->subject_len);
             i2d_X509_NAME(name, &der);

Modified: redwax-tool/trunk/redwax_p11kit.c
==============================================================================
--- redwax-tool/trunk/redwax_p11kit.c	(original)
+++ redwax-tool/trunk/redwax_p11kit.c	Fri Dec 10 00:20:04 2021
@@ -405,18 +405,31 @@
         redwax_pkcs11_add_attribute(template, CKA_TOKEN, (void *)&true,
                 sizeof(true));
 
+        /* LABEL comes first from the URL... */
         attr = p11_kit_uri_get_attribute(parsed, CKA_LABEL);
         if (attr) {
             redwax_pkcs11_add_attribute(template, CKA_LABEL,
                     attr->pValue, attr->ulValueLen);
         }
+        /* ...otherwise LABEL comes from command line... */
         else if (label) {
             redwax_pkcs11_add_attribute(template, CKA_LABEL,
                     (void *)label, strlen(label));
         }
+        /* ...otherwise LABEL comes from the matching key... */
+        else if (cert->common.klabel_der) {
+            redwax_pkcs11_add_attribute(template, CKA_LABEL,
+                    (void *)cert->common.klabel_der, cert->common.klabel_len);
+        }
+        /* ...otherwise LABEL comes from the original input key... */
         else if (cert->label) {
             redwax_pkcs11_add_attribute(template, CKA_LABEL,
                     (void *)cert->label, cert->label_len);
+        }
+        /* ...otherwise LABEL is generated from the CN of the subject */
+        else if (cert->common.glabel) {
+            redwax_pkcs11_add_attribute(template, CKA_LABEL,
+                    (void *)cert->common.glabel, cert->common.glabel_len);
         }
 
         /* CKA_CERTIFICATE_TYPE */
@@ -568,7 +581,8 @@
 
 static apr_status_t redwax_pkcs11_write_key(redwax_tool_t *r,
         P11KitUri *parsed, CK_FUNCTION_LIST *module, CK_TOKEN_INFO *tokenInfo,
-        CK_SESSION_HANDLE session, const redwax_key_t *key)
+        CK_SESSION_HANDLE session, const redwax_key_t *key,
+        const char *label)
 {
     CK_OBJECT_CLASS publicKeyClass = CKO_PUBLIC_KEY;
 
@@ -631,6 +645,7 @@
         redwax_pkcs11_add_attribute(privateTemplate, CKA_EXTRACTABLE, (void *)&true,
                 sizeof(true));
 
+        /* ID comes from the URL... */
         attr = p11_kit_uri_get_attribute(parsed, CKA_ID);
         if (attr) {
             redwax_pkcs11_add_attribute(publicTemplate, CKA_ID,
@@ -638,23 +653,56 @@
             redwax_pkcs11_add_attribute(privateTemplate, CKA_ID,
                     attr->pValue, attr->ulValueLen);
         }
-        else if (key->common.kid_len) {
+        /* ...otherwise ID comes from a matching certificate... */
+        else if (key->common.cid_len) {
             redwax_pkcs11_add_attribute(publicTemplate, CKA_ID,
-                    (void *)key->common.kid_der, key->common.kid_len);
+                    (void *)key->common.cid_der, key->common.cid_len);
             redwax_pkcs11_add_attribute(privateTemplate, CKA_ID,
-                    (void *)key->common.kid_der, key->common.kid_len);
-        }
+                    (void *)key->common.cid_der, key->common.cid_len);
+        }
+        /* ...otherwise ID comes from the input key... */
         else if (key->common.id_len) {
             redwax_pkcs11_add_attribute(publicTemplate, CKA_ID,
                     (void *)key->common.id_der, key->common.id_len);
             redwax_pkcs11_add_attribute(privateTemplate, CKA_ID,
                     (void *)key->common.id_der, key->common.id_len);
         }
+        /* ...failing all of that, ID is generated from public key */
         else if (key->common.gid_len) {
             redwax_pkcs11_add_attribute(publicTemplate, CKA_ID,
                     (void *)key->common.gid_der, key->common.gid_len);
             redwax_pkcs11_add_attribute(privateTemplate, CKA_ID,
                     (void *)key->common.gid_der, key->common.gid_len);
+        }
+
+        /* LABEL comes from the URL... */
+        attr = p11_kit_uri_get_attribute(parsed, CKA_LABEL);
+        if (attr) {
+            redwax_pkcs11_add_attribute(publicTemplate, CKA_LABEL,
+                    attr->pValue, attr->ulValueLen);
+            redwax_pkcs11_add_attribute(privateTemplate, CKA_LABEL,
+                    attr->pValue, attr->ulValueLen);
+        }
+        /* ...otherwise LABEL comes from the command line... */
+        else if (label) {
+            redwax_pkcs11_add_attribute(publicTemplate, CKA_LABEL,
+                    (void *)label, strlen(label));
+            redwax_pkcs11_add_attribute(privateTemplate, CKA_LABEL,
+                    (void *)label, strlen(label));
+        }
+        /* ...otherwise LABEL comes from a matching certificate... */
+        else if (key->common.clabel_len) {
+            redwax_pkcs11_add_attribute(publicTemplate, CKA_LABEL,
+                    (void *)key->common.clabel_der, key->common.clabel_len);
+            redwax_pkcs11_add_attribute(privateTemplate, CKA_LABEL,
+                    (void *)key->common.clabel_der, key->common.clabel_len);
+        }
+        /* ...otherwise LABEL comes from the input key. */
+        else if (key->label_len) {
+            redwax_pkcs11_add_attribute(publicTemplate, CKA_LABEL,
+                    (void *)key->label, key->label_len);
+            redwax_pkcs11_add_attribute(privateTemplate, CKA_LABEL,
+                    (void *)key->label, key->label_len);
         }
 
         if (key->common.subject_len) {
@@ -1081,7 +1129,8 @@
 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)
+        apr_size_t *id_len, const unsigned char **label_der,
+        apr_size_t *label_len, apr_pool_t *pool)
 {
     int ret;
 
@@ -1111,10 +1160,11 @@
         CK_ULONG object_count;
 
         CK_ATTRIBUTE id_template[] = {
-                {CKA_ID, NULL_PTR, 0}
+                {CKA_ID, NULL_PTR, 0},
+                {CKA_LABEL, NULL_PTR, 0}
         };
 
-        int id_template_len = 1;
+        int id_template_len = 2;
 
         ret = module->C_FindObjects(session, &object, 1,
                 &object_count);
@@ -1128,6 +1178,10 @@
                 *id_der = id_template[0].pValue;
                 *id_len = id_template[0].ulValueLen;
 
+                /* overwrite our label (if present) with the label already present */
+                *label_der = id_template[1].pValue;
+                *label_len = id_template[1].ulValueLen;
+
             }
 
             module->C_FindObjectsFinal (session);
@@ -1144,7 +1198,8 @@
 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)
+        apr_size_t *id_len, const unsigned char **label_der,
+        apr_size_t *label_len, apr_pool_t *pool)
 {
     int ret;
 
@@ -1171,10 +1226,11 @@
         CK_ULONG object_count;
 
         CK_ATTRIBUTE id_template[] = {
-                {CKA_ID, NULL_PTR, 0}
+                {CKA_ID, NULL_PTR, 0},
+                {CKA_LABEL, NULL_PTR, 0}
         };
 
-        int id_template_len = 1;
+        int id_template_len = 2;
 
         ret = module->C_FindObjects(session, &object, 1,
                 &object_count);
@@ -1187,6 +1243,10 @@
                 /* overwrite our ID (if present) with the ID already present */
                 *id_der = id_template[0].pValue;
                 *id_len = id_template[0].ulValueLen;
+
+                /* overwrite our label (if present) with the label already present */
+                *label_der = id_template[1].pValue;
+                *label_len = id_template[1].ulValueLen;
 
             }
 
@@ -1249,23 +1309,33 @@
         return status;
     }
 
+    label = r->label_out;
+
     if (r->key_out) {
         for (i = 0; i < r->keys_out->nelts; i++)
         {
             redwax_key_t
                 *key = &APR_ARRAY_IDX(r->keys_out, i, redwax_key_t);
 
+            const unsigned char *id_der = NULL;
+            apr_size_t id_len = 0;
+            const unsigned char *label_der = NULL;
+            apr_size_t label_len = 0;
+
             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)) {
+                            &id_der, &id_len,
+                            &label_der, &label_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));
+                        "pkcs11-out: key with id '%s' / label '%s' already exists, skipping.\n",
+                        redwax_pencode_base16_binary(pool, id_der,
+                                id_len,
+                                REDWAX_ENCODE_LOWER, NULL),
+                                redwax_pstrntrim(pool, (const char*) label_der,
+                                        label_len));
 
                 continue;
             }
@@ -1273,10 +1343,13 @@
             redwax_print_error(r, "pkcs11-out: key\n");
 
             status = redwax_pkcs11_write_key(r, parsed, module, tokenInfo,
-                    session, key);
+                    session, key, label);
             if (status != APR_SUCCESS) {
                 return status;
             }
+
+            /* we use the label once and once only */
+            label = NULL;
 
         }
     }
@@ -1286,28 +1359,33 @@
     if (r->cert_out) {
         for (i = 0; i < r->certs_out->nelts; i++)
         {
-            const redwax_certificate_t
+            redwax_certificate_t
                 *cert = &APR_ARRAY_IDX(r->certs_out, i,
-                        const redwax_certificate_t);
+                        redwax_certificate_t);
 
             if (r->auto_out && cert->x509) {
 
                 const unsigned char *id_der = NULL;
                 apr_size_t id_len = 0;
+                const unsigned char *label_der = NULL;
+                apr_size_t label_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);
+                        &cert->x509->kid_der, &cert->x509->kid_len,
+                        &cert->common.klabel_der, &cert->common.klabel_len,
+                        cert->pool);
 
                 if (redwax_pk11_cert_exists(r, module, session, cert->der,
-                        cert->len, &id_der, &id_len, pool)) {
+                        cert->len, &id_der, &id_len, &label_der, &label_len, pool)) {
 
                     redwax_print_error(r,
-                            "pkcs11-out: certificate '%s' with id '%s' already exists, skipping.\n",
+                            "pkcs11-out: certificate '%s' with id '%s' / label '%s' already exists, skipping.\n",
                             cert->common.subject,
                             redwax_pencode_base16_binary(pool, id_der, id_len,
-                            REDWAX_ENCODE_LOWER, NULL));
+                            REDWAX_ENCODE_LOWER, NULL),
+                            redwax_pstrntrim(pool, (const char*) label_der, label_len));
 
                     continue;
                 }
@@ -1331,28 +1409,33 @@
     if (r->chain_out) {
         for (i = 0; i < r->intermediates_out->nelts; i++)
         {
-            const redwax_certificate_t
+            redwax_certificate_t
                 *cert = &APR_ARRAY_IDX(r->intermediates_out, i,
-                        const redwax_certificate_t);
+                        redwax_certificate_t);
 
             if (r->auto_out && cert->x509) {
 
                 const unsigned char *id_der = NULL;
                 apr_size_t id_len = 0;
+                const unsigned char *label_der = NULL;
+                apr_size_t label_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);
+                        &cert->x509->kid_der, &cert->x509->kid_len,
+                        &cert->common.klabel_der, &cert->common.klabel_len,
+                        cert->pool);
 
                 if (redwax_pk11_cert_exists(r, module, session, cert->der,
-                        cert->len, &id_der, &id_len, pool)) {
+                        cert->len, &id_der, &id_len, &label_der, &label_len, pool)) {
 
                     redwax_print_error(r,
-                            "pkcs11-out: intermediate '%s' with id '%s' already exists, skipping.\n",
+                            "pkcs11-out: intermediate '%s' with id '%s' / label '%s' already exists, skipping.\n",
                             cert->common.subject,
                             redwax_pencode_base16_binary(pool, id_der, id_len,
-                            REDWAX_ENCODE_LOWER, NULL));
+                            REDWAX_ENCODE_LOWER, NULL),
+                            redwax_pstrntrim(pool, (const char*) label_der,    label_len));
 
                     continue;
                 }
@@ -1373,27 +1456,32 @@
     if (r->root_out || r->trust_out) {
         for (i = 0; i < r->trusted_out->nelts; i++)
         {
-            const redwax_certificate_t *cert =
-                    &APR_ARRAY_IDX(r->trusted_out, i, const redwax_certificate_t);
+            redwax_certificate_t *cert =
+                    &APR_ARRAY_IDX(r->trusted_out, i, redwax_certificate_t);
 
             if (r->auto_out && cert->x509) {
 
                 const unsigned char *id_der = NULL;
                 apr_size_t id_len = 0;
+                const unsigned char *label_der = NULL;
+                apr_size_t label_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);
+                        &cert->x509->kid_der, &cert->x509->kid_len,
+                        &cert->common.klabel_der, &cert->common.klabel_len,
+                        cert->pool);
 
                 if (redwax_pk11_cert_exists(r, module, session, cert->der,
-                        cert->len, &id_der, &id_len, pool)) {
+                        cert->len, &id_der, &id_len, &label_der, &label_len, pool)) {
 
                     redwax_print_error(r,
-                            "pkcs11-out: trusted '%s' with id '%s' already exists, skipping.\n",
+                            "pkcs11-out: trusted '%s' with id '%s' / label '%s' already exists, skipping.\n",
                             cert->common.subject,
                             redwax_pencode_base16_binary(pool, id_der, id_len,
-                            REDWAX_ENCODE_LOWER, NULL));
+                            REDWAX_ENCODE_LOWER, NULL),
+                            redwax_pstrntrim(pool, (const char*) label_der,    label_len));
 
                     continue;
                 }



More information about the rt-commit mailing list