Can not find issuer 'C=US,O=(STAGING) Internet Security Research Group,CN=(STAGING) Doctored Durian Root CA X3' for certificate 'C=US,O=(STAGING) Internet Security Research Group,CN=(STAGING) Pretend Pear X1'

I am about to create a new wildcard certificate by fszlin.certes(GitHub - fszlin/certes: A client implementation for the Automated Certificate Management Environment (ACME) protocol).

Here is my code:
var context = await Login();///code for login
var order = await context.NewOrder(new { ".aaa.com" });
var certKey = KeyFactory.NewKey(KeyAlgorithm.RS256);
var authz = (await order.Authorizations()).First();
var dnsChallenge = await authz.Dns();
var httpChallenge = await authz.Http();
var tlsAlpnChallenge = await authz.TlsAlpn();
var dnsTxt = context.AccountKey.DnsTxt(dnsChallenge.Token);
await AddDomainRecord(dnsTxt);///Add domain record
var challenges = await authz.Challenges();
var alpnCertKey = KeyFactory.NewKey(KeyAlgorithm.ES256);
var alpnCert = context.AccountKey.TlsAlpnCertificate(challenges.First().Token, "
.aaa.com", alpnCertKey);
var challenge=await challenges.First().Validate();
int tryCount = 1;
while (challenge.Status == ChallengeStatus.Pending && tryCount <= 10) {
tryCount++;
await Task.Delay(1000);
}
if (challenge.Status == ChallengeStatus.Valid)
{
Logger.LogInformation("Valided");
await order.Finalize(
new CsrInfo
{
CountryName = "CountryName",
State = "State",
Locality = "Locality",
Organization = "Organization",
}, certKey);
var certChain = await order.Download();
var privateKey = KeyFactory.NewKey(KeyAlgorithm.ES256);
var pfxBuilder = certChain?.ToPfx(privateKey);
var PemContent = await ReadCAPEM();//Read PEM from https://letsencrypt.org/certs/staging/letsencrypt-stg-root-x1-signed-by-dst.pem
PemContent = PemContent.Replace("-----BEGIN CERTIFICATE-----", "");
PemContent = PemContent.Replace("-----END CERTIFICATE-----", "");
PemContent = PemContent.Replace("\r\n", "");
PemContent = PemContent.Replace(" ", "");
Logger.LogInformation("PemContent:" + PemContent);
pfxBuilder.AddIssuer(Convert.FromBase64String(PemContent));
byte B = pfxBuilder.Build("*.aaa.com", "000000");
File.WriteAllText("Generated.pfx", System.Text.Encoding.UTF8.GetString(B));
Logger.LogInformation("Success!");
}
else {
Logger.LogError("Failed!");
}

The code above is running on asp.net core 5(IIS) and about to renew the certificate by hangfire of asp.net core with a schedule.

After the program ran, it reports this error:
Can not find issuer 'C=US,O=(STAGING) Internet Security Research Group,CN=(STAGING) Doctored Durian Root CA X3' for certificate 'C=US,O=(STAGING) Internet Security Research Group,CN=(STAGING) Pretend Pear X1'.
at Certes.Pkcs.CertificateStore.GetIssuers(Byte der)
at Certes.Pkcs.PfxBuilder.FindIssuers()
at Certes.Pkcs.PfxBuilder.Build(String friendlyName, String password)

What causes my problem? It seems I missed an issuer. How can I find an issuer? Thank you.

Certes builds the PFX chain using a combination of the issuer certs stored in the computer trust store and any embedded certs it has as resources. It does this because the underlying BounceCastle library implementation requires the issuer public certs.

To fix this you need to add the missing issuer cert to the pfx builder before you try to build the PFX using pfxBuilder.AddIssuers. In https://certifytheweb.com we do this for staging by allowing users to specify custom (untrusted by the OS) issuers so that the PFX will still build.

Note that although I have contributed to certes, it's not my project and the original author is no longer communicating. If building something new I would consider using GitHub - PKISharp/ACMESharpCore: An ACME v2 client library for .NET Standard (Let's Encrypt)

4 Likes

Thank you very much.

I have also now forked this project and published an updated NuGet package as Webprofusion.Certes - this includes things like preferred chain support and various other improvements:

GitHub - webprofusion/certes: A client implementation for the Automated Certificate Management Environment (ACME) protocol

1 Like

I tried Certify SSL Manager and it always can't get the DNS zone Id.

What's more, I tried to learn about the PKISharp and there is almost no tutorial about it.

Finally, I tried the fszlin.certes again by AddIssuer before building the PFX. However, I don't know how to get a Certificate to add.

It seems I have to face the Issuer problem even using Webprofusion.Certes.

Yes you certainly will have to provider the issuer yourself and you would also have to provide it as a custom CA cert for Certify The Web as well.

Regarding the issue with Certify The Web not loading your zoneid, it depends which DNS provider you are using but you can provide it manually if you know it (it's usually a number or the domain name). Which DNS provider are you using? I've only seens that before if you have many zones (like 100) and you hit an API results limit.

I continue trying by fszlin.certes.

Now I followed your suggestion by adding an issuer(crt.sh | 3958242236). The issuer is from Chain of Trust - Let's Encrypt - Free SSL/TLS Certificates

Whereas, after the program ran, it no longer report the previous error while a new one:
Certes.AcmeRequestException: Fail to load resource from 'https://acme-staging-v02.api.letsencrypt.org/acme/finalize/18424772/11733931'.
urn:ietf:params:acme:error:rejectedIdentifier: Error finalizing order :: Cannot issue for "dst root ca x3": Domain name contains an invalid character

I am not sure but I doubt that's because I used a wildcard domain(such as *.aaa.com).

What's wrong with this?

Can you say what your actual domain name is? It seems like you're at a different stage in the process now - you previously got a certificate but couldn't build the PFX, now you can't finalize your order (which is the step where you get ready to download your certficate, after validation but before building the PFX).

Did your domain change? Note that your certificate signing request must exactly match the domains you requested in your certificate order.

'domain name contains an invalid character' sounds pretty specific to me.

My domain name is sealintelligence.com. I have got a free SSL certificate from my server provider while it is not a wildcard certificate. My server provider won't give me the subdomain certificate unless I pay a large amount of money.

I used Win-Acme to create and renew the subdomain certificate before. However, I have to update the new certificate one by one to the CDN of the subdomain every month. It is so troublesome.

So I want to create a free wildcard certificate, renew them and update them to the CDN by asp.net core.

It sounds like it reports this error because my previous certificate exists, right?

I am very sorry for bothering you so much.

How do you update the CDN, is there any API you could access from powershell or node etc? You can make that a (powershell script) deployment task in Certify The Web or I'm sure you could do the same with win-acme somehow.

I feel like developing your own ACME client (even if it is via certes) is the hard way to do this.

I just noticed that in your example code you are not adding your domain as the common name in your CSR, you just want something like this:

 order = await orderContext.Finalize(new CsrInfo
                        {
                            CommonName = _idnMapping.GetAscii(config.PrimaryDomain)
                        }, csrKey);

// than wait for cert to be generate and call Download ..

Further to @webprofusion's reply, the existence of a previous certificate does not affect the issuance of a new one. (There is a limit to how frequently you can request the same certificate from Let's Encrypt, but otherwise the existence of a valid certificate for the same name or names from either Let's Encrypt or another CA doesn't affect this. Simultaneous certificates for the same name are valid and don't contradict or invalidate each other.)

The server provider(also the CDN provider) provides SDK to achieve this. However, the provider(Aliyun) doesn't provide any tutorial about how to create or renew by Let's Encrypt.

I set the CommonName to "DST Root CA X3" as crt.sh | 3958242236 showed.

Maybe I made some mistake and I will try to set it to the domain name.

I am afraid I know less about this while our company is a start-up company and has not so much money to buy from any provider.

I did this for I am about to develop several Blazor WSAM projects. Each project needs to bind to a subdomain so I don't want to update the new certificate one by one to the CDN every month.

So either I develop it or have to continue the trouble way before.

I will try my best in spite maybe fault.

Thank you for your help.

Ok, well if you are using Aliyun and the DNS API failed in Certify The Web I can help fix that because Certify is the app I develop, then you would just need to add your own custom deployment task script to distribute your certificate. The community edition of Certify The Web is free and is probably capable enough for what you need to do. Of course if you want to code it yourself that's great!

In the beginning, I feel surprised that it supports Aliyun. I consider I should help to fix this no matter whether I use it.

Now my code can addDomainRecord or deleteDomainRecord by Aliyun SDK(AlibabaCloud.SDK.Alidns20150109 Nuget Package) successfully. I can provide my code if you need it.

Thanks, you're welcome to take a look :slight_smile: our Aliyun provider code (contributed by another user in our community) is here: certify/DnsProviderAliyun.cs at development · webprofusion/certify · GitHub

They are much different from mine.

Here is my code(You should install AlibabaCloud.SDK.Alidns20150109 Nuget Package first):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Tea;
using Tea.Utils;

namespace Sample.SDK
{
public class Aliyun
{
private AlibabaCloud.SDK.Alidns20150109.Client CreateClient()
{
AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config
{
// Your AccessKey ID
AccessKeyId = "AccessKeyId ",
// Your AccessKey Secret
AccessKeySecret = "AccessKeySecret ",
};
// Domain of Aliyun DNS,default for dns.aliyuncs.com
config.Endpoint = "dns.aliyuncs.com";
return new AlibabaCloud.SDK.Alidns20150109.Client(config);
}
public async Task AddDomainRecord(string Value)
{
await DeleteDomainRecord();
AlibabaCloud.SDK.Alidns20150109.Client client = CreateClient();
AlibabaCloud.SDK.Alidns20150109.Models.AddDomainRecordRequest addDomainRecordRequest = new AlibabaCloud.SDK.Alidns20150109.Models.AddDomainRecordRequest() {
DomainName="aaa.com",
RR= "_acme-challenge",
Type="TXT",
Value= Value
};
try
{
var Result = client.AddDomainRecord(addDomainRecordRequest);
}
catch (Exception ex)
{
}
}
private async Task DeleteDomainRecord()
{
AlibabaCloud.SDK.Alidns20150109.Client client = CreateClient();
AlibabaCloud.SDK.Alidns20150109.Models.DeleteSubDomainRecordsRequest deleteSubDomainRecordsRequest = new AlibabaCloud.SDK.Alidns20150109.Models.DeleteSubDomainRecordsRequest() {
DomainName="aaa.com",
RR= "_acme-challenge"
};
try
{
client.DeleteSubDomainRecords(deleteSubDomainRecordsRequest);
}
catch (Exception ex)
{
}
}
}
}

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.