diff options
-rw-r--r-- | cryptography/hazmat/backends/__init__.py | 7 | ||||
-rw-r--r-- | cryptography/hazmat/backends/multibackend.py | 45 | ||||
-rw-r--r-- | tests/conftest.py | 5 |
3 files changed, 53 insertions, 4 deletions
diff --git a/cryptography/hazmat/backends/__init__.py b/cryptography/hazmat/backends/__init__.py index cb1fee90..b4ef210d 100644 --- a/cryptography/hazmat/backends/__init__.py +++ b/cryptography/hazmat/backends/__init__.py @@ -12,16 +12,17 @@ # limitations under the License. from cryptography.hazmat.backends import openssl +from cryptography.hazmat.backends.multibackend import PrioritizedMultiBackend from cryptography.hazmat.bindings.commoncrypto.binding import ( - Binding as CCBinding + Binding as CommonCryptoBinding ) _ALL_BACKENDS = [openssl.backend] -if CCBinding.is_available(): +if CommonCryptoBinding.is_available(): from cryptography.hazmat.backends import commoncrypto _ALL_BACKENDS.append(commoncrypto.backend) def default_backend(): - return openssl.backend + return PrioritizedMultiBackend(_ALL_BACKENDS) diff --git a/cryptography/hazmat/backends/multibackend.py b/cryptography/hazmat/backends/multibackend.py new file mode 100644 index 00000000..9b91ff45 --- /dev/null +++ b/cryptography/hazmat/backends/multibackend.py @@ -0,0 +1,45 @@ +# 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 + +from cryptography import utils +from cryptography.exceptions import UnsupportedAlgorithm +from cryptography.hazmat.backends.interfaces import CipherBackend + + +@utils.register_interface(CipherBackend) +class PrioritizedMultiBackend(object): + name = "multibackend" + + def __init__(self, backends): + self._backends = backends + + def cipher_supported(self, algorithm, mode): + return any(b.cipher_supported(algorithm, mode) for b in self._backends) + + def create_symmetric_encryption_ctx(self, algorithm, mode): + for b in self._backends: + try: + return b.create_symmetric_encryption_ctx(algorithm, mode) + except UnsupportedAlgorithm: + pass + raise UnsupportedAlgorithm + + def create_symmetric_decryption_ctx(self, algorithm, mode): + for b in self._backends: + try: + return b.create_symmetric_decryption_ctx(algorithm, mode) + except UnsupportedAlgorithm: + pass + raise UnsupportedAlgorithm diff --git a/tests/conftest.py b/tests/conftest.py index ecad1b23..00c44ca9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,13 +4,16 @@ from cryptography.hazmat.backends import _ALL_BACKENDS from cryptography.hazmat.backends.interfaces import ( HMACBackend, CipherBackend, HashBackend, PBKDF2HMACBackend ) +from cryptography.hazmat.backends.multibackend import PrioritizedMultiBackend from .utils import check_for_iface, check_backend_support, select_backends def pytest_generate_tests(metafunc): names = metafunc.config.getoption("--backend") - selected_backends = select_backends(names, _ALL_BACKENDS) + selected_backends = select_backends( + names, _ALL_BACKENDS + [PrioritizedMultiBackend(_ALL_BACKENDS)] + ) if "backend" in metafunc.fixturenames: metafunc.parametrize("backend", selected_backends) |