Can't revoke EC certs (error), but RSA cert revokes OK

( Not getting any replies on this over in ‘Client dev’ or in Certbot’s issue queue, so let’s try here …)

i created both EC and RSA certs

cd /etc/letsencrypt/live/example.com
ls -1
	cert.ec.crt.pem
	cert.rsa.crt.pem
	chain.ec.crt.pem
	chain.rsa.crt.pem
	fullchain.ec.crt.pem
	fullchain.rsa.crt.pem

revoking rsa cert appears to work,

CA="https://acme-v01.api.letsencrypt.org/directory"
certbot-auto revoke \
--server ${CA} \
--key-path ./privkey_rsa.pem \
--cert-path ./cert.rsa.crt.pem \
-d example.com

since if I try again

...
An unexpected error occurred:
The request message was malformed :: Certificate already revoked
Please see the logfiles in /var/log/letsencrypt for more details.

now if I try to revoke the ec cert

certbot-auto revoke \
--server ${CA} \
--key-path ./privkey_ec.pem \
--cert-path ./cert.ec.crt.pem \
-d example.com

it fails with the

An unexpected error occurred:
TypeError: __init__() takes exactly the following arguments:  (key given)
Please see the logfiles in /var/log/letsencrypt for more details.

error

what’s the problem with revoking EC certs?

Could you provide the full logs (in /var/log/letsencrypt)?

tailing

tail -f  /var/log/letsencrypt/letsencrypt.log

for successful revoke of the rsa cert

2016-08-30 00:16:33,924:DEBUG:certbot.main:Root logging level set at 30
2016-08-30 00:16:33,925:INFO:certbot.main:Saving debug log to /var/log/letsencrypt/letsencrypt.log
2016-08-30 00:16:33,926:DEBUG:certbot.main:certbot version: 0.8.1
2016-08-30 00:16:33,926:DEBUG:certbot.main:Arguments: ['--server', 'https://acme-staging.api.letsencrypt.org/directory', '--standalone', '--standalone-supported-challenges', 'tls-sni-01', '--key-path', '/etc/ssl/le/keys/privkey_rsa.pem', '--cert-path', '/etc/letsencrypt/live/test0001.example.com/cert.rsa.crt.pem', '-d', 'test0001.example.com']
2016-08-30 00:16:33,926:DEBUG:certbot.main:Discovered plugins: PluginsRegistry(PluginEntryPoint#apache,PluginEntryPoint#webroot,PluginEntryPoint#null,PluginEntryPoint#manual,PluginEntryPoint#standalone)
2016-08-30 00:16:33,932:DEBUG:certbot.main:Revoking /etc/letsencrypt/live/test0001.example.com/cert.rsa.crt.pem using cert key /etc/ssl/le/keys/privkey_rsa.pem
2016-08-30 00:16:34,088:DEBUG:root:Sending GET request to https://acme-staging.api.letsencrypt.org/directory. args: (), kwargs: {}
2016-08-30 00:16:34,092:INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): acme-staging.api.letsencrypt.org
2016-08-30 00:16:34,160:DEBUG:requests.packages.urllib3.connectionpool:"GET /directory HTTP/1.1" 200 296
2016-08-30 00:16:34,161:DEBUG:root:Received <Response [200]>. Headers: {'Content-Length': '296', 'Expires': 'Tue, 30 Aug 2016 00:16:35 GMT', 'Boulder-Request-Id': '7b4gGu3TOF8_Gr6ULVEOSVBeYnSd4vf_ThkdZ1-4sMw', 'Strict-Transport-Security': 'max-age=604800', 'Server': 'nginx', 'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'max-age=0, no-cache, no-store', 'Date': 'Tue, 30 Aug 2016 00:16:35 GMT', 'X-Frame-Options': 'DENY', 'Content-Type': 'application/json', 'Replay-Nonce': 'gBl7jt9wnvPAKFYVEQ7b2zA6yE0k-v3j82I4aU8sW1Y'}. Content: '{\n  "new-authz": "https://acme-staging.api.letsencrypt.org/acme/new-authz",\n  "new-cert": "https://acme-staging.api.letsencrypt.org/acme/new-cert",\n  "new-reg": "https://acme-staging.api.letsencrypt.org/acme/new-reg",\n  "revoke-cert": "https://acme-staging.api.letsencrypt.org/acme/revoke-cert"\n}'
2016-08-30 00:16:34,161:DEBUG:acme.client:Received response <Response [200]> (headers: {'Content-Length': '296', 'Expires': 'Tue, 30 Aug 2016 00:16:35 GMT', 'Boulder-Request-Id': '7b4gGu3TOF8_Gr6ULVEOSVBeYnSd4vf_ThkdZ1-4sMw', 'Strict-Transport-Security': 'max-age=604800', 'Server': 'nginx', 'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'max-age=0, no-cache, no-store', 'Date': 'Tue, 30 Aug 2016 00:16:35 GMT', 'X-Frame-Options': 'DENY', 'Content-Type': 'application/json', 'Replay-Nonce': 'gBl7jt9wnvPAKFYVEQ7b2zA6yE0k-v3j82I4aU8sW1Y'}): '{\n  "new-authz": "https://acme-staging.api.letsencrypt.org/acme/new-authz",\n  "new-cert": "https://acme-staging.api.letsencrypt.org/acme/new-cert",\n  "new-reg": "https://acme-staging.api.letsencrypt.org/acme/new-reg",\n  "revoke-cert": "https://acme-staging.api.letsencrypt.org/acme/revoke-cert"\n}'
2016-08-30 00:16:34,162:DEBUG:root:Requesting fresh nonce
2016-08-30 00:16:34,162:DEBUG:root:Sending HEAD request to https://acme-staging.api.letsencrypt.org/acme/revoke-cert. args: (), kwargs: {}
2016-08-30 00:16:34,208:DEBUG:requests.packages.urllib3.connectionpool:"HEAD /acme/revoke-cert HTTP/1.1" 405 0
2016-08-30 00:16:34,209:DEBUG:root:Received <Response [405]>. Headers: {'Content-Length': '91', 'Pragma': 'no-cache', 'Boulder-Request-Id': 'AO_jx2l3csDXa1LveG0ZlBiLFPrBjmfFdQIdoyqcY_g', 'Expires': 'Tue, 30 Aug 2016 00:16:35 GMT', 'Server': 'nginx', 'Connection': 'keep-alive', 'Allow': 'POST', 'Cache-Control': 'max-age=0, no-cache, no-store', 'Date': 'Tue, 30 Aug 2016 00:16:35 GMT', 'Content-Type': 'application/problem+json', 'Replay-Nonce': 'Fc7kyPl0ssCE4O-paa5BcgA22g5xToubBT53qauyrtE'}. Content: ''
2016-08-30 00:16:34,209:DEBUG:acme.client:Storing nonce: '\x15\xce\xe4\xc8\xf9t\xb2\xc0\x84\xe0\xef\xa9i\xaeAr\x006\xda\x0eqN\x8b\x9b\x05>w\xa9\xab\xb2\xae\xd1'
2016-08-30 00:16:34,210:DEBUG:acme.client:Serialized JSON: {"resource": "revoke-cert", "certificate": "MIIF5TCCBM2gAwIBAgITA...xq-Pk7_2e5O6WsUmhPwCFnA"}
2016-08-30 00:16:34,212:DEBUG:acme.jose.json_util:Omitted empty fields: cty=None, x5t=None, crit=(), x5tS256=None, x5u=None, x5c=(), alg=None, jku=None, typ=None, kid=None, jwk=None
2016-08-30 00:16:34,231:DEBUG:acme.jose.json_util:Omitted empty fields: cty=None, x5t=None, crit=(), x5tS256=None, x5u=None, x5c=(), jku=None, typ=None, nonce=None, kid=None
2016-08-30 00:16:34,232:DEBUG:root:Sending POST request to https://acme-staging.api.letsencrypt.org/acme/revoke-cert. args: (), kwargs: {'data': '{"header": {"alg": "RS256", "jwk": {"e": "AQAB", "kty": "RSA", "n": "zl2blY2nAMkv2I...ODi6B9tn7QLq09kBEOWdBos"}'}
2016-08-30 00:16:34,296:DEBUG:requests.packages.urllib3.connectionpool:"POST /acme/revoke-cert HTTP/1.1" 200 0
2016-08-30 00:16:34,297:DEBUG:root:Received <Response [200]>. Headers: {'Content-Length': '0', 'Expires': 'Tue, 30 Aug 2016 00:16:35 GMT', 'Boulder-Request-Id': 'LldYZg01ysuOKfYaXTbH-x8TI8EPMI9eBX-fC-JI7P4', 'Strict-Transport-Security': 'max-age=604800', 'Server': 'nginx', 'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'max-age=0, no-cache, no-store', 'Date': 'Tue, 30 Aug 2016 00:16:35 GMT', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/plain; charset=utf-8', 'Replay-Nonce': 'deIOZEugv83umuq2yGx4KrsmMb2IlTe4XDm34TbjTPY'}. Content: ''
2016-08-30 00:16:34,297:DEBUG:acme.client:Storing nonce: 'u\xe2\x0edK\xa0\xbf\xcd\xee\x9a\xea\xb6\xc8lx*\xbb&1\xbd\x88\x957\xb8\\9\xb7\xe16\xe3L\xf6'
2016-08-30 00:16:34,298:DEBUG:acme.client:Received response <Response [200]> (headers: {'Content-Length': '0', 'Expires': 'Tue, 30 Aug 2016 00:16:35 GMT', 'Boulder-Request-Id': 'LldYZg01ysuOKfYaXTbH-x8TI8EPMI9eBX-fC-JI7P4', 'Strict-Transport-Security': 'max-age=604800', 'Server': 'nginx', 'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'max-age=0, no-cache, no-store', 'Date': 'Tue, 30 Aug 2016 00:16:35 GMT', 'X-Frame-Options': 'DENY', 'Content-Type': 'text/plain; charset=utf-8', 'Replay-Nonce': 'deIOZEugv83umuq2yGx4KrsmMb2IlTe4XDm34TbjTPY'}): ''

and for try/fail of revoke for the ec cert

2016-08-30 00:18:00,522:DEBUG:certbot.main:Root logging level set at 30
2016-08-30 00:18:00,525:INFO:certbot.main:Saving debug log to /var/log/letsencrypt/letsencrypt.log
2016-08-30 00:18:00,526:DEBUG:certbot.main:certbot version: 0.8.1
2016-08-30 00:18:00,526:DEBUG:certbot.main:Arguments: ['--server', 'https://acme-staging.api.letsencrypt.org/directory', '--standalone', '--standalone-supported-challenges', 'tls-sni-01', '--key-path', '/etc/ssl/le/keys/privkey_ec.pem', '--cert-path', '/etc/letsencrypt/live/test0001.example.com/cert.ec.crt.pem', '-d', 'test0001.example.com']
2016-08-30 00:18:00,527:DEBUG:certbot.main:Discovered plugins: PluginsRegistry(PluginEntryPoint#apache,PluginEntryPoint#webroot,PluginEntryPoint#null,PluginEntryPoint#manual,PluginEntryPoint#standalone)
2016-08-30 00:18:00,535:DEBUG:certbot.main:Revoking /etc/letsencrypt/live/test0001.example.com/cert.ec.crt.pem using cert key /etc/ssl/le/keys/privkey_ec.pem
2016-08-30 00:18:00,743:DEBUG:certbot.main:Exiting abnormally:
Traceback (most recent call last):
  File "/root/.local/share/letsencrypt/bin/letsencrypt", line 11, in <module>
    sys.exit(main())
  File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/certbot/main.py", line 744, in main
    return config.func(config, plugins)
  File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/certbot/main.py", line 479, in revoke
    key = jose.JWK.load(config.key_path[1])
  File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/acme/jose/jwk.py", line 123, in load
    return jwk_cls(key=key)
  File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/acme/jose/json_util.py", line 222, in __init__
    **(dict(self._defaults(), **kwargs)))
  File "/root/.local/share/letsencrypt/lib/python2.7/site-packages/acme/jose/util.py", line 149, in __init__
    ', '.join(kwargs) if kwargs else 'none'))
TypeError: __init__() takes exactly the following arguments:  (key given)

@pfg

?

logs, as requested, above …

I was able to reproduce this. I believe the library that’s responsible for signing revocation requests in certbot (python-jose, or the glue code) might not support EC keys at the moment. This is probably related to this certbot issue.

Revocation requests can also be signed using the account key. If you still have the same account key that you used when you originally requested the certificate, you can get certbot to use the account key by getting rid of the --key-path argument. Alternatively, you might be able to revoke this certificate using a different client with support for revocation using EC keys. Unfortunately, I haven’t checked which clients do support this.

2 Likes

I was able to reproduce this. I believe the library that's responsible for signing revocation requests in certbot (python-jose, or the glue code) might not support EC keys at the moment. This is probably related to this certbot issue2.

Reading here, and there ... wouldn't that suggest that it'd be similarly impossible to sign a request for creating a key? That's certainly working ... after all, I have an ECDSA key & cert.

Or is there something unique to the revocation request?

Revocation requests can also be signed using the account key. If you still have the same account key that you used when you originally requested the certificate, you can get certbot to use the account key by getting rid of the --key-path argument.

I'll play with that, but the goal is to use cert-based revocation for both RSA & ECDSA keys

Alternatively, you might be able to revoke this certificate using a different client with support for revocation using EC keys.

Possible. Not really interested. The solution I'm building will be based off the recommended & 'most mainstream' (since I can't call it 'official') client. For now, that appears to be certbot.

Revocation requests are a bit of an outlier in that they can be signed both using the account key (which, in certbot's case, is always a RSA key) and the certificate's private key. This means you're still able to revoke certificates if you lose an account key. All other API requests are signed by the account key, so you wouldn't run into that problem for anything other than revocation.

(Note: Signed API requests are separate from things like signing CSRs, for which certbot relies on openssl.)

Revocation requests are a bit of an outlier in that they can be signed both using the account key (which, in certbot's case, is always a RSA key) and the certificate's private key. This means you're still able to revoke certificates if you lose an account key. All other API requests are signed by the account key, so you wouldn't run into that problem for anything other than revocation.

got it. at the least the reason why they'd be different.

This of course needs to be fixed, so let's let this stand as is -- with no "use another client" workaround -- and see what can be done.

If more info from here's needed let me know; but, sounds like you can reproduce in any case.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.