From 6a02ab627eeee585cd54efc9db7a50b129a60516 Mon Sep 17 00:00:00 2001 From: Ranjan Prasad Date: Thu, 22 Aug 2024 15:55:10 +0530 Subject: [PATCH 1/3] Updated webhook helper to use a different edcsa library --- requirements.txt | 2 +- sendgrid/helpers/eventwebhook/__init__.py | 30 +++++++++++++---------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/requirements.txt b/requirements.txt index 0c34aafd..7ec4a517 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,5 +2,5 @@ Flask==1.1.2 PyYAML>=4.2b1 python-http-client>=3.2.1 six==1.11.0 -starkbank-ecdsa>=2.0.1 +ecdsa>=0.19.0,<1 more-itertools==5.0.0 diff --git a/sendgrid/helpers/eventwebhook/__init__.py b/sendgrid/helpers/eventwebhook/__init__.py index c1ec7d1c..d97604df 100644 --- a/sendgrid/helpers/eventwebhook/__init__.py +++ b/sendgrid/helpers/eventwebhook/__init__.py @@ -1,8 +1,7 @@ -from ellipticcurve.ecdsa import Ecdsa -from ellipticcurve.publicKey import PublicKey -from ellipticcurve.signature import Signature - -from .eventwebhook_header import EventWebhookHeader +from ecdsa import VerifyingKey, BadSignatureError +from ecdsa.util import sigdecode_der +import base64 +import hashlib class EventWebhook: """ @@ -20,14 +19,15 @@ def __init__(self, public_key=None): def convert_public_key_to_ecdsa(self, public_key): """ - Convert the public key string to a ECPublicKey. + Convert the public key string to a VerifyingKey object. :param public_key: verification key under Mail Settings :type public_key string - :return: public key using the ECDSA algorithm - :rtype PublicKey + :return: VerifyingKey object using the ECDSA algorithm + :rtype VerifyingKey """ - return PublicKey.fromPem('\n-----BEGIN PUBLIC KEY-----\n'+public_key+'\n-----END PUBLIC KEY-----\n') + pem_key = "-----BEGIN PUBLIC KEY-----\n" + public_key + "\n-----END PUBLIC KEY-----" + return VerifyingKey.from_pem(pem_key) def verify_signature(self, payload, signature, timestamp, public_key=None): """ @@ -40,11 +40,15 @@ def verify_signature(self, payload, signature, timestamp, public_key=None): :param timestamp: value obtained from the 'X-Twilio-Email-Event-Webhook-Timestamp' header :type timestamp: string :param public_key: elliptic curve public key - :type public_key: PublicKey + :type public_key: VerifyingKey :return: true or false if signature is valid """ - timestamped_payload = timestamp + payload - decoded_signature = Signature.fromBase64(signature) + timestamped_payload = (timestamp + payload).encode('utf-8') + decoded_signature = base64.b64decode(signature) key = public_key or self.public_key - return Ecdsa.verify(timestamped_payload, decoded_signature, key) + try: + key.verify(decoded_signature, timestamped_payload, hashfunc=hashlib.sha256, sigdecode=sigdecode_der) + return True + except BadSignatureError: + return False From 2a12493488fe85f4080a8b2bdea5265add836186 Mon Sep 17 00:00:00 2001 From: Shubham Date: Fri, 9 May 2025 12:07:58 +0530 Subject: [PATCH 2/3] chore: dummy commit From 81f3d8d3f43bf4b00bf6e25179b0bbe8d2e9e695 Mon Sep 17 00:00:00 2001 From: Ranjan Prasad Date: Fri, 9 May 2025 12:30:02 +0530 Subject: [PATCH 3/3] Update dependencies --- requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 7ec4a517..c9520448 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ -Flask==1.1.2 +Flask==3.1.0 PyYAML>=4.2b1 python-http-client>=3.2.1 -six==1.11.0 -ecdsa>=0.19.0,<1 +six==1.17.0 +ecdsa>=0.19.1,<1 more-itertools==5.0.0