With pkcs11 support it's now possible to spefify keys
with URI format. To use this feature the filename must
begin "pkcs11:.." and have valid URI pointing to certificate
and private key in HSM.

The environemnt variable PKCS11_MODULE_PATH must point to the
right pkcs11 provider i.e. with softhsm:
export PKCS11_MODULE_PATH=<path>/libsofthsm2.so

Example command line:
tools/mkeficapsule --monotonic-count 1 \
 --private-key "pkcs11:token=EX;object=capsule;type=private;pin-source=pin.txt" 
\
 --certificate "pkcs11:token=EX;object=capsule;type=cert;pin-source=pin.txt" \
 --index 1 \
 --guid XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX \
 "capsule-payload" \
 "capsule.cap"

Signed-off-by: Wojciech Dubowik <[email protected]>
---
 tools/mkeficapsule.c | 102 +++++++++++++++++++++++++++++++------------
 1 file changed, 74 insertions(+), 28 deletions(-)

diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
index 0f41cdb64f54..c55d4f1000b3 100644
--- a/tools/mkeficapsule.c
+++ b/tools/mkeficapsule.c
@@ -228,21 +228,46 @@ static int create_auth_data(struct auth_context *ctx)
        gnutls_pkcs7_t pkcs7;
        gnutls_datum_t data;
        gnutls_datum_t signature;
+       gnutls_pkcs11_obj_t *obj_list;
+       unsigned int obj_list_size = 0;
+       const char *lib;
        int ret;
+       bool pkcs11 = false;
 
-       ret = read_bin_file(ctx->cert_file, &cert.data, &file_size);
-       if (ret < 0)
-               return -1;
-       if (file_size > UINT_MAX)
-               return -1;
-       cert.size = file_size;
+       if (!strncmp(ctx->cert_file, "pkcs11:", 7) &&
+           !strncmp(ctx->key_file, "pkcs11:", 7)) {
+               pkcs11 = true;
 
-       ret = read_bin_file(ctx->key_file, &key.data, &file_size);
-       if (ret < 0)
-               return -1;
-       if (file_size > UINT_MAX)
-               return -1;
-       key.size = file_size;
+               lib = getenv("PKCS11_MODULE_PATH");
+               if (!lib) {
+                       fprintf(stdout,
+                               "PKCS11_MODULE_PATH not set in the 
environment\n");
+                       return -1;
+               }
+
+               gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
+               gnutls_global_init();
+
+               ret = gnutls_pkcs11_add_provider(lib, "trusted");
+               if (ret < 0) {
+                       fprintf(stdout, "Failed to add pkcs11 provider\n");
+                       return -1;
+               }
+       } else {
+               ret = read_bin_file(ctx->cert_file, &cert.data, &file_size);
+               if (ret < 0)
+                       return -1;
+               if (file_size > UINT_MAX)
+                       return -1;
+               cert.size = file_size;
+
+               ret = read_bin_file(ctx->key_file, &key.data, &file_size);
+               if (ret < 0)
+                       return -1;
+               if (file_size > UINT_MAX)
+                       return -1;
+               key.size = file_size;
+       }
 
        /*
         * For debugging,
@@ -264,25 +289,41 @@ static int create_auth_data(struct auth_context *ctx)
                        gnutls_strerror(ret));
                return -1;
        }
+       if (pkcs11) {
+               ret = gnutls_pkcs11_obj_list_import_url4(&obj_list, 
&obj_list_size,
+                                                        ctx->cert_file, 0);
+               if (ret < 0 || obj_list_size == 0) {
+                       fprintf(stdout, "Failed to import crt_file URI 
objects\n");
+                       return -1;
+               }
 
-       /* load a private key */
-       ret = gnutls_privkey_import_x509_raw(pkey, &key, GNUTLS_X509_FMT_PEM,
-                                            0, 0);
-       if (ret < 0) {
-               fprintf(stderr,
-                       "error in gnutls_privkey_import_x509_raw(): %s\n",
-                       gnutls_strerror(ret));
-               return -1;
-       }
+               gnutls_x509_crt_import_pkcs11(x509, obj_list[0]);
 
-       /* load x509 certificate */
-       ret = gnutls_x509_crt_import(x509, &cert, GNUTLS_X509_FMT_PEM);
-       if (ret < 0) {
-               fprintf(stderr, "error in gnutls_x509_crt_import(): %s\n",
-                       gnutls_strerror(ret));
-               return -1;
-       }
+               ret = gnutls_privkey_import_pkcs11_url(pkey, ctx->key_file);
+               if (ret < 0) {
+                       fprintf(stderr, "error in %d: %s\n", __LINE__,
+                               gnutls_strerror(ret));
+                       return -1;
+               }
+       } else {
+               /* load a private key */
+               ret = gnutls_privkey_import_x509_raw(pkey, &key, 
GNUTLS_X509_FMT_PEM,
+                                                    0, 0);
+               if (ret < 0) {
+                       fprintf(stderr,
+                               "error in gnutls_privkey_import_x509_raw(): 
%s\n",
+                               gnutls_strerror(ret));
+                       return -1;
+               }
 
+               /* load x509 certificate */
+               ret = gnutls_x509_crt_import(x509, &cert, GNUTLS_X509_FMT_PEM);
+               if (ret < 0) {
+                       fprintf(stderr, "error in gnutls_x509_crt_import(): 
%s\n",
+                               gnutls_strerror(ret));
+                       return -1;
+               }
+       }
        /* generate a PKCS #7 structure */
        ret = gnutls_pkcs7_init(&pkcs7);
        if (ret < 0) {
@@ -349,6 +390,11 @@ static int create_auth_data(struct auth_context *ctx)
         *   gnutls_free(signature.data);
         */
 
+       if (pkcs11) {
+               gnutls_global_deinit();
+               gnutls_pkcs11_deinit();
+       }
+
        return 0;
 }
 
-- 
2.47.3

Reply via email to