From f9b4cea9340ea2b6f0f2309886d305974720ae8c Mon Sep 17 00:00:00 2001 From: Egor Ignatov Date: Mon, 29 Jan 2024 15:42:32 +0300 Subject: [PATCH] efikeygen: handle tokens that do not support trust When generating keys on a token efikeygen fails with the following error: efikeygen.c:add_trust:104: could not set trust for certificate This happens because CERT_ChangeCertTrust tries to write trust to the actual token first and then to the internal token that is not authenticated yet. Fix this by authenticating internal token and trying again. --- src/efikeygen.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/efikeygen.c b/src/efikeygen.c index 74e6011..8d0bd06 100644 --- a/src/efikeygen.c +++ b/src/efikeygen.c @@ -102,10 +102,28 @@ add_trust(cms_context *cms, CERTIssuerAndSN *ias, cmsreterr(-1, cms, "Could not find certificate"); status = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, &trust); - if (status != SECSuccess) - cmsreterr(-1, cms, "could not set trust for certificate"); + if (status != SECSuccess) { + // Some tokens doesn't supprot trust so CERT_ChangeCertTrust writes + // it to the internal token. Authenticate internal token and retry. + PK11SlotInfo *internal_slot = PK11_GetInternalKeySlot(); + if (PK11_NeedLogin(internal_slot) && !PK11_IsLoggedIn(internal_slot, cms)) { + secuPWData pwdata; + memset(&pwdata, 0, sizeof(pwdata)); + pwdata.source = pwdata.orig_source = PW_PROMPT; + cms_set_pw_data(cms, &pwdata); + status = PK11_Authenticate(internal_slot, PR_TRUE, cms); + if (status != SECSuccess) { + CERT_DestroyCertificate(cert); + cmsreterr(-1, cms, "authentication failed for internal token"); + } + status = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, &trust); + } + } CERT_DestroyCertificate(cert); + if (status != SECSuccess) { + cmsreterr(-1, cms, "could not set trust for certificate"); + } return 0; }