Skip to content

Commit

Permalink
Merge pull request #698 from ae-utbm/update-cryptography
Browse files Browse the repository at this point in the history
update cryptography
  • Loading branch information
imperosol authored Jul 5, 2024
2 parents e47f29a + 70fdc2e commit 3014d8c
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 81 deletions.
11 changes: 7 additions & 4 deletions eboutic/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,14 @@
import json
import urllib

from cryptography.hazmat.primitives.asymmetric.padding import PKCS1v15
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
from cryptography.hazmat.primitives.hashes import SHA1
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from django.conf import settings
from django.db.models import Max
from django.test import TestCase
from django.urls import reverse
from OpenSSL import crypto

from core.models import User
from counter.models import Counter, Customer, Product, Selling
Expand Down Expand Up @@ -67,12 +70,12 @@ def generate_bank_valid_answer(self) -> str:
basket_id = basket.id
amount = int(basket.get_total() * 100)
query = f"Amount={amount}&BasketID={basket_id}&Auto=42&Error=00000"
with open("./eboutic/tests/private_key.pem") as f:
with open("./eboutic/tests/private_key.pem", "br") as f:
PRIVKEY = f.read()
with open("./eboutic/tests/public_key.pem") as f:
settings.SITH_EBOUTIC_PUB_KEY = f.read()
privkey = crypto.load_privatekey(crypto.FILETYPE_PEM, PRIVKEY)
sig = crypto.sign(privkey, query.encode("utf-8"), "sha1")
key: RSAPrivateKey = load_pem_private_key(PRIVKEY, None)
sig = key.sign(query.encode("utf-8"), PKCS1v15(), SHA1())
b64sig = base64.b64encode(sig).decode("ascii")

url = reverse("eboutic:etransation_autoanswer") + "?%s&Sig=%s" % (
Expand Down
31 changes: 18 additions & 13 deletions eboutic/tests/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,33 @@

import base64

from OpenSSL import crypto
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives.asymmetric.padding import PKCS1v15
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey
from cryptography.hazmat.primitives.hashes import SHA1
from cryptography.hazmat.primitives.serialization import (
load_pem_private_key,
load_pem_public_key,
)

with open("./private_key.pem") as f:
PRVKEY = f.read()
with open("./public_key.pem") as f:
with open("./private_key.pem", "br") as f:
PRIVKEY = f.read()
with open("./public_key.pem", "br") as f:
PUBKEY = f.read()

data = "Amount=400&BasketID=4000&Auto=42&Error=00000\n".encode("utf-8")

# Sign
prvkey = crypto.load_privatekey(crypto.FILETYPE_PEM, PRVKEY)
sig = crypto.sign(prvkey, data, "sha1")
b64sig = base64.b64encode(sig)
privkey: RSAPrivateKey = load_pem_private_key(PRIVKEY, None)
signature = privkey.sign(data, PKCS1v15(), SHA1())
b64sig = base64.b64encode(signature)
print(b64sig)

# Verify
pubkey = crypto.load_publickey(crypto.FILETYPE_PEM, PUBKEY)
cert = crypto.X509()
cert.set_pubkey(pubkey)
sig = base64.b64decode(b64sig)
pubkey = load_pem_public_key(PUBKEY)
signature = base64.b64decode(b64sig)
try:
crypto.verify(cert, sig, data, "sha1")
pubkey.verify(signature, data, PKCS1v15(), SHA1())
print("Verify OK")
except:
except InvalidSignature as e:
print("Verify failed")
24 changes: 12 additions & 12 deletions eboutic/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
from urllib.parse import unquote

import sentry_sdk
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives.asymmetric.padding import PKCS1v15
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey
from cryptography.hazmat.primitives.hashes import SHA1
from cryptography.hazmat.primitives.serialization import load_pem_public_key
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.exceptions import SuspiciousOperation
Expand All @@ -29,7 +34,6 @@
from django.utils.decorators import method_decorator
from django.views.decorators.http import require_GET, require_POST
from django.views.generic import TemplateView, View
from OpenSSL import crypto

from counter.forms import BillingInfoForm
from counter.models import Counter, Customer, Product
Expand Down Expand Up @@ -180,18 +184,14 @@ def get(self, request, *args, **kwargs):
required = {"Amount", "BasketID", "Error", "Sig"}
if not required.issubset(set(request.GET.keys())):
return HttpResponse("Bad arguments", status=400)
key = crypto.load_publickey(crypto.FILETYPE_PEM, settings.SITH_EBOUTIC_PUB_KEY)
cert = crypto.X509()
cert.set_pubkey(key)
sig = base64.b64decode(request.GET["Sig"])
pubkey: RSAPublicKey = load_pem_public_key(
settings.SITH_EBOUTIC_PUB_KEY.encode("utf-8")
)
signature = base64.b64decode(request.GET["Sig"])
try:
crypto.verify(
cert,
sig,
"&".join(request.META["QUERY_STRING"].split("&")[:-1]).encode("utf-8"),
"sha1",
)
except:
data = "&".join(request.META["QUERY_STRING"].split("&")[:-1])
pubkey.verify(signature, data.encode("utf-8"), PKCS1v15(), SHA1())
except InvalidSignature:
return HttpResponse("Bad signature", status=400)
# Payment authorized:
# * 'Error' is '00000'
Expand Down
93 changes: 44 additions & 49 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ python = "^3.10,<3.12" # Version is held back by mistune
Django = "^4.2.13"
Pillow = "^10.4.0"
mistune = "^0.8.4"
django-jinja = "^2.10"
cryptography = "^40.0"
pyOpenSSL = "^23.1.1"
django-jinja = "^2.11"
cryptography = "^42.0.8"
pytz = "^2021.1"
djangorestframework = "^3.13"
django-phonenumber-field = "^6.3"
Expand Down

0 comments on commit 3014d8c

Please sign in to comment.