From fde359f4dac0c9d9ad7659d4f3682ee755c122ed Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Thu, 8 May 2025 15:43:37 -0700 Subject: [PATCH] fixup http01_example.py (#10285) it looks like https://github.com/certbot/certbot/pull/10098 introduced a couple bugs into this file: 1. [RSAPrivateKeys](https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/#cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey) don't have a `public_bytes` method 2. `cryptography.x509` wasn't imported and [load_pem_x509_certificate](https://cryptography.io/en/latest/x509/reference/#cryptography.x509.load_pem_x509_certificate) takes bytes, not a string i think avoiding this is unfortunately difficult as this file has no tests, but it was useful for me just now when testing https://github.com/certbot/certbot/pull/10283 so i wanted to fix it up i also changed the script to initially create the account without an email address as the fake@example.com email causes registration with LE's staging server to fail early in execution with the changes in this PR changes, if you: 1. change the value of [DOMAIN](https://github.com/certbot/certbot/blob/0075104805e2e4fd9cf0e6ec69d80ab203e03655/acme/examples/http01_example.py#L57) to a domain pointing at your machine 2. as root, activate your certbot dev environment, and run `python acme/examples/http01_example.py ` it will fail late in the script with: ``` Traceback (most recent call last): File "/home/brad/certbot/acme/examples/http01_example.py", line 237, in example_http() ~~~~~~~~~~~~^^ File "/home/brad/certbot/acme/examples/http01_example.py", line 223, in example_http regr = client_acme.update_registration( regr.update( ...<3 lines>... ) ) File "/home/brad/certbot/acme/src/acme/client.py", line 101, in update_registration updated_regr = self._send_recv_regr(regr, body=body) File "/home/brad/certbot/acme/src/acme/client.py", line 373, in _send_recv_regr response = self._post(regr.uri, body) File "/home/brad/certbot/acme/src/acme/client.py", line 392, in _post return self.net.post(*args, **kwargs) ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^ File "/home/brad/certbot/acme/src/acme/client.py", line 766, in post return self._post_once(*args, **kwargs) ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^ File "/home/brad/certbot/acme/src/acme/client.py", line 781, in _post_once response = self._check_response(response, content_type=content_type) File "/home/brad/certbot/acme/src/acme/client.py", line 630, in _check_response raise messages.Error.from_json(jobj) acme.messages.Error: urn:ietf:params:acme:error:invalidContact :: The provided contact URI was invalid :: Unable to update account :: invalid contact: contact email has forbidden domain "example.org" ``` if you also change [this email variable](https://github.com/certbot/certbot/blob/0075104805e2e4fd9cf0e6ec69d80ab203e03655/acme/examples/http01_example.py#L223) to a valid email address, the script will run successfully --- acme/examples/http01_example.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/acme/examples/http01_example.py b/acme/examples/http01_example.py index 0598fda41..d1ff8a4ef 100644 --- a/acme/examples/http01_example.py +++ b/acme/examples/http01_example.py @@ -27,11 +27,11 @@ Workflow: """ from contextlib import contextmanager +from cryptography import x509 from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa import josepy as jose -import OpenSSL from acme import challenges from acme import client @@ -70,7 +70,9 @@ def new_csr_comp(domain_name, pkey_pem=None): if pkey_pem is None: # Create private key. pkey = rsa.generate_private_key(public_exponent=65537, key_size=CERT_PKEY_BITS) - pkey_pem = pkey.public_bytes(serialization.Encoding.PEM) + pkey_pem = pkey.private_bytes(encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption()) csr_pem = crypto_util.make_csr(pkey_pem, [domain_name]) return pkey_pem, csr_pem @@ -168,11 +170,8 @@ def example_http(): # Terms of Service URL is in client_acme.directory.meta.terms_of_service # Registration Resource: regr - # Creates account with contact information. - email = ('fake@example.com') regr = client_acme.new_account( - messages.NewRegistration.from_data( - email=email, terms_of_service_agreed=True)) + messages.NewRegistration.from_data(terms_of_service_agreed=True)) # Create domain private key and CSR pkey_pem, csr_pem = new_csr_comp(DOMAIN) @@ -200,7 +199,7 @@ def example_http(): # Revoke certificate - fullchain_com = x509.load_pem_x509_certificate(fullchain_pem) + fullchain_com = x509.load_pem_x509_certificate(fullchain_pem.encode()) try: client_acme.revoke(fullchain_com, 0) # revocation reason = 0