mirror of
https://github.com/aljazceru/python-teos.git
synced 2026-02-20 22:14:41 +01:00
Refactors signing/verifiying functionality to be part of the Cryptographer
- All encryption/decryption and signing/verifying calls are performed by the cryptographer now. - The current signature format is temporal. We should define something not base on json. - Some Cryptographer tests are still missing. - The cli tests should be modified to fit this too.
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import os
|
||||
import json
|
||||
from flask import Flask, request, abort, jsonify
|
||||
from binascii import hexlify
|
||||
|
||||
from pisa import HOST, PORT, logging
|
||||
from pisa.logger import Logger
|
||||
@@ -40,7 +39,7 @@ def add_appointment():
|
||||
|
||||
if appointment_added:
|
||||
rcode = HTTP_OK
|
||||
response = {"locator": appointment.locator, "signature": hexlify(signature).decode("utf-8")}
|
||||
response = {"locator": appointment.locator, "signature": signature}
|
||||
else:
|
||||
rcode = HTTP_SERVICE_UNAVAILABLE
|
||||
error = "appointment rejected"
|
||||
|
||||
@@ -32,7 +32,7 @@ class Appointment:
|
||||
|
||||
return appointment
|
||||
|
||||
def to_dict(self):
|
||||
def to_dict(self, include_triggered=True):
|
||||
# ToDO: #3-improve-appointment-structure
|
||||
appointment = {
|
||||
"locator": self.locator,
|
||||
@@ -40,15 +40,16 @@ class Appointment:
|
||||
"end_time": self.end_time,
|
||||
"dispute_delta": self.dispute_delta,
|
||||
"encrypted_blob": self.encrypted_blob.data,
|
||||
"triggered": self.triggered,
|
||||
}
|
||||
|
||||
if include_triggered:
|
||||
appointment["triggered"] = self.triggered
|
||||
|
||||
return appointment
|
||||
|
||||
def to_json(self):
|
||||
return json.dumps(self.to_dict(), sort_keys=True, separators=(",", ":"))
|
||||
|
||||
def serialize(self):
|
||||
data = self.to_dict()
|
||||
data.pop("triggered")
|
||||
return json.dumps(data, sort_keys=True, separators=(",", ":")).encode("utf-8")
|
||||
# FIXME: This is temporary serialization. A proper one is required
|
||||
return self.to_dict(include_triggered=False)
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
import json
|
||||
import re
|
||||
from binascii import unhexlify
|
||||
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.primitives.serialization import load_pem_public_key
|
||||
from cryptography.exceptions import InvalidSignature
|
||||
|
||||
from common.constants import LOCATOR_LEN_HEX
|
||||
from common.cryptographer import Cryptographer
|
||||
|
||||
from pisa import errors
|
||||
import pisa.conf as conf
|
||||
@@ -200,7 +194,7 @@ class Inspector:
|
||||
|
||||
@staticmethod
|
||||
# Verifies that the appointment signature is a valid signature with public key
|
||||
def check_appointment_signature(appointment, signature, pk_pem):
|
||||
def check_appointment_signature(appointment, signature, pk_der):
|
||||
message = None
|
||||
rcode = 0
|
||||
|
||||
@@ -208,13 +202,10 @@ class Inspector:
|
||||
rcode = errors.APPOINTMENT_EMPTY_FIELD
|
||||
message = "empty signature received"
|
||||
|
||||
try:
|
||||
sig_bytes = unhexlify(signature.encode("utf-8"))
|
||||
client_pk = load_pem_public_key(pk_pem.encode("utf-8"), backend=default_backend())
|
||||
data = json.dumps(appointment, sort_keys=True, separators=(",", ":")).encode("utf-8")
|
||||
client_pk.verify(sig_bytes, data, ec.ECDSA(hashes.SHA256()))
|
||||
pk = Cryptographer.load_public_key_der(unhexlify(pk_der.encode("utf-8")))
|
||||
valid_sig = Cryptographer.verify(Cryptographer.signature_format(appointment), signature, pk)
|
||||
|
||||
except InvalidSignature:
|
||||
if not valid_sig:
|
||||
rcode = errors.APPOINTMENT_INVALID_SIGNATURE
|
||||
message = "invalid signature"
|
||||
|
||||
|
||||
@@ -2,11 +2,6 @@ from uuid import uuid4
|
||||
from queue import Queue
|
||||
from threading import Thread
|
||||
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
||||
|
||||
from common.cryptographer import Cryptographer
|
||||
from common.constants import LOCATOR_LEN_HEX
|
||||
|
||||
@@ -36,18 +31,14 @@ class Watcher:
|
||||
if pisa_sk_file is None:
|
||||
raise ValueError("No signing key provided. Please fix your pisa.conf")
|
||||
else:
|
||||
with open(PISA_SECRET_KEY, "r") as key_file:
|
||||
secret_key_pem = key_file.read().encode("utf-8")
|
||||
self.signing_key = load_pem_private_key(secret_key_pem, password=None, backend=default_backend())
|
||||
with open(PISA_SECRET_KEY, "rb") as key_file:
|
||||
secret_key_der = key_file.read()
|
||||
self.signing_key = Cryptographer.load_private_key_der(secret_key_der)
|
||||
|
||||
@staticmethod
|
||||
def compute_locator(tx_id):
|
||||
return tx_id[:LOCATOR_LEN_HEX]
|
||||
|
||||
def sign_appointment(self, appointment):
|
||||
data = appointment.serialize()
|
||||
return self.signing_key.sign(data, ec.ECDSA(hashes.SHA256()))
|
||||
|
||||
def add_appointment(self, appointment):
|
||||
# Rationale:
|
||||
# The Watcher will analyze every received block looking for appointment matches. If there is no work
|
||||
@@ -87,7 +78,8 @@ class Watcher:
|
||||
|
||||
logger.info("New appointment accepted.", locator=appointment.locator)
|
||||
|
||||
signature = self.sign_appointment(appointment)
|
||||
signature = Cryptographer.sign(Cryptographer.signature_format(appointment.to_dict()), self.signing_key)
|
||||
|
||||
else:
|
||||
appointment_added = False
|
||||
signature = None
|
||||
|
||||
Reference in New Issue
Block a user