diff options
author | Colin Watson <cjwatson@debian.org> | 2020-01-10 00:00:04 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2020-01-10 00:00:33 +0000 |
commit | 079099a6e6b5606874398f96a7a50fbc95477e35 (patch) | |
tree | d20a370af4935ceddcf46f1e65299d824335754f | |
parent | 6a3934d4e31402e517db7df0297168807c2410c5 (diff) | |
parent | d9266e17907a20e05c29d6027c55eb453627a662 (diff) |
Update upstream source from tag 'upstream/1.7.1'
Update to upstream version '1.7.1'
with Debian dir d1ed40b6f476fffb9fb1f03923d047a00a972501
96 files changed, 724 insertions, 196 deletions
diff --git a/MANIFEST.in b/MANIFEST.in index 434232a..c5c3bf6 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,6 @@ include LICENSE include AUTHORS include README.rst -recursive-include tests * +recursive-include tests *.py recursive-include doc * recursive-include pkg * @@ -1,12 +1,11 @@ Metadata-Version: 1.1 Name: libnacl -Version: 1.6.1 +Version: 1.7.1 Summary: Python bindings for libsodium based on ctypes Home-page: https://libnacl.readthedocs.org/ Author: Thomas S Hatch Author-email: thatch@saltstack.com License: UNKNOWN -Description-Content-Type: UNKNOWN Description: UNKNOWN Platform: UNKNOWN Classifier: Operating System :: OS Independent @@ -15,6 +14,8 @@ Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Topic :: Security :: Cryptography diff --git a/debian/changelog b/debian/changelog index 72b329b..4434dbc 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +python-libnacl (1.7.1-1) UNRELEASED; urgency=medium + + * New upstream release. + - Fix unreliability in verify tests (closes: #922259). + + -- Colin Watson <cjwatson@debian.org> Fri, 10 Jan 2020 00:00:08 +0000 + python-libnacl (1.6.1-5) unstable; urgency=medium [ Ondřej Nový ] diff --git a/doc/conf.py b/doc/conf.py index e9af469..6d6817b 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -48,7 +48,7 @@ master_doc = 'index' # General information about the project. project = u'libnacl' -copyright = u'2017, Thomas S Hatch' +copyright = u'2020, Thomas S Hatch' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -267,7 +267,7 @@ texinfo_documents = [ epub_title = u'libnacl' epub_author = u'Thomas S Hatch' epub_publisher = u'Thomas S Hatch' -epub_copyright = u'2017, Thomas S Hatch' +epub_copyright = u'2020, Thomas S Hatch' # The basename for the epub file. It defaults to the project name. #epub_basename = u'libnacl' diff --git a/doc/topics/releases/1.6.1.rst b/doc/topics/releases/1.6.1.rst index f8d1241..9ae5a43 100644 --- a/doc/topics/releases/1.6.1.rst +++ b/doc/topics/releases/1.6.1.rst @@ -1,5 +1,5 @@ =========================== -libnacl 1.6.0 Release Notes +libnacl 1.6.1 Release Notes =========================== Add support for libsodium 1.0.15 diff --git a/doc/topics/releases/1.7.1.rst b/doc/topics/releases/1.7.1.rst new file mode 100644 index 0000000..2941198 --- /dev/null +++ b/doc/topics/releases/1.7.1.rst @@ -0,0 +1,21 @@ +=========================== +libnacl 1.7.1 Release Notes +=========================== + +This release fixes a few minor bugs, primarily in tests, and restores +functionality with older versions of libsodium. + +Compatibility With Older libsodium +================================== + +PR #118 fixes compatibility with Debian 8. + +Test Fixes +========== + +Some unreliability in tests were found by the Debian team. These +issues were fixed in PRs #115 and #116. + +Travis no longer supports the same pypy tests on all platforms, +these were removed in PR #119. + diff --git a/doc/topics/releases/1.7.rst b/doc/topics/releases/1.7.rst new file mode 100644 index 0000000..5ee5549 --- /dev/null +++ b/doc/topics/releases/1.7.rst @@ -0,0 +1,18 @@ +========================= +libnacl 1.7 Release Notes +========================= + +Bindings for kdf in libsodium +============================= + +Thanks to Michael Mendoza, PR #109 + +Added extra key validation +========================== + +Thanks to Kent Ross, PR #106 + +Add Crypto_box_easy +=================== + +Thanks to jheling PR #114 diff --git a/libnacl.egg-info/PKG-INFO b/libnacl.egg-info/PKG-INFO index d4b7933..fc8b348 100644 --- a/libnacl.egg-info/PKG-INFO +++ b/libnacl.egg-info/PKG-INFO @@ -1,12 +1,11 @@ Metadata-Version: 1.1 Name: libnacl -Version: 1.6.1 +Version: 1.7.1 Summary: Python bindings for libsodium based on ctypes Home-page: https://libnacl.readthedocs.org/ Author: Thomas S Hatch Author-email: thatch@saltstack.com License: UNKNOWN -Description-Content-Type: UNKNOWN Description: UNKNOWN Platform: UNKNOWN Classifier: Operating System :: OS Independent @@ -15,6 +14,8 @@ Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Topic :: Security :: Cryptography diff --git a/libnacl.egg-info/SOURCES.txt b/libnacl.egg-info/SOURCES.txt index 669a78d..2b20d14 100644 --- a/libnacl.egg-info/SOURCES.txt +++ b/libnacl.egg-info/SOURCES.txt @@ -38,6 +38,8 @@ doc/topics/releases/1.5.1.rst doc/topics/releases/1.5.2.rst doc/topics/releases/1.6.0.rst doc/topics/releases/1.6.1.rst +doc/topics/releases/1.7.1.rst +doc/topics/releases/1.7.rst doc/topics/releases/index.rst libnacl/__init__.py libnacl/aead.py @@ -48,6 +50,7 @@ libnacl/encode.py libnacl/public.py libnacl/sealed.py libnacl/secret.py +libnacl/secret_easy.py libnacl/sign.py libnacl/utils.py libnacl/version.py @@ -60,95 +63,25 @@ pkg/suse/python-libnacl.changes pkg/suse/python-libnacl.spec tests/runtests.py tests/unit/__init__.py -tests/unit/__init__.pyc tests/unit/test_aead.py -tests/unit/test_aead.pyc tests/unit/test_auth_verify.py -tests/unit/test_auth_verify.pyc tests/unit/test_blake.py -tests/unit/test_blake.pyc tests/unit/test_dual.py -tests/unit/test_dual.pyc tests/unit/test_public.py -tests/unit/test_public.pyc tests/unit/test_raw_auth_sym.py -tests/unit/test_raw_auth_sym.pyc +tests/unit/test_raw_auth_sym_easy.py tests/unit/test_raw_generichash.py -tests/unit/test_raw_generichash.pyc tests/unit/test_raw_hash.py -tests/unit/test_raw_hash.pyc tests/unit/test_raw_public.py -tests/unit/test_raw_public.pyc tests/unit/test_raw_random.py -tests/unit/test_raw_random.pyc tests/unit/test_raw_secret.py -tests/unit/test_raw_secret.pyc +tests/unit/test_raw_secret_easy.py tests/unit/test_raw_sign.py -tests/unit/test_raw_sign.pyc tests/unit/test_save.py -tests/unit/test_save.pyc tests/unit/test_seal.py -tests/unit/test_seal.pyc tests/unit/test_secret.py -tests/unit/test_secret.pyc +tests/unit/test_secret_easy.py tests/unit/test_sign.py -tests/unit/test_sign.pyc +tests/unit/test_stream.py tests/unit/test_verify.py -tests/unit/test_verify.pyc -tests/unit/test_version.py -tests/unit/test_version.pyc -tests/unit/__pycache__/__init__.cpython-36.pyc -tests/unit/__pycache__/test_aead.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_aead.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_aead.cpython-36.pyc -tests/unit/__pycache__/test_auth_verify.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_auth_verify.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_auth_verify.cpython-36.pyc -tests/unit/__pycache__/test_blake.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_blake.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_blake.cpython-36.pyc -tests/unit/__pycache__/test_dual.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_dual.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_dual.cpython-36.pyc -tests/unit/__pycache__/test_public.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_public.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_public.cpython-36.pyc -tests/unit/__pycache__/test_raw_auth_sym.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_raw_auth_sym.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_raw_auth_sym.cpython-36.pyc -tests/unit/__pycache__/test_raw_generichash.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_raw_generichash.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_raw_generichash.cpython-36.pyc -tests/unit/__pycache__/test_raw_hash.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_raw_hash.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_raw_hash.cpython-36.pyc -tests/unit/__pycache__/test_raw_public.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_raw_public.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_raw_public.cpython-36.pyc -tests/unit/__pycache__/test_raw_random.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_raw_random.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_raw_random.cpython-36.pyc -tests/unit/__pycache__/test_raw_secret.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_raw_secret.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_raw_secret.cpython-36.pyc -tests/unit/__pycache__/test_raw_sign.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_raw_sign.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_raw_sign.cpython-36.pyc -tests/unit/__pycache__/test_save.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_save.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_save.cpython-36.pyc -tests/unit/__pycache__/test_seal.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_seal.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_seal.cpython-36.pyc -tests/unit/__pycache__/test_secret.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_secret.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_secret.cpython-36.pyc -tests/unit/__pycache__/test_sign.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_sign.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_sign.cpython-36.pyc -tests/unit/__pycache__/test_verify.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_verify.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_verify.cpython-36.pyc -tests/unit/__pycache__/test_version.cpython-27-PYTEST.pyc -tests/unit/__pycache__/test_version.cpython-36-PYTEST.pyc -tests/unit/__pycache__/test_version.cpython-36.pyc
\ No newline at end of file +tests/unit/test_version.py
\ No newline at end of file diff --git a/libnacl/__init__.py b/libnacl/__init__.py index 4709aa2..b99d063 100644 --- a/libnacl/__init__.py +++ b/libnacl/__init__.py @@ -80,7 +80,13 @@ def _get_nacl(): msg += 'libsodium.so.{0}, '.format(soname_ver) raise OSError(msg) -nacl = _get_nacl() +# Don't load libnacl if we are in sphinx +if not 'sphinx' in sys.argv[0]: + nacl = _get_nacl() + DOC_RUN = False +else: + nacl = None + DOC_RUN = True # Define exceptions @@ -89,74 +95,101 @@ class CryptError(Exception): Base Exception for cryptographic errors """ -sodium_init = nacl.sodium_init -sodium_init.res_type = ctypes.c_int -if sodium_init() < 0: - raise RuntimeError('sodium_init() call failed!') - -# Define constants -try: - crypto_box_SEALBYTES = nacl.crypto_box_sealbytes() - HAS_SEAL = True -except AttributeError: - HAS_SEAL = False -try: - crypto_aead_aes256gcm_KEYBYTES = nacl.crypto_aead_aes256gcm_keybytes() - crypto_aead_aes256gcm_NPUBBYTES = nacl.crypto_aead_aes256gcm_npubbytes() - crypto_aead_aes256gcm_ABYTES = nacl.crypto_aead_aes256gcm_abytes() - HAS_AEAD_AES256GCM = bool(nacl.crypto_aead_aes256gcm_is_available()) - crypto_aead_chacha20poly1305_ietf_KEYBYTES = nacl.crypto_aead_chacha20poly1305_ietf_keybytes() - crypto_aead_chacha20poly1305_ietf_NPUBBYTES = nacl.crypto_aead_chacha20poly1305_ietf_npubbytes() - crypto_aead_chacha20poly1305_ietf_ABYTES = nacl.crypto_aead_chacha20poly1305_ietf_abytes() - HAS_AEAD_CHACHA20POLY1305_IETF = True - HAS_AEAD = True -except AttributeError: - HAS_AEAD_AES256GCM = False - HAS_AEAD_CHACHA20POLY1305_IETF = False - HAS_AEAD = False - -crypto_box_SECRETKEYBYTES = nacl.crypto_box_secretkeybytes() -crypto_box_SEEDBYTES = nacl.crypto_box_seedbytes() -crypto_box_PUBLICKEYBYTES = nacl.crypto_box_publickeybytes() -crypto_box_NONCEBYTES = nacl.crypto_box_noncebytes() -crypto_box_ZEROBYTES = nacl.crypto_box_zerobytes() -crypto_box_BOXZEROBYTES = nacl.crypto_box_boxzerobytes() -crypto_box_BEFORENMBYTES = nacl.crypto_box_beforenmbytes() -crypto_scalarmult_BYTES = nacl.crypto_scalarmult_bytes() -crypto_scalarmult_SCALARBYTES = nacl.crypto_scalarmult_scalarbytes() -crypto_sign_BYTES = nacl.crypto_sign_bytes() -crypto_sign_SEEDBYTES = nacl.crypto_sign_secretkeybytes() // 2 -crypto_sign_PUBLICKEYBYTES = nacl.crypto_sign_publickeybytes() -crypto_sign_SECRETKEYBYTES = nacl.crypto_sign_secretkeybytes() -crypto_sign_ed25519_PUBLICKEYBYTES = nacl.crypto_sign_ed25519_publickeybytes() -crypto_sign_ed25519_SECRETKEYBYTES = nacl.crypto_sign_ed25519_secretkeybytes() -crypto_box_MACBYTES = crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES -crypto_secretbox_KEYBYTES = nacl.crypto_secretbox_keybytes() -crypto_secretbox_NONCEBYTES = nacl.crypto_secretbox_noncebytes() -crypto_secretbox_ZEROBYTES = nacl.crypto_secretbox_zerobytes() -crypto_secretbox_BOXZEROBYTES = nacl.crypto_secretbox_boxzerobytes() -crypto_secretbox_MACBYTES = crypto_secretbox_ZEROBYTES - crypto_secretbox_BOXZEROBYTES -crypto_stream_KEYBYTES = nacl.crypto_stream_keybytes() -crypto_stream_NONCEBYTES = nacl.crypto_stream_noncebytes() -crypto_auth_BYTES = nacl.crypto_auth_bytes() -crypto_auth_KEYBYTES = nacl.crypto_auth_keybytes() -crypto_onetimeauth_BYTES = nacl.crypto_onetimeauth_bytes() -crypto_onetimeauth_KEYBYTES = nacl.crypto_onetimeauth_keybytes() -crypto_generichash_BYTES = nacl.crypto_generichash_bytes() -crypto_generichash_BYTES_MIN = nacl.crypto_generichash_bytes_min() -crypto_generichash_BYTES_MAX = nacl.crypto_generichash_bytes_max() -crypto_generichash_KEYBYTES = nacl.crypto_generichash_keybytes() -crypto_generichash_KEYBYTES_MIN = nacl.crypto_generichash_keybytes_min() -crypto_generichash_KEYBYTES_MAX = nacl.crypto_generichash_keybytes_max() -crypto_scalarmult_curve25519_BYTES = nacl.crypto_scalarmult_curve25519_bytes() -crypto_hash_BYTES = nacl.crypto_hash_sha512_bytes() -crypto_hash_sha256_BYTES = nacl.crypto_hash_sha256_bytes() -crypto_hash_sha512_BYTES = nacl.crypto_hash_sha512_bytes() -crypto_verify_16_BYTES = nacl.crypto_verify_16_bytes() -crypto_verify_32_BYTES = nacl.crypto_verify_32_bytes() -crypto_verify_64_BYTES = nacl.crypto_verify_64_bytes() -# pylint: enable=C0103 - +if not DOC_RUN: + sodium_init = nacl.sodium_init + sodium_init.res_type = ctypes.c_int + if sodium_init() < 0: + raise RuntimeError('sodium_init() call failed!') + + # Define constants + try: + crypto_box_SEALBYTES = nacl.crypto_box_sealbytes() + HAS_SEAL = True + except AttributeError: + HAS_SEAL = False + try: + crypto_aead_aes256gcm_KEYBYTES = nacl.crypto_aead_aes256gcm_keybytes() + crypto_aead_aes256gcm_NPUBBYTES = nacl.crypto_aead_aes256gcm_npubbytes() + crypto_aead_aes256gcm_ABYTES = nacl.crypto_aead_aes256gcm_abytes() + HAS_AEAD_AES256GCM = bool(nacl.crypto_aead_aes256gcm_is_available()) + crypto_aead_chacha20poly1305_ietf_KEYBYTES = nacl.crypto_aead_chacha20poly1305_ietf_keybytes() + crypto_aead_chacha20poly1305_ietf_NPUBBYTES = nacl.crypto_aead_chacha20poly1305_ietf_npubbytes() + crypto_aead_chacha20poly1305_ietf_ABYTES = nacl.crypto_aead_chacha20poly1305_ietf_abytes() + HAS_AEAD_CHACHA20POLY1305_IETF = True + HAS_AEAD = True + except AttributeError: + HAS_AEAD_AES256GCM = False + HAS_AEAD_CHACHA20POLY1305_IETF = False + HAS_AEAD = False + + crypto_box_SECRETKEYBYTES = nacl.crypto_box_secretkeybytes() + crypto_box_SEEDBYTES = nacl.crypto_box_seedbytes() + crypto_box_PUBLICKEYBYTES = nacl.crypto_box_publickeybytes() + crypto_box_NONCEBYTES = nacl.crypto_box_noncebytes() + crypto_box_ZEROBYTES = nacl.crypto_box_zerobytes() + crypto_box_BOXZEROBYTES = nacl.crypto_box_boxzerobytes() + crypto_box_BEFORENMBYTES = nacl.crypto_box_beforenmbytes() + crypto_scalarmult_BYTES = nacl.crypto_scalarmult_bytes() + crypto_scalarmult_SCALARBYTES = nacl.crypto_scalarmult_scalarbytes() + crypto_sign_BYTES = nacl.crypto_sign_bytes() + crypto_sign_SEEDBYTES = nacl.crypto_sign_secretkeybytes() // 2 + crypto_sign_PUBLICKEYBYTES = nacl.crypto_sign_publickeybytes() + crypto_sign_SECRETKEYBYTES = nacl.crypto_sign_secretkeybytes() + crypto_sign_ed25519_PUBLICKEYBYTES = nacl.crypto_sign_ed25519_publickeybytes() + crypto_sign_ed25519_SECRETKEYBYTES = nacl.crypto_sign_ed25519_secretkeybytes() + crypto_box_MACBYTES = crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES + crypto_secretbox_KEYBYTES = nacl.crypto_secretbox_keybytes() + crypto_secretbox_NONCEBYTES = nacl.crypto_secretbox_noncebytes() + crypto_secretbox_ZEROBYTES = nacl.crypto_secretbox_zerobytes() + crypto_secretbox_BOXZEROBYTES = nacl.crypto_secretbox_boxzerobytes() + crypto_secretbox_MACBYTES = crypto_secretbox_ZEROBYTES - crypto_secretbox_BOXZEROBYTES + crypto_stream_KEYBYTES = nacl.crypto_stream_keybytes() + crypto_stream_NONCEBYTES = nacl.crypto_stream_noncebytes() + crypto_auth_BYTES = nacl.crypto_auth_bytes() + crypto_auth_KEYBYTES = nacl.crypto_auth_keybytes() + crypto_onetimeauth_BYTES = nacl.crypto_onetimeauth_bytes() + crypto_onetimeauth_KEYBYTES = nacl.crypto_onetimeauth_keybytes() + crypto_generichash_BYTES = nacl.crypto_generichash_bytes() + crypto_generichash_BYTES_MIN = nacl.crypto_generichash_bytes_min() + crypto_generichash_BYTES_MAX = nacl.crypto_generichash_bytes_max() + crypto_generichash_KEYBYTES = nacl.crypto_generichash_keybytes() + crypto_generichash_KEYBYTES_MIN = nacl.crypto_generichash_keybytes_min() + crypto_generichash_KEYBYTES_MAX = nacl.crypto_generichash_keybytes_max() + crypto_scalarmult_curve25519_BYTES = nacl.crypto_scalarmult_curve25519_bytes() + crypto_hash_BYTES = nacl.crypto_hash_sha512_bytes() + crypto_hash_sha256_BYTES = nacl.crypto_hash_sha256_bytes() + crypto_hash_sha512_BYTES = nacl.crypto_hash_sha512_bytes() + crypto_verify_16_BYTES = nacl.crypto_verify_16_bytes() + crypto_verify_32_BYTES = nacl.crypto_verify_32_bytes() + crypto_verify_64_BYTES = nacl.crypto_verify_64_bytes() + + try: + randombytes_SEEDBYTES = nacl.randombytes_seedbytes() + HAS_RAND_SEED = True + except AttributeError: + HAS_RAND_SEED = False + + try: + crypto_kdf_PRIMITIVE = nacl.crypto_kdf_primitive() + crypto_kdf_BYTES_MIN = nacl.crypto_kdf_bytes_min() + crypto_kdf_BYTES_MAX = nacl.crypto_kdf_bytes_max() + crypto_kdf_CONTEXTBYTES = nacl.crypto_kdf_contextbytes() + crypto_kdf_KEYBYTES = nacl.crypto_kdf_keybytes() + HAS_CRYPT_KDF = True + except AttributeError: + HAS_CRYPT_KDF = False + + try: + crypto_kx_PUBLICKEYBYTES = nacl.crypto_kx_publickeybytes() + crypto_kx_SECRETKEYBYTES = nacl.crypto_kx_secretkeybytes() + crypto_kx_SEEDBYTES = nacl.crypto_kx_seedbytes() + crypto_kx_SESSIONKEYBYTES = nacl.crypto_kx_sessionkeybytes() + crypto_kx_PRIMITIVE = nacl.crypto_kx_primitive() + HAS_CRYPT_KX = True + except AttributeError: + HAS_CRYPT_KX = False + + # pylint: enable=C0103 # Pubkey defs @@ -187,15 +220,19 @@ def crypto_box_seed_keypair(seed): def crypto_scalarmult_base(sk): ''' - Generate a public key from a secret key + Compute and return the scalar product of a standard group element and the given integer. + + This can be used to derive a Curve25519 public key from a Curve25519 secret key, + such as for usage with crypto_box and crypto_box_seal. ''' if len(sk) != crypto_box_SECRETKEYBYTES: raise ValueError('Invalid secret key') pk = ctypes.create_string_buffer(crypto_box_PUBLICKEYBYTES) - nacl.crypto_scalarmult_base(pk, sk) + if nacl.crypto_scalarmult_base(pk, sk): + raise CryptError('Failed to compute scalar product') return pk.raw - - + + def crypto_box(msg, nonce, pk, sk): ''' Using a public key and a secret key encrypt the given message. A nonce @@ -444,6 +481,9 @@ def crypto_sign_ed25519_sk_to_pk(sk): ''' Extract the public key from the secret key ''' + if len(sk) != crypto_sign_ed25519_SECRETKEYBYTES: + raise ValueError('Invalid secret key') + pk = ctypes.create_string_buffer(crypto_sign_PUBLICKEYBYTES) ret = nacl.crypto_sign_ed25519_sk_to_pk(pk, sk) if ret: @@ -455,6 +495,9 @@ def crypto_sign_ed25519_sk_to_seed(sk): ''' Extract the seed from the secret key ''' + if len(sk) != crypto_sign_ed25519_SECRETKEYBYTES: + raise ValueError('Invalid secret key') + seed = ctypes.create_string_buffer(crypto_sign_SEEDBYTES) ret = nacl.crypto_sign_ed25519_sk_to_seed(seed, sk) if ret: @@ -466,6 +509,9 @@ def crypto_sign(msg, sk): ''' Sign the given message with the given signing key ''' + if len(sk) != crypto_sign_SECRETKEYBYTES: + raise ValueError('Invalid secret key') + sig = ctypes.create_string_buffer(len(msg) + crypto_sign_BYTES) slen = ctypes.pointer(ctypes.c_ulonglong()) ret = nacl.crypto_sign( @@ -483,6 +529,9 @@ def crypto_sign_detached(msg, sk): ''' Return signature for the given message with the given signing key ''' + if len(sk) != crypto_sign_SECRETKEYBYTES: + raise ValueError('Invalid secret key') + sig = ctypes.create_string_buffer(crypto_sign_BYTES) slen = ctypes.pointer(ctypes.c_ulonglong()) ret = nacl.crypto_sign_detached( @@ -502,6 +551,7 @@ def crypto_sign_seed_keypair(seed): ''' if len(seed) != crypto_sign_SEEDBYTES: raise ValueError('Invalid Seed') + sk = ctypes.create_string_buffer(crypto_sign_SECRETKEYBYTES) vk = ctypes.create_string_buffer(crypto_sign_PUBLICKEYBYTES) @@ -515,6 +565,9 @@ def crypto_sign_open(sig, vk): ''' Verifies the signed message sig using the signer's verification key ''' + if len(vk) != crypto_sign_PUBLICKEYBYTES: + raise ValueError('Invalid public key') + msg = ctypes.create_string_buffer(len(sig)) msglen = ctypes.c_ulonglong() msglenp = ctypes.pointer(msglen) @@ -533,6 +586,11 @@ def crypto_sign_verify_detached(sig, msg, vk): ''' Verifies that sig is a valid signature for the message msg using the signer's verification key ''' + if len(sig) != crypto_sign_BYTES: + raise ValueError('Invalid signature') + if len(vk) != crypto_sign_PUBLICKEYBYTES: + raise ValueError('Invalid public key') + ret = nacl.crypto_sign_verify_detached( sig, msg, @@ -600,6 +658,37 @@ def crypto_secretbox_open(ctxt, nonce, key): raise ValueError('Failed to decrypt message') return msg.raw[crypto_secretbox_ZEROBYTES:] +# Authenticated Symmetric Encryption improved version + + +def crypto_secretbox_easy(cmessage, nonce, key): + if len(key) != crypto_secretbox_KEYBYTES: + raise ValueError('Invalid key') + + if len(nonce) != crypto_secretbox_NONCEBYTES: + raise ValueError('Invalid nonce') + + + ctxt = ctypes.create_string_buffer(crypto_secretbox_MACBYTES + len(cmessage)) + ret = nacl.crypto_secretbox_easy(ctxt, cmessage, ctypes.c_ulonglong(len(cmessage)), nonce, key) + if ret: + raise ValueError('Failed to encrypt message') + return ctxt.raw[0:] + +def crypto_secretbox_open_easy(ctxt, nonce, key): + + if len(key) != crypto_secretbox_KEYBYTES: + raise ValueError('Invalid key') + + if len(nonce) != crypto_secretbox_NONCEBYTES: + raise ValueError('Invalid nonce') + + msg = ctypes.create_string_buffer(len(ctxt)) + ret = nacl.crypto_secretbox_open_easy(msg, ctxt, ctypes.c_ulonglong(len(ctxt)), nonce, key) + if ret: + raise ValueError('Failed to decrypt message') + return msg.raw[0:len(ctxt) - crypto_secretbox_MACBYTES] + # Authenticated Symmetric Encryption with Additional Data @@ -748,6 +837,11 @@ def crypto_stream(slen, nonce, key): ''' Generates a stream using the given secret key and nonce ''' + if len(key) != crypto_stream_KEYBYTES: + raise ValueError('Invalid secret key') + if len(nonce) != crypto_stream_NONCEBYTES: + raise ValueError('Invalid nonce') + stream = ctypes.create_string_buffer(slen) ret = nacl.crypto_stream(stream, ctypes.c_ulonglong(slen), nonce, key) if ret: @@ -763,6 +857,11 @@ def crypto_stream_xor(msg, nonce, key): plaintext (xor) the output of crypto_stream. Consequently crypto_stream_xor can also be used to decrypt ''' + if len(key) != crypto_stream_KEYBYTES: + raise ValueError('Invalid secret key') + if len(nonce) != crypto_stream_NONCEBYTES: + raise ValueError('Invalid nonce') + stream = ctypes.create_string_buffer(len(msg)) ret = nacl.crypto_stream_xor( stream, @@ -783,6 +882,9 @@ def crypto_auth(msg, key): Constructs a one time authentication token for the given message msg using a given secret key ''' + if len(key) != crypto_auth_KEYBYTES: + raise ValueError('Invalid secret key') + tok = ctypes.create_string_buffer(crypto_auth_BYTES) ret = nacl.crypto_auth(tok, msg, ctypes.c_ulonglong(len(msg)), key) if ret: @@ -795,6 +897,11 @@ def crypto_auth_verify(tok, msg, key): Verifies that the given authentication token is correct for the given message and key ''' + if len(key) != crypto_auth_KEYBYTES: + raise ValueError('Invalid secret key') + if len(tok) != crypto_auth_BYTES: + raise ValueError('Invalid authenticator') + ret = nacl.crypto_auth_verify(tok, msg, ctypes.c_ulonglong(len(msg)), key) if ret: raise ValueError('Failed to auth msg') @@ -919,19 +1026,6 @@ def crypto_generichash(msg, key=None): ctypes.c_size_t(key_len)) return hbuf.raw -# scalarmult - - -def crypto_scalarmult_base(n): - ''' - Computes and returns the scalar product of a standard group element and an - integer "n". - ''' - buf = ctypes.create_string_buffer(crypto_scalarmult_BYTES) - ret = nacl.crypto_scalarmult_base(buf, n) - if ret: - raise CryptError('Failed to compute scalar product') - return buf.raw # String cmp @@ -946,7 +1040,8 @@ def crypto_verify_16(string1, string2): matching prefix of string1 and string2. This often allows for easy timing attacks. ''' - return not nacl.crypto_verify_16(string1, string2) + a, b, c = (len(string1) >= 16), (len(string2) >= 16), (not nacl.crypto_verify_16(string1, string2)) + return a & b & c def crypto_verify_32(string1, string2): @@ -959,7 +1054,8 @@ def crypto_verify_32(string1, string2): matching prefix of string1 and string2. This often allows for easy timing attacks. ''' - return not nacl.crypto_verify_32(string1, string2) + a, b, c = (len(string1) >= 32), (len(string2) >= 32), (not nacl.crypto_verify_32(string1, string2)) + return a & b & c def crypto_verify_64(string1, string2): @@ -972,7 +1068,8 @@ def crypto_verify_64(string1, string2): matching prefix of string1 and string2. This often allows for easy timing attacks. ''' - return not nacl.crypto_verify_64(string1, string2) + a, b, c = (len(string1) >= 64), (len(string2) >= 64), (not nacl.crypto_verify_64(string1, string2)) + return a & b & c def bytes_eq(a, b): @@ -1017,6 +1114,22 @@ def randombytes_buf(size): nacl.randombytes_buf(buf, size) return buf.raw +def randombytes_buf_deterministic(size, seed): + ''' + Returns a string of random byles of the given size for a given seed. + For a given seed, this function will always output the same sequence. + Size can be up to 2^70 (256 GB). + ''' + + if not HAS_RAND_SEED: + raise ValueError('Underlying Sodium library does not support randombytes_seedbytes') + if len(seed) != randombytes_SEEDBYTES: + raise ValueError('Invalid key seed') + + size = int(size) + buf = ctypes.create_string_buffer(size) + nacl.randombytes_buf_deterministic(buf, size, seed) + return buf.raw def randombytes_close(): ''' @@ -1049,6 +1162,85 @@ def randombytes_uniform(upper_bound): ''' return nacl.randombytes_uniform(upper_bound) +# Key derivation API + +def crypto_kdf_keygen(): + ''' + Returns a string of random bytes to generate a master key + ''' + if not HAS_CRYPT_KDF: + raise ValueError('Underlying Sodium library does not support crypto_kdf_keybytes') + size = crypto_kdf_KEYBYTES + buf = ctypes.create_string_buffer(size) + nacl.crypto_kdf_keygen(buf) + return buf.raw + +def crypto_kdf_derive_from_key(subkey_size, subkey_id, context, master_key): + ''' + Returns a subkey generated from a master key for a given subkey_id. + For a given subkey_id, the subkey will always be the same string. + ''' + size = int(subkey_size) + buf = ctypes.create_string_buffer(size) + nacl.crypto_kdf_derive_from_key(buf, subkey_size, subkey_id, context, master_key) + return buf.raw + +# Key Exchange API + +def crypto_kx_keypair(): + ''' + Generate and return a new keypair + ''' + if not HAS_CRYPT_KX: + raise ValueError('Underlying Sodium library does not support crypto_kx') + pk = ctypes.create_string_buffer(crypto_kx_PUBLICKEYBYTES) + sk = ctypes.create_string_buffer(crypto_kx_SECRETKEYBYTES) + nacl.crypto_kx_keypair(pk, sk) + return pk.raw, sk.raw + +def crypto_kx_seed_keypair(seed): + ''' + Generate and return a keypair from a key seed + ''' + if not HAS_CRYPT_KX: + raise ValueError('Underlying Sodium library does not support crypto_kx') + + if len(seed) != crypto_kx_SEEDBYTES: + raise ValueError('Invalid key seed') + pk = ctypes.create_string_buffer(crypto_kx_PUBLICKEYBYTES) + sk = ctypes.create_string_buffer(crypto_kx_SECRETKEYBYTES) + nacl.crypto_kx_seed_keypair(pk, sk, seed) + return pk.raw, sk.raw + +def crypto_kx_client_session_keys(client_pk, client_sk, server_pk): + ''' + Computes a pair of shared keys (rx and tx) using the client's public key client_pk, + the client's secret key client_sk and the server's public key server_pk. + Status returns 0 on success, or -1 if the server's public key is not acceptable. + ''' + if not HAS_CRYPT_KX: + raise ValueError('Underlying Sodium library does not support crypto_kx') + + rx = ctypes.create_string_buffer(crypto_kx_SESSIONKEYBYTES) + tx = ctypes.create_string_buffer(crypto_kx_SESSIONKEYBYTES) + status = nacl.crypto_kx_client_session_keys(rx, tx, client_pk, client_sk, server_pk) + return rx.raw, tx.raw, status + +def crypto_kx_server_session_keys(server_pk, server_sk, client_pk): + ''' + Computes a pair of shared keys (rx and tx) using the server's public key server_pk, + the server's secret key server_sk and the client's public key client_pk. + Status returns 0 on success, or -1 if the client's public key is not acceptable. + ''' + if not HAS_CRYPT_KX: + raise ValueError('Underlying Sodium library does not support crypto_kx') + + rx = ctypes.create_string_buffer(crypto_kx_SESSIONKEYBYTES) + tx = ctypes.create_string_buffer(crypto_kx_SESSIONKEYBYTES) + status = nacl.crypto_kx_server_session_keys(rx, tx, server_pk, server_sk, client_pk) + return rx.raw, tx.raw, status + + # Utility functions @@ -1075,28 +1267,13 @@ def sodium_version_string(): return func() -def crypto_box_seed_keypair(seed): - ''' - Computes and returns the public and secret keys from the given seed - ''' - if len(seed) != crypto_box_SEEDBYTES: - raise ValueError('Invalid Seed') - pk = ctypes.create_string_buffer(crypto_box_PUBLICKEYBYTES) - sk = ctypes.create_string_buffer(crypto_box_SECRETKEYBYTES) - - ret = nacl.crypto_box_seed_keypair(pk, sk, seed) - if ret: - raise CryptError('Failed to generate keypair from seed') - return (pk.raw, sk.raw) - - def crypto_sign_ed25519_pk_to_curve25519(ed25519_pk): ''' Convert an Ed25519 public key to a Curve25519 public key ''' if len(ed25519_pk) != crypto_sign_ed25519_PUBLICKEYBYTES: - raise ValueError('Invalid Ed25519 Key') - + raise ValueError('Invalid public key') + curve25519_pk = ctypes.create_string_buffer(crypto_scalarmult_curve25519_BYTES) ret = nacl.crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk) if ret: @@ -1109,10 +1286,12 @@ def crypto_sign_ed25519_sk_to_curve25519(ed25519_sk): Convert an Ed25519 secret key to a Curve25519 secret key ''' if len(ed25519_sk) != crypto_sign_ed25519_SECRETKEYBYTES: - raise ValueError('Invalid Ed25519 Key') - + raise ValueError('Invalid secret key') + curve25519_sk = ctypes.create_string_buffer(crypto_scalarmult_curve25519_BYTES) ret = nacl.crypto_sign_ed25519_sk_to_curve25519(curve25519_sk, ed25519_sk) if ret: raise CryptError('Failed to generate Curve25519 secret key') return curve25519_sk.raw + + diff --git a/libnacl/secret_easy.py b/libnacl/secret_easy.py new file mode 100644 index 0000000..15dea1b --- /dev/null +++ b/libnacl/secret_easy.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +''' +Utilities to make secret box easy encryption simple +''' +# Import libnacl +import libnacl +import libnacl.utils +import libnacl.base + + +class SecretBoxEasy(libnacl.base.BaseKey): + ''' + Manage symetric encryption using the salsa20 algorithm + ''' + def __init__(self, key=None): + if key is None: + key = libnacl.utils.salsa_key() + if len(key) != libnacl.crypto_secretbox_KEYBYTES: + raise ValueError('Invalid key') + self.sk = key + + def encrypt(self, msg, nonce=None, pack_nonce=True): + ''' + Encrypt the given message. If a nonce is not given it will be + generated via the rand_nonce function + ''' + if nonce is None: + nonce = libnacl.utils.rand_nonce() + if len(nonce) != libnacl.crypto_secretbox_NONCEBYTES: + raise ValueError('Invalid nonce size') + ctxt = libnacl.crypto_secretbox_easy(msg, nonce, self.sk) + if pack_nonce: + return nonce + ctxt + else: + return nonce, ctxt + + def decrypt(self, ctxt, nonce=None): + ''' + Decrypt the given message, if no nonce is given the nonce will be + extracted from the message + ''' + if nonce is None: + nonce = ctxt[:libnacl.crypto_secretbox_NONCEBYTES] + ctxt = ctxt[libnacl.crypto_secretbox_NONCEBYTES:] + if len(nonce) != libnacl.crypto_secretbox_NONCEBYTES: + raise ValueError('Invalid nonce') + return libnacl.crypto_secretbox_open_easy(ctxt, nonce, self.sk) diff --git a/libnacl/version.py b/libnacl/version.py index bb64aa4..48c2f6b 100644 --- a/libnacl/version.py +++ b/libnacl/version.py @@ -1 +1 @@ -__version__ = '1.6.1' +__version__ = '1.7.1' @@ -25,6 +25,8 @@ setup(name=NAME, 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'Topic :: Security :: Cryptography', diff --git a/tests/unit/__init__.pyc b/tests/unit/__init__.pyc Binary files differdeleted file mode 100644 index 5755694..0000000 --- a/tests/unit/__init__.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/__init__.cpython-36.pyc b/tests/unit/__pycache__/__init__.cpython-36.pyc Binary files differdeleted file mode 100644 index 6f9db8e..0000000 --- a/tests/unit/__pycache__/__init__.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_aead.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_aead.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index fff63d2..0000000 --- a/tests/unit/__pycache__/test_aead.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_aead.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_aead.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index dbcd4ef..0000000 --- a/tests/unit/__pycache__/test_aead.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_aead.cpython-36.pyc b/tests/unit/__pycache__/test_aead.cpython-36.pyc Binary files differdeleted file mode 100644 index 9a3b3ba..0000000 --- a/tests/unit/__pycache__/test_aead.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_auth_verify.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_auth_verify.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index 91f252e..0000000 --- a/tests/unit/__pycache__/test_auth_verify.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_auth_verify.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_auth_verify.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index 1a0cc48..0000000 --- a/tests/unit/__pycache__/test_auth_verify.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_auth_verify.cpython-36.pyc b/tests/unit/__pycache__/test_auth_verify.cpython-36.pyc Binary files differdeleted file mode 100644 index 408df62..0000000 --- a/tests/unit/__pycache__/test_auth_verify.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_blake.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_blake.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index 9038180..0000000 --- a/tests/unit/__pycache__/test_blake.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_blake.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_blake.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index 4943254..0000000 --- a/tests/unit/__pycache__/test_blake.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_blake.cpython-36.pyc b/tests/unit/__pycache__/test_blake.cpython-36.pyc Binary files differdeleted file mode 100644 index 9cbc06b..0000000 --- a/tests/unit/__pycache__/test_blake.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_dual.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_dual.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index 2224627..0000000 --- a/tests/unit/__pycache__/test_dual.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_dual.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_dual.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index e36c90b..0000000 --- a/tests/unit/__pycache__/test_dual.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_dual.cpython-36.pyc b/tests/unit/__pycache__/test_dual.cpython-36.pyc Binary files differdeleted file mode 100644 index 83ef279..0000000 --- a/tests/unit/__pycache__/test_dual.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_public.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_public.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index a4cbdb8..0000000 --- a/tests/unit/__pycache__/test_public.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_public.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_public.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index 871dc8f..0000000 --- a/tests/unit/__pycache__/test_public.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_public.cpython-36.pyc b/tests/unit/__pycache__/test_public.cpython-36.pyc Binary files differdeleted file mode 100644 index be39fd5..0000000 --- a/tests/unit/__pycache__/test_public.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_auth_sym.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_raw_auth_sym.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index ef87b61..0000000 --- a/tests/unit/__pycache__/test_raw_auth_sym.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_auth_sym.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_raw_auth_sym.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index 0ad767f..0000000 --- a/tests/unit/__pycache__/test_raw_auth_sym.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_auth_sym.cpython-36.pyc b/tests/unit/__pycache__/test_raw_auth_sym.cpython-36.pyc Binary files differdeleted file mode 100644 index b71259b..0000000 --- a/tests/unit/__pycache__/test_raw_auth_sym.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_generichash.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_raw_generichash.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index 9d90f8a..0000000 --- a/tests/unit/__pycache__/test_raw_generichash.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_generichash.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_raw_generichash.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index b898524..0000000 --- a/tests/unit/__pycache__/test_raw_generichash.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_generichash.cpython-36.pyc b/tests/unit/__pycache__/test_raw_generichash.cpython-36.pyc Binary files differdeleted file mode 100644 index 28cf70e..0000000 --- a/tests/unit/__pycache__/test_raw_generichash.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_hash.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_raw_hash.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index e4215a3..0000000 --- a/tests/unit/__pycache__/test_raw_hash.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_hash.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_raw_hash.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index 588fbc3..0000000 --- a/tests/unit/__pycache__/test_raw_hash.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_hash.cpython-36.pyc b/tests/unit/__pycache__/test_raw_hash.cpython-36.pyc Binary files differdeleted file mode 100644 index d16fca9..0000000 --- a/tests/unit/__pycache__/test_raw_hash.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_public.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_raw_public.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index 60b843b..0000000 --- a/tests/unit/__pycache__/test_raw_public.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_public.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_raw_public.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index 315752e..0000000 --- a/tests/unit/__pycache__/test_raw_public.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_public.cpython-36.pyc b/tests/unit/__pycache__/test_raw_public.cpython-36.pyc Binary files differdeleted file mode 100644 index c849e4b..0000000 --- a/tests/unit/__pycache__/test_raw_public.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_random.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_raw_random.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index 690c1bc..0000000 --- a/tests/unit/__pycache__/test_raw_random.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_random.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_raw_random.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index d07ccbc..0000000 --- a/tests/unit/__pycache__/test_raw_random.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_random.cpython-36.pyc b/tests/unit/__pycache__/test_raw_random.cpython-36.pyc Binary files differdeleted file mode 100644 index 88f12d8..0000000 --- a/tests/unit/__pycache__/test_raw_random.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_secret.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_raw_secret.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index 162b0b3..0000000 --- a/tests/unit/__pycache__/test_raw_secret.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_secret.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_raw_secret.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index 382d116..0000000 --- a/tests/unit/__pycache__/test_raw_secret.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_secret.cpython-36.pyc b/tests/unit/__pycache__/test_raw_secret.cpython-36.pyc Binary files differdeleted file mode 100644 index 28ddd9a..0000000 --- a/tests/unit/__pycache__/test_raw_secret.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_sign.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_raw_sign.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index 997d888..0000000 --- a/tests/unit/__pycache__/test_raw_sign.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_sign.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_raw_sign.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index ac9fa8c..0000000 --- a/tests/unit/__pycache__/test_raw_sign.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_raw_sign.cpython-36.pyc b/tests/unit/__pycache__/test_raw_sign.cpython-36.pyc Binary files differdeleted file mode 100644 index 2b439dd..0000000 --- a/tests/unit/__pycache__/test_raw_sign.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_save.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_save.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index 25aef81..0000000 --- a/tests/unit/__pycache__/test_save.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_save.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_save.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index 5587f49..0000000 --- a/tests/unit/__pycache__/test_save.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_save.cpython-36.pyc b/tests/unit/__pycache__/test_save.cpython-36.pyc Binary files differdeleted file mode 100644 index 76a6393..0000000 --- a/tests/unit/__pycache__/test_save.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_seal.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_seal.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index 9065ea2..0000000 --- a/tests/unit/__pycache__/test_seal.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_seal.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_seal.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index 4ab8b51..0000000 --- a/tests/unit/__pycache__/test_seal.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_seal.cpython-36.pyc b/tests/unit/__pycache__/test_seal.cpython-36.pyc Binary files differdeleted file mode 100644 index fa376a6..0000000 --- a/tests/unit/__pycache__/test_seal.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_secret.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_secret.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index b1942e4..0000000 --- a/tests/unit/__pycache__/test_secret.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_secret.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_secret.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index 385caa9..0000000 --- a/tests/unit/__pycache__/test_secret.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_secret.cpython-36.pyc b/tests/unit/__pycache__/test_secret.cpython-36.pyc Binary files differdeleted file mode 100644 index c488bd3..0000000 --- a/tests/unit/__pycache__/test_secret.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_sign.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_sign.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index 21f4297..0000000 --- a/tests/unit/__pycache__/test_sign.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_sign.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_sign.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index 932db76..0000000 --- a/tests/unit/__pycache__/test_sign.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_sign.cpython-36.pyc b/tests/unit/__pycache__/test_sign.cpython-36.pyc Binary files differdeleted file mode 100644 index e3535be..0000000 --- a/tests/unit/__pycache__/test_sign.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_verify.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_verify.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index c00f86f..0000000 --- a/tests/unit/__pycache__/test_verify.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_verify.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_verify.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index ecbc11d..0000000 --- a/tests/unit/__pycache__/test_verify.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_verify.cpython-36.pyc b/tests/unit/__pycache__/test_verify.cpython-36.pyc Binary files differdeleted file mode 100644 index 382a6bf..0000000 --- a/tests/unit/__pycache__/test_verify.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_version.cpython-27-PYTEST.pyc b/tests/unit/__pycache__/test_version.cpython-27-PYTEST.pyc Binary files differdeleted file mode 100644 index 1274216..0000000 --- a/tests/unit/__pycache__/test_version.cpython-27-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_version.cpython-36-PYTEST.pyc b/tests/unit/__pycache__/test_version.cpython-36-PYTEST.pyc Binary files differdeleted file mode 100644 index d5576e8..0000000 --- a/tests/unit/__pycache__/test_version.cpython-36-PYTEST.pyc +++ /dev/null diff --git a/tests/unit/__pycache__/test_version.cpython-36.pyc b/tests/unit/__pycache__/test_version.cpython-36.pyc Binary files differdeleted file mode 100644 index 0dcc47b..0000000 --- a/tests/unit/__pycache__/test_version.cpython-36.pyc +++ /dev/null diff --git a/tests/unit/test_aead.pyc b/tests/unit/test_aead.pyc Binary files differdeleted file mode 100644 index af62b5b..0000000 --- a/tests/unit/test_aead.pyc +++ /dev/null diff --git a/tests/unit/test_auth_verify.py b/tests/unit/test_auth_verify.py index 90a45e9..919011b 100644 --- a/tests/unit/test_auth_verify.py +++ b/tests/unit/test_auth_verify.py @@ -57,3 +57,46 @@ class TestAuthVerify(unittest.TestCase): libnacl.crypto_onetimeauth_verify(sig2, msg, key1) self.assertTrue('Failed to auth message' in context.exception.args) + def test_auth_rejects_wrong_lengths(self): + msg = b'Time is an illusion. Lunchtime doubly so.' + for bad_key in (b'too short', b'too long' * 100): + with self.assertRaises(ValueError) as context: + libnacl.crypto_auth(msg, bad_key) + self.assertEqual(context.exception.args, ('Invalid secret key',)) + + def test_auth_verify_rejects_wrong_key_lengths(self): + msg = b"I'd take the awe of understanding over the awe of ignorance any day." + good_key = b'This valid key is 32 bytes long.' + good_token = b'This token is likewise also 32B.' + + for bad_key in (b'too short', b'too long' * 100): + with self.assertRaises(ValueError) as context: + libnacl.crypto_auth_verify(good_token, msg, bad_key) + self.assertEqual(context.exception.args, ('Invalid secret key',)) + + for bad_token in (b'too short', b'too long' * 100): + with self.assertRaises(ValueError) as context: + libnacl.crypto_auth_verify(bad_token, msg, good_key) + self.assertEqual(context.exception.args, ('Invalid authenticator',)) + + def test_onetimeauth_rejects_wrong_lengths(self): + msg = b"Are the most dangerous creatures the ones that use doors or the ones that don't?" + for bad_key in (b'too short', b'too long' * 100): + with self.assertRaises(ValueError) as context: + libnacl.crypto_onetimeauth(msg, bad_key) + self.assertEqual(context.exception.args, ('Invalid secret key',)) + + def test_onetimeauth_verify_rejects_wrong_key_lengths(self): + msg = b"Of all the dogs I've known in my life, I've never seen a better driver." + good_key = b'This valid key is 32 bytes long.' + good_token = b'1time tokens=16B' + + for bad_key in (b'too short', b'too long' * 100): + with self.assertRaises(ValueError) as context: + libnacl.crypto_onetimeauth_verify(good_token, msg, bad_key) + self.assertEqual(context.exception.args, ('Invalid secret key',)) + + for bad_token in (b'too short', b'too long' * 100): + with self.assertRaises(ValueError) as context: + libnacl.crypto_onetimeauth_verify(bad_token, msg, good_key) + self.assertEqual(context.exception.args, ('Invalid authenticator',)) diff --git a/tests/unit/test_auth_verify.pyc b/tests/unit/test_auth_verify.pyc Binary files differdeleted file mode 100644 index 0e78823..0000000 --- a/tests/unit/test_auth_verify.pyc +++ /dev/null diff --git a/tests/unit/test_blake.pyc b/tests/unit/test_blake.pyc Binary files differdeleted file mode 100644 index c66faeb..0000000 --- a/tests/unit/test_blake.pyc +++ /dev/null diff --git a/tests/unit/test_dual.pyc b/tests/unit/test_dual.pyc Binary files differdeleted file mode 100644 index 6d449f8..0000000 --- a/tests/unit/test_dual.pyc +++ /dev/null diff --git a/tests/unit/test_public.pyc b/tests/unit/test_public.pyc Binary files differdeleted file mode 100644 index c562509..0000000 --- a/tests/unit/test_public.pyc +++ /dev/null diff --git a/tests/unit/test_raw_auth_sym.pyc b/tests/unit/test_raw_auth_sym.pyc Binary files differdeleted file mode 100644 index ea6be6e..0000000 --- a/tests/unit/test_raw_auth_sym.pyc +++ /dev/null diff --git a/tests/unit/test_raw_auth_sym_easy.py b/tests/unit/test_raw_auth_sym_easy.py new file mode 100644 index 0000000..945e6b0 --- /dev/null +++ b/tests/unit/test_raw_auth_sym_easy.py @@ -0,0 +1,20 @@ +# Import nacl libs +import libnacl +import libnacl.utils + +# Import python libs +import unittest + + +class TestSecretBox(unittest.TestCase): + ''' + Test sign functions + ''' + def test_secret_box_easy(self): + msg = b'Are you suggesting coconuts migrate?' + sk1 = libnacl.utils.salsa_key() + nonce1 = libnacl.utils.rand_nonce() + enc_msg = libnacl.crypto_secretbox_easy(msg, nonce1, sk1) + self.assertNotEqual(msg, enc_msg) + clear_msg = libnacl.crypto_secretbox_open_easy(enc_msg, nonce1, sk1) + self.assertEqual(msg, clear_msg) diff --git a/tests/unit/test_raw_generichash.pyc b/tests/unit/test_raw_generichash.pyc Binary files differdeleted file mode 100644 index 0ada34d..0000000 --- a/tests/unit/test_raw_generichash.pyc +++ /dev/null diff --git a/tests/unit/test_raw_hash.pyc b/tests/unit/test_raw_hash.pyc Binary files differdeleted file mode 100644 index e9562aa..0000000 --- a/tests/unit/test_raw_hash.pyc +++ /dev/null diff --git a/tests/unit/test_raw_public.py b/tests/unit/test_raw_public.py index 6ef768f..85fd63f 100644 --- a/tests/unit/test_raw_public.py +++ b/tests/unit/test_raw_public.py @@ -79,3 +79,13 @@ class TestPublic(unittest.TestCase): self.assertEqual(clear_msg2, msg) # Check bits self.assertNotEqual(enc_msg, enc_msg2) + + def test_scalarmult_rejects_wrong_length(self): + good_key = b'This valid key is 32 bytes long.' + + for bad_key in (b'too short', b'too long' * 100): + with self.assertRaises(ValueError) as context: + libnacl.crypto_scalarmult_base(bad_key) + self.assertEqual(context.exception.args, ('Invalid secret key',)) + + self.assertEqual(libnacl.crypto_box_PUBLICKEYBYTES, len(libnacl.crypto_scalarmult_base(good_key))) diff --git a/tests/unit/test_raw_public.pyc b/tests/unit/test_raw_public.pyc Binary files differdeleted file mode 100644 index bdc8e83..0000000 --- a/tests/unit/test_raw_public.pyc +++ /dev/null diff --git a/tests/unit/test_raw_random.py b/tests/unit/test_raw_random.py index b695986..8821731 100644 --- a/tests/unit/test_raw_random.py +++ b/tests/unit/test_raw_random.py @@ -27,3 +27,78 @@ class TestRandomBytes(unittest.TestCase): self.assertEqual(256, len(freq)) self.assertTrue(all(freq.values())) + + def test_randombytes_buf_deterministic(self): + + seed = libnacl.randombytes_buf(32) + seed2 = libnacl.randombytes_buf(32) + data = libnacl.randombytes_buf_deterministic(32, seed) + data2 = libnacl.randombytes_buf_deterministic(32, seed) + data3 = libnacl.randombytes_buf_deterministic(32, seed2) + + self.assertEqual(32, len(data)) + self.assertEqual(32, len(data)) + self.assertEqual(32, len(data)) + self.assertEqual(data, data2) + self.assertNotEqual(data, data3) + + def test_crypto_kdf_keygen(self): + + master_key = libnacl.crypto_kdf_keygen() + + freq = {x: 1 for x in master_key} + + self.assertEqual(32, len(master_key)) + self.assertTrue(all(freq.values())) + + def test_crypto_kdf_derive_from_key(self): + + master_key = libnacl.crypto_kdf_keygen() + subkey = libnacl.crypto_kdf_derive_from_key(16, 1, "Examples", master_key) + subkey2 = libnacl.crypto_kdf_derive_from_key(16, 1, "Examples", master_key) + subkey3 = libnacl.crypto_kdf_derive_from_key(16, 2, "Examples", master_key) + + self.assertEqual(16, len(subkey)) + self.assertEqual(16, len(subkey2)) + self.assertEqual(16, len(subkey3)) + self.assertEqual(subkey, subkey2) + self.assertNotEqual(subkey, subkey3) + + def test_crypto_kx_keypair(self): + pk, sk = libnacl.crypto_kx_keypair() + self.assertEqual(32, len(pk)) + self.assertEqual(32, len(sk)) + + def test_crypto_kx_seed_keypair(self): + seed = libnacl.randombytes_buf(32) + seed2 = libnacl.randombytes_buf(32) + pk, sk = libnacl.crypto_kx_seed_keypair(seed) + pk2, sk2 = libnacl.crypto_kx_seed_keypair(seed) + pk3, sk3 = libnacl.crypto_kx_seed_keypair(seed2) + + self.assertEqual(pk, pk2) + self.assertNotEqual(pk, pk3) + self.assertEqual(sk, sk2) + self.assertNotEqual(sk, sk3) + + def test_crypto_kx_client_session_keys(self): + client_pk, client_sk = libnacl.crypto_kx_keypair() + server_pk, server_sk = libnacl.crypto_kx_keypair() + rx, tx, status = libnacl.crypto_kx_client_session_keys(client_pk, client_sk, server_pk) + rx2, tx2, status = libnacl.crypto_kx_client_session_keys(client_pk, client_sk, server_pk) + + self.assertEqual(32, len(rx)) + self.assertEqual(32, len(tx)) + self.assertEqual(rx, rx2) + self.assertEqual(tx, tx2) + + def test_crypto_kx_server_session_keys(self): + client_pk, client_sk = libnacl.crypto_kx_keypair() + server_pk, server_sk = libnacl.crypto_kx_keypair() + rx, tx, status = libnacl.crypto_kx_server_session_keys(client_pk, client_sk, server_pk) + rx2, tx2, status = libnacl.crypto_kx_server_session_keys(client_pk, client_sk, server_pk) + + self.assertEqual(32, len(rx)) + self.assertEqual(32, len(tx)) + self.assertEqual(rx, rx2) + self.assertEqual(tx, tx2) diff --git a/tests/unit/test_raw_random.pyc b/tests/unit/test_raw_random.pyc Binary files differdeleted file mode 100644 index 125e277..0000000 --- a/tests/unit/test_raw_random.pyc +++ /dev/null diff --git a/tests/unit/test_raw_secret.pyc b/tests/unit/test_raw_secret.pyc Binary files differdeleted file mode 100644 index c197b8b..0000000 --- a/tests/unit/test_raw_secret.pyc +++ /dev/null diff --git a/tests/unit/test_raw_secret_easy.py b/tests/unit/test_raw_secret_easy.py new file mode 100644 index 0000000..77e0966 --- /dev/null +++ b/tests/unit/test_raw_secret_easy.py @@ -0,0 +1,33 @@ +# Import libnacl libs +import libnacl +import libnacl.utils + +# Import python libs +import unittest + + +class TestSecret(unittest.TestCase): + """ + Test secret functions + """ + def test_secretbox_easy(self): + msg = b'Are you suggesting coconuts migrate?' + + nonce = libnacl.utils.rand_nonce() + key = libnacl.utils.salsa_key() + + c = libnacl.crypto_secretbox_easy(msg, nonce, key) + m = libnacl.crypto_secretbox_open_easy(c, nonce, key) + self.assertEqual(msg, m) + + with self.assertRaises(ValueError): + libnacl.crypto_secretbox_easy(msg, b'too_short', key) + + with self.assertRaises(ValueError): + libnacl.crypto_secretbox_easy(msg, nonce, b'too_short') + + with self.assertRaises(ValueError): + libnacl.crypto_secretbox_open_easy(c, b'too_short', key) + + with self.assertRaises(ValueError): + libnacl.crypto_secretbox_open_easy(c, nonce, b'too_short') diff --git a/tests/unit/test_raw_sign.pyc b/tests/unit/test_raw_sign.pyc Binary files differdeleted file mode 100644 index 3adaf36..0000000 --- a/tests/unit/test_raw_sign.pyc +++ /dev/null diff --git a/tests/unit/test_save.pyc b/tests/unit/test_save.pyc Binary files differdeleted file mode 100644 index d75a488..0000000 --- a/tests/unit/test_save.pyc +++ /dev/null diff --git a/tests/unit/test_seal.pyc b/tests/unit/test_seal.pyc Binary files differdeleted file mode 100644 index e25ea7e..0000000 --- a/tests/unit/test_seal.pyc +++ /dev/null diff --git a/tests/unit/test_secret.pyc b/tests/unit/test_secret.pyc Binary files differdeleted file mode 100644 index 6c4eb38..0000000 --- a/tests/unit/test_secret.pyc +++ /dev/null diff --git a/tests/unit/test_secret_easy.py b/tests/unit/test_secret_easy.py new file mode 100644 index 0000000..f77fdfc --- /dev/null +++ b/tests/unit/test_secret_easy.py @@ -0,0 +1,22 @@ +# Import libnacl libs +import libnacl.secret_easy +# Import python libs +import unittest + +class TestSecretEasy(unittest.TestCase): + ''' + ''' + def test_secret(self): + msg = b'But then of course African swallows are not migratory.' + box = libnacl.secret_easy.SecretBoxEasy() + ctxt = box.encrypt(msg) + self.assertNotEqual(msg, ctxt) + box2 = libnacl.secret_easy.SecretBoxEasy(box.sk) + clear1 = box.decrypt(ctxt) + self.assertEqual(msg, clear1) + clear2 = box2.decrypt(ctxt) + self.assertEqual(clear1, clear2) + ctxt2 = box2.encrypt(msg) + clear3 = box.decrypt(ctxt2) + self.assertEqual(clear3, msg) + diff --git a/tests/unit/test_sign.py b/tests/unit/test_sign.py index c223ee9..b639c95 100644 --- a/tests/unit/test_sign.py +++ b/tests/unit/test_sign.py @@ -21,3 +21,73 @@ class TestSigning(unittest.TestCase): self.assertEqual(verified, msg) self.assertEqual(verified2, msg) + def test_key_decomposition(self): + prv_key = b'The two halves are understood to' + pub_key = b'be essentially arbitrary values.' + secret_key = prv_key + pub_key + # The following functions should simply decompose a secret key + # without performing real computation. libsodium understands secret + # keys to be (private seed bytes || derived public key bytes). + self.assertEqual(prv_key, libnacl.crypto_sign_ed25519_sk_to_seed(secret_key)) + self.assertEqual(pub_key, libnacl.crypto_sign_ed25519_sk_to_pk(secret_key)) + + def test_key_decomposition_rejects_wrong_key_lengths(self): + """ + Too few bytes in a key passed through to libsodium will lead to bytes past the end + of the string being read. We should be guarding against this dangerous case. + """ + for test_func in (libnacl.crypto_sign_ed25519_sk_to_seed, libnacl.crypto_sign_ed25519_sk_to_pk): + for bad_key in (b'too short', b'too long' * 100): + with self.assertRaises(ValueError) as context: + test_func(bad_key) + self.assertEqual(context.exception.args, ('Invalid secret key',)) + + def test_sign_rejects_wrong_key_lengths(self): + """ + Too few bytes in a key passed through to libsodium will lead to bytes past the end + of the string being read. We should be guarding against this dangerous case. + """ + msg = b'The message does not matter.' + for test_func in (libnacl.crypto_sign, libnacl.crypto_sign_detached): + for bad_key in (b'too short', b'too long' * 100): + with self.assertRaises(ValueError) as context: + test_func(msg, bad_key) + self.assertEqual(context.exception.args, ('Invalid secret key',)) + + def test_open_rejects_wrong_key_lengths(self): + """ + Too few bytes in a key passed through to libsodium will lead to bytes past the end + of the string being read. We should be guarding against this dangerous case. + """ + msg = b'The message does not matter.' + good_key = b'This valid key is 32 bytes long.' + for bad_key in (b'too short', b'too long' * 100): + with self.assertRaises(ValueError) as context: + libnacl.crypto_sign_open(msg, bad_key) + self.assertEqual(context.exception.args, ('Invalid public key',)) + + with self.assertRaises(ValueError) as context: + libnacl.crypto_sign_open(msg, good_key) + self.assertEqual(context.exception.args, ('Failed to validate message',)) + + def test_verify_detached_rejects_wrong_key_lengths(self): + """ + Too few bytes in a key passed through to libsodium will lead to bytes past the end + of the string being read. We should be guarding against this dangerous case. + """ + msg = b'The message does not matter.' + good_signature = b'This is a valid signature; it is 64 bytes long, no more, no less' + good_key = b'This valid key is 32 bytes long.' + for bad_key in (b'too short', b'too long' * 100): + with self.assertRaises(ValueError) as context: + libnacl.crypto_sign_verify_detached(good_signature, msg, bad_key) + self.assertEqual(context.exception.args, ('Invalid public key',)) + + for bad_signature in (b'too short', b'too long' * 100): + with self.assertRaises(ValueError) as context: + libnacl.crypto_sign_verify_detached(bad_signature, msg, good_key) + self.assertEqual(context.exception.args, ('Invalid signature',)) + + with self.assertRaises(ValueError) as context: + libnacl.crypto_sign_verify_detached(good_signature, msg, good_key) + self.assertEqual(context.exception.args, ('Failed to validate message',)) diff --git a/tests/unit/test_sign.pyc b/tests/unit/test_sign.pyc Binary files differdeleted file mode 100644 index 45a5233..0000000 --- a/tests/unit/test_sign.pyc +++ /dev/null diff --git a/tests/unit/test_stream.py b/tests/unit/test_stream.py new file mode 100644 index 0000000..3629e9e --- /dev/null +++ b/tests/unit/test_stream.py @@ -0,0 +1,43 @@ +# Import libnacl libs +import libnacl.sign + +# Import pythonlibs +import unittest + + +class TestStream(unittest.TestCase): + def test_stream_rejects_wrong_lengths(self): + """ + Too few bytes in a key or nonce passed through to libsodium will lead to bytes past the end + of the string being read. We should be guarding against this dangerous case. + """ + msg_len = 100 # whatever + good_nonce= b'Nonces must be 24 bytes.' + good_key = b'This valid key is 32 bytes long.' + for bad_nonce in (b'too short', b'too long' * 100): + with self.assertRaises(ValueError) as context: + libnacl.crypto_stream(msg_len, bad_nonce, good_key) + self.assertEqual(context.exception.args, ('Invalid nonce',)) + + for bad_key in (b'too short', b'too long' * 100): + with self.assertRaises(ValueError) as context: + libnacl.crypto_stream(msg_len, good_nonce, bad_key) + self.assertEqual(context.exception.args, ('Invalid secret key',)) + + def test_stream_xor_rejects_wrong_lengths(self): + """ + Too few bytes in a key or nonce passed through to libsodium will lead to bytes past the end + of the string being read. We should be guarding against this dangerous case. + """ + msg = b'The message does not matter.' + good_nonce = b'Nonces must be 24 bytes.' + good_key = b'This valid key is 32 bytes long.' + for bad_nonce in (b'too short', b'too long' * 100): + with self.assertRaises(ValueError) as context: + libnacl.crypto_stream_xor(msg, bad_nonce, good_key) + self.assertEqual(context.exception.args, ('Invalid nonce',)) + + for bad_key in (b'too short', b'too long' * 100): + with self.assertRaises(ValueError) as context: + libnacl.crypto_stream_xor(msg, good_nonce, bad_key) + self.assertEqual(context.exception.args, ('Invalid secret key',)) diff --git a/tests/unit/test_verify.py b/tests/unit/test_verify.py index 7c03ea7..ea872f8 100644 --- a/tests/unit/test_verify.py +++ b/tests/unit/test_verify.py @@ -14,7 +14,8 @@ class TestVerify(unittest.TestCase): self.assertTrue(libnacl.crypto_verify_16(v16, v16x))
self.assertTrue(libnacl.bytes_eq(v16, v16x))
v16x = bytearray(v16x)
- v16x[libnacl.randombytes_random() & 15] += 1
+ i = libnacl.randombytes_random() & 15
+ v16x[i] = (v16x[i] + 1) % 256
v16x = bytes(v16x)
self.assertFalse(libnacl.crypto_verify_16(v16, v16x))
self.assertFalse(libnacl.bytes_eq(v16, v16x))
@@ -27,7 +28,8 @@ class TestVerify(unittest.TestCase): self.assertTrue(libnacl.crypto_verify_32(v32, v32x))
self.assertTrue(libnacl.bytes_eq(v32, v32x))
v32x = bytearray(v32x)
- v32x[libnacl.randombytes_random() & 31] += 1
+ i = libnacl.randombytes_random() & 31
+ v32x[i] = (v32x[i] + 1) % 256
v32x = bytes(v32x)
self.assertFalse(libnacl.crypto_verify_32(v32, v32x))
self.assertFalse(libnacl.bytes_eq(v32, v32x))
@@ -40,7 +42,8 @@ class TestVerify(unittest.TestCase): self.assertTrue(libnacl.crypto_verify_64(v64, v64x))
self.assertTrue(libnacl.bytes_eq(v64, v64x))
v64x = bytearray(v64x)
- v64x[libnacl.randombytes_random() & 63] += 1
+ i = libnacl.randombytes_random() & 63
+ v64x[i] = (v64x[i] + 1) % 256
v64x = bytes(v64x)
self.assertFalse(libnacl.crypto_verify_64(v64, v64x))
self.assertFalse(libnacl.bytes_eq(v64, v64x))
@@ -57,7 +60,7 @@ class TestVerifyBytesEq(unittest.TestCase): def test_different(self):
a = libnacl.randombytes_buf(122)
b = bytearray(a)
- b[87] += 1
+ b[87] = (b[87] + 1) % 256
b = bytes(b)
self.assertFalse(libnacl.bytes_eq(a, b))
diff --git a/tests/unit/test_verify.pyc b/tests/unit/test_verify.pyc Binary files differdeleted file mode 100644 index f2ef027..0000000 --- a/tests/unit/test_verify.pyc +++ /dev/null diff --git a/tests/unit/test_version.pyc b/tests/unit/test_version.pyc Binary files differdeleted file mode 100644 index db08547..0000000 --- a/tests/unit/test_version.pyc +++ /dev/null |