From edd60e3a17a3dbc9d85f6f4f5fe1ef48f095bd75 Mon Sep 17 00:00:00 2001 From: Brianna Poulos Date: Thu, 22 Feb 2018 16:32:18 -0500 Subject: [PATCH] Address verifier DeprecationWarning The use of signer and verifier in cryptography has been deprecated, and causes the following warning: cursive/cursive/signature_utils.py:139: DeprecationWarning: signer and verifier have been deprecated. Please use sign and verify instead. This patch adds a wrapper around the use of verifier, so that sign and verify are used with cryptography, but the client use of the library doesn't have to change. Change-Id: Ib4aaa4fc9eb893b74f08bc8ff732a4dae152f685 --- cursive/signature_utils.py | 33 ++++++++-- cursive/tests/unit/test_signature_utils.py | 8 +-- cursive/verifiers.py | 77 ++++++++++++++++++++++ 3 files changed, 104 insertions(+), 14 deletions(-) create mode 100644 cursive/verifiers.py diff --git a/cursive/signature_utils.py b/cursive/signature_utils.py index 6d939f2..af27cbe 100644 --- a/cursive/signature_utils.py +++ b/cursive/signature_utils.py @@ -30,6 +30,7 @@ from oslo_utils import encodeutils from cursive import exception from cursive.i18n import _, _LE +from cursive import verifiers LOG = logging.getLogger(__name__) @@ -126,6 +127,10 @@ def create_verifier_for_pss(signature, hash_method, public_key): are invalid :returns: the verifier to use to verify the signature for RSA-PSS """ + # confirm none of the inputs are None + if not signature or not hash_method or not public_key: + return None + # default to MGF1 mgf = padding.MGF1(hash_method) @@ -133,10 +138,14 @@ def create_verifier_for_pss(signature, hash_method, public_key): salt_length = padding.PSS.MAX_LENGTH # return the verifier - return public_key.verifier( + return verifiers.RSAVerifier( signature, - padding.PSS(mgf=mgf, salt_length=salt_length), - hash_method + hash_method, + public_key, + padding.PSS( + mgf=mgf, + salt_length=salt_length + ) ) @@ -148,10 +157,15 @@ def create_verifier_for_ecc(signature, hash_method, public_key): :param public_key: the public key to use, as a cryptography object :returns: the verifier to use to verify the signature for ECC_*. """ + # confirm none of the inputs are None + if not signature or not hash_method or not public_key: + return None + # return the verifier - return public_key.verifier( + return verifiers.ECCVerifier( signature, - ec.ECDSA(hash_method) + hash_method, + public_key, ) @@ -163,10 +177,15 @@ def create_verifier_for_dsa(signature, hash_method, public_key): :param public_key: the public key to use, as a cryptography object :returns: the verifier to use to verify the signature for DSA """ + # confirm none of the inputs are None + if not signature or not hash_method or not public_key: + return None + # return the verifier - return public_key.verifier( + return verifiers.DSAVerifier( signature, - hash_method + hash_method, + public_key, ) diff --git a/cursive/tests/unit/test_signature_utils.py b/cursive/tests/unit/test_signature_utils.py index ee51377..e4e0877 100644 --- a/cursive/tests/unit/test_signature_utils.py +++ b/cursive/tests/unit/test_signature_utils.py @@ -106,12 +106,6 @@ class FakeCryptoCertificate(object): return self.cert_not_valid_after -class BadPublicKey(object): - - def verifier(self, signature, padding, hash_method): - return None - - class TestSignatureUtils(base.TestCase): """Test methods of signature_utils""" @@ -248,7 +242,7 @@ class TestSignatureUtils(base.TestCase): @mock.patch('cursive.signature_utils.get_public_key') def test_get_verifier_none(self, mock_get_pub_key): - mock_get_pub_key.return_value = BadPublicKey() + mock_get_pub_key.return_value = None img_sig_cert_uuid = 'fea14bc2-d75f-4ba5-bccc-b5c924ad0693' self.assertRaisesRegex(exception.SignatureVerificationError, 'Error occurred while creating' diff --git a/cursive/verifiers.py b/cursive/verifiers.py new file mode 100644 index 0000000..23e59cd --- /dev/null +++ b/cursive/verifiers.py @@ -0,0 +1,77 @@ +# 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. + +"""Wrap cryptography verify with verifier.""" + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives.asymmetric import ec +from cryptography.hazmat.primitives.asymmetric import utils +from cryptography.hazmat.primitives import hashes + + +class RSAVerifier(object): + def __init__(self, signature, hash_method, public_key, padding): + self._signature = signature + self._hash_method = hash_method + self._public_key = public_key + self._padding = padding + self._hasher = hashes.Hash(hash_method, default_backend()) + + def update(self, data): + self._hasher.update(data) + + def verify(self): + digest = self._hasher.finalize() + self._public_key.verify( + self._signature, + digest, + self._padding, + utils.Prehashed(self._hash_method) + ) + + +class ECCVerifier(object): + def __init__(self, signature, hash_method, public_key): + self._signature = signature + self._hash_method = hash_method + self._public_key = public_key + self._hasher = hashes.Hash(hash_method, default_backend()) + + def update(self, data): + self._hasher.update(data) + + def verify(self): + digest = self._hasher.finalize() + self._public_key.verify( + self._signature, + digest, + ec.ECDSA(utils.Prehashed(self._hash_method)) + ) + + +class DSAVerifier(object): + def __init__(self, signature, hash_method, public_key): + self._signature = signature + self._hash_method = hash_method + self._public_key = public_key + self._hasher = hashes.Hash(hash_method, default_backend()) + + def update(self, data): + self._hasher.update(data) + + def verify(self): + digest = self._hasher.finalize() + self._public_key.verify( + self._signature, + digest, + utils.Prehashed(self._hash_method) + )