summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWojciech Dubowik <[email protected]>2026-02-20 10:15:11 +0100
committerSimon Glass <[email protected]>2026-03-18 06:14:17 -0600
commit0c716a157be460006a4b762625de329b5e36dbf9 (patch)
tree0fd9bfd4213ff35d31587d6b83e625ed8ff5d1c6
parent4d17632b9a2866695a312e049f94aa386145bafa (diff)
tools: mkeficapsule: Add support for pkcs11
With pkcs11 support it's now possible to specify 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 environment 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]> Reviewed-by: Ilias Apalodimas <[email protected]>
-rw-r--r--tools/mkeficapsule.c110
1 files changed, 84 insertions, 26 deletions
diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
index 0f41cdb64f5..a0ee76295a1 100644
--- a/tools/mkeficapsule.c
+++ b/tools/mkeficapsule.c
@@ -228,21 +228,54 @@ 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_cert = false;
+ bool pkcs11_key = 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:", strlen("pkcs11:")))
+ pkcs11_cert = 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;
+ if (!strncmp(ctx->key_file, "pkcs11:", strlen("pkcs11:")))
+ pkcs11_key = true;
+
+ if (pkcs11_cert || pkcs11_key) {
+ 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;
+ }
+ }
+
+ if (!pkcs11_cert) {
+ 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 (!pkcs11_key) {
+ 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,
@@ -265,22 +298,42 @@ static int create_auth_data(struct auth_context *ctx)
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;
+ /* load x509 certificate */
+ if (pkcs11_cert) {
+ 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;
+ }
+
+ gnutls_x509_crt_import_pkcs11(x509, obj_list[0]);
+ } else {
+ 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;
+ }
}
- /* 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;
+ /* load a private key */
+ if (pkcs11_key) {
+ 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 {
+ 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;
+ }
}
/* generate a PKCS #7 structure */
@@ -349,6 +402,11 @@ static int create_auth_data(struct auth_context *ctx)
* gnutls_free(signature.data);
*/
+ if (pkcs11_cert || pkcs11_key) {
+ gnutls_global_deinit();
+ gnutls_pkcs11_deinit();
+ }
+
return 0;
}