diff --git a/Dockerfile b/Dockerfile index fa0ad6338..9a225af5b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,8 +3,7 @@ ENV DOMAIN=localhost RUN apt-get update && \ apt-get -y install \ imagemagick \ - python3-crypto \ - python3-pycryptodome \ + python3-cryptography \ python3-dateutil \ python3-idna \ python3-requests \ diff --git a/README.md b/README.md index bcf442eed..8a0afc7c5 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ You will need python version 3.7 or later. On Arch/Parabola: ``` bash -sudo pacman -S tor python-pip python-pysocks python-pycryptodome \ +sudo pacman -S tor python-pip python-pysocks python-cryptography \ imagemagick python-requests \ perl-image-exiftool python-dateutil \ certbot flake8 bandit @@ -36,7 +36,7 @@ Or on Debian: sudo apt install -y \ tor python3-socks imagemagick \ python3-setuptools \ - python3-crypto python3-pycryptodome \ + python3-crypto python3-cryptography \ python3-dateutil \ python3-idna python3-requests \ python3-django-timezone-field \ diff --git a/deploy/i2p b/deploy/i2p index 2afeb74ab..79e5d7b7b 100755 --- a/deploy/i2p +++ b/deploy/i2p @@ -60,7 +60,7 @@ fi echo 'Adding Epicyon dependencies' if [ -f /usr/bin/pacman ]; then pacman -Syy - pacman -S --noconfirm python-pip python-pysocks python-pycryptodome \ + pacman -S --noconfirm python-pip python-pysocks python-cryptography \ imagemagick python-pillow python-requests \ perl-image-exiftool python-numpy python-dateutil \ certbot flake8 git i2pd wget qrencode \ @@ -68,7 +68,7 @@ if [ -f /usr/bin/pacman ]; then pip3 install pyLD pyqrcode pypng else apt-get update - apt-get -y install imagemagick python3-crypto python3-pycryptodome \ + apt-get -y install imagemagick python3-crypto python3-cryptography \ python3-dateutil python3-idna python3-requests \ python3-numpy python3-pil.imagetk python3-pip \ python3-setuptools python3-socks python3-idna \ diff --git a/deploy/onion b/deploy/onion index ea99ffea4..983866db6 100755 --- a/deploy/onion +++ b/deploy/onion @@ -35,14 +35,14 @@ EPICYON_PORT=7157 echo 'Adding Epicyon dependencies' if [ -f /usr/bin/pacman ]; then pacman -Syy - pacman -S --noconfirm tor python-pip python-pysocks python-pycryptodome \ + pacman -S --noconfirm tor python-pip python-pysocks python-cryptography \ imagemagick python-pillow python-requests \ perl-image-exiftool python-numpy python-dateutil \ certbot flake8 git qrencode bandit pip3 install pyLD pyqrcode pypng else apt-get update - apt-get -y install imagemagick python3-crypto python3-pycryptodome \ + apt-get -y install imagemagick python3-crypto python3-cryptography \ python3-dateutil python3-idna python3-requests \ python3-numpy python3-pil.imagetk python3-pip \ python3-setuptools python3-socks python3-idna \ diff --git a/gemini/EN/install.gmi b/gemini/EN/install.gmi index 49dfaec68..35a28dba9 100644 --- a/gemini/EN/install.gmi +++ b/gemini/EN/install.gmi @@ -4,7 +4,7 @@ You will need python version 3.7 or later. On a Debian based system: - sudo apt install -y tor python3-socks imagemagick python3-setuptools python3-crypto python3-pycryptodome python3-dateutil python3-idna python3-requests python3-flake8 python3-django-timezone-field python3-pyqrcode python3-png python3-bandit libimage-exiftool-perl certbot nginx wget + sudo apt install -y tor python3-socks imagemagick python3-setuptools python3-crypto python3-cryptography python3-dateutil python3-idna python3-requests python3-flake8 python3-django-timezone-field python3-pyqrcode python3-png python3-bandit libimage-exiftool-perl certbot nginx wget The following instructions install Epicyon to the /opt directory. It's not essential that it be installed there, and it could be in any other preferred directory. diff --git a/httpsig.py b/httpsig.py index 443cd9a2c..a1d852284 100644 --- a/httpsig.py +++ b/httpsig.py @@ -1,4 +1,4 @@ -__filename__ = "posts.py" +__filename__ = "httpsig.py" __author__ = "Bob Mottram" __credits__ = ['lamia'] __license__ = "AGPL3+" @@ -9,26 +9,28 @@ __status__ = "Production" # see https://tools.ietf.org/html/draft-cavage-http-signatures-06 -try: - from Cryptodome.PublicKey import RSA - from Cryptodome.Hash import SHA256 - from Cryptodome.Signature import pkcs1_15 -except ImportError: - from Crypto.PublicKey import RSA - from Crypto.Hash import SHA256 - # from Crypto.Signature import PKCS1_v1_5 - from Crypto.Signature import pkcs1_15 - +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives.serialization import load_pem_private_key +from cryptography.hazmat.primitives.serialization import load_pem_public_key +from cryptography.hazmat.primitives.asymmetric import padding +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import utils as hazutils import base64 from time import gmtime, strftime import datetime from utils import getFullDomain +def _getSHA256(msg: str): + digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) + digest.update(msg) + return digest.finalize() + + def messageContentDigest(messageBodyJsonStr: str) -> str: msg = messageBodyJsonStr.encode('utf-8') - digestStr = SHA256.new(msg).digest() - return base64.b64encode(digestStr).decode('utf-8') + hashResult = _getSHA256(msg) + return base64.b64encode(hashResult).decode('utf-8') def signPostHeaders(dateStr: str, privateKeyPem: str, @@ -66,7 +68,8 @@ def signPostHeaders(dateStr: str, privateKeyPem: str, 'content-type': 'application/activity+json', 'content-length': str(contentLength) } - privateKeyPem = RSA.import_key(privateKeyPem) + key = load_pem_private_key(privateKeyPem.encode('utf-8'), + None, backend=default_backend()) # headers.update({ # '(request-target)': f'post {path}', # }) @@ -76,10 +79,14 @@ def signPostHeaders(dateStr: str, privateKeyPem: str, for headerKey in signedHeaderKeys: signedHeaderText += f'{headerKey}: {headers[headerKey]}\n' signedHeaderText = signedHeaderText.strip() - headerDigest = SHA256.new(signedHeaderText.encode('ascii')) + # signedHeaderText.encode('ascii') matches + headerDigest = _getSHA256(signedHeaderText.encode('ascii')) + # print('headerDigest2: ' + str(headerDigest)) # Sign the digest - rawSignature = pkcs1_15.new(privateKeyPem).sign(headerDigest) + rawSignature = key.sign(headerDigest, + padding.PKCS1v15(), + hazutils.Prehashed(hashes.SHA256())) signature = base64.b64encode(rawSignature).decode('ascii') # Put it into a valid HTTP signature format @@ -176,7 +183,8 @@ def verifyPostHeaders(httpPrefix: str, publicKeyPem: str, headers: dict, if debug: print('DEBUG: verifyPostHeaders ' + method) - publicKeyPem = RSA.import_key(publicKeyPem) + pubkey = load_pem_public_key(publicKeyPem.encode('utf-8'), + backend=default_backend()) # Build a dictionary of the signature values signatureHeader = headers['signature'] signatureDict = { @@ -244,16 +252,19 @@ def verifyPostHeaders(httpPrefix: str, publicKeyPem: str, headers: dict, print('DEBUG: signedHeaderList: ' + str(signedHeaderList)) # Now we have our header data digest signedHeaderText = '\n'.join(signedHeaderList) - headerDigest = SHA256.new(signedHeaderText.encode('ascii')) + headerDigest = _getSHA256(signedHeaderText.encode('ascii')) # Get the signature, verify with public key, return result signature = base64.b64decode(signatureDict['signature']) try: - pubKey = pkcs1_15.new(publicKeyPem) - pubKey.verify(headerDigest, signature) + pubkey.verify( + signature, + headerDigest, + padding.PKCS1v15(), + hazutils.Prehashed(hashes.SHA256())) return True - except (ValueError, TypeError): + except BaseException: if debug: print('DEBUG: verifyPostHeaders pkcs1_15 verify failure') return False diff --git a/setup.cfg b/setup.cfg index f7985ac16..3f3e838ff 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,7 +29,7 @@ install_requires = idna >= 2.5, < 3 numpy >= 1.20.0, < 2 pillow >= 8.1.0, < 9 - pycryptodome >= 3.9.9, < 4 + cryptography pyqrcode >= 1.2.1, < 2 python-dateutil >= 2.8.1, < 3 requests >= 2.25.1, < 3 diff --git a/website/EN/index.html b/website/EN/index.html index 39a8b3af8..ea28c162b 100644 --- a/website/EN/index.html +++ b/website/EN/index.html @@ -1267,7 +1267,7 @@
You will need python version 3.7 or later.
On a Debian based system:
sudo apt install -y tor python3-socks imagemagick python3-setuptools python3-crypto python3-pycryptodome python3-dateutil python3-idna python3-requests python3-flake8 python3-django-timezone-field python3-pyqrcode python3-png python3-bandit libimage-exiftool-perl certbot nginx wget
+sudo apt install -y tor python3-socks imagemagick python3-setuptools python3-crypto python3-cryptography python3-dateutil python3-idna python3-requests python3-flake8 python3-django-timezone-field python3-pyqrcode python3-png python3-bandit libimage-exiftool-perl certbot nginx wget