Files
noiseprotocol/noise/backends/noise_backend.py
Piotr Lizończyk e84db3c232 Added possibilty to use different crypto backends.
* Created NoiseBackend class serving as a base for backends

* Refactored NoiseProtocol name parsing

* Refactored existing spec-defined functions into abstract classes.
Implementing classes are connecting crypto primitives to expected
interfaces.

* Refactored existing usage of Cryptography as source of crypto into
"default" backend (along with in-house implementation of X448).

* Provisioned "experimental" backend, it will contain e.g. non-default
crypto algorithms

* Backend can be chosen while creating NoiseConnection, though by
default, the Cryptography backend ("default") is used

Closes #7
2018-07-16 01:47:29 +02:00

65 lines
2.1 KiB
Python

from noise.exceptions import NoiseProtocolNameError
from noise.functions.hash import hkdf
from noise.patterns import (PatternN, PatternK, PatternX, PatternNN, PatternKN, PatternNK, PatternKK, PatternNX,
PatternKX, PatternXN, PatternIN, PatternXK, PatternIK, PatternXX, PatternIX)
class NoiseBackend:
"""
Base for creating backends.
Implementing classes must define supported crypto methods in appropriate dict (diffie_hellmans, ciphers, etc.)
HMAC function must be defined as well.
Dicts use convention for keys - they must match the string that occurs in Noise Protocol name.
"""
def __init__(self):
self.patterns = {
'N': PatternN,
'K': PatternK,
'X': PatternX,
'NN': PatternNN,
'KN': PatternKN,
'NK': PatternNK,
'KK': PatternKK,
'NX': PatternNX,
'KX': PatternKX,
'XN': PatternXN,
'IN': PatternIN,
'XK': PatternXK,
'IK': PatternIK,
'XX': PatternXX,
'IX': PatternIX,
}
self.diffie_hellmans = {}
self.ciphers = {}
self.hashes = {}
self.keypairs = {}
self.hmac = None
self.hkdf = hkdf
@property
def methods(self):
return {
'pattern': self.patterns,
'dh': self.diffie_hellmans,
'cipher': self.ciphers,
'hash': self.hashes,
'keypair': self.keypairs
}
def map_protocol_name_to_crypto(self, unpacked_name):
mappings = {}
# Validate if we know everything that Noise Protocol is supposed to use and map appropriate functions
for method, map_dict in self.methods.items():
looked_up_func = getattr(unpacked_name, method)
func = map_dict.get(looked_up_func)
if not func:
raise NoiseProtocolNameError('Unknown {} in Noise Protocol name, given {}, known {}'.format(
method, looked_up_func, " ".join(map_dict)))
mappings[method] = func
return mappings