fszlin / certes Goto Github PK
View Code? Open in Web Editor NEWA client implementation for the Automated Certificate Management Environment (ACME) protocol
License: MIT License
A client implementation for the Automated Certificate Management Environment (ACME) protocol
License: MIT License
Certes should be listed on https://letsencrypt.org/docs/client-options/
(Unfortunately for me, I did not find Certes for a while because it wasn't there, so I used a vastly inferior client for my application until I discovered Certes on Nuget)
Instructions and rules are here
If allowed, I can create the necessary pull request there.
Hi,
I'm trying to generate a SAN certificate. The SubjectAlternativeName property is readonly (and returns an empty list of string by default).
any attempt to add a name of type "DNS" fails since there is a validation on "X509Name.DefaultLookup" and the DNS is part of the X509Name.Extension
Any help would be appreciated
Thanks !
Does certes support Proxy?
I'm new to Acme/Let's Encrypt/Certes, so please forgive me if this is an obvious question.
I'm working through the sample calls to order a wildcard cert through Acme v2, but I'm running into a problem with "refreshing" (for lack of a better word) the status of a challenge after I call Validate(). It seems that there is a short delay (30~60 seconds) before the server validates the DNS challenge and moves it from "pending" to "valid". That's fine, but how do I poll for this update using Certes? It seems that when I try to re-get the Order using the Location property pulled from the server response, it just hands me back the same order and linked authorizations/challenges, and the challenge status is still "pending". But if I manually get that same location by URL in a browser, it shows "valid".
Do I have to create a new AcmeContext every time?
I can post some code if necessary, but I think this is more of a conceptual/process flow question.
When I try to bind the certificate I get the following error:
A specified logon session does not exist. It may already have been terminated. (Exception from HRESULT: 0x80070520)
After some research I best I could find is this:
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/8b78f6ca-d4db-4de1-a642-6223aa0252e7/unable-to-bind-a-new-certificate-in-ssrs-2008-r2?forum=sqlreportingservices
Any help would be greatly appreciated.
Not sure why, but Install-Package Certes is failing. It works fine if I download the source and include it. To reproduce, create a .NET Core Web Application in VS2017 and run 'Install-Package Certes' in the Package Manager Console.
Install-Package : Package Certes 1.0.4.167 is not compatible with netcoreapp1.1 (.NETCoreApp,Version=v1.1). Package Certes 1.0.4.167 supports: net (.NETFramework,Version=v0.0)
At line:1 char:1
+ Install-Package Certes
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Install-Package], Exception
+ FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
Install-Package : One or more packages are incompatible with .NETCoreApp,Version=v1.1.
At line:1 char:1
+ Install-Package Certes
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Install-Package], Exception
+ FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
Install-Package : Package restore failed. Rolling back package changes for 'ASORSYNC2Server'.
At line:1 char:1
+ Install-Package Certes
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Install-Package], Exception
+ FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
CSProj (default):
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" />
</ItemGroup>
</Project>
Hello,
during development we noticed, that our (ASP.NET MVC 4) solution doesn't work anymore. We started getting error:
Compiler Error Message: CS0012: The type 'System.Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=4.0.0.0, ...
During investigation we found that adding:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5.2">
<assemblies>
<add assembly="System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</assemblies>
</compilation>
</system.web>
</configuration>
to the web config like this solves the issue.
When we started investigating, we found that this started happening after we updated certes to version 1.0.7. And the main culprit is System.ValueTuple NuGet that got installed with the new certes version. Not entirely sure if this is a problem for you or anyone who uses your client, but just wanted to make you aware that the latest version might break peoples solutions. And to solve it you can use the web.config code above. Maybe it will be useful for anyone.
Cheers
Mindaugas
should be able to install cli as dotnet global tool
e.g. dotnet install tool dotnet-certes -g
Need to design new client APIs for the upcoming LE v2 endpoint.
V1 APIs should remain intact as long as LE supports v1 endpoint.
I'm following the example code in the readme for the V2 API. When using the code to obtain a wildcard cert and then save it as a PFX cert (for use in .Net Core Kestrel HTTP server) I can't seem to get a valid PFX certificate.
Kestrel throws this error: "Uncaught exception from the OnConnectionAsync method of an IConnectionAdapter." From investigating this seems to occur when a bad PFX is ingested.
I've used certutil on Windows to dump out the info on the PFX there are some problems. I'm not an expert on this so it isn't clear what the problem is.
Interestingly I can import the PFX into Windows Cert Manager and then re-export to PFX. The newly created PFX works with Kestrel and also certutil has no errors.
Also if I manually write out a PEM file (for the cert and private key) and then use openssl to create the PFX everything works fine.
Any help is much appreciated. I've attached the output of CertUtil for both the cert that was created with Certes, as well as the exported cert. I've also attached the code used to generate the cert (minus the DNS validation bits). If I could use the PEM format in .Net Core I would, however all API's I could find want to use the PFX format.
LetsEncryptCertRequest.txt
testing_dump.txt
testing_export_dump.txt
I tried almost all combinations but cant make it works.
// Comptue key authorization for dns-01
dnsChallenge = authz.Data.Challenges.First(c => c.Type == ChallengeTypes.Dns01);
keyAuthString = client.ComputeKeyAuthorization(dnsChallenge);
// Do something to fullfill the challenge,
// e.g. upload key auth string to well known path, or make changes to DNS
Let`s say i try to get certificate for "test.example.com" where "example.com" is registered domain.
I tried to create txt record with keyAuthString value in
_acme-challenge.test.example.com
but process is always failed.
Can you give example how does this works?
I'm unable to use the Certes library in PowerShell Core due to the dependency on NewtonSoft.Json 11.0.1. At present you will receive a type init exception as soon as you try to create a new AcmeContext. This is due to the unique way pwsh works where it will stick with the first version of a module it loads, and unfortunately since pwsh itself has a dependency on Newtonsoft.Json, it sticks with the version it loads on startup.
See here: PowerShell/PowerShell#2083
Currently there is no way for a module to have its own AppDomain or context. Until the PowerShell team fix that (maybe in 6.2), please could you revert the version of Newtonsoft.Json used by Certes to 10.0.3? I've grabbed the repo, made the change, and it compiled ok. The referenced assembly then works ok in PowerShell Core.
I'm considering using certes in a project of mine, but can't yet because the assemblies in the certes project aren't strong named. Any chance you'd be willing to add as strong name to your assemblies?
The value must be application/jose+json
.
Hi,
I've got a custom implementation of Certes working using the Nuget package, however, I'm not sure how to handle the registrations. Is it appropriate and expected that I call client.NewRegistraton("mailto:[email protected]")
each time I run the application, or is there a mechanism that allows you to reuse previous registrations?
account show [-k|key <path-to-pem>] [--s|server <dir-uri>]
account set <path-to-pem> [--s|server <dir-uri>]
account new <email> [-k|key <path-to-pem>]|[--out <path-to-pem>] [--s|server <dir-uri>]
account update <email> [-k|key <path-to-pem>] [--s|server <dir-uri>]
It seems that there is a problem with the challenge creation. Every time I want to create an HTTP-challenge, I receive a DNS-challenge.
I use this functions to create the challenge:
var acme = new AcmeContext(WellKnownServers.LetsEncryptV2, caAccountKey); // caAccountKey is null
var newOrder = await acme.NewOrder(new[] {data.Fqdn}); // data.Fqdn is ssl2.r4wfreak.ch
var newAuthz = (await newOrder.Authorizations()).First();
var newChallenge = await newAuthz.Http();
// ...
The challenge was validated in a second step:
var challenge = (await orderAuthz.Challenges()).FirstOrDefault();
var challengeRessource = await challenge.Resource();
var challengeResult = await challenge.Validate();
while (challengeResult.Status == ChallengeStatus.Pending)
{
await Task.Delay(50);
challengeResult = await challenge.Validate(); // throws an error
}
// ...
The error message says: 'Unable to update challenge :: The challenge is not pending.'
The challenge looks like this:
{
"type": "dns-01",
"status": "invalid",
"error": {
"type": "urn:ietf:params:acme:error:dns",
"detail": "DNS problem: NXDOMAIN looking up TXT for _acme-challenge.ssl2.r4wfreak.ch",
"status": 400
},
"url": "https://acme-v02.api.letsencrypt.org/acme/challenge/9x3eslMywskdeg2KN9Tsqb0WLur05wTqs89Ahg4t7QY/4880068128",
"token": "IIh43p5OzCR_ZL_BftJKzlAFM-VKSQSITMyPqyKKAi4"
}
Am I doing anything wrong?
order list
order new <domain> [domain...]
order show <order-id>
order authz <order-id> <domain> <http|dns>
order validate <order-id> <domain> <http|dns>
order finalize <order-id> [--dn <distinguished-name>] [--out <private-key-path>]
cert pem <order-id> [--out <pem-path>]
cert pfx <order-id> <private-key> <pwd> [--out <pfx-path>]
Hi,
I wondered if you had any current plans to support the v2 API, in particular people are pretty keen on the idea that wildcard certificates might be supported.
I'm currently looking at existing c# acme client implementations and gauging whether to implement my own or adopt an existing one.
I just succeeded in creating my first wildcard certificate for an Azure Web App. The docs are telling me how to create a certificate, but not how to do the renewal. Can tell me what to do to renew the certificate? Iโm aiming to create a webjob to do this automatically.
Add command for setting the default ACME server
server set -server https://acme-staging-v02.api.letsencrypt.org/directory
server show -server https://acme-staging-v02.api.letsencrypt.org/directory
When running with Portable.BouncyCastle v1.8.1.3, CertificationRequestBuilderBase.AddName fails with
System.MissingFieldException:
'Field not found: 'Org.BouncyCastle.Asn1.X509.X509Name.DefaultLookup'.'
fw: netstandard2.0
This due to the type of X509Name.DefaultLookup changed from IDictionary
(v1.8.1.2) to Hashtable
(v1.8.1.3)
When attempting to the Certes library in a project utilizing the latest .Net framework, it fails to load (possibly due to conflicting dependency versions related to System.Net.Http and System.ValueTuple).
Hi,
I'm getting AcmeRequestException: Fail to load resource from 'https://acme-staging-v02.api.letsencrypt.org/acme/new-acct'
at line
var order = await acme.NewOrder(new[] { "some.domain.net" });
How to understand what's I'm doing wrong?
I am requesting a wildcard certificate like so:
*.sub.example.com and that works.
When getting a wildcard certificate from a paid CA, I usually get a certificate which are valid for:
*.sub.example.com
sub.example.com
How do I do that?
Is that possible with certes? (Or LetsEncrypt even?)
Present ToS from directory metadata if available.
While using the Certes API for a while (1.1.3 / 1.1.4) I noticed that error responses from the ACME endpoint are returned as a System.Exception
with the message only being the Certes.Acme.AcmeHttpResponse<T>.Error.Detail
variable. Specifically speaking of: EntityContext.cs Line 50 and IAcmeHttpClient.cs Line 61
In order to enable better error handling wouldn't it be nice to encapsulate the error object? Or even better the hole response, as the object that caused the exception. This way there is access to the http status code and the ACME error type. When creating a custom exception type, like AcmeErrorException
or something, you could still set the exception message to the Error.Detail
variable. So this change should not break any existing code. Any thoughts?
I couldn't find any option to specify a custom private key size.
Maybe I haven't looked hard enough and in that case I'm sorry for the noise.
I saw in certes/src/Certes/Crypto/RS256Algorithm.cs that GenerateKey()
seems to have 2048 hardcoded.
Is there any plan to allow generating 3072 and 4096 bits keys?
Thanks!
Recently I noticed that trying to issue a certificate on LE staging environment no longer works. After an investigation I've noticed that calls are never made to the domain to check for the challenge. Undergoing the same procedure but using LE production environment works fine.
The domain I tried to issue a certificate to was buduls.tk,
allow for creating random RSA key with size KeyFactory.NewRsaKey(3072)
I can create a wildcard certificate but the certificate has this data:
Common name: *.example.com
SANs: *.example.com
This means I cannot use the certificate for the raw domain (example.com).
Is this how LetsEncrypt works you are missing something in your CsrInfo?
Or maybe I need to make an order for both, *.example.com and example.com?
How to generate the private key file and full-chain file like certbot? I want to use them in Nginx and instead of the pfx file.
As I understand it, a Let's Encrypt account only needs to be registered one time.
So if I call:
var account = await client.NewRegistraton($"mailto:{Email}");
I need to save the account so I can re-use it on future registrations. (According to the LE documentation there is a penalty for registering a single account too many times.)
I can re-use the registered account by calling the Use method:
client.Use(account.Key);
What I can't figure out is how to save the key in my database so I can re-use it later.
The key is a type KeyInfo but it only contains one property "PrivateKeyInfo". I can store this byte array but I need a way to turn it back into a key. Do you have any examples of how to do that?
When using IChallengeContext.Resource()
the response is a Challenge
object with a status. If the status comes back invalid there should be an error object. The current IList<object> Errors
in the code is always null
becouse the property has been replaced since draft 10. It is now a single error with subproblems. It can be fould in section-8
At the moment I am not able to get the reason why validation vailed.
Is this something you want to fix yourself or should I create a Pull request?
As spec section 7.3
Could you give an example of how to request a certificate using an existing account (rather than creating a new one)?
Hello,
Recently AcmeClient.NewRegistration stopped working. It gives out this error:
JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Uri' because the type requires a JSON primitive value (e.g. string, number, boolean, null) to deserialize correctly.
Upon closer investigation, it was noticed that Json in LetEncrypt API (https://acme-staging.api.letsencrypt.org/directory) has changed (link to the change commit: letsencrypt/boulder@8c54747). Not all values are URIs now. There is a new object in the response called "meta".
Currently Certes works with live LetsEncrypt API, but not with staging.
I noticed my service is not working last 24 hours or maybe last few days. Once debugging locally, I noticed that Certes is stucking without error or timeout. I tried 1.1.0, 1.0.7 and also reverting to 1.06 but no luck.
Certes is stucking in my projects as MVC, but it's working fine in a Console app.
Visual Studio:
Fiddler debugger shows how Certes is getting HTTP response for /directory and stucking after that.
`
GET https://acme-staging.api.letsencrypt.org/directory HTTP/1.1
Host: acme-staging.api.letsencrypt.org
Connection: Keep-Alive
HTTP/1.1 200 OK
Server: nginx
Content-Type: application/json
Content-Length: 581
Boulder-Request-Id: ZC8.....
Replay-Nonce: hEfFm......
X-Frame-Options: DENY
Strict-Transport-Security: max-age=604800
Expires: Sun, 20 Aug 2017 23:50:00 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Sun, 20 Aug 2017 23:50:00 GMT
Connection: keep-alive
{
"V6lWPRqlCVw": "https://community.letsencrypt.org/t/adding-random-entries-to-the-directory/33417",
"key-change": "https://acme-staging.api.letsencrypt.org/acme/key-change",
"meta": {
"terms-of-service": "https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf"
},
"new-authz": "https://acme-staging.api.letsencrypt.org/acme/new-authz",
"new-cert": "https://acme-staging.api.letsencrypt.org/acme/new-cert",
"new-reg": "https://acme-staging.api.letsencrypt.org/acme/new-reg",
"revoke-cert": "https://acme-staging.api.letsencrypt.org/acme/revoke-cert"
}
`
Do i miss something?
How would I go about getting the certificate information after it's registered?
var cert = await client.NewCertificate(csr);
Given the code above, would I use cert.Json
and just parse the results or is there an easier way?
fszlin,
I love this library, its really great that it works with .Net Core. Thank you!
I had a question about dealing with Let's Encrypt certs. I am getting two certs returned but neither are the root, and it is failing to create the PfxBuilder because of this line:
https://github.com/fszlin/certes/blob/master/src/Certes/Pkcs/PfxBuilder.cs#L119
I have some more details about the issue here:
http://stackoverflow.com/questions/43381531/lets-encrypt-api-not-returning-root-cert
This is more of a question than an issue with the library I believe, but I would greatly appreciate any insight.
Thanks,
Louis
Hi guys,
how to add multiples hosts (ex01.example.com, ex02.example.com) in one certificate?
Regards
Update sample with generating SHA-256 digest of the key authorization for dns-01.
var keyAuthBytes = Encoding.UTF8.GetBytes(keyAuthString);
var sha256 = new Sha256Digest();
var hashed = new byte[sha256.GetDigestSize()];
sha256.BlockUpdate(keyAuthBytes, 0, keyAuthBytes.Length);
sha256.DoFinal(hashed, 0);
var dnsValue = JwsConvert.ToBase64String(hashed);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.