diff options
author | Alex Gaynor <alex.gaynor@gmail.com> | 2013-12-17 07:35:34 -0800 |
---|---|---|
committer | Alex Gaynor <alex.gaynor@gmail.com> | 2013-12-17 07:35:34 -0800 |
commit | 875b36be29e6bcfd1cb2a9cb216aba49c1d9d2f0 (patch) | |
tree | 71372f15c53afdd4bf2459e9a4774f3d526075a5 | |
parent | 4eec0bb4e1d79f107f40b3856f2c9ec76c3eef88 (diff) | |
parent | a4aa420cc6c0203d201a0f418af68d1f11abbcf5 (diff) | |
download | cryptography-875b36be29e6bcfd1cb2a9cb216aba49c1d9d2f0.tar.gz cryptography-875b36be29e6bcfd1cb2a9cb216aba49c1d9d2f0.tar.bz2 cryptography-875b36be29e6bcfd1cb2a9cb216aba49c1d9d2f0.zip |
Merge branch 'master' into no-more-generator
Conflicts:
tests/hazmat/primitives/utils.py
-rw-r--r-- | cryptography/hazmat/backends/__init__.py (renamed from cryptography/hazmat/bindings/__init__.py) | 2 | ||||
-rw-r--r-- | cryptography/hazmat/backends/interfaces.py (renamed from cryptography/hazmat/bindings/interfaces.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/__init__.py (renamed from cryptography/hazmat/bindings/openssl/__init__.py) | 2 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/asn1.py (renamed from cryptography/hazmat/bindings/openssl/asn1.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/backend.py (renamed from cryptography/hazmat/bindings/openssl/backend.py) | 4 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/bignum.py (renamed from cryptography/hazmat/bindings/openssl/bignum.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/bio.py (renamed from cryptography/hazmat/bindings/openssl/bio.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/conf.py (renamed from cryptography/hazmat/bindings/openssl/conf.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/crypto.py (renamed from cryptography/hazmat/bindings/openssl/crypto.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/dh.py (renamed from cryptography/hazmat/bindings/openssl/dh.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/dsa.py (renamed from cryptography/hazmat/bindings/openssl/dsa.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/engine.py (renamed from cryptography/hazmat/bindings/openssl/engine.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/err.py (renamed from cryptography/hazmat/bindings/openssl/err.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/evp.py (renamed from cryptography/hazmat/bindings/openssl/evp.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/hmac.py (renamed from cryptography/hazmat/bindings/openssl/hmac.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/nid.py (renamed from cryptography/hazmat/bindings/openssl/nid.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/opensslv.py (renamed from cryptography/hazmat/bindings/openssl/opensslv.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/pem.py (renamed from cryptography/hazmat/bindings/openssl/pem.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/pkcs12.py (renamed from cryptography/hazmat/bindings/openssl/pkcs12.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/pkcs7.py (renamed from cryptography/hazmat/bindings/openssl/pkcs7.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/rand.py (renamed from cryptography/hazmat/bindings/openssl/rand.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/rsa.py (renamed from cryptography/hazmat/bindings/openssl/rsa.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/ssl.py (renamed from cryptography/hazmat/bindings/openssl/ssl.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/x509.py (renamed from cryptography/hazmat/bindings/openssl/x509.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/x509name.py (renamed from cryptography/hazmat/bindings/openssl/x509name.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/backends/openssl/x509v3.py (renamed from cryptography/hazmat/bindings/openssl/x509v3.py) | 0 | ||||
-rw-r--r-- | cryptography/hazmat/primitives/constant_time.py | 53 | ||||
-rw-r--r-- | docs/architecture.rst | 6 | ||||
-rw-r--r-- | docs/conf.py | 1 | ||||
-rw-r--r-- | docs/contributing.rst | 3 | ||||
-rw-r--r-- | docs/hazmat/backends/index.rst (renamed from docs/hazmat/bindings/index.rst) | 2 | ||||
-rw-r--r-- | docs/hazmat/backends/interfaces.rst (renamed from docs/hazmat/bindings/interfaces.rst) | 2 | ||||
-rw-r--r-- | docs/hazmat/backends/openssl.rst (renamed from docs/hazmat/bindings/openssl.rst) | 2 | ||||
-rw-r--r-- | docs/hazmat/primitives/constant-time.rst | 38 | ||||
-rw-r--r-- | docs/hazmat/primitives/cryptographic-hashes.rst | 4 | ||||
-rw-r--r-- | docs/hazmat/primitives/hmac.rst | 4 | ||||
-rw-r--r-- | docs/hazmat/primitives/index.rst | 1 | ||||
-rw-r--r-- | docs/hazmat/primitives/symmetric-encryption.rst | 19 | ||||
-rw-r--r-- | docs/index.rst | 42 | ||||
-rw-r--r-- | tests/conftest.py | 2 | ||||
-rw-r--r-- | tests/hazmat/backends/__init__.py (renamed from tests/hazmat/bindings/__init__.py) | 0 | ||||
-rw-r--r-- | tests/hazmat/backends/test_openssl.py (renamed from tests/hazmat/bindings/test_openssl.py) | 4 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_constant_time.py | 41 | ||||
-rw-r--r-- | tox.ini | 1 |
44 files changed, 194 insertions, 39 deletions
diff --git a/cryptography/hazmat/bindings/__init__.py b/cryptography/hazmat/backends/__init__.py index bd158198..215aa4d3 100644 --- a/cryptography/hazmat/bindings/__init__.py +++ b/cryptography/hazmat/backends/__init__.py @@ -11,7 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from cryptography.hazmat.bindings import openssl +from cryptography.hazmat.backends import openssl _ALL_BACKENDS = [ diff --git a/cryptography/hazmat/bindings/interfaces.py b/cryptography/hazmat/backends/interfaces.py index 912476bb..912476bb 100644 --- a/cryptography/hazmat/bindings/interfaces.py +++ b/cryptography/hazmat/backends/interfaces.py diff --git a/cryptography/hazmat/bindings/openssl/__init__.py b/cryptography/hazmat/backends/openssl/__init__.py index 44267efd..a8dfad06 100644 --- a/cryptography/hazmat/bindings/openssl/__init__.py +++ b/cryptography/hazmat/backends/openssl/__init__.py @@ -11,7 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from cryptography.hazmat.bindings.openssl.backend import backend +from cryptography.hazmat.backends.openssl.backend import backend __all__ = ["backend"] diff --git a/cryptography/hazmat/bindings/openssl/asn1.py b/cryptography/hazmat/backends/openssl/asn1.py index 719a523c..719a523c 100644 --- a/cryptography/hazmat/bindings/openssl/asn1.py +++ b/cryptography/hazmat/backends/openssl/asn1.py diff --git a/cryptography/hazmat/bindings/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py index f19c8cca..bd092bec 100644 --- a/cryptography/hazmat/bindings/openssl/backend.py +++ b/cryptography/hazmat/backends/openssl/backend.py @@ -20,7 +20,7 @@ import cffi from cryptography import utils from cryptography.exceptions import UnsupportedAlgorithm, InvalidTag -from cryptography.hazmat.bindings.interfaces import ( +from cryptography.hazmat.backends.interfaces import ( CipherBackend, HashBackend, HMACBackend ) from cryptography.hazmat.primitives import interfaces @@ -102,7 +102,7 @@ class Backend(object): macros = [] customizations = [] for name in cls._modules: - module_name = "cryptography.hazmat.bindings.openssl." + name + module_name = "cryptography.hazmat.backends.openssl." + name __import__(module_name) module = sys.modules[module_name] diff --git a/cryptography/hazmat/bindings/openssl/bignum.py b/cryptography/hazmat/backends/openssl/bignum.py index 1b0fe5ab..1b0fe5ab 100644 --- a/cryptography/hazmat/bindings/openssl/bignum.py +++ b/cryptography/hazmat/backends/openssl/bignum.py diff --git a/cryptography/hazmat/bindings/openssl/bio.py b/cryptography/hazmat/backends/openssl/bio.py index c23dd0d8..c23dd0d8 100644 --- a/cryptography/hazmat/bindings/openssl/bio.py +++ b/cryptography/hazmat/backends/openssl/bio.py diff --git a/cryptography/hazmat/bindings/openssl/conf.py b/cryptography/hazmat/backends/openssl/conf.py index 4846252c..4846252c 100644 --- a/cryptography/hazmat/bindings/openssl/conf.py +++ b/cryptography/hazmat/backends/openssl/conf.py diff --git a/cryptography/hazmat/bindings/openssl/crypto.py b/cryptography/hazmat/backends/openssl/crypto.py index 773d9b14..773d9b14 100644 --- a/cryptography/hazmat/bindings/openssl/crypto.py +++ b/cryptography/hazmat/backends/openssl/crypto.py diff --git a/cryptography/hazmat/bindings/openssl/dh.py b/cryptography/hazmat/backends/openssl/dh.py index b8fbf368..b8fbf368 100644 --- a/cryptography/hazmat/bindings/openssl/dh.py +++ b/cryptography/hazmat/backends/openssl/dh.py diff --git a/cryptography/hazmat/bindings/openssl/dsa.py b/cryptography/hazmat/backends/openssl/dsa.py index e6c369a6..e6c369a6 100644 --- a/cryptography/hazmat/bindings/openssl/dsa.py +++ b/cryptography/hazmat/backends/openssl/dsa.py diff --git a/cryptography/hazmat/bindings/openssl/engine.py b/cryptography/hazmat/backends/openssl/engine.py index 1f377665..1f377665 100644 --- a/cryptography/hazmat/bindings/openssl/engine.py +++ b/cryptography/hazmat/backends/openssl/engine.py diff --git a/cryptography/hazmat/bindings/openssl/err.py b/cryptography/hazmat/backends/openssl/err.py index f31c2405..f31c2405 100644 --- a/cryptography/hazmat/bindings/openssl/err.py +++ b/cryptography/hazmat/backends/openssl/err.py diff --git a/cryptography/hazmat/bindings/openssl/evp.py b/cryptography/hazmat/backends/openssl/evp.py index 8cb44610..8cb44610 100644 --- a/cryptography/hazmat/bindings/openssl/evp.py +++ b/cryptography/hazmat/backends/openssl/evp.py diff --git a/cryptography/hazmat/bindings/openssl/hmac.py b/cryptography/hazmat/backends/openssl/hmac.py index 10e67141..10e67141 100644 --- a/cryptography/hazmat/bindings/openssl/hmac.py +++ b/cryptography/hazmat/backends/openssl/hmac.py diff --git a/cryptography/hazmat/bindings/openssl/nid.py b/cryptography/hazmat/backends/openssl/nid.py index 9816dde4..9816dde4 100644 --- a/cryptography/hazmat/bindings/openssl/nid.py +++ b/cryptography/hazmat/backends/openssl/nid.py diff --git a/cryptography/hazmat/bindings/openssl/opensslv.py b/cryptography/hazmat/backends/openssl/opensslv.py index d463776c..d463776c 100644 --- a/cryptography/hazmat/bindings/openssl/opensslv.py +++ b/cryptography/hazmat/backends/openssl/opensslv.py diff --git a/cryptography/hazmat/bindings/openssl/pem.py b/cryptography/hazmat/backends/openssl/pem.py index cef7839f..cef7839f 100644 --- a/cryptography/hazmat/bindings/openssl/pem.py +++ b/cryptography/hazmat/backends/openssl/pem.py diff --git a/cryptography/hazmat/bindings/openssl/pkcs12.py b/cryptography/hazmat/backends/openssl/pkcs12.py index d91d100f..d91d100f 100644 --- a/cryptography/hazmat/bindings/openssl/pkcs12.py +++ b/cryptography/hazmat/backends/openssl/pkcs12.py diff --git a/cryptography/hazmat/bindings/openssl/pkcs7.py b/cryptography/hazmat/backends/openssl/pkcs7.py index 60ea3c52..60ea3c52 100644 --- a/cryptography/hazmat/bindings/openssl/pkcs7.py +++ b/cryptography/hazmat/backends/openssl/pkcs7.py diff --git a/cryptography/hazmat/bindings/openssl/rand.py b/cryptography/hazmat/backends/openssl/rand.py index 848ee05a..848ee05a 100644 --- a/cryptography/hazmat/bindings/openssl/rand.py +++ b/cryptography/hazmat/backends/openssl/rand.py diff --git a/cryptography/hazmat/bindings/openssl/rsa.py b/cryptography/hazmat/backends/openssl/rsa.py index ad0d37b4..ad0d37b4 100644 --- a/cryptography/hazmat/bindings/openssl/rsa.py +++ b/cryptography/hazmat/backends/openssl/rsa.py diff --git a/cryptography/hazmat/bindings/openssl/ssl.py b/cryptography/hazmat/backends/openssl/ssl.py index 04611309..04611309 100644 --- a/cryptography/hazmat/bindings/openssl/ssl.py +++ b/cryptography/hazmat/backends/openssl/ssl.py diff --git a/cryptography/hazmat/bindings/openssl/x509.py b/cryptography/hazmat/backends/openssl/x509.py index b2ee672e..b2ee672e 100644 --- a/cryptography/hazmat/bindings/openssl/x509.py +++ b/cryptography/hazmat/backends/openssl/x509.py diff --git a/cryptography/hazmat/bindings/openssl/x509name.py b/cryptography/hazmat/backends/openssl/x509name.py index 896f0ae4..896f0ae4 100644 --- a/cryptography/hazmat/bindings/openssl/x509name.py +++ b/cryptography/hazmat/backends/openssl/x509name.py diff --git a/cryptography/hazmat/bindings/openssl/x509v3.py b/cryptography/hazmat/backends/openssl/x509v3.py index bc26236c..bc26236c 100644 --- a/cryptography/hazmat/bindings/openssl/x509v3.py +++ b/cryptography/hazmat/backends/openssl/x509v3.py diff --git a/cryptography/hazmat/primitives/constant_time.py b/cryptography/hazmat/primitives/constant_time.py new file mode 100644 index 00000000..a8351504 --- /dev/null +++ b/cryptography/hazmat/primitives/constant_time.py @@ -0,0 +1,53 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +import cffi + +import six + + +_ffi = cffi.FFI() +_ffi.cdef(""" +bool Cryptography_constant_time_bytes_eq(uint8_t *, size_t, uint8_t *, size_t); +""") +_lib = _ffi.verify(""" +#include <stdbool.h> + +bool Cryptography_constant_time_bytes_eq(uint8_t *a, size_t len_a, uint8_t *b, + size_t len_b) { + size_t i = 0; + uint8_t mismatch = 0; + if (len_a != len_b) { + return false; + } + for (i = 0; i < len_a; i++) { + mismatch |= a[i] ^ b[i]; + } + + /* Make sure any bits set are copied to the lowest bit */ + mismatch |= mismatch >> 4; + mismatch |= mismatch >> 2; + mismatch |= mismatch >> 1; + /* Now check the low bit to see if it's set */ + return (mismatch & 1) == 0; +} +""") + + +def bytes_eq(a, b): + if isinstance(a, six.text_type) or isinstance(b, six.text_type): + raise TypeError("Unicode-objects must be encoded before comparing") + + return _lib.Cryptography_constant_time_bytes_eq(a, len(a), b, len(b)) == 1 diff --git a/docs/architecture.rst b/docs/architecture.rst index 5ca2c252..bacde1bb 100644 --- a/docs/architecture.rst +++ b/docs/architecture.rst @@ -8,6 +8,6 @@ Architecture ``cryptography.hazmat.primitives``. * ``cryptography.hazmat.primitives``: This packages contains low level algorithms, things like ``AES`` or ``SHA1``. This is implemented on top of - ``cryptography.hazmat.bindings``. -* ``cryptography.hazmat.bindings``: This package contains bindings to low level - cryptographic libraries. Our initial target will be OpenSSL. + ``cryptography.hazmat.backends``. +* ``cryptography.hazmat.backends``: This package contains bindings to low level + cryptographic libraries. Our initial target is OpenSSL. diff --git a/docs/conf.py b/docs/conf.py index 77050e72..5092e4d3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -257,6 +257,5 @@ texinfo_documents = [ # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' - # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/docs/contributing.rst b/docs/contributing.rst index 100f13f5..cb9c7283 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -28,6 +28,7 @@ devastating, ``cryptography`` has a strict code review policy: * If somehow the tests get into a failing state on ``master`` (such as by a backwards incompatible release of a dependency) no pull requests may be merged until this is rectified. +* All merged patches must have 100% test coverage. The purpose of these policies is to minimize the chances we merge a change which jeopardizes our users' security. @@ -78,7 +79,7 @@ whether the signature was valid. APIs at the :doc:`/hazmat/primitives/index` layer should always take an explicit backend, APIs at the recipes layer should automatically use the -:func:`~cryptography.hazmat.bindings.default_backend`, but optionally allow +:func:`~cryptography.hazmat.backends.default_backend`, but optionally allow specifying a different backend. C bindings diff --git a/docs/hazmat/bindings/index.rst b/docs/hazmat/backends/index.rst index 746f4596..a89cf0d5 100644 --- a/docs/hazmat/bindings/index.rst +++ b/docs/hazmat/backends/index.rst @@ -13,7 +13,7 @@ Bindings Getting a Backend Provider ~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. currentmodule:: cryptography.hazmat.bindings +.. currentmodule:: cryptography.hazmat.backends ``cryptography`` aims to support multiple backends to ensure it can provide the widest number of supported cryptographic algorithms as well as supporting diff --git a/docs/hazmat/bindings/interfaces.rst b/docs/hazmat/backends/interfaces.rst index 711c82c2..b524943d 100644 --- a/docs/hazmat/bindings/interfaces.rst +++ b/docs/hazmat/backends/interfaces.rst @@ -3,7 +3,7 @@ Backend Interfaces ================== -.. currentmodule:: cryptography.hazmat.bindings.interfaces +.. currentmodule:: cryptography.hazmat.backends.interfaces Backend implementations may provide a number of interfaces to support operations diff --git a/docs/hazmat/bindings/openssl.rst b/docs/hazmat/backends/openssl.rst index d6bfa672..12fbff04 100644 --- a/docs/hazmat/bindings/openssl.rst +++ b/docs/hazmat/backends/openssl.rst @@ -5,7 +5,7 @@ OpenSSL These are `CFFI`_ bindings to the `OpenSSL`_ C library. -.. data:: cryptography.hazmat.bindings.openssl.backend +.. data:: cryptography.hazmat.backends.openssl.backend This is the exposed API for the OpenSSL bindings. It has two public attributes: diff --git a/docs/hazmat/primitives/constant-time.rst b/docs/hazmat/primitives/constant-time.rst new file mode 100644 index 00000000..632e7c68 --- /dev/null +++ b/docs/hazmat/primitives/constant-time.rst @@ -0,0 +1,38 @@ +.. hazmat:: + +Constant time functions +======================= + +.. currentmodule:: cryptography.hazmat.primitives.constant_time + +This module contains functions for operating with secret data in a way that +does not leak information about that data through how long it takes to perform +the operation. These functions should be used whenever operating on secret data +along with data that is user supplied. + +An example would be comparing a HMAC signature received from a client to the +one generated by the server code for authentication purposes. + +For more information about this sort of issue, see `Coda Hale's blog post`_ +about the timing attacks on KeyCzar and Java's ``MessageDigest.isEqual()``. + + +.. function:: bytes_eq(a, b) + + Compare ``a`` and ``b`` to one another in constant time if they are of the + same length. + + .. doctest:: + + >>> from cryptography.hazmat.primitives import constant_time + >>> constant_time.bytes_eq(b"foo", b"foo") + True + >>> constant_time.bytes_eq(b"foo", b"bar") + False + + :param a bytes: The left-hand side. + :param b bytes: The right-hand side. + :returns boolean: True if ``a`` has the same bytes as ``b``. + + +.. _`Coda Hale's blog post`: http://codahale.com/a-lesson-in-timing-attacks/ diff --git a/docs/hazmat/primitives/cryptographic-hashes.rst b/docs/hazmat/primitives/cryptographic-hashes.rst index 312d7e69..90ca198a 100644 --- a/docs/hazmat/primitives/cryptographic-hashes.rst +++ b/docs/hazmat/primitives/cryptographic-hashes.rst @@ -20,7 +20,7 @@ Message Digests .. doctest:: - >>> from cryptography.hazmat.bindings import default_backend + >>> from cryptography.hazmat.backends import default_backend >>> from cryptography.hazmat.primitives import hashes >>> digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) >>> digest.update(b"abc") @@ -39,7 +39,7 @@ Message Digests provider such as those described in :ref:`below <cryptographic-hash-algorithms>`. :param backend: A - :class:`~cryptography.hazmat.bindings.interfaces.HashBackend` + :class:`~cryptography.hazmat.backends.interfaces.HashBackend` provider. .. method:: update(data) diff --git a/docs/hazmat/primitives/hmac.rst b/docs/hazmat/primitives/hmac.rst index db5e98d3..0c0d0220 100644 --- a/docs/hazmat/primitives/hmac.rst +++ b/docs/hazmat/primitives/hmac.rst @@ -27,7 +27,7 @@ message. .. doctest:: - >>> from cryptography.hazmat.bindings import default_backend + >>> from cryptography.hazmat.backends import default_backend >>> from cryptography.hazmat.primitives import hashes, hmac >>> h = hmac.HMAC(key, hashes.SHA256(), backend=default_backend()) >>> h.update(b"message to hash") @@ -41,7 +41,7 @@ message. provider such as those described in :ref:`Cryptographic Hashes <cryptographic-hash-algorithms>`. :param backend: A - :class:`~cryptography.hazmat.bindings.interfaces.HMACBackend` + :class:`~cryptography.hazmat.backends.interfaces.HMACBackend` provider. .. method:: update(msg) diff --git a/docs/hazmat/primitives/index.rst b/docs/hazmat/primitives/index.rst index 614c414a..b115fdbc 100644 --- a/docs/hazmat/primitives/index.rst +++ b/docs/hazmat/primitives/index.rst @@ -10,4 +10,5 @@ Primitives hmac symmetric-encryption padding + constant-time interfaces diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index 2f390175..f4d0457a 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -12,9 +12,6 @@ Symmetric Encryption key = binascii.unhexlify(b"0" * 32) iv = binascii.unhexlify(b"0" * 32) - from cryptography.hazmat.bindings import default_backend - backend = default_backend() - Symmetric encryption is a way to encrypt (hide the plaintext value) material where the sender and receiver both use the same key. Note that symmetric @@ -37,6 +34,8 @@ an "encrypt-then-MAC" formulation as `described by Colin Percival`_. .. doctest:: >>> from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes + >>> from cryptography.hazmat.backends import default_backend + >>> backend = default_backend() >>> cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) >>> encryptor = cipher.encryptor() >>> ct = encryptor.update(b"a secret message") + encryptor.finalize() @@ -52,7 +51,7 @@ an "encrypt-then-MAC" formulation as `described by Colin Percival`_. provider such as those described :ref:`below <symmetric-encryption-modes>`. :param backend: A - :class:`~cryptography.hazmat.bindings.interfaces.CipherBackend` + :class:`~cryptography.hazmat.backends.interfaces.CipherBackend` provider. .. method:: encryptor() @@ -230,8 +229,9 @@ Weak Ciphers .. doctest:: >>> from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes + >>> from cryptography.hazmat.backends import default_backend >>> algorithm = algorithms.ARC4(key) - >>> cipher = Cipher(algorithm, mode=None, backend=backend) + >>> cipher = Cipher(algorithm, mode=None, backend=default_backend()) >>> encryptor = cipher.encryptor() >>> ct = encryptor.update(b"a secret message") >>> decryptor = cipher.decryptor() @@ -266,16 +266,18 @@ Modes A good construction looks like: - .. code-block:: pycon + .. doctest:: >>> import os + >>> from cryptography.hazmat.primitives.ciphers.modes import CBC >>> iv = os.urandom(16) >>> mode = CBC(iv) While the following is bad and will leak information: - .. code-block:: pycon + .. doctest:: + >>> from cryptography.hazmat.primitives.ciphers.modes import CBC >>> iv = "a" * 16 >>> mode = CBC(iv) @@ -356,7 +358,8 @@ Modes .. doctest:: >>> from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes - >>> cipher = Cipher(algorithms.AES(key), modes.GCM(iv), backend) + >>> from cryptography.hazmat.backends import default_backend + >>> cipher = Cipher(algorithms.AES(key), modes.GCM(iv), backend=default_backend()) >>> encryptor = cipher.encryptor() >>> encryptor.authenticate_additional_data(b"authenticated but not encrypted payload") >>> ct = encryptor.update(b"a secret message") + encryptor.finalize() diff --git a/docs/index.rst b/docs/index.rst index a1a650a8..381063df 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,10 +1,6 @@ Welcome to ``cryptography`` =========================== -.. warning:: - - ``cryptography`` is very young, and very incomplete. - ``cryptography`` is a Python library which exposes cryptographic recipes and primitives. We hope it'll be your one-stop-shop for all your cryptographic needs in Python. @@ -36,9 +32,24 @@ existing libraries: * Poor introspectability, and thus poor testability. * Extremely error prone APIs, and bad defaults. +Layout +------ + +``cryptography`` is broadly divided into two levels. One with safe +cryptographic recipes, "cryptography for humans" if you will. These are safe +and easy to use and don't require developers to make many decisions. + +The other level is low-level cryptographic primitives. These are often +dangerous and can be used incorrectly. They require making decisions and having +an in-depth knowledge of the cryptographic concepts at work. Because of the +potential danger in working at this level, this is referred to as the +"hazardous materials" or "hazmat" layer. -Contents --------- +We recommend using the recipes layer whenever possible, and falling back to the +hazmat layer only when necessary. + +The recipes layer +~~~~~~~~~~~~~~~~~ .. toctree:: :maxdepth: 2 @@ -46,15 +57,22 @@ Contents architecture exceptions glossary - contributing - security - community -Hazardous Materials -------------------- +The hazardous materials layer +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. toctree:: :maxdepth: 2 hazmat/primitives/index - hazmat/bindings/index + hazmat/backends/index + +The ``cryptography`` open source project +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 2 + + contributing + security + community diff --git a/tests/conftest.py b/tests/conftest.py index fab40b14..71662802 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,5 @@ def pytest_generate_tests(metafunc): - from cryptography.hazmat.bindings import _ALL_BACKENDS + from cryptography.hazmat.backends import _ALL_BACKENDS if "backend" in metafunc.fixturenames: metafunc.parametrize("backend", _ALL_BACKENDS) diff --git a/tests/hazmat/bindings/__init__.py b/tests/hazmat/backends/__init__.py index e69de29b..e69de29b 100644 --- a/tests/hazmat/bindings/__init__.py +++ b/tests/hazmat/backends/__init__.py diff --git a/tests/hazmat/bindings/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 1eb6f200..962959b9 100644 --- a/tests/hazmat/bindings/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -15,8 +15,8 @@ import pytest from cryptography import utils from cryptography.exceptions import UnsupportedAlgorithm -from cryptography.hazmat.bindings import default_backend -from cryptography.hazmat.bindings.openssl.backend import backend, Backend +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.backends.openssl.backend import backend, Backend from cryptography.hazmat.primitives import interfaces from cryptography.hazmat.primitives.ciphers import Cipher from cryptography.hazmat.primitives.ciphers.algorithms import AES diff --git a/tests/hazmat/primitives/test_constant_time.py b/tests/hazmat/primitives/test_constant_time.py new file mode 100644 index 00000000..dd910dee --- /dev/null +++ b/tests/hazmat/primitives/test_constant_time.py @@ -0,0 +1,41 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +import pytest + +import six + +from cryptography.hazmat.primitives import constant_time + + +class TestConstantTimeBytesEq(object): + def test_reject_unicode(self): + with pytest.raises(TypeError): + constant_time.bytes_eq(b"foo", six.u("foo")) + + with pytest.raises(TypeError): + constant_time.bytes_eq(six.u("foo"), b"foo") + + with pytest.raises(TypeError): + constant_time.bytes_eq(six.u("foo"), six.u("foo")) + + def test_compares(self): + assert constant_time.bytes_eq(b"foo", b"foo") is True + + assert constant_time.bytes_eq(b"foo", b"bar") is False + + assert constant_time.bytes_eq(b"foobar", b"foo") is False + + assert constant_time.bytes_eq(b"foo", b"foobar") is False @@ -17,6 +17,7 @@ deps = basepython = python2.7 commands = sphinx-build -W -b html -d {envtmpdir}/doctrees docs docs/_build/html + sphinx-build -W -b latex -d {envtmpdir}/doctrees docs docs/_build/latex sphinx-build -W -b doctest -d {envtmpdir}/doctrees docs docs/_build/html sphinx-build -W -b linkcheck docs docs/_build/html |