Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with acme_ca_handler.py and Sectigo #122

Closed
pfisterer opened this issue Oct 27, 2023 · 5 comments
Closed

Issue with acme_ca_handler.py and Sectigo #122

pfisterer opened this issue Oct 27, 2023 · 5 comments
Labels
bug Something isn't working

Comments

@pfisterer
Copy link
Contributor

pfisterer commented Oct 27, 2023

Hi all,
thanks a lot for providing acme_ca_handler.py. I tried to use it with Sectigo in the context of Trusted Certificate Service where Sectigo provides certicates for EU's NRENs (national research and education networks).

It works fine using certbot (see logs at the end of this issue):

certbot certonly --manual --preferred-challenges dns -d 'some.allowed.domain' \
   --agree-tos --email some@valid.email --server https://acme.sectigo.com/v2/OV \
   --eab-kid XXXXXXXXXXX  --eab-hmac-key YYYYYYYYYYYYY

Basically, I get a valid certificate without the need to complete any challenge (i.e., as I'm a trusted admin, I can issue certificates).

But issuing a certificate fails using acme_ca_handler.py as ca_handler. I tried debugging it and it seems that Sectigo is using some proprietary challenge sectigo-email-01 (without any actions to perform):

{
    "identifier": {
        "type": "dns",
        "value": "some.valid.domain"
    },
    "status": "valid",
    "expires": "2023-11-26T08:16:56Z",
    "challenges": [
        {
            "type": "sectigo-email-01",
            "url": "https://acme.sectigo.com/v2/OV/chall/XXXXXXXXXXXXXXXXXXX",
            "status": "valid",
            "validated": "2023-10-27T08:16:56Z"
        }
    ]
}

which results in the following message:

sectigo-email-01 was not recognized, full message: {'type': 'sectigo-email-01', 'url': 'https://acme.sectigo.com/v2/OV/chall/XXXXXXXXXXXXXXXXXXX', 'status': 'valid', 'validated': '2023-10-27T08:16:56Z'}
CAhandler._http_challenge_info()
CAhandler._challenge_filter(http-01)
CAhandler._challenge_filter() ended. Could not find challenge of type http-01
CAhandler.enroll: error: 'NoneType' object has no attribute 'chall'

Any ideas how to fix this?
Best,
Dennis


The full log of acme_ca_handler is as follows:

Storing nonce: XXXXXXXXXXXXXXXXXX
CAhandler.__account_register(): new account reqistered: https://acme.sectigo.com/v2/OV/account/XXXXXXXXXXXXXXXXXXXXXXX
CAhandler._account_create() ended with: True
acme-account id is /account/XXXXXXXXXXXXXXXXXXX. Please add an corresponding acme_account parameter to your acme_srv.cfg to avoid unnecessary lookups
CAhandler.enroll(): account is valid, now invoking order
CAhandler.enroll() issuing signing order
CAhandler.enroll() csr: -----BEGIN CERTIFICATE REQUEST-----
XXXXXXXXXXXXXXXXXXXXXX
-----END CERTIFICATE REQUEST-----

JWS payload:
b'{\n  "identifiers": [\n    {\n      "type": "dns",\n      "value": "some.valid.domain"\n    }\n  ]\n}'
Sending POST request to https://acme.sectigo.com/v2/OV/newOrder:
{
  "protected": "XXXXXXXXXXXXXXXXXXXXXXx",
  "signature": "XXXXXXXXXXXXXX",
  "payload": "XXXXXXXXXXXXXXX"
}
https://acme.sectigo.com:443 "POST /v2/OV/newOrder HTTP/1.1" 201 283
Received response:
HTTP 201
Server: nginx
Date: Fri, 27 Oct 2023 08:16:56 GMT
Content-Type: application/json
Content-Length: 283
Connection: keep-alive
Replay-Nonce: XXXXXXXXXXXXXXXXXXXXXX
Cache-Control: max-age=0, no-cache, no-store
Access-Control-Allow-Origin: *
Location: https://acme.sectigo.com/v2/OV/order/XXXXXXXXXXXXXXXXXXX
Strict-Transport-Security: max-age=15724800; includeSubDomains

{"status":"ready","expires":"2024-10-26T08:16:56Z","identifiers":[{"type":"dns","value":"some.valid.domain"}],"authorizations":["https://acme.sectigo.com/v2/OV/authz/XXXXXXXXXXXXXXXXXXX"],"finalize":"https://acme.sectigo.com/v2/OV/order/XXXXXXXXXXXXXXXXXXX/finalize"}
Storing nonce: XXXXXXXXXXXXXXXXXXX
JWS payload:
b''
Sending POST request to https://acme.sectigo.com/v2/OV/authz/XXXXXXXXXXXXXXXXXXX:
{
  "protected": "XXXXXXXXXXXXXXXXXXX",
  "signature": "XXXXXXXXXXXXXXXXXXX",
  "payload": ""
}
https://acme.sectigo.com:443 "POST /v2/OV/authz/XXXXXXXXXXXXXXXXXXX HTTP/1.1" 200 280
Received response:
HTTP 200
Server: nginx
Date: Fri, 27 Oct 2023 08:16:56 GMT
Content-Type: application/json
Content-Length: 280
Connection: keep-alive
Replay-Nonce: XXXXXXXXXXXXXXXXXXX
Cache-Control: max-age=0, no-cache, no-store
Access-Control-Allow-Origin: *
Link: <https://acme.sectigo.com/v2/OV>;rel="index"
Retry-After: 300
Strict-Transport-Security: max-age=15724800; includeSubDomains

{"identifier":{"type":"dns","value":"some.valid.domain"},"status":"valid","expires":"2023-11-26T08:16:56Z","challenges":[{"type":"sectigo-email-01","url":"https://acme.sectigo.com/v2/OV/chall/XXXXXXXXXXXXXXXXXXX","status":"valid","validated":"2023-10-27T08:16:56Z"}]}
Storing nonce: XXXXXXXXXXXXXXXXXXX
sectigo-email-01 was not recognized, full message: {'type': 'sectigo-email-01', 'url': 'https://acme.sectigo.com/v2/OV/chall/XXXXXXXXXXXXXXXXXXX', 'status': 'valid', 'validated': '2023-10-27T08:16:56Z'}
CAhandler._http_challenge_info()
CAhandler._challenge_filter(http-01)
CAhandler._challenge_filter() ended. Could not find challenge of type http-01
CAhandler.enroll: error: 'NoneType' object has no attribute 'chall'
Certificate.enroll() ended: error="'NoneType' object has no attribute 'chall'", cert_bundle=None, cert_raw=None, poll_indentifier=None
acme2certifier enrollment error: 'NoneType' object has no attribute 'chall'
Certificate._enroll_and_store('NoneType' object has no attribute 'chall')
Certificate._enroll_and_store(): invalidating order as there is no certificate and no poll_identifier: 'NoneType' object has no attribute 'chall'/rLrTThJRyEPm
Certificate._order_update({'name': 'rLrTThJRyEPm', 'status': 'invalid'})

This is the output of certbotwith -vvvvv --debug flags:

https://acme.sectigo.com:443 "POST /v2/OV/authz/XXXXXXXXXXXX HTTP/1.1" 200 296
Received response:
HTTP 200
Server: nginx
Date: Fri, 27 Oct 2023 12:45:40 GMT
Content-Type: application/json
Content-Length: 296
Connection: keep-alive
Replay-Nonce: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
Cache-Control: max-age=0, no-cache, no-store
Access-Control-Allow-Origin: *
Link: <https://acme.sectigo.com/v2/OV>;rel="index"
Retry-After: 300
Strict-Transport-Security: max-age=15724800; includeSubDomains

{"identifier":{"type":"dns","value":"some.valid.domain"},"status":"valid","expires":"2023-11-26T12:45:39Z","challenges":[{"type":"sectigo-email-01","url":"https://acme.sectigo.com/v2/OV/chall/XXXXXXXXXXXX","status":"valid","validated":"2023-10-27T12:45:39Z"}],"wildcard":true}
Storing nonce: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
sectigo-email-01 was not recognized, full message: {'type': 'sectigo-email-01', 'url': 'https://acme.sectigo.com/v2/OV/chall/XXXXXXXXXXXX', 'status': 'valid', 'validated': '2023-10-27T12:45:39Z'}
CSR: CSR(file=None, data=b'-----BEGIN CERTIFICATE REQUEST-----\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n-----END CERTIFICATE REQUEST-----\n', form='pem')
Will poll for certificate issuance until 2023-10-27 14:47:10.731015
JWS payload:
b'{\n  "csr": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"\n}'
Sending POST request to https://acme.sectigo.com/v2/OV/order/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/finalize:
{
  "protected": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "signature": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "payload": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
https://acme.sectigo.com:443 "POST /v2/OV/order/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/finalize HTTP/1.1" 200 290
Received response:
HTTP 200
Server: nginx
Date: Fri, 27 Oct 2023 12:45:41 GMT
Content-Type: application/json
Content-Length: 290
Connection: keep-alive
Replay-Nonce: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Cache-Control: max-age=0, no-cache, no-store
Access-Control-Allow-Origin: *
Location: https://acme.sectigo.com/v2/OV/order/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Retry-After: 15
Strict-Transport-Security: max-age=15724800; includeSubDomains

{"status":"processing","expires":"2024-10-26T12:45:39Z","identifiers":[{"type":"dns","value":"*.some.valid.domain"}],"authorizations":["https://acme.sectigo.com/v2/OV/authz/XXXXXXXXXXXX"],"finalize":"https://acme.sectigo.com/v2/OV/order/XXXXXXXXXXXX/finalize"}
Storing nonce: XXXXXXXXXXXX
JWS payload:
b''
Sending POST request to https://acme.sectigo.com/v2/OV/order/XXXXXXXXXXXX:
{
  "protected": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "signature": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "payload": ""
}
https://acme.sectigo.com:443 "POST /v2/OV/order/XXXXXXXXXXXX HTTP/1.1" 200 290
Received response:
HTTP 200
Server: nginx
Date: Fri, 27 Oct 2023 12:45:42 GMT
Content-Type: application/json
Content-Length: 290
Connection: keep-alive
Replay-Nonce: XXXXXXXXXXXX
Cache-Control: max-age=0, no-cache, no-store
Access-Control-Allow-Origin: *
Location: https://acme.sectigo.com/v2/OV/order/XXXXXXXXXXXX
Retry-After: 15
Strict-Transport-Security: max-age=15724800; includeSubDomains

{"status":"processing","expires":"2024-10-26T12:45:39Z","identifiers":[{"type":"dns","value":"*.some.valid.domain"}],"authorizations":["https://acme.sectigo.com/v2/OV/authz/XXXXXXXXXXXX"],"finalize":"https://acme.sectigo.com/v2/OV/order/XXXXXXXXXXXX/finalize"}
Storing nonce: XXXXXXXXXXXX
JWS payload:
b''
Sending POST request to https://acme.sectigo.com/v2/OV/order/XXXXXXXXXXXX:
{
  "protected": "XXXXXXXXXXXX",
  "signature": "XXXXXXXXXXXX",
  "payload": ""
}
https://acme.sectigo.com:443 "POST /v2/OV/order/XXXXXXXXXXXX HTTP/1.1" 200 290
Received response:
HTTP 200
Server: nginx
Date: Fri, 27 Oct 2023 12:45:43 GMT
Content-Type: application/json
Content-Length: 290
Connection: keep-alive
Replay-Nonce: XXXXXXXXXXXX
Cache-Control: max-age=0, no-cache, no-store
Access-Control-Allow-Origin: *
Location: https://acme.sectigo.com/v2/OV/order/XXXXXXXXXXXX
Retry-After: 15
Strict-Transport-Security: max-age=15724800; includeSubDomains

{"status":"processing","expires":"2024-10-26T12:45:39Z","identifiers":[{"type":"dns","value":"*.some.valid.domain"}],"authorizations":["https://acme.sectigo.com/v2/OV/authz/XXXXXXXXXXXX"],"finalize":"https://acme.sectigo.com/v2/OV/order/XXXXXXXXXXXX/finalize"}
Storing nonce: XXXXXXXXXXXX
JWS payload:
b''
Sending POST request to https://acme.sectigo.com/v2/OV/order/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:
{
  "protected": "XXXXXXXXXXXX",
  "signature": "XXXXXXXXXXXX",
  "payload": ""
}
https://acme.sectigo.com:443 "POST /v2/OV/order/XXXXXXXXXXXX HTTP/1.1" 200 360
Received response:
HTTP 200
Server: nginx
Date: Fri, 27 Oct 2023 12:45:44 GMT
Content-Type: application/json
Content-Length: 360
Connection: keep-alive
Replay-Nonce: XXXXXXXXXXXX
Cache-Control: max-age=0, no-cache, no-store
Access-Control-Allow-Origin: *
Location: https://acme.sectigo.com/v2/OV/order/XXXXXXXXXXXX
Strict-Transport-Security: max-age=15724800; includeSubDomains

{"status":"valid","expires":"2024-10-26T12:45:39Z","identifiers":[{"type":"dns","value":"*.some.valid.domain"}],"authorizations":["https://acme.sectigo.com/v2/OV/authz/XXXXXXXXXXXX"],"finalize":"https://acme.sectigo.com/v2/OV/order/XXXXXXXXXXXX/finalize","certificate":"https://acme.sectigo.com/v2/OV/cert/XXXXXXXXXXXX"}
Storing nonce: XXXXXXXXXXXX
JWS payload:
b''
Sending POST request to https://acme.sectigo.com/v2/OV/cert/XXXXXXXXXXXX:
{
  "protected": "XXXXXXXXXXXX",
  "signature": "XXXXXXXXXXXX",
  "payload": ""
}
https://acme.sectigo.com:443 "POST /v2/OV/cert/XXXXXXXXXXXX HTTP/1.1" 200 4689
Received response:
HTTP 200
Server: nginx
Date: Fri, 27 Oct 2023 12:45:45 GMT
Content-Type: application/pem-certificate-chain
Content-Length: 4689
Connection: keep-alive
Replay-Nonce: XXXXXXXXXXXX
Cache-Control: max-age=0, no-cache, no-store
Access-Control-Allow-Origin: *
Link: <https://acme.sectigo.com/v2/OV>;rel="index"
Strict-Transport-Security: max-age=15724800; includeSubDomains

-----BEGIN CERTIFICATE-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END CERTIFICATE-----

Storing nonce: XXXXXXXXXXXX
Writing new private key to /tmp/archive/some.valid.domain/privkey2.pem.
Writing certificate to /tmp/archive/some.valid.domain/cert2.pem.
Writing chain to /tmp/archive/some.valid.domain/chain2.pem.
Writing full chain to /tmp/archive/some.valid.domain/fullchain2.pem.
@grindsa grindsa added the bug Something isn't working label Oct 29, 2023
@grindsa
Copy link
Owner

grindsa commented Oct 29, 2023

Hi,

Thank you for providing the logs. Sectigo is using a non-standardized challenge-type sectigo-email-01 which is not supported by the ca_handler. I have an idea about a fix. Is there any way to get test-access to the sertigo acme-server? Otherwise I need to mock the implementation which will take a bid longer...

/GrindSa

@pfisterer
Copy link
Contributor Author

Hi @grindsa,
Thank you for your support. Afaik, there is not test access. I also don't have a full account, I only have an ACME account valid for a subdomain of our institution. So I guess mocking it is the only way to test it. However, I can offer to test code changes at any time using my sectigo access.

Best,
Dennis

@grindsa
Copy link
Owner

grindsa commented Nov 1, 2023

Hi,

I pushed some fixes into a separate branch which should hopefully address your issue. The changes are in the acme_ca_handler.py only; it should be enough to replace this file on your system.

Please test and let me know if it works for you.

/G.

@pfisterer
Copy link
Contributor Author

Hi @grindsa,
Great - it works. Thanks a million!

Best,
Dennis

@grindsa
Copy link
Owner

grindsa commented Nov 2, 2023

Thank you for your confirmation. Changes got merged into devel and will be release in the upcoming days. Closing the issue....

@grindsa grindsa closed this as completed Nov 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants