From a9854f30e1825240edc839e5f508f9d189fb31af Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Thu, 28 Apr 2022 16:31:51 +0200 Subject: svl: fix testSignDocument_PEM_PDF with "dbm:" NSS DB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CentOS 7 system NSS defaults to legacy "dbm:" DB. test_desktop_lib.cxx:2943:Assertion Test name: DesktopLOKTest::testSignDocument_PEM_PDF assertion failed - Expression: bResult NSS_CMSSignerInfo_Sign() (called from NSS_CMSEncoder_Finish()) internally calls PK11_FindKeyByAnyCert() and that fails likely for same reasons as documented in previous commit. The workaround here is a bit more involved, it turns out there's another path with NSSCMSSignerID_SubjectKeyID where the caller can pass in a SECKEYPrivateKey, let's try to do that as a fallback if a manual call to find the key fails. Change-Id: I298ee72f178220bcf644093917dba8143b092c92 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133577 Tested-by: Jenkins Reviewed-by: Michael Stahl (cherry picked from commit 5592ee094ca9f09bfcc16537d931518d4e6b2231) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134291 Reviewed-by: Caolán McNamara --- svl/source/crypto/cryptosign.cxx | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/svl/source/crypto/cryptosign.cxx b/svl/source/crypto/cryptosign.cxx index 06080d221364..f19c4dfcd663 100644 --- a/svl/source/crypto/cryptosign.cxx +++ b/svl/source/crypto/cryptosign.cxx @@ -34,6 +34,8 @@ #if USE_CRYPTO_NSS // NSS headers for PDF signing #include +#include +#include #include #include #include @@ -635,7 +637,30 @@ NSSCMSMessage *CreateCMSMessage(const PRTime* time, return nullptr; } - *cms_signer = NSS_CMSSignerInfo_Create(result, cert, SEC_OID_SHA256); + // workaround: with legacy "dbm:", NSS can't find the private key - try out + // if it works, and fallback if it doesn't. + if (SECKEYPrivateKey * pPrivateKey = PK11_FindKeyByAnyCert(cert, nullptr)) + { + SECKEY_DestroyPrivateKey(pPrivateKey); + *cms_signer = NSS_CMSSignerInfo_Create(result, cert, SEC_OID_SHA256); + } + else + { + pPrivateKey = PK11_FindKeyByDERCert(cert->slot, cert, nullptr); + SECKEYPublicKey *const pPublicKey = CERT_ExtractPublicKey(cert); + if (pPublicKey && pPrivateKey) + { + *cms_signer = NSS_CMSSignerInfo_CreateWithSubjKeyID(result, &cert->subjectKeyID, pPublicKey, pPrivateKey, SEC_OID_SHA256); + SECKEY_DestroyPrivateKey(pPrivateKey); + SECKEY_DestroyPublicKey(pPublicKey); + if (*cms_signer) + { + // this is required in NSS_CMSSignerInfo_IncludeCerts() + // (and NSS_CMSSignerInfo_GetSigningCertificate() doesn't work) + (**cms_signer).cert = CERT_DupCertificate(cert); + } + } + } if (!*cms_signer) { SAL_WARN("svl.crypto", "NSS_CMSSignerInfo_Create failed"); -- cgit