Closed palo-manel closed 1 year ago
The operation of EAB is checked only with ZeroSSL. Only three parameters are required, as described in the following Wiki. https://github.com/shibayan/keyvault-acmebot/wiki/External-Account-Binding
I am checking the details of the shared exception, but it is failing because the account creation API is returning an Internal Server Error, not sure why it is returning an Internal Server Error.
Thank you so much @shibayan!
Will double check with the provider what's the MAC algorithm, as this is the only parameter we're not providing.
I also tried to get a new ZeroSSL and Google Public CA certificate using EAB and it worked fine. it seems that the problem only occurs when combined with Entrust.
@palo-manel looks like you can configure the algorithm when setting up EAB, but the typical default for all ACME clients is HS256 and it's rare to have to specify it in a client.
Thanks for the help gentlemen. I'm trying to debug the issue with the vendor. Probably has to do with their ACME API implementation.
I'll report back when we get to the bottom of it... Meanwhile should the issue be kept open? Or should I close it?
If it is a bug in Acmebot's EAB implementation, we would like to address it, so please leave the Issue as is.
Confirmed the issue is related to the provider's implementation... apparently only the RSA algorithm has been implemented, HS256 will becoming available in the near future š¤¦āāļø
I'm guessing you intentionally chose to leave RSA out š sorry for wasting your time.
I think I understand the problem, Acmebot uses EC as the default for JWK, whereas Entrust only uses RSA. certbot seems to work as RSA seems to be the default.
I think RSA is a legacy option nowadays...
The ACMEv2 RFC clearly states that:
An ACME server MUST implement the "ES256" signature algorithm [RFC7518] and SHOULD implement the "EdDSA" signature algorithm using the "Ed25519" variant (indicated by "crv") [RFC8037].
Since version 2.0.0, Certbot defaults to ECDSA ecp256r1
, documentation here.
Cert-manager also defaults to HS256 since version 1.3.0, they have marked the Issuer.spec.acme.externalAccountBinding.keyAlgorithm
as a deprecated option., documentation here.
@shibayan Can we add RS256 option in below code and then try to make EAB connection to test if it works. I reckon that ACME client should also be compatible with RS256.
@pahunisaharan EAB key algorithms are nothing to do with ACME really, they are an agreed way to have a shared secret between you and the CA and they relate only to EAB, not certificates, CSRs or private keys. We are assuming a SHA256 hash is the required output but you'd need to know exactly if that's what they're asking for as "RSA" means nothing by itself.
you are correct that "RSA" by itself does not specify a specific hash algorithm. RSA is a cryptographic algorithm used for key generation and encryption/decryption, and it can work with different hash algorithms for different purposes. Having said this, Entrust ECS, in their beta version of Entrust ACME, they are only supporting the RSA-based flow of the ACMEv2 protocol (which is the default used by certbot). It looks like the code given here is configured to make a request using ES256 and they are adding support for ES256 with 13.7 versions so this issue should be resolved with their next release in October. Not sure if this code can be modified to accomodate RSA based workflow as it is supported in certbot.
The ACME v2 implementation provided by Entrust does not appear to be complete; support for JWS using ES256 is mandatory, but that implementation is missing.
Note: ACMEv2 included in the 13.6 version of the Entrust Certificate Services Enterprise Portal is not fully implemented and is not recommended for use in a production environment.
Since there seems to be practically no other choice than HS256 for the algorithm at the time of EAB registration, we will consider fixing EAB to HS256 and removing the setting.
Perhaps changing the following part of ACMESharpCore from EC to RSA may work correctly with Entrust.
However, we have received comments that ES256 will be supported in October, so we are wondering if we should change the default value, since according to the RFC it seems that ES256 implementation is mandatory.
@shibayan, can we add a conditional switch in the code to support both ES256 and RSA algorithms. By implementing this conditional check, the code can use RSA if it is available and fall back to ES256 if RSA is not supported by the CA. Since ES256 support is expected to be available in the next release, although they have mentioned in month of october but cannot be guaranteed that it will be there by that time, so is it possible to adjust the code to support RSA-based workflow until the new release is available. if we can do this then code will be able to support for both the workflow and our team can test the code to see if this works out. However this can be removed at later stage as needed.
@gmakker Since the fallback is more complex in terms of conditions, I think it could be supported by way of a list of endpoints that do not support ES256, but I do not have a testable environment for Entrust, so I cannot confirm that this fix will work correctly.
Personally, I have a problem with Entrust's ACME implementation that does not support ES256, so I would not want to implement anything too special.
@shibayan Instead of trying to maintain a list of endpoints that do not support ES256,can we configure an option in the code that allows users to choose the signature algorithm they prefer (e.g., "ES256" or "RSA")? if you can amend the code and share the changes with us. We can test the code with Entrust's ACME implementation and verify the functionality of both "ES256" and "RSA" signature algorithms.
@gmakker I don't want to let the user choose the signature algorithm, both from a usability standpoint and from an implementation standpoint, and if we do support RS256, I would prefer to keep the list only as a temporary implementation.
I'm going to get in touch with Entrust because I'd like to check compatibility for https://certifytheweb.com (which I develop) - if I get any extra useful implementation information I'll share it here.
@shibayan Understood, we will default to 'ES256' for now and is it possible for you to implement a temporary fallback to 'RSA' for endpoints that lack 'ES256' support. We can collaborate and test with Entrust's ACME implementation once it's testable plus we will be ready to switch back to 'ES256' when Entrust introduces support for it in the upcoming release. Is that possible to do? if not then not an issue, but will need to wait as to when they are going to launch the ES256 at their side.
@gmakker It is difficult to determine which ACMEs do not support ES256; Entrust is returning a 500 Internal Server Error, but it could be a temporary problem, and I consider a fallback with a 500 error to be aggressive.
@shibayan Is it possible to analyze the response from the CA more thoroughly and check for specific error codes or headers that indicate ES256 is not supported?Not sure, but may be doing this we can avoid aggressive fallbacks based solely on the 500 error, and make the fallback more accurate and less intrusive.
@gmakker I added a new option in PR #619 to allow switching between RSA / EC, and will consider merging if I can confirm that it works correctly with Entrust.
@shibayan Sounds great! Thank you for taking the initiative to add the new option for switching between RSA and EC. This flexibility will certainly enhance the adaptability of your codebase. Let me check the code's compatibility with Entrust, we can than later move forward with confidence in merging the PR.
and will consider merging if I can confirm that it works correctly with Entrust
Looking into it! Thanks
Hi @shibayan I tried but it is giving same error . It seems the zip(https://stacmebotprod.blob.core.windows.net/keyvault-acmebot/v4/latest.zip) needs to rebuild , can you rebuild and provide the path of new zip , I can then make changes in azure deploy template and then deploy as well as test changes.
The PR cannot be merged because it has not been tested, but you can try it by overwriting WEBSITE_RUN_FROM_PACKAGE
with the following URL, since we have prepared a pre-built package.
https://stacmebotprod.blob.core.windows.net/keyvault-acmebot/v4/4.1.1-preview.zip
Tried building a package mimicking the instructions in the CI jobs. Unfortunately that package doesn't seem to work, I get:
Orchestrator function 'IssueCertificate' failed: The activity function 'Order' failed: "The signature algorithm RS256 is not supported.".
Will try the package you made available! Thank you so much for this.
Adding a little more detail about what I've tried.
Acmebot:DefaultSigner
configuration option and removing the Acmebot:ExternalAccountBinding:Algorithm
option, will yield an error similar to the original one. It apparently talks to the server and returns status code InternalServerErrorAcmeProtocolClientFactory.cs
does not have an option for RSA.What's the correct usage for the new option?
Thank you!
@palo-manel Thanks for sharing the information. I did not share enough information with you.
RSA
for Acmebot:DefaultSigner
Acmebot:ExternalAccountBinding:Algorithm
should be unspecified or HS256
After reviewing the error message you shared, it seems that CreateAccount was successful, so I guess we are one step closer. My honest impression is that Entrust's ACME implementation still looks incomplete.
@shibayan Thanks for helping us out this far. We were already setting Acmebot:DefaultSigner as RSA but we also had Acmebot:ExternalAccountBinding:Algorithm so I unspecified it and used the preview zip(https://stacmebotprod.blob.core.windows.net/keyvault-acmebot/v4/4.1.1-preview.zip). Now , it has progressed and failing with Exception while executing function: Order illegal RSA key bit length Do we have hardcoded bit length in our code anywhere ?
Detailed trace is pasted below:
Microsoft.Azure.WebJobs.Host.FunctionInvocationException:
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor+<ExecuteWithLoggingAsync>d__26.MoveNext (Microsoft.Azure.WebJobs.Host, Version=3.0.37.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:352)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor+<TryExecuteAsync>d__18.MoveNext (Microsoft.Azure.WebJobs.Host, Version=3.0.37.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:108)
Inner exception System.InvalidOperationException handled at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw:
at ACMESharp.Crypto.JOSE.Impl.RSJwsTool.Init (ACMESharp, Version=4.1.1.0, Culture=neutral, PublicKeyToken=null)
at KeyVault.Acmebot.Internal.AccountKey.GenerateSigner (KeyVault.Acmebot, Version=4.1.1.0, Culture=neutral, PublicKeyToken=null: C:\Users\shibayan\Documents\GitHub\keyvault-acmebot\KeyVault.Acmebot\Internal\AccountKey.cs:31)
at KeyVault.Acmebot.Internal.AcmeProtocolClientFactory+<CreateClientAsync>d__2.MoveNext (KeyVault.Acmebot, Version=4.1.1.0, Culture=neutral, PublicKeyToken=null: C:\Users\shibayan\Documents\GitHub\keyvault-acmebot\KeyVault.Acmebot\Internal\AcmeProtocolClientFactory.cs:34)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at KeyVault.Acmebot.Functions.SharedActivity+<Order>d__14.MoveNext (KeyVault.Acmebot, Version=4.1.1.0, Culture=neutral, PublicKeyToken=null: C:\Users\shibayan\Documents\GitHub\keyvault-acmebot\KeyVault.Acmebot\Functions\SharedActivity.cs:145)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2+<InvokeAsync>d__10.MoveNext (Microsoft.Azure.WebJobs.Host, Version=3.0.37.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:52)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor+<InvokeWithTimeoutAsync>d__33.MoveNext (Microsoft.Azure.WebJobs.Host, Version=3.0.37.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:581)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor+<ExecuteWithWatchersAsync>d__32.MoveNext (Microsoft.Azure.WebJobs.Host, Version=3.0.37.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:527)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult (System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor+<ExecuteWithLoggingAsync>d__26.MoveNext (Microsoft.Azure.WebJobs.Host, Version=3.0.37.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35: D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:306)
@pahunisaharan Thanks for the report. This error was a simple coding error on my part. I have built a corrected version, could you please try again here?
https://stacmebotprod.blob.core.windows.net/keyvault-acmebot/v4/4.1.1-preview2.zip
@shibayan I'm happy to share that it successfully issued a certificate using Entrust as the EAB. We @gmakker @palo-manel appreciate all of your work and really value your assistance. I believe you can merge the code into the main branch sans any issues.
@pahunisaharan Thanks for the nice report. I am working on merging the modified PR.
@palo-manel Did the new Acmebot version I published in my comment issue the certificate correctly?
Yes! Thanks so much @shibayan!
We're actually working on the same team, but on different timezones, so we were doing a relay race.
Understood, thank you. I'll work on the merge.
You even updated the Wiki šŖ
Again, thank you so much @shibayan, you're awesome!
Issue description
We are trying to connect to Entrust's ACME API. We have obtained EAB credentials from the provider and we have been able to verify the API works as expected using certbot. As ZeroSSL is supported by
vault-acmebot
, this provider should work as well.The
README
didn't provide any information on how to use ZeroSSL, so we did a little digging to understand how EAB support worked. When trying to connect to the provider we are adding these configuration parameters:However it seems we hit an error inside
CreateClientAsync()
in line 60 of AcmeProtocolClientFactory.cs. The full error trace is included below, maybe we're not providing all of the necessary parameters?Any help will be greatly appreciated!
To Reproduce
Steps to reproduce the behavior:
Environment (please complete the following information):
Additional context
Error trace: