Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expired self-issued certificate has different chain building status on Linux #48794

Open
Tracked by #64488
heng-liu opened this issue Feb 26, 2021 · 6 comments
Open
Tracked by #64488

Comments

@heng-liu
Copy link

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:

  1. On Windows, git clone https://github.com/NuGet/Entropy.git
  2. On Windows, type "powershell" and cd <path_to_Entropy>\ TestCertGenerator.
  3. On Windows,create a new test certificate: .\CreateTestCertificate.ps1 -AddAsTrustedRootAuthority -NotAfter "<10 minutes in the future from current local time>" -GenerateCerFile
  4. Copy the .cer file(is generated in step 3) from the above Windows machine to Linux machine. (before the certificate expires)
  5. On Linux, change the .cer to .crt format: (before the certificate expires)
    openssl x509 -inform DER -in <.cer file path> -out <.crt file path>
  6. 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
  1. 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;
  1. 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

@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Security untriaged New issue has not been triaged by the area owner labels Feb 26, 2021
@ghost
Copy link

ghost commented Feb 26, 2021

Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq, @GrabYourPitchforks
See info in area-owners.md if you want to be subscribed.

Issue Details

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:

  1. On Windows, git clone https://github.com/NuGet/Entropy.git
  2. On Windows, type "powershell" and cd <path_to_Entropy>\ TestCertGenerator.
  3. On Windows,create a new test certificate: .\CreateTestCertificate.ps1 -AddAsTrustedRootAuthority -NotAfter "<10 minutes in the future from current local time>" -GenerateCerFile
  4. Copy the .cer file(is generated in step 3) from the above Windows machine to Linux machine. (before the certificate expires)
  5. On Linux, change the .cer to .crt format: (before the certificate expires)
    openssl x509 -inform DER -in <.cer file path> -out <.crt file path>
  6. 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
  1. 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;
  1. 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

Author: heng-liu
Assignees: -
Labels:

area-System.Security, untriaged

Milestone: -

@vcsjones
Copy link
Member

The issue seems to be UntrustedRoot I saw this step here:

On Linux, add the certificate(.crt) to trusted store

But given that it's reporting UntrustedRoot, that is likely why the chain is not building.

As for NotTimeValid, note that even if Build returns true, 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
Copy link
Author

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
Copy link
Member

bartonjs commented 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.

@bartonjs bartonjs removed the untriaged New issue has not been triaged by the area owner label Jul 3, 2021
@bartonjs bartonjs added this to the 7.0.0 milestone Jul 3, 2021
@jherby2k
Copy link

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=accept but it made no difference.

error: NU3018: PartialChain: unable to get local issuer certificate
error: NU3018: Certificate chain validation failed.

If so, any suggested workaround? Other than copying the files over to Windows I mean :) Trying to do this via CI.

@virzak
Copy link
Contributor

virzak commented Mar 7, 2023

This would be an awesome fix for .net 8, since it allows library maintainers to sign their packages on ubuntu-latest which is much faster than windows-latest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants