import json, urllib.request, base64, hmac, hashlib, sys

def b64url(b): return base64.urlsafe_b64encode(b).rstrip(b'=').decode()

acct = json.load(open('/root/.acme.sh/ca/acme.zerossl.com/v2/DV90/account.json'))
orders = acct.get('orders', [])
print("=== ORDERS in account ===")
for o in orders:
    print(json.dumps(o, indent=2)[:800])

# Load account key (PEM)
key_pem = open('/root/.acme.sh/ca/acme.zerossl.com/v2/DV90/account.key','rb').read()
caconf = open('/root/.acme.sh/ca/acme.zerossl.com/v2/DV90/ca.conf').read()
import re
kid = re.search(r"CA_EAB_KEY_ID='([^']+)'", caconf).group(1)
hmac_key = re.search(r"CA_EAB_HMAC_KEY='([^']+)'", caconf).group(1)

# Build JWK from RSA key using cryptography
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers
key = load_pem_private_key(key_pem, password=None)
pub = key.public_key()
n = pub.n; e = pub.e
jwk = {
  "kty":"RSA","use":"sig",
  "n": b64url(n.to_bytes((n.bit_length()+7)//8,'big')),
  "e": b64url(e.to_bytes((e.bit_length()+7)//8,'big')),
}
# EAB
eab_jwk = {"alg":"HS256","kid":kid}
eab_hdr = {"alg":"HS256","jwk":eab_jwk}
eab_payload = b''
eab_sig = hmac.new(base64.urlsafe_b64decode(hmac_key+'=='), 
                   (b64url(json.dumps(eab_hdr,separators=(',',':')))+b'.'+b64url(eab_payload)),
                   hashlib.sha256).digest()
eab = {"protected": b64url(json.dumps(eab_hdr,separators=(',',':')).encode()),
       "payload": b64url(eab_payload),
       "signature": b64url(eab_sig)}

ORDER_URL = "https://acme.zerossl.com/v2/DV90/order/xjUXizbxcyKU_DcU7c_cBA"

def sign_nonce(url, method, nonce, payload=None):
    hdr = {"alg":"RS256","jwk":jwk,"nonce":nonce,"url":url}
    h64 = b64url(json.dumps(hdr,separators=(',',':')).encode())
    p64 = b64url(json.dumps(payload).encode()) if payload else b64url(b'')
    signing_input = f"{h64}.{p64}".encode()
    sig = key.sign(signing_input, __import__('cryptography.hazmat.primitives.asymmetric',fromlist=['padding']).padding.PSS(mgf=__import__('cryptography.hazmat.primitives.asymmetric',fromlist=['mgf1']).mgf1(__import__('cryptography.hazmat.primitives.hashes',fromlist=['SHA256']).SHA256()), salt_length=32))
    body = {"protected":h64,"payload":p64,"signature":b64url(sig)}
    req = urllib.request.Request(f"{url}", data=json.dumps(body).encode(), headers={"Content-Type":"application/jose+json","User-Agent":"zsquery/1"})
    resp = urllib.request.urlopen(req, timeout=20)
    return resp.status, json.loads(resp.read().decode())

# Get nonce
req = urllib.request.Request(ORDER_URL, method="HEAD", headers={"User-Agent":"zsquery/1"})
try:
    r = urllib.request.urlopen(req, timeout=15)
except Exception as ex:
    # HEAD may fail, use GET on directory for nonce
    pass
# Use a POST-as-GET with nonce from a new request
# First get a nonce via a dummy request
req = urllib.request.Request("https://acme.zerossl.com/v2/DV90/new-nonce", method="HEAD")
r = urllib.request.urlopen(req, timeout=15)
nonce = r.headers.get("Replay-Nonce")
print("\nnonce:", nonce)
status, result = sign_nonce(ORDER_URL, "POST", nonce, {})
print("\n=== ORDER STATUS ===")
print("HTTP", status)
print(json.dumps(result, indent=2)[:1500])
