diff --git a/.travis.yml b/.travis.yml index 41e4cb7..a77f25a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,9 +2,9 @@ language: python notifications: email: false python: -# - "3.5" + - "3.5" - "3.6" -# - "3.5-dev" # 3.5 development branch + - "3.5-dev" # 3.5 development branch - "3.6-dev" # 3.6 development branch # - "3.7-dev" # 3.7 development branch # command to install dependencies diff --git a/CHANGELOG.rst b/CHANGELOG.rst new file mode 100644 index 0000000..9e337aa --- /dev/null +++ b/CHANGELOG.rst @@ -0,0 +1,19 @@ +Changelog +========= + +.. _v0-2-0: + +0.2.0 - `trunk` +~~~~~~~~~~~~~~~~ + +.. note:: This version is not yet released and is under active development. + +* Cryptography requirement updated to the newest version (2.1) - **Python 3.5** is supported again. + + +.. _v0-1-0: + +0.1.1 - 2017-09-12 +~~~~~~~~~~~~~~~~~~ + +Initial release. \ No newline at end of file diff --git a/README.md b/README.md index 3d649b1..fc92d6e 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This package shall not be used (yet) for production purposes. There was little t Use common sense while using - until this package becomes stable. ## Installation and prerequisites -For now, only Python 3.6 is supported. +For now, only Python 3.5+ is supported. Install via pip: ``` @@ -82,11 +82,9 @@ pytest ### Todo-list for the project: - [ ] fallback patterns support -- [ ] documentation on Read the Docs and more extensive readme - [ ] scripts for keypair generation (+ console entry points) - [ ] "echo" (noise-c like) example - [ ] extensive logging -- [ ] bringing back Python 3.5 support and supporting Python 3.7 (dependent on Cryptography package updates) - [ ] move away from custom ed448 implementation - [ ] implement countermeasures for side-channel attacks - [ ] **get peer review of the code** diff --git a/noise/builder.py b/noise/builder.py index 4bc853e..fc6ca61 100644 --- a/noise/builder.py +++ b/noise/builder.py @@ -1,4 +1,4 @@ -from enum import Enum, auto +from enum import Enum from typing import Union, List from cryptography.exceptions import InvalidTag @@ -9,10 +9,10 @@ from .noise_protocol import NoiseProtocol class Keypair(Enum): - STATIC = auto() - REMOTE_STATIC = auto() - EPHEMERAL = auto() - REMOTE_EPHEMERAL = auto() + STATIC = 1 + REMOTE_STATIC = 2 + EPHEMERAL = 3 + REMOTE_EPHEMERAL = 4 _keypairs = {Keypair.STATIC: 's', Keypair.REMOTE_STATIC: 'rs', diff --git a/noise/functions.py b/noise/functions.py index 0b86d31..3f5c44b 100644 --- a/noise/functions.py +++ b/noise/functions.py @@ -1,15 +1,13 @@ import abc import warnings -from functools import partial # Turn back on when Cryptography gets fixed -import hashlib -import hmac +from functools import partial import os from cryptography.hazmat.backends import default_backend -# from cryptography.hazmat.primitives import hashes # Turn back on when Cryptography gets fixed +from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import x25519 from cryptography.hazmat.primitives.ciphers.aead import AESGCM, ChaCha20Poly1305 -# from cryptography.hazmat.primitives.hmac import HMAC # Turn back on when Cryptography gets fixed +from cryptography.hazmat.primitives.hmac import HMAC from noise.constants import MAX_NONCE from noise.exceptions import NoiseValueError from .crypto import X448 @@ -103,60 +101,44 @@ class Hash(object): self.hashlen = 32 self.blocklen = 64 self.hash = self._hash_sha256 - # self.fn = hashes.SHA256 # Turn back on when Cryptography gets fixed - self.fn = 'SHA256' + self.fn = hashes.SHA256 elif method == 'SHA512': self.hashlen = 64 self.blocklen = 128 self.hash = self._hash_sha512 - # self.fn = hashes.SHA512 # Turn back on when Cryptography gets fixed - self.fn = 'SHA512' + self.fn = hashes.SHA512 elif method == 'BLAKE2s': self.hashlen = 32 self.blocklen = 64 self.hash = self._hash_blake2s - # self.fn = partial(hashes.BLAKE2s, digest_size=self.hashlen) # Turn back on when Cryptography gets fixed - self.fn = 'blake2s' + self.fn = partial(hashes.BLAKE2s, digest_size=self.hashlen) elif method == 'BLAKE2b': self.hashlen = 64 self.blocklen = 128 self.hash = self._hash_blake2b - # self.fn = partial(hashes.BLAKE2b, digest_size=self.hashlen) # Turn back on when Cryptography gets fixed - self.fn = 'blake2b' + self.fn = partial(hashes.BLAKE2b, digest_size=self.hashlen) else: raise NotImplementedError('Hash method: {}'.format(method)) def _hash_sha256(self, data): - return hashlib.sha256(data).digest() + digest = hashes.Hash(hashes.SHA256(), backend) + digest.update(data) + return digest.finalize() def _hash_sha512(self, data): - return hashlib.sha512(data).digest() + digest = hashes.Hash(hashes.SHA512(), backend) + digest.update(data) + return digest.finalize() def _hash_blake2s(self, data): - return hashlib.blake2s(data).digest() + digest = hashes.Hash(hashes.BLAKE2s(digest_size=self.hashlen), backend) + digest.update(data) + return digest.finalize() def _hash_blake2b(self, data): - return hashlib.blake2b(data).digest() - - # def _hash_sha256(self, data): # Turn back on when Cryptography gets fixed - # digest = hashes.Hash(hashes.SHA256(), backend) - # digest.update(data) - # return digest.finalize() - # - # def _hash_sha512(self, data): # Turn back on when Cryptography gets fixed - # digest = hashes.Hash(hashes.SHA512(), backend) - # digest.update(data) - # return digest.finalize() - # - # def _hash_blake2s(self, data): # Turn back on when Cryptography gets fixed - # digest = hashes.Hash(hashes.BLAKE2s(digest_size=self.hashlen), backend) - # digest.update(data) - # return digest.finalize() - # - # def _hash_blake2b(self, data): # Turn back on when Cryptography gets fixed - # digest = hashes.Hash(hashes.BLAKE2b(digest_size=self.hashlen), backend) - # digest.update(data) - # return digest.finalize() + digest = hashes.Hash(hashes.BLAKE2b(digest_size=self.hashlen), backend) + digest.update(data) + return digest.finalize() class _KeyPair(object): @@ -244,15 +226,11 @@ keypair_map = { } -# def hmac_hash(key, data, algorithm): # Turn back on when Cryptography gets fixed -# # Applies HMAC using the HASH() function. -# hmac = HMAC(key=key, algorithm=algorithm(), backend=backend) -# hmac.update(data=data) -# return hmac.finalize() - def hmac_hash(key, data, algorithm): # Applies HMAC using the HASH() function. - return hmac.new(key, data, algorithm).digest() + hmac = HMAC(key=key, algorithm=algorithm(), backend=backend) + hmac.update(data=data) + return hmac.finalize() def hkdf(chaining_key, input_key_material, num_outputs, hmac_hash_fn): diff --git a/requirements.txt b/requirements.txt index aa49793..f540345 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -cryptography==2.0.3 +cryptography==2.1.0 diff --git a/setup.py b/setup.py index 2f1aaa8..6f11631 100644 --- a/setup.py +++ b/setup.py @@ -26,12 +26,12 @@ setup( 'Topic :: Security :: Cryptography', 'License :: OSI Approved :: MIT License', 'Programming Language :: Python :: 3', - # 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', # 'Programming Language :: Python :: 3.7', ], keywords='cryptography noiseprotocol noise security', packages=find_packages(exclude=['contrib', 'docs', 'tests', 'examples']), install_requires=['cryptography==2.0.3'], - python_requires='~=3.6', + python_requires='~=3.5,~=3.6', )