Bug 161872 - regression: ODF X.509 signing doesn't work since libxmlsec 1.2.37 -> 1.3.1 (reason: LO >= 24.2 requires trusted CA)
Summary: regression: ODF X.509 signing doesn't work since libxmlsec 1.2.37 -> 1.3.1 (r...
Status: NEW
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: LibreOffice (show other bugs)
Version:
(earliest affected)
24.2.0.0 alpha1+
Hardware: All All
: medium normal
Assignee: Not Assigned
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: Digital-Signatures
  Show dependency treegraph
 
Reported: 2024-07-02 14:30 UTC by Moritz Duge (allotropia) (a.k.a. kolAflash)
Modified: 2024-08-11 05:58 UTC (History)
5 users (show)

See Also:
Crash report or crash signature:


Attachments
SAL_LOG="+INFO+WARN" output (254.16 KB, application/x-xz)
2024-07-10 09:39 UTC, Moritz Duge (allotropia) (a.k.a. kolAflash)
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Moritz Duge (allotropia) (a.k.a. kolAflash) 2024-07-02 14:30:54 UTC
Since this commit between 7.6 and 24.2.0.0.alpha1 I can't X.509 sign ODF files anymore.
(ODF signing! PDF signing is NOT affected)

https://git.libreoffice.org/core/+/bfd479abf0d1d8ce36c3b0dcc6c824216f88a95b%5E!/
Commit message:
> Update libxmlsec to 1.3.1
> This time try to do it in a way that doesn't re-introduce tdf#155034,
> i.e. patch out code that would use NSS symbols which are in the RHEL7
> baseline, but are not in Ubuntu 18.04. This is all code like RSA OAEP or
> AES GCM which is relatively new, so not really required for our
> signature needs.
> It also helps that this release has a lowered baseline for NSS.

Tested OS: Debian-12

In LO-7.6 X.509 ODF signing worked with currently valid X.509 certificates. Now in LO-24.2 I get this on STDERR:
warn:xmlsecurity.xmlsec:3979175:3979175:xmlsecurity/source/xmlsec/errorcallback.cxx:54: x509vfy.c:480: xmlSecNssX509StoreVerifyCert() '' '' 71 'subject="E=EMAIL@EXAMPLE.ORG,CN=FIRSTNAME LASTNAME"; reason=-8179'

Interestingly in LO-7.6 X.509 ODF signing with outdated X.509 certificates also worked. But with LO-24.2 I get this on STDERR:
warn:xmlsecurity.xmlsec:3976088:3976088:xmlsecurity/source/xmlsec/errorcallback.cxx:54: x509vfy.c:470: xmlSecNssX509StoreVerifyCert() '' '' 76 'subject="E=EMAIL@EXAMPLE.ORG,CN=FIRSTNAME LASTNAME"; reason=expired'

--

Bug moved out of this meta bug:

(OpenPGP) - [META] OpenPGP bugs and enhancements
Bug 158839 comment 1, section: X.509: ODF signing: X.509 signing doesn't work

Turns out this has probably nothing to do with GPG. So there's no further relation between bug 158839 and this bug.
Comment 1 Miklos Vajna 2024-07-08 06:49:52 UTC
> Interestingly in LO-7.6 X.509 ODF signing with outdated X.509 certificates also worked.

Hmm, this sounds like a good change, we should not allow signing with invalid certs, including expired ones, I would say. What do you think?

Related: did you see the xmlsecurity/qa/create-certs/create-certs.sh script that gives you a non-expired signing cert for testing purposes?
Comment 2 steve 2024-07-08 07:33:20 UTC
> We should not allow signing with invalid certs, including expired ones, I would say. What do you think?

💯
Comment 3 Moritz Duge (allotropia) (a.k.a. kolAflash) 2024-07-08 08:56:19 UTC
(In reply to Miklos Vajna from comment #1)
> > Interestingly in LO-7.6 X.509 ODF signing with outdated X.509 certificates also worked.
> 
> Hmm, this sounds like a good change, we should not allow signing with
> invalid certs, including expired ones, I would say. What do you think?

-> This bug is about the regression, that no more ODF signing is possible since LibreOffice-24.2 (libxmlsec-1.3.1).

The thing about the outdated cert was just a side note.
-> If you like to discuss this in depth please move it to a new ticket.
I would maybe warn the user that he's using an invalid cert, but not block the action. There's always a way to forcefully create a signature with an invalid cert (e.g. change system time for outdated certs). Checking the validity is the job of the software validating the signature, not the job of the software creating the signature!


> Related: did you see the xmlsecurity/qa/create-certs/create-certs.sh script
> that gives you a non-expired signing cert for testing purposes?

I've just tested that. Those certs also don't work with current LO master.

Before I've used a www.cacert.org cert for testing.
Comment 4 Miklos Vajna 2024-07-08 13:27:30 UTC
> I've just tested that. Those certs also don't work with current LO master.

I see. We need to track down what is the different in your master build vs my master build where it does work to run ./create-certs.sh, import the result to the Firefox profile, point LO to use it, then then I can just sign a new document with the just created X509 certificate.

My build uses --enable-dbgutil and --without-system-nss, so both xmlsec and nss are internal. Thanks.
Comment 5 Moritz Duge (allotropia) (a.k.a. kolAflash) 2024-07-08 18:22:19 UTC
(In reply to Miklos Vajna from comment #4)
> [...]
> My build uses --enable-dbgutil and --without-system-nss, so both xmlsec and
> nss are internal. Thanks.

I've bisected the problem using the builds from this binary repo.
https://bibisect.libreoffice.org/linux-64-24.2
First bad commit in that repo is: cfe7f35909ab57642b1ca64de1fbc033ce6c2a60

I've also reproduced the problem with my local master builds in the last weeks. And I'm also using --enable-dbgutil for those builds, but I have not used --without-system-nss and config.log says "checking which nss to use" -> "result: external".

So I just build with --enable-dbgutil and --without-system-nss. But X.509 ODF signing is still broken.

Then I installed the libxmlsec1-dev Debian-12 package which wasn't installed before (Debian-12 comes with libxmlsec1-1.2.37). And I rebuild using --with-system-nss and --with-system-xmlsec. And with that build X.509 ODF signing works. But I guess it's simply because Debian-12 ships libxmlsec version 1.2.37 instead of 1.3.1.


Interestingly signing and encrypting ODF with GPG seems to work always.

My system:
OS: Debian-12 (x86_64)
Mozilla profile is freshly created with Thunderbird 115.12.0 (64-Bit build Debian-12).
Comment 6 Miklos Vajna 2024-07-09 07:47:16 UTC
Aha, exciting. :-) So probably this will be a problem in upstream xmlsec, but most likely Aleksey don't want to build libreoffice to debug this, so we should make this as easy for him as possible.

It may make sense to file an issue at https://github.com/lsh123/xmlsec/ and point to this bug.

If signing fails, we should emit warnings in the dbgutil case on stderr.

Could you please check:

1) In XMLSignature_NssImpl::generate(), when we do the xmlSecDSigCtxSign() call that is the actual signing, do you get an error?

2) If you get an error, then ideally we get error details via the xmlsec log callback, can you check if errorCallback() gets called? If so, do we get any details there, why the signing fails?

3) Last idea: we have this own code at verifyCertificate(), there we emit lots of SAL_INFOs, can you check that finds no errors?

Thanks. FWIW I'm on openSUSE Leap 15.5, I guess there is some openSUSE vs Debian difference here that makes signing work here, but not there.
Comment 7 Moritz Duge (allotropia) (a.k.a. kolAflash) 2024-07-09 14:08:35 UTC
(In reply to Miklos Vajna from comment #6)
> [...]
> Could you please check:
> 
> 1) In XMLSignature_NssImpl::generate(), when we do the xmlSecDSigCtxSign()
> call that is the actual signing, do you get an error?
> 
> 2) If you get an error, then ideally we get error details via the xmlsec log
> callback, can you check if errorCallback() gets called? If so, do we get any
> details there, why the signing fails?

Indeed when XMLSignature_NssImpl::generate() calls xmlSecDSigCtxSign() the errorCallback() is being triggered. It outputs these lines to the shell:

  warn:xmlsecurity.xmlsec:394210:394210:xmlsecurity/source/xmlsec/errorcallback.cxx:54: x509vfy.c:480: xmlSecNssX509StoreVerifyCert() '' '' 71 'subject="E=MyName@my_domain.org,CN=My Name"; reason=-8179'
  warn:xmlsecurity.xmlsec:394210:394210:xmlsecurity/source/xmlsec/errorcallback.cxx:54: keys.c:1346: xmlSecKeysMngrGetKey() '' '' 45 'details=NULL'
  warn:xmlsecurity.xmlsec:394210:394210:xmlsecurity/source/xmlsec/errorcallback.cxx:54: xmldsig.c:822: xmlSecDSigCtxProcessKeyInfoNode() '' '' 45 'details=NULL'
  warn:xmlsecurity.xmlsec:394210:394210:xmlsecurity/source/xmlsec/errorcallback.cxx:54: xmldsig.c:537: xmlSecDSigCtxProcessSignatureNode() '' 'xmlSecDSigCtxProcessKeyInfoNode' 1 ' '
  warn:xmlsecurity.xmlsec:394210:394210:xmlsecurity/source/xmlsec/errorcallback.cxx:54: xmldsig.c:301: xmlSecDSigCtxSign() '' 'xmlSecDSigCtxProcessSignatureNode' 1 ' '

xmlSecDSigCtxSign() returns -1.



> Thanks. FWIW I'm on openSUSE Leap 15.5, I guess there is some openSUSE vs
> Debian difference here that makes signing work here, but not there.

I've ran the following build on an openSUSE-15.5 (LEAP) live system and got the same problem.
https://download.documentfoundation.org/libreoffice/stable/24.2.4/rpm/x86_64/LibreOffice_24.2.4_Linux_x86-64_rpm.tar.gz
Same with builds from the LO-24.2 bibisect repo on openSUSE-15.5.
Only the LibreOffice-24.2.4 build which comes with openSUSE-15.5 works, but I guess it's simply because it uses xmlsec-1.2.37 from openSUSE-15.5 instead of an internal xmlsec-1.3.x.
Used live image:
https://download.opensuse.org/distribution/leap/15.5/live/openSUSE-Leap-15.5-KDE-Live-x86_64-Build13.217-Media.iso

Linux distros shipping xmlsec >= 1.3 still seem to be very rare. Even openSUSE-Tumbleweed-20240705 currently remains on xmlsec-1.2.x.
But fortunately the current Manjaro-24.0.3 live image comes with xmlsec-1.3.4 and has LibreOffice-24.2.4:
https://download.manjaro.org/kde/24.0.3/manjaro-kde-24.0.3-minimal-240702-linux69.iso
Test result: ODF X.509 signing is broken on Manjaro 24.0.3 (240702), using Manjaros LibreOffice build.
Comment 8 Miklos Vajna 2024-07-10 06:49:09 UTC
Aha, that's interesting, thanks.

1) This doesn't seem to be a distro difference.

2) The signing fails in xmlSecNssX509StoreVerifyCert(), one could argue that this is a bug in xmlsec, given that we specify XMLSEC_KEYINFO_FLAGS_X509DATA_DONT_VERIFY_CERTS during signing. Do you want to take this to xmlsec upstream? The logs in this bug may be enough of a hint to show that cert verify happens in the no-verify case.

3) Do you understand why the cert verify fails in your case? When you import the result of create-certs.sh, do you perform the import correctly, as in you import both the CA chain & the signing cert? When you import the CA chain, do you mark it as trusted on the Firefox UI?

Probably either 2) and 3) resolves the problem, just at different levels.
Comment 9 Moritz Duge (allotropia) (a.k.a. kolAflash) 2024-07-10 09:39:26 UTC
Created attachment 195198 [details]
SAL_LOG="+INFO+WARN" output

(In reply to Miklos Vajna from comment #8)
> [...]
> 3) Do you understand why the cert verify fails in your case? When you import
> the result of create-certs.sh, do you perform the import correctly, as in
> you import both the CA chain & the signing cert? When you import the CA
> chain, do you mark it as trusted on the Firefox UI?

Nice guess! :-)

Indeed, when I mark the root and intermediate certificate from create-certs.sh as trusted in Thunderbird (for mail and websites) then ODF signing works.


OK I really didn't thought of that. I rarely use X.509 in Thunderbird. And when I do, I use a certificate from https://www.cacert.org/ whose X.509 CA isn't trusted by default in Mozilla software. But Thunderbird never needed me to mark the CACert CA as trusted. Signing and encrypting mails always worked fine without. And so did ODF signing in LibreOffice < 24.2.

Thunderbird doesn't make it very convenient to mark the X.509 CA of the users own certificate as trusted. At least I see no direct way from my own certificate in Thunderbird to the trust dialog for the CA. Instead I've had to lookup the CA name in my own certificate and then search trough the long list of CAs. 
Thunderbird also doesn't notify the user to trust the CA when importing an own certificate. And as said, Thunderbird itself doesn't require CA trust, so that's consistent inside Thunderbird.


Conclusion:

In LibreOffice 24.2 I can still sign PDF files with X.509 certificates without having the CA trusted. So that's an inconsistency.

And if ODF signing shall stay the way it's now, it should get a proper error dialog informing the user about the missing CA trust. And additionally it might be worth a thought, to look for a way to make it easier to mark the own certificates CA as trusted in Thunderbird/Firefox/Seamonkey.

Unfortunately I'm currently too busy to care further about this bug. Same goes for an upstream bug at xmlsec. This bug was more of a side discovery and I don't really use that feature. Sorry!
But I've still attached the requested SAL_INFOs, in case they are of any use.
Comment 10 Thorsten Behrens (allotropia) 2024-07-10 20:46:01 UTC
Ah, with the additional description, can confirm this new behaviour.
Comment 11 Miklos Vajna 2024-07-11 06:52:04 UTC
I researched this a bit, and it seems that you're right Moritz, it's not common to require that the CA is trusted at signature creation time. Could you please report this at xmlsec upstream? The ideal would be to get this fixed there and we just update xmlsec in LO.

Failing that, a compromise would be to get xmlsec to at least not do this in the XMLSEC_KEYINFO_FLAGS_X509DATA_DONT_VERIFY_CERTS case. The usage of that flag is discouraged by upstream (they say it should be a debug option in the long term and LO should not use it by default, but it's the behavior we inherited from OOo), but that would give us a way to have the behavior we want without changing default xmlsec behavior.

Thanks.
Comment 12 Moritz Duge (allotropia) (a.k.a. kolAflash) 2024-08-08 00:08:51 UTC
Just found something by the way:

On Windows the X.509 ODF signing may be completely broken. I imported a certificate into the Windows certmgr (mscrypt). And the CA is in the folder with trusted CAs in the Windows certmgr. But I can't sign an ODF with current LO master. I didn't do a bisect, but the latest 7.6 works fine.

warn:xmlsecurity.xmlsec:9484:10996:xmlsecurity/source/xmlsec/errorcallback.cxx:54: ..\src\mscng\x509vfy.c:421: xmlSecMSCngX509StoreVerifySubject() '' '' 71 'details=CertVerifySubjectCertificateContext: CERT_STORE_SIGNATURE_FLAG' Cannot find object or property.
warn:xmlsecurity.xmlsec:9484:10996:xmlsecurity/source/xmlsec/errorcallback.cxx:54: ..\src\mscng\x509vfy.c:476: xmlSecMSCngX509StoreContainsCert() '' '' 71 'details=xmlSecMSCngX509StoreVerifySubject' Cannot find object or property.
warn:xmlsecurity.xmlsec:9484:10996:xmlsecurity/source/xmlsec/errorcallback.cxx:54: ..\src\mscng\x509vfy.c:549: xmlSecMSCngX509StoreVerifyCertificateOwn() '' 'xmlSecMSCngX509StoreContainsCert' 1 ' ' Cannot find object or property.
warn:xmlsecurity.xmlsec:9484:10996:xmlsecurity/source/xmlsec/errorcallback.cxx:54: ..\src\mscng\x509vfy.c:797: xmlSecMSCngX509StoreVerifyCertificate() '' 'xmlSecMSCngX509StoreVerifyCertificateOwn' 1 ' ' Cannot find object or property.
warn:xmlsecurity.xmlsec:9484:10996:xmlsecurity/source/xmlsec/errorcallback.cxx:54: ..\src\mscng\x509vfy.c:931: xmlSecMSCngX509StoreVerify() 'x509-store' 'xmlSecMSCngX509StoreVerifyCertificate' 1 ' ' Cannot find object or property.
warn:xmlsecurity.xmlsec:9484:10996:xmlsecurity/source/xmlsec/errorcallback.cxx:54: ..\src\keys.c:1344: xmlSecKeysMngrGetKey() '' '' 45 'details=NULL' Cannot find object or property.
warn:xmlsecurity.xmlsec:9484:10996:xmlsecurity/source/xmlsec/errorcallback.cxx:54: ..\src\xmldsig.c:822: xmlSecDSigCtxProcessKeyInfoNode() '' '' 45 'details=NULL' Cannot find object or property.
warn:xmlsecurity.xmlsec:9484:10996:xmlsecurity/source/xmlsec/errorcallback.cxx:54: ..\src\xmldsig.c:537: xmlSecDSigCtxProcessSignatureNode() '' 'xmlSecDSigCtxProcessKeyInfoNode' 1 ' ' Cannot find object or property.
warn:xmlsecurity.xmlsec:9484:10996:xmlsecurity/source/xmlsec/errorcallback.cxx:54: ..\src\xmldsig.c:301: xmlSecDSigCtxSign() '' 'xmlSecDSigCtxProcessSignatureNode' 1 ' ' Cannot find object or property.