rmbolger / Posh-ACME

PowerShell module and ACME client to create certificates from Let's Encrypt (or other ACME CA)
https://poshac.me/docs/latest/
MIT License
746 stars 184 forks source link

Finalize URL not set in order object, cannot Submit-OrderFinalize #510

Closed Coleman0701 closed 1 year ago

Coleman0701 commented 1 year ago

Hello, we are currently testing our implementation of ACME server with various ACME clients (so far I've successfully tested WIN-ACME client) and I am facing issues with Posh-ACME.

I couldn't complete the flow since I was not able to Submit-OrderFinalize. Finalize URL is not set in order object -> URL is not set in header -> URL is not present for web request in InvokeACME.ps1

I am getting error: C:\Program Files\WindowsPowerShell\Modules\posh-acme\4.18.0\Private\Invoke-ACME.ps1:60 char:21 $response = Invoke-WebRequest @iwrSplat @script:UseBasic CategoryInfo : NotSpecified: (:) [Invoke-WebRequest], UriFormatException FullyQualifiedErrorId : System.UriFormatException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand I was able to complete the flow (submit finalize order and download certificate) using some workarounds:

A) Manually modififed order.json saved on disk, added finalize URL to finalize object within order object.

B) Modified Update-PAOrder function

$respObj = $response.Content | ConvertFrom-Json

            # update the things that could have changed
            $Order | Add-Member 'status' $respObj.status -Force
            $Order | Add-Member 'expires' (Repair-ISODate $respObj.expires) -Force

# I have added the following line (added member 'finalize'

        $Order | Add-Member 'finalize' $respObj.finalize -Force
            if ($respObj.certificate) {
                $Order | Add-Member 'certificate' $respObj.certificate -Force
            }

Is this really a bug or am I doing something wrong? At which point Posh-Acme normally sets finalize URL?
I don't believe it is a bug. It wouldn't be working at all and somebody else would have noticed and reported that before for sure.

Thank you for your help

rmbolger commented 1 year ago

Hi @Coleman0701

I believe the finalize field must be returned as part of the original response from the ACME server during a call to the newOrder endpoint. This is described in section 7.4 of RFC8555. The finalize field is also listed as "required" in section 7.1.3 that describes the order object.

So if the local order object Posh-ACME has is missing its finalize field, I'd guess the server didn't include it in the response originally. If you want to check without going through the entire certificate flow, you can initial just a new order call with debug output like this. Among other things, it should show the raw response from the server

$DebugPreference = 'Continue'
New-PAOrder example.com -verbose
Coleman0701 commented 1 year ago

You are correct :) Thank you.

I tried $DebugPreference = 'Continue' New-PAOrder example.com -verbose

and our implementation of ACME server doesn't provide finalize URL in the new-order response.

I checked with the developer. He thought he should have provided response with finalize URL as soon as order is in Ready status. This is not correct according to RFC.

Your implementation is OK. Finalize URL is not thing that can change in order object that is why you don't have that in Update-PAOrder function.

Thank you a lot!!!

P.S. It is strange that WIN-ACME could finalize the order without URL set in order object. This client must set the URL somehow differently. I also noticed other things in this client that are implemented "leisurely". Not strictly following the RFC.

rmbolger commented 1 year ago

Glad I could help. Good luck on your ACME server implementation!

If I had to guess, WIN-ACME might be re-querying the order object's details prior to submitting the finalization and so doesn't show the problem. Ultimately, RFCs in general are open to interpretation. So there's bound to be variations in both client and server implementations.