-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Description
I tried to issue a new certificate today, but I messed up my nginx config so the issuing failed initially. Subsequent attempts also failed, but after staring at the debug log a bit, it seemed to me that it was an issue with acme.sh.
The debug log makes the issue pretty clear.
[Wed Dec 27 10:49:00 UTC 2023] _idn_temp
[Wed Dec 27 10:49:00 UTC 2023] _candidates='cloud.arborusgroup.com,{"identifier":{"type":"dns","value":"example.com"},"status":"invalid","expires":"2024-01-26T09:37:10Z","challenges":[{"type":"http-01","url":"https://acme.zerossl.com/v2/DV90/chall/X_zibH7gBsX9FDpNLsKPvw","status":"invalid","error":{},"token":"O4-YzxyoyvzhVw54KSGFCIZSXyvG2RW_B_rKOshx5CE"}]}#https://acme.zerossl.com/v2/DV90/authz/h60LmUF30XYAqWDFop_azg'
[Wed Dec 27 10:49:00 UTC 2023] response='{"identifier":{"type":"dns","value":"example.com"},"status":"invalid","expires":"2024-01-26T09:37:10Z","challenges":[{"type":"http-01","url":"https://acme.zerossl.com/v2/DV90/chall/X_zibH7gBsX9FDpNLsKPvw","status":"invalid","error":{},"token":"O4-YzxyoyvzhVw54KSGFCIZSXyvG2RW_B_rKOshx5CE"}]}#https://acme.zerossl.com/v2/DV90/authz/h60LmUF30XYAqWDFop_azg'
[Wed Dec 27 10:49:00 UTC 2023] _authz_url='https://acme.zerossl.com/v2/DV90/authz/h60LmUF30XYAqWDFop_azg'
[Wed Dec 27 10:49:00 UTC 2023] entry='"type":"http-01","url":"https://acme.zerossl.com/v2/DV90/chall/X_zibH7gBsX9FDpNLsKPvw","status":"invalid","error":{'
[Wed Dec 27 10:49:00 UTC 2023] token
[Wed Dec 27 10:49:00 UTC 2023] Error, can not get domain token "type":"http-01","url":"https://acme.zerossl.com/v2/DV90/chall/X_zibH7gBsX9FDpNLsKPvw","status":"invalid","error":{
The extracted variable entry from response is not correct. It gets cut off right on the closing brace of the error:{ JSON object.
Lines 4693 to 4718 in afacdfc
| entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')" | |
| _debug entry "$entry" | |
| if [ -z "$keyauthorization" -a -z "$entry" ]; then | |
| _err "Error, can not get domain token entry $d for $vtype" | |
| _supported_vtypes="$(echo "$response" | _egrep_o "\"challenges\":\[[^]]*]" | tr '{' "\n" | grep type | cut -d '"' -f 4 | tr "\n" ' ')" | |
| if [ "$_supported_vtypes" ]; then | |
| _err "The supported validation types are: $_supported_vtypes, but you specified: $vtype" | |
| fi | |
| _clearup | |
| _on_issue_err "$_post_hook" | |
| return 1 | |
| fi | |
| if [ -z "$keyauthorization" ]; then | |
| token="$(echo "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')" | |
| _debug token "$token" | |
| if [ -z "$token" ]; then | |
| _err "Error, can not get domain token $entry" | |
| _clearup | |
| _on_issue_err "$_post_hook" | |
| return 1 | |
| fi | |
| uri="$(echo "$entry" | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1)" |
The problem is that the regex _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*' can not properly handle the error objects, because it starts looking for the first closing } after finding the type of challenge that was requested. This is problematic when the challenge entry itself contains an object which, of course, needs to be terminated with a } leading to this unintended behavior.
I would have submitted a PR to fix this, but I just could not figure out a good way to extract the entry with regex when the error object can be arbitrarily complex.
The error can be arbitrarily complex, because the ACME RFC specifies:
error (optional, object): Error that occurred while the server was
validating the challenge, if any, structured as a problem document
[RFC7807]. Multiple errors can be indicated by using subproblems
Section 6.7.1. A challenge object with an error MUST have status
equal to "invalid".
And Section 6.7.1 gives a good example of a possible arbitrarily complex error object
{
"type": "urn:ietf:params:acme:error:malformed",
"detail": "Some of the identifiers requested were rejected",
"subproblems": [
{
"type": "urn:ietf:params:acme:error:malformed",
"detail": "Invalid underscore in DNS name \"_example.org\"",
"identifier": {
"type": "dns",
"value": "_example.org"
}
},
{
"type": "urn:ietf:params:acme:error:rejectedIdentifier",
"detail": "This CA will not issue for \"example.net\"",
"identifier": {
"type": "dns",
"value": "example.net"
}
}
]
}
If anyone has a good idea for how to deal with these error objects that would fit into the codebase, I'd be happy to write it out and submit a PR.