Repository navigation
Open
Labels
Milestone
Description
Description
If we build the chain for the expired self-issued certificate (add it to trusted store before it expires) by setting the policy as following:
ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreNotTimeValid;
ChainPolicy.RevocationMode = X509RevocationMode.Online;
ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
ChainPolicy.VerificationTime = DateTime.Now;
The chain build on Linux is different from other platforms:
Chain status: "NotTimeValid,RevocationStatusUnknown,UntrustedRoot"
While on Windows the chain build is successful.
But if we build the chain for the expired leaf certificate issued by intermediate CA by using the same policy setting,
the chain build is successful for both Linux and Windows.
Configuration
- Which version of .NET is the code running on?
.NET 5 - What OS and version, and what distro if applicable?
Linux, Ubuntu 18.08
Regression?
I'm not sure
Other information
Repro steps:
- On Windows,
git clone https://github.com/NuGet/Entropy.git - On Windows, type "powershell" and
cd <path_to_Entropy>\ TestCertGenerator. - On Windows,create a new test certificate:
.\CreateTestCertificate.ps1 -AddAsTrustedRootAuthority -NotAfter "<10 minutes in the future from current local time>" -GenerateCerFile - Copy the .cer file(is generated in step 3) from the above Windows machine to Linux machine. (before the certificate expires)
- On Linux, change the .cer to .crt format: (before the certificate expires)
openssl x509 -inform DER -in <.cer file path> -out <.crt file path> - On Linux, add the certificate(.crt) to trusted store: (before the certificate expires)
cd /usr/local/share/ca-certificates/
sudo cp <.crt file path> ./
sudo chmod 644 ./<.crt file name>
sudo update-ca-certificates
- On Linux, run chain build with following settings on policy
ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreNotTimeValid;
ChainPolicy.RevocationMode = X509RevocationMode.Online;
ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
ChainPolicy.VerificationTime = DateTime.Now;
- The chain status is: "NotTimeValid,RevocationStatusUnknown,UntrustedRoot" on Linux but good on Windows.
If we change it into an expired leaf cert issued by intermediate CA, the chain build result will be good.
Attached are the certs from leaf to root:
certifaicates.zip
Reacted by Victor Irzak
Activity
vcsjones commentedon Feb 26, 2021
The issue seems to be
UntrustedRootI saw this step here:But given that it's reporting
UntrustedRoot, that is likely why the chain is not building.As for
NotTimeValid, note that even ifBuildreturnstrue, but you used verification flags to suppress an error, it will still be reported in the chain element status. I noticed this in #38005 (comment) and that seems to be "working as expected".heng-liu commentedon Feb 26, 2021
On Linux:
For expired leaf certificate issued by intermediate CA, the chain building is successful.
For expired self-issued certificate,
before it expires, the chain status is "RevocationStatusUnknown"
after it expires, the chain status is "NotTimeValid,RevocationStatusUnknown,UntrustedRoot"
bartonjs commentedon Jul 3, 2021
Seems like we're treating the (about to be ignored) NotTimeValid as a reason to not do revocation processing, but that Windows' logic doesn't quite match there.
There's probably room for improvement, but I don't think there's a compelling scenario to drive this for 6.0.
jherby2k commentedon Dec 18, 2021
Is this why i'm throwing exceptions when I try to "nuget sign" with a self-signed PFX on Linux? Works on Windows and Mac just fine. Tried doing
nuget config -set signaturevalidationmode=acceptbut it made no difference.If so, any suggested workaround? Other than copying the files over to Windows I mean :) Trying to do this via CI.
virzak commentedon Mar 7, 2023
This would be an awesome fix for .net 8, since it allows library maintainers to sign their packages on
ubuntu-latestwhich is much faster thanwindows-latestAdd regression test for expired self-signed trusted chain (dotnet#48794)
Add regression test for expired self-signed trusted chain (dotnet#48794)
virzak commentedon Jul 26, 2026
This appears to have been fixed some time ago. The spurious
RevocationStatusUnknownandUntrustedRootflags for an expired, trusted self-issued certificate were addressed by 8b42dff ("Fix revocation processing on expired chains", #66968), which first shipped in .NET 7.0.0 (it was not backported to 5.0/6.0).I reproduced the original scenario faithfully on Linux — an already-expired self-signed CA cert trusted via the OpenSSL system store (
SSL_CERT_DIR, i.e. default trust, noCustomRootTrust), built with the exact policy from the report:Results on current runtimes:
Build()falseNotTimeValid, RevocationStatusUnknown, UntrustedRoottrueNotTimeValidtrueNotTimeValidOn .NET 7+ the build succeeds with
NotTimeValid(the ignored condition) as the only reported status, matching Windows/macOS.Since no product code needed to change, I opened #131398 to add a regression test locking in this behavior so it can't silently regress. This issue looks safe to close as already-fixed.