summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2022-04-28 16:31:51 +0200
committerCaolán McNamara <caolanm@redhat.com>2022-05-14 16:28:32 +0200
commita9854f30e1825240edc839e5f508f9d189fb31af (patch)
tree995443654204e23fb6b0190b8f786489064da709
parentfae560a9348e43d4af55cce2e27586a5bcb170b8 (diff)
svl: fix testSignDocument_PEM_PDF with "dbm:" NSS DB
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 <michael.stahl@allotropia.de> (cherry picked from commit 5592ee094ca9f09bfcc16537d931518d4e6b2231) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134291 Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--svl/source/crypto/cryptosign.cxx27
1 files changed, 26 insertions, 1 deletions
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 <cert.h>
+#include <keyhi.h>
+#include <pk11pub.h>
#include <hasht.h>
#include <secerr.h>
#include <sechash.h>
@@ -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");