natemcmaster/LettuceEncrypt

Can not find issuer for staging server

Tvde1 opened this issue · 17 comments

Tvde1 commented

Describe the bug
A clear and concise description of what the bug is.

When setting "UseStagingServer": true, the following output is given when my server runs:

fail: LettuceEncrypt.Internal.AcmeCertificateLoader[0]
      Failed to automatically create a certificate for [url removed]
      Certes.AcmeException: Can not find issuer 'C=US,O=(STAGING) Internet Security Research Group,CN=(STAGING) Pretend Pear X1' for certificate 'C=US,O=(STAGING) Internet Security Research Group,CN=(STAGING) Bogus Broccoli X2'.
         at Certes.Pkcs.CertificateStore.GetIssuers(Byte[] der)
         at Certes.Pkcs.PfxBuilder.FindIssuers()
         at Certes.Pkcs.PfxBuilder.Build(String friendlyName, String password)
         at LettuceEncrypt.Internal.CertificateFactory.CompleteCertificateRequestAsync(IOrderContext order, CancellationToken cancellationToken)
         at LettuceEncrypt.Internal.CertificateFactory.CreateCertificateAsync(CancellationToken cancellationToken)
         at LettuceEncrypt.Internal.AcmeCertificateLoader.CreateCertificateAsync(String[] domainNames, CancellationToken cancellationToken)
fail: LettuceEncrypt.Internal.AcmeCertificateLoader[0]
      Failed to create certificate
      Certes.AcmeException: Can not find issuer 'C=US,O=(STAGING) Internet Security Research Group,CN=(STAGING) Pretend Pear X1' for certificate 'C=US,O=(STAGING) Internet Security Research Group,CN=(STAGING) Bogus Broccoli X2'.
         at Certes.Pkcs.CertificateStore.GetIssuers(Byte[] der)
         at Certes.Pkcs.PfxBuilder.FindIssuers()
         at Certes.Pkcs.PfxBuilder.Build(String friendlyName, String password)
         at LettuceEncrypt.Internal.CertificateFactory.CompleteCertificateRequestAsync(IOrderContext order, CancellationToken cancellationToken)
         at LettuceEncrypt.Internal.CertificateFactory.CreateCertificateAsync(CancellationToken cancellationToken)
         at LettuceEncrypt.Internal.AcmeCertificateLoader.CreateCertificateAsync(String[] domainNames, CancellationToken cancellationToken)
         at LettuceEncrypt.Internal.AcmeCertificateLoader.LoadCerts(CancellationToken cancellationToken)
         at LettuceEncrypt.Internal.AcmeCertificateLoader.<>c__DisplayClass15_0.<<ExecuteAsync>b__0>d.MoveNext()
Failed to automatically create a certificate for [url removed]
      Certes.AcmeException: Can not find issuer 'C=US,O=(STAGING) Internet Security Research Group,CN=(STAGING) Pretend Pear X1' for certificate 'C=US,O=(STAGING) Internet Security Research Group,CN=(STAGING) Bogus Broccoli X2'.

To Reproduce
Steps to reproduce the behavior:

  1. Using this version of the library 'v1.0.1'
  2. Run this code '....'
  3. With these arguments '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

A staging cert will be generated

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context
Add any other context about the problem here.

Tvde1 commented

Apparently this is due to the fact that Let's Encrypt is changing their staging keys, and my server does not have their CE trusted (see https://letsencrypt.org/docs/staging-environment/#root-certificates).

I don't think this is something for this library to solve so feel free to close it if I am correct with this assumption.

If I remember right, I think @huesie ran into this issue as well, and solved it by forking this project and adding automatic fetching of the staging server CA certs. If this is a general problem for others, I'd be interested in taking a contribution to make it easier to solve.

MxFr commented

The root cause for this problem lies in the fact that Certes does not include the new staging keys in their set of embedded certificates.

I've tried to install the staging certificates to the current users certificate store for testing but that did not work. So I would be thankful for some pointers on how to mitigate this issue.

This issue has been automatically marked as stale because it has no recent activity. It will be closed if no further activity occurs. Please comment if you believe this should remain open, otherwise it will be closed in 14 days. Thank you for your contributions to this project.

Closing due to inactivity.
If you are looking at this issue in the future and think it should be reopened, please make a commented here and mention natemcmaster so he sees the notification.

I've just merged #279. Can you take a look at this and see if it solves your problem?

I've just merged #279. Can you take a look at this and see if it solves your problem?

It doesn't solve the issue. With the latest version (1.2.0), I get the same problem on my own end here.

You have to test against main, the NuGet is does not have the fix.

I'm seeing the same issue with the current beta version: 1.3.0-beta.249

@netclectic can you share the steps you are using so I can reproduce the problem?

@netclectic can you share the steps you are using so I can reproduce the problem?

I made a repo - https://github.com/netclectic/Blazor_LettuceEncrypt

Its using ngrok, so you will need to follow the integration test instructions and change the values in the appsettings.

https://github.com/natemcmaster/LettuceEncrypt/tree/main/test/Integration

I'm also seeing this same issue with 1.3.0-beta.249

Have you tried using the AdditionalIssuers option?

/// <summary>
/// Additional issuers passed to certes before building the successfully downloaded certificate,
/// used internally by certes to verify the issuer for authenticity.
/// <para>
/// This is useful especially when using a staging server (e.g. for integration tests) with a root certificate
/// that is not part of certes' embedded resources.
/// See https://github.com/fszlin/certes/tree/v3.0.0/src/Certes/Resources/Certificates for context.
/// </para>
/// </summary>
/// <remarks>
/// Lettuce encrypt uses certes internally, while certes depends on BouncyCastle.Cryptography to parse
/// certificates. See https://github.com/bcgit/bc-csharp/blob/830d9b8c7bdfcec511bff0a6cf4a0e8ed568e7c1/crypto/src/x509/X509CertificateParser.cs#L20
/// if you're wondering what certificate formats are supported.
/// </remarks>
public string[] AdditionalIssuers { get; set; } = Array.Empty<string>();

Mafii commented

@orkylish @netclectic alternatively you can use ICertificateAuthorityConfiguration's new property IssuerCertificates. Internally, it is passed into certes the same way the AdditionalIssuers are, as shown by nate. You will have to manually pass the staging root certificate (what certificate exactly can be learned here: https://letsencrypt.org/docs/staging-environment/). For example, just read the text and add it to the options (or the property). LettuceEncrypt does not automatically register a staging certificate when you set UseStagingServer to true - it has be done manually (unlike Certbot, when you pass --test-cert).

Everything else should be clear if you read the xml documentation of AdditionalIssuers that nate included in his comment! I can also help if needed, you can just reply to me, here.

This issue has been automatically marked as stale because it has no recent activity. It will be closed if no further activity occurs. Please comment if you believe this should remain open, otherwise it will be closed in 14 days. Thank you for your contributions to this project.

Closing due to inactivity.
If you are looking at this issue in the future and think it should be reopened, please make a commented here and mention natemcmaster so he sees the notification.