diff --git a/requirements-testing.txt b/requirements-testing.txt index e8f289c..0d3256e 100644 --- a/requirements-testing.txt +++ b/requirements-testing.txt @@ -1,3 +1,4 @@ pytest>=2.9.1 cffi>=1.5.2 tox>=2.3.1 +sphinx_rtd_theme>=0.1.9 diff --git a/setup.py b/setup.py index cf6d7af..df972fa 100755 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ os.chdir(os.path.dirname(sys.argv[0]) or ".") setup( name="wolfcrypt", - version="0.1", + version="0.1.0", description="A Python wrapper that encapsulates wolfSSL's wolfCrypt API", long_description=open("README.rst", "rt").read(), url="https://github.com/wolfssl/wolfcrypt-py", diff --git a/test/test_ciphers.py b/test/test_ciphers.py index 57dd2c6..74657be 100644 --- a/test/test_ciphers.py +++ b/test/test_ciphers.py @@ -32,9 +32,6 @@ class TestDes3(unittest.TestCase): def test_raises(self): - # invalid construction - self.assertRaises(ValueError, Des3) - # invalid key length self.assertRaises(ValueError, Des3.new, "key", MODE_CBC, self.IV) @@ -91,9 +88,6 @@ class TestAes(unittest.TestCase): def test_raises(self): - # invalid construction - self.assertRaises(ValueError, Aes) - # invalid key length self.assertRaises(ValueError, Aes.new, "key", MODE_CBC, self.IV) diff --git a/test/test_hashes.py b/test/test_hashes.py index 5ed2454..3c79bd0 100644 --- a/test/test_hashes.py +++ b/test/test_hashes.py @@ -26,13 +26,10 @@ class TestSha(unittest.TestCase): def setUp(self): - self.hash = Sha.new() + self.hash = Sha() def test_new(self): - # invalid construction - self.assertRaises(ValueError, Sha) - # update inside constructor assert Sha.new("wolfcrypt").hexdigest() == self.digest @@ -71,13 +68,10 @@ class TestSha256(unittest.TestCase): def setUp(self): - self.hash = Sha256.new() + self.hash = Sha256() def test_new(self): - # invalid construction - self.assertRaises(ValueError, Sha256) - # update inside constructor assert Sha256.new("wolfcrypt").hexdigest() == self.digest @@ -117,13 +111,10 @@ class TestSha384(unittest.TestCase): def setUp(self): - self.hash = Sha384.new() + self.hash = Sha384() def test_new(self): - # invalid construction - self.assertRaises(ValueError, Sha384) - # update inside constructor assert Sha384.new("wolfcrypt").hexdigest() == self.digest @@ -163,13 +154,10 @@ class TestSha512(unittest.TestCase): def setUp(self): - self.hash = Sha512.new() + self.hash = Sha512() def test_new(self): - # invalid construction - self.assertRaises(ValueError, Sha512) - # update inside constructor assert Sha512.new("wolfcrypt").hexdigest() == self.digest @@ -211,13 +199,10 @@ class TestHmacSha(unittest.TestCase): def setUp(self): - self.hash = HmacSha.new(_HMAC_KEY) + self.hash = HmacSha(_HMAC_KEY) def test_new(self): - # invalid construction - self.assertRaises(ValueError, HmacSha) - # update inside constructor assert HmacSha.new(_HMAC_KEY, "wolfcrypt").hexdigest() == self.digest @@ -256,13 +241,10 @@ class TestHmacSha256(unittest.TestCase): def setUp(self): - self.hash = HmacSha256.new(_HMAC_KEY) + self.hash = HmacSha256(_HMAC_KEY) def test_new(self): - # invalid construction - self.assertRaises(ValueError, HmacSha256) - # update inside constructor assert HmacSha256.new(_HMAC_KEY, "wolfcrypt").hexdigest() == self.digest @@ -302,13 +284,10 @@ class TestHmacSha384(unittest.TestCase): def setUp(self): - self.hash = HmacSha384.new(_HMAC_KEY) + self.hash = HmacSha384(_HMAC_KEY) def test_new(self): - # invalid construction - self.assertRaises(ValueError, HmacSha384) - # update inside constructor assert HmacSha384.new(_HMAC_KEY, "wolfcrypt").hexdigest() == self.digest @@ -348,13 +327,10 @@ class TestHmacSha512(unittest.TestCase): def setUp(self): - self.hash = HmacSha512.new(_HMAC_KEY) + self.hash = HmacSha512(_HMAC_KEY) def test_new(self): - # invalid construction - self.assertRaises(ValueError, HmacSha512) - # update inside constructor assert HmacSha512.new(_HMAC_KEY, "wolfcrypt").hexdigest() == self.digest diff --git a/wolfcrypt/ciphers.py b/wolfcrypt/ciphers.py index 2aa6972..8f64e18 100644 --- a/wolfcrypt/ciphers.py +++ b/wolfcrypt/ciphers.py @@ -38,25 +38,13 @@ _FEEDBACK_MODES = [MODE_ECB, MODE_CBC, MODE_CFB, MODE_OFB, MODE_CTR] class _Cipher(object): - # Magic object that protects against constructors. - _JAPANESE_CYBER_SWORD = object() - - - def __init__(self, token=""): - if token is not self._JAPANESE_CYBER_SWORD: - # PEP 272 -- API for Block Encryption Algorithms v1.0 - raise ValueError("don't construct directly, use new([string])") - - - @classmethod - def new(cls, key, mode, IV=None, **kwargs): + def __init__(self, key, mode, IV=None): if mode not in _FEEDBACK_MODES: raise ValueError("this mode is not supported") + if mode != MODE_CBC: raise ValueError("this mode is not supported by this cipher") - self = cls(_Cipher._JAPANESE_CYBER_SWORD) - if self.key_size: if self.key_size != len(key): raise ValueError("key must be %d in length" % self.key_size) @@ -71,13 +59,16 @@ class _Cipher(object): raise ValueError("IV must be %d in length" % self.block_size) self._native_object = _ffi.new(self._native_type) - self._enc = None self._dec = None self._key = key - self._IV = IV if IV else "\0" * self.block_size + self._IV = IV if IV else "\0" * self.block_size - return self + + @classmethod + def new(cls, key, mode, IV=None, **kwargs): + # PEP 272 -- API for Block Encryption Algorithms + return cls(key, mode, IV) def encrypt(self, string): diff --git a/wolfcrypt/exceptions.py b/wolfcrypt/exceptions.py new file mode 100644 index 0000000..ab36844 --- /dev/null +++ b/wolfcrypt/exceptions.py @@ -0,0 +1,35 @@ +# exceptions.py +# +# Copyright (C) 2006-2016 wolfSSL Inc. +# +# This file is part of wolfSSL. (formerly known as CyaSSL) +# +# wolfSSL is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# wolfSSL is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + + +class UsageError(Exception): + pass + + +class InvalidKey(Exception): + pass + + +class InvalidIV(Exception): + pass + + +class InvalidInput(Exception): + pass diff --git a/wolfcrypt/hashes.py b/wolfcrypt/hashes.py index 18c0b54..9cabfc8 100644 --- a/wolfcrypt/hashes.py +++ b/wolfcrypt/hashes.py @@ -22,23 +22,15 @@ from wolfcrypt._ffi import lib as _lib class _Hash(object): - # Magic object that protects against constructors. - _JAPANESE_CYBER_SWORD = object() - - - def __init__(self, token=""): - if token is not self._JAPANESE_CYBER_SWORD: - # PEP 247 -- API for Cryptographic Hash Functions - raise ValueError("don't construct directly, use new([string])") + def __init__(self, string=None): + self._native_object = _ffi.new(self._native_type) + self._init() @classmethod def new(cls, string=None): - self = cls(cls._JAPANESE_CYBER_SWORD) - - self._native_object = _ffi.new(self._native_type) - - self._init() + # PEP 247 -- API for Cryptographic Hash Functions + self = cls(string) if (string): self._update(string) @@ -46,6 +38,7 @@ class _Hash(object): return self + def copy(self): copy = self.new("") @@ -164,13 +157,15 @@ class _Hmac(_Hash): _native_size = _ffi.sizeof("Hmac") + def __init__(self, key): + self._native_object = _ffi.new(self._native_type) + self._init(self._type, key) + + @classmethod def new(cls, key, string=None): - self = cls(cls._JAPANESE_CYBER_SWORD) - - self._native_object = _ffi.new(self._native_type) - - self._init(self._type, key) + # PEP 247 -- API for Cryptographic Hash Functions + self = cls(key) if (string): self._update(string)