mirror of
https://github.com/moepman/acertmgr.git
synced 2024-12-28 18:21:51 +01:00
tools: add support for EC account keys
Allows usage of pre-generated EC account keys (P-256, P-384, P-521) in addition to already supported RSA keys.
This commit is contained in:
parent
1f5ef9322b
commit
4df74d67d5
@ -12,7 +12,7 @@ Requirements
|
||||
------------
|
||||
|
||||
* Python (2.7+ and 3.5+ should work)
|
||||
* cryptography (includes the optional idna module)
|
||||
* cryptography>=0.6 (includes the optional idna module)
|
||||
|
||||
Optional packages (required to use specified features)
|
||||
------------------------------------------------------
|
||||
@ -21,7 +21,7 @@ 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)
|
||||
|
||||
|
||||
Setup
|
||||
-----
|
||||
|
||||
|
@ -17,8 +17,10 @@ import traceback
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import hashes, serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa, padding
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa, ec, padding
|
||||
from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature
|
||||
from cryptography.x509.oid import NameOID, ExtensionOID
|
||||
from cryptography.utils import int_to_bytes
|
||||
|
||||
try:
|
||||
from urllib.request import urlopen, Request # Python 3
|
||||
@ -241,6 +243,24 @@ def get_key_alg_and_jwk(key):
|
||||
return "RS256", {"kty": "RSA",
|
||||
"e": bytes_to_base64url(number_to_byte_format(numbers.e)),
|
||||
"n": bytes_to_base64url(number_to_byte_format(numbers.n))}
|
||||
elif isinstance(key, ec.EllipticCurvePrivateKey):
|
||||
# See https://tools.ietf.org/html/rfc7518#section-6.2
|
||||
numbers = key.public_key().public_numbers()
|
||||
if isinstance(numbers.curve, ec.SECP256R1):
|
||||
alg = 'ES256'
|
||||
crv = 'P-256'
|
||||
elif isinstance(numbers.curve, ec.SECP384R1):
|
||||
alg = 'ES384'
|
||||
crv = 'P-384'
|
||||
elif isinstance(numbers.curve, ec.SECP521R1):
|
||||
alg = 'ES512'
|
||||
crv = 'P-521'
|
||||
else:
|
||||
raise ValueError("Unsupported EC curve in key: {}".format(key))
|
||||
full_octets = (int(crv[2:]) + 7) // 8
|
||||
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))}
|
||||
else:
|
||||
raise ValueError("Unsupported key: {}".format(key))
|
||||
|
||||
@ -251,6 +271,19 @@ def signature_of_str(key, string):
|
||||
data = string.encode('utf8')
|
||||
if alg == 'RS256':
|
||||
return key.sign(data, padding.PKCS1v15(), hashes.SHA256())
|
||||
elif alg.startswith('ES'):
|
||||
full_octets = (int(alg[2:]) + 7) // 8
|
||||
if alg == 'ES256':
|
||||
der_sig = key.sign(data, ec.ECDSA(hashes.SHA256()))
|
||||
elif alg == 'ES384':
|
||||
der_sig = key.sign(data, ec.ECDSA(hashes.SHA384()))
|
||||
elif alg == 'ES512':
|
||||
der_sig = key.sign(data, ec.ECDSA(hashes.SHA512()))
|
||||
else:
|
||||
raise ValueError("Unsupported EC signature algorithm: {}".format(alg))
|
||||
# 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)
|
||||
else:
|
||||
raise ValueError("Unsupported signature algorithm: {}".format(alg))
|
||||
|
||||
|
@ -6,11 +6,11 @@ pkgdesc='An automated certificate manager using ACME/letsencrypt'
|
||||
arch=('any')
|
||||
url='https://github.com/moepman/acertmgr'
|
||||
license=('ISC')
|
||||
depends=('python-cryptography')
|
||||
depends=('python-cryptography>=0.6')
|
||||
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-dnspython: Support for dns challenge handlers'
|
||||
'python-cryptography>=2.1: Support for the OCSP must-staple flag'
|
||||
)
|
||||
makedepends=('git')
|
||||
conflicts=('python-acertmgr')
|
||||
|
@ -6,11 +6,11 @@ pkgdesc='An automated certificate manager using ACME/letsencrypt'
|
||||
arch=('any')
|
||||
url='https://github.com/moepman/acertmgr'
|
||||
license=('ISC')
|
||||
depends=('python2-cryptography')
|
||||
depends=('python2-cryptography>=0.6')
|
||||
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-dnspython: Support for dns challenge handlers'
|
||||
'python2-cryptography>=2.1: Support for the OCSP must-staple flag'
|
||||
)
|
||||
makedepends=('git')
|
||||
conflicts=('python-acertmgr')
|
||||
|
5
setup.py
5
setup.py
@ -65,7 +65,7 @@ setup(
|
||||
"License :: OSI Approved :: ISC License",
|
||||
],
|
||||
install_requires=[
|
||||
"cryptography",
|
||||
"cryptography>=0.6",
|
||||
],
|
||||
extras_require={
|
||||
"dns": [
|
||||
@ -80,6 +80,9 @@ setup(
|
||||
"ocsp-must-staple": [
|
||||
"cryptography>=2.1",
|
||||
],
|
||||
"ed25519": [
|
||||
"cryptography>=2.6",
|
||||
],
|
||||
},
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
|
Loading…
Reference in New Issue
Block a user