Skip to content

Instantly share code, notes, and snippets.

@pettinen
Created January 11, 2024 21:55
Show Gist options
  • Save pettinen/c385c546ac0862fe1671c7a67c086ed4 to your computer and use it in GitHub Desktop.
Save pettinen/c385c546ac0862fe1671c7a67c086ed4 to your computer and use it in GitHub Desktop.
Register a new account with an ACME server.
import hashlib
import json
import os
import platform
from datetime import datetime, UTC
from acme.client import ClientNetwork, ClientV2
from acme.messages import NewRegistration
from cryptography.hazmat.primitives.asymmetric.ec import generate_private_key, SECP256R1
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
from josepy import ES256, JWKEC
def register(
email: str | None,
*,
output_dir: str | None = None,
server: str = "https://acme-staging-v02.api.letsencrypt.org/directory",
) -> None:
"""Register a new account with an ACME server.
The sole reason you would use this instead of `certbot register` is to
get an ECDSA account key; currently (2024-01-11) Certbot has no option
to change the key type for account keys.
"""
if output_dir is not None:
os.chdir(output_dir)
key = generate_private_key(SECP256R1())
jwk = JWKEC(key=key)
network = ClientNetwork(jwk, alg=ES256)
directory = ClientV2.get_directory(server, network)
acme = ClientV2(directory, network)
regr = acme.new_account(
NewRegistration.from_data(email=email, terms_of_service_agreed=True)
)
hasher = hashlib.md5()
hasher.update(
key.public_key().public_bytes(
encoding=Encoding.PEM,
format=PublicFormat.SubjectPublicKeyInfo,
)
)
public_key_hash = hasher.hexdigest()
print(f"Key:\n{jwk.json_dumps_pretty()}")
print(f"Account URI: {regr.uri}")
print(f"Public key hash: {public_key_hash}")
os.mkdir(public_key_hash, mode=0o700)
os.chdir(public_key_hash)
os.umask(0o177)
with open("private_key.json", "x") as f:
json.dump(jwk, f, default=jwk.json_dump_default)
with open("regr.json", "x") as f:
json.dump(regr, f, default=regr.json_dump_default)
with open("meta.json", "x") as f:
meta = {
"creation_dt": datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%SZ"),
"creation_host": platform.node(),
}
json.dump(meta, f)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment