From 4f0fe2c74a88115be78d711f05f92ba0293b89c3 Mon Sep 17 00:00:00 2001 From: Kishi85 Date: Mon, 15 Apr 2019 18:12:50 +0200 Subject: [PATCH] tools: Add support for Ed25519 and Ed448 account keys Add support for Ed25519 and Ed448 account keys in addition to already supported algorithms --- README.md | 3 ++- acertmgr/tools.py | 20 ++++++++++++++++++++ docs/archlinux/python-acertmgr/PKGBUILD | 1 + docs/archlinux/python2-acertmgr/PKGBUILD | 1 + 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4307b6c..e702799 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,8 @@ Optional packages (required to use specified features) * dnspython: used by dns.* challenge handlers * idna: to allow automatic conversion of unicode domain names to their IDNA2008 counterparts * cryptography>=2.1: for creating certificates with the OCSP must-staple flag (cert_must_staple) - + * cryptography>=2.6: for usage of (pre-created) Ed25519 keys + Setup ----- diff --git a/acertmgr/tools.py b/acertmgr/tools.py index f4e5f20..d495c4b 100644 --- a/acertmgr/tools.py +++ b/acertmgr/tools.py @@ -21,6 +21,11 @@ from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature from cryptography.utils import int_to_bytes from cryptography.x509.oid import NameOID, ExtensionOID +try: + from cryptography.hazmat.primitives.asymmetric import ed25519, ed448 +except ImportError: + pass + try: from urllib.request import urlopen, Request # Python 3 except ImportError: @@ -260,6 +265,19 @@ def get_key_alg_and_jwk(key): return alg, {"kty": "EC", "crv": crv, "x": bytes_to_base64url(int_to_bytes(numbers.x, full_octets)), "y": bytes_to_base64url(int_to_bytes(numbers.y, full_octets))} + elif "cryptography.hazmat.primitives.asymmetric.ed25519" in sys.modules and isinstance(key, + ed25519.Ed25519PrivateKey): + # See https://tools.ietf.org/html/rfc8037#appendix-A.2 + return "EdDSA", {"kty": "OKP", "crv": "Ed25519", + "x": bytes_to_base64url(key.public_key().public_bytes(encoding=serialization.Encoding.Raw, + format=serialization.PublicFormat.Raw) + )} + elif "cryptography.hazmat.primitives.asymmetric.ed448" in sys.modules and isinstance(key, + ed448.Ed448PrivateKey): + return "EdDSA", {"kty": "OKP", "crv": "Ed448", + "x": bytes_to_base64url(key.public_key().public_bytes(encoding=serialization.Encoding.Raw, + format=serialization.PublicFormat.Raw) + )} else: raise ValueError("Unsupported key: {}".format(key)) @@ -283,6 +301,8 @@ def signature_of_str(key, string): # convert DER signature to RAW format (https://tools.ietf.org/html/rfc7518#section-3.4) r, s = decode_dss_signature(der_sig) return int_to_bytes(r, full_octets) + int_to_bytes(s, full_octets) + elif alg == 'EdDSA': + return key.sign(data) else: raise ValueError("Unsupported signature algorithm: {}".format(alg)) diff --git a/docs/archlinux/python-acertmgr/PKGBUILD b/docs/archlinux/python-acertmgr/PKGBUILD index f61d6cd..67125e0 100644 --- a/docs/archlinux/python-acertmgr/PKGBUILD +++ b/docs/archlinux/python-acertmgr/PKGBUILD @@ -11,6 +11,7 @@ optdepends=('python-yaml: Support config files in YAML format' 'python-idna: Support conversion of unicode domains' 'python-dnspython: Support for dns challenge handlers' 'python-cryptography>=2.1: Support for the OCSP must-staple flag' + 'python-cryptography>=2.6: Support for Ed25519 key support' ) makedepends=('git') conflicts=('python-acertmgr') diff --git a/docs/archlinux/python2-acertmgr/PKGBUILD b/docs/archlinux/python2-acertmgr/PKGBUILD index 2d45788..f87000f 100644 --- a/docs/archlinux/python2-acertmgr/PKGBUILD +++ b/docs/archlinux/python2-acertmgr/PKGBUILD @@ -11,6 +11,7 @@ optdepends=('python2-yaml: Support config files in YAML format' 'python2-idna: Support conversion of unicode domains' 'python2-dnspython: Support for dns challenge handlers' 'python2-cryptography>=2.1: Support for the OCSP must-staple flag' + 'python2-cryptography>=2.6: Support for Ed25519 key support' ) makedepends=('git') conflicts=('python-acertmgr')