GEThttps://acme-staging-v02.api.letsencrypt.org/acme/authz/ xxxx -> OK
“type”: “http-01”,
“status”: “pending”,
“url”: “/acme/challenge/xxxx”,
“token”: “yyy”
After creating file .well-known/acme-challenge on my end with $token.$thumb I I send
If I send POST-as-GET with empty payload on 3rd step I get following answer from acme server
“type”: “urn:ietf:params:acme:error:malformed”,
“detail”: “Invalid status value”,
“status”: 400
Your client needs to send a POST request with the trivial JSON JWS Body {} in this step to initiate the challenge. Note, this is different from a POST-as-GET request that would send a null JWS body.
The client indicates to the server it is ready for the challenge validation by sending an empty JSON body ("{}"), carried in a POST request to the challenge URL (not authorization URL).
POST https://acme-staging-v02.api.letsencrypt.org/acme/challenge/xxxx -> Bad Request / 400
{
“type”: “urn:ietf:params:acme:error:badNonce”,
“detail”: "JWS has an invalid anti-replay nonce: “nonce1"”,
“status”: 400
}
Hmm but why? I used trivial JWS body like you suggested and I used second nonce since there was no third one. And why first nonce displayed in error detail. I tried to send first nonce instead second but it didn’t help either. IETF draft says that in this case I can use nonce from this reply and resend my request. That’s what I did and ta-da it worked
But to me it looks like a problem that I can’t form a valid request and have to request new nonce. I’m attaching full debug output from my client just in case you want to take a look at headers
Thanks acme-chat.txt (10.6 KB)
Sorry I wasn’t very clear there. I didn’t use nonce twice I meant that I used second nonce to form 4th request because there was no reply-nonce after 3rd. Here simplified step by step process
.
Step 1
first nonce after requesting GET-> /directory
Step 2
first nonce used to place new order “/acme/new-order”
second nonce received as answer to POST -> " /acme/new-order"
Step 3
didn’t use second nonce to make GET acme/authz/xxxx
didn’t receive third nonce either
Step 4
using second nonce to make POST to acme/challenge/xxxx
receiving error with a new nonce a third one
Step 5
using third nonce to resend POST to acme/challenge/xxxx
all is good except that I wasn’t able to form a valid request on step 4 and had to rely on fallback procedure
This communication takes less than 5 seconds. To be precise it takes 3.398s so pretty quick.
My current implementations looks ugly to me because I have to resend post request twice but I don’t understand what’s wrong and why there is always content of the first nonce in the answer:
GET /directory -> OK -> receiving nonce1
POST /acme/new-order -> sending nonce1 -> OK -> receiving nonce2
GET /acme/authz/xxxx -> OK -> didn’t receive a nonce
POST /acme/challenge/xxxx -> sending nonce2 -> Bad Request -> receiving nonce3
{
"type": "urn:ietf:params:acme:error:badNonce",
"detail": "JWS has an invalid anti-replay nonce: \"content of the nonce1\"",
"status": 400
}
POST /acme/challenge/xxxx -> sending nonce3 -> OK -> receiving nonce4
I also tried to make GET and use reply-nonce from it but it didn’t help and again I see a weird relation to first nonce in the answer.
GET /directory -> OK -> receiving nonce1
POST /acme/new-order -> sending nonce1 -> OK -> receiving nonce2
GET /acme/authz/xxxx -> OK -> didn’t receive a nonce
GET /acme/challenge/xxxx -> OK -> receiving nonce3
POST /acme/challenge/xxxx -> sending nonce3 -> Bad Request -> receiving nonce4
{
"type": "urn:ietf:params:acme:error:badNonce",
"detail": "JWS has an invalid anti-replay nonce: \"content of the nonce1\"",
"status": 400
}
POST /acme/challenge/xxxx -> sending nonce4 -> OK -> receiving nonce5
Nonce's aren't sent for GET requests to URLs, only POST and HEAD requests. You can also use the explicit newNonce endpoint.
Looking at your log I think your code is saying its using nonce2 (VWE68SLTym-Ap0d5QcBDRj3iipfe5UuWBNrvGjO5QKI) but when I decode the protected field of the JWS used in the subsequent curl -s -i -d command I see "nonce": "Z13l3uFpQOhNIPt6CAJF8XGIfx4VgOs2wEp3Czs82Ck" which is nonce1 and the nonce included in the error message.
The errors seem correct to me given the logs and I think you have a bug somewhere.
I noticed you're using GET for a lot of endpoints (authz, challenge, etc) that are now deprecated for use with GET requests. If you're actively working on new client code, you should definitely migrate to using POST-as-GET for those endpoints. The GETs will continue to work only until November 2019.
See the original announcement here:
And some additional discussion here:
In short, the only endpoints that will support GET after November 2019 are directory and newNonce (and newNonce should ideally use HEAD instead).