create-gpg-shadow-key-from-x509-cert-req.py 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. #!/usr/bin/env python3
  2. import cryptography.hazmat.backends
  3. import cryptography.hazmat.primitives.serialization
  4. import cryptography.x509
  5. import math
  6. def convert_to_sexp(data):
  7. if isinstance(data, int):
  8. return convert_to_sexp(data.to_bytes(
  9. math.ceil(data.bit_length() / 8),
  10. 'big',
  11. ))
  12. elif isinstance(data, str):
  13. return convert_to_sexp(data.encode())
  14. elif isinstance(data, bytes):
  15. return str(len(data)).encode() + b':' + data
  16. else:
  17. return b'(' + b''.join(convert_to_sexp(i) for i in data) + b')'
  18. def main(argv):
  19. backend = cryptography.hazmat.backends.default_backend()
  20. with open('smartcard-app-id.hex', 'r') as f:
  21. appid = int(f.read(), 16)
  22. with open('cert-request.pem', 'rb') as f:
  23. req = cryptography.x509.load_pem_x509_csr(f.read(), backend)
  24. assert req.is_signature_valid
  25. pubnums = req.public_key().public_numbers()
  26. key_data = ['shadowed-private-key', [
  27. 'rsa',
  28. ['n', pubnums.n],
  29. ['e', pubnums.e],
  30. ['shadowed', 't1-v1', [appid, 'OPENPGP.1']],
  31. ]]
  32. key = convert_to_sexp(key_data)
  33. with open('gpg-key.sexp', 'wb') as f:
  34. f.write(key)
  35. if __name__ == '__main__':
  36. import sys
  37. sys.exit(main(sys.argv))