Skip to content

Commit 4815737

Browse files
committed
refactor: change verify_interface to isinstance
1 parent edeec7c commit 4815737

File tree

7 files changed

+71
-65
lines changed

7 files changed

+71
-65
lines changed

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
boto3>=1.10.0
2-
cryptography>=2.5.0
2+
cryptography>=2.5.0,<3.3.2
33
attrs>=17.4.0
44
wrapt>=1.10.11

src/aws_encryption_sdk/internal/crypto/authentication.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
from cryptography.hazmat.primitives import hashes, serialization
1919
from cryptography.hazmat.primitives.asymmetric import ec
2020
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed
21-
from cryptography.utils import InterfaceNotImplemented, verify_interface
2221

2322
from ...exceptions import NotSupportedError
2423
from .elliptic_curve import (
@@ -47,11 +46,10 @@ def __init__(self, algorithm, key):
4746

4847
def _set_signature_type(self):
4948
"""Ensures that the algorithm signature type is a known type and sets a reference value."""
50-
try:
51-
verify_interface(ec.EllipticCurve, self.algorithm.signing_algorithm_info)
52-
return ec.EllipticCurve
53-
except InterfaceNotImplemented:
54-
raise NotSupportedError("Unsupported signing algorithm info")
49+
for method in ec.EllipticCurve.__abstractmethods__:
50+
if not hasattr(self.algorithm.signing_algorithm_info(), method):
51+
raise NotSupportedError("Unsupported signing algorithm info")
52+
return ec.EllipticCurve
5553

5654
def _build_hasher(self):
5755
"""Builds the hasher instance which will calculate the digest of all passed data.

src/aws_encryption_sdk/internal/crypto/elliptic_curve.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from cryptography.hazmat.backends import default_backend
1919
from cryptography.hazmat.primitives.asymmetric import ec
2020
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed, decode_dss_signature, encode_dss_signature
21-
from cryptography.utils import InterfaceNotImplemented, int_from_bytes, int_to_bytes, verify_interface
21+
from cryptography.utils import int_from_bytes, int_to_bytes
2222

2323
from ...exceptions import NotSupportedError
2424
from ..str_ops import to_bytes
@@ -183,8 +183,7 @@ def generate_ecc_signing_key(algorithm):
183183
:returns: Generated signing key
184184
:raises NotSupportedError: if signing algorithm is not supported on this platform
185185
"""
186-
try:
187-
verify_interface(ec.EllipticCurve, algorithm.signing_algorithm_info)
188-
return ec.generate_private_key(curve=algorithm.signing_algorithm_info(), backend=default_backend())
189-
except InterfaceNotImplemented:
190-
raise NotSupportedError("Unsupported signing algorithm info")
186+
for method in ec.EllipticCurve.__abstractmethods__:
187+
if not hasattr(algorithm.signing_algorithm_info(), method):
188+
raise NotSupportedError("Unsupported signing algorithm info")
189+
return ec.generate_private_key(curve=algorithm.signing_algorithm_info(), backend=default_backend())

test/unit/test_crypto_authentication_signer.py

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
1-
# Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2-
#
3-
# Licensed under the Apache License, Version 2.0 (the "License"). You
4-
# may not use this file except in compliance with the License. A copy of
5-
# the License is located at
6-
#
7-
# http://aws.amazon.com/apache2.0/
8-
#
9-
# or in the "license" file accompanying this file. This file is
10-
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11-
# ANY KIND, either express or implied. See the License for the specific
12-
# language governing permissions and limitations under the License.
131
"""Unit test suite for ``aws_encryption_sdk.internal.crypto.authentication.Signer``."""
142
import pytest
15-
from mock import MagicMock, sentinel
3+
from mock import MagicMock, sentinel, patch
164
from pytest_mock import mocker # noqa pylint: disable=unused-import
175

186
import aws_encryption_sdk.internal.crypto.authentication
@@ -31,6 +19,12 @@ def patch_default_backend(mocker):
3119

3220

3321
@pytest.yield_fixture
22+
def patch_ec(mocker):
23+
mocker.patch.object(aws_encryption_sdk.internal.crypto.authentication, "ec")
24+
yield aws_encryption_sdk.internal.crypto.authentication.ec
25+
26+
27+
@pytest.fixture
3428
def patch_serialization(mocker):
3529
mocker.patch.object(aws_encryption_sdk.internal.crypto.authentication, "serialization")
3630
yield aws_encryption_sdk.internal.crypto.authentication.serialization
@@ -71,8 +65,11 @@ def test_f_signer_key_bytes():
7165
assert test.key_bytes() == VALUES["ecc_private_key_prime_private_bytes"]
7266

7367

74-
def test_signer_from_key_bytes(patch_default_backend, patch_serialization, patch_build_hasher):
75-
_algorithm = MagicMock()
68+
def test_signer_from_key_bytes(patch_default_backend, patch_serialization, patch_build_hasher, patch_ec):
69+
patch_ec.EllipticCurve.__abstractmethods__ = set()
70+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve)
71+
_algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
72+
7673
signer = Signer.from_key_bytes(algorithm=_algorithm, key_bytes=sentinel.key_bytes)
7774

7875
patch_serialization.load_der_private_key.assert_called_once_with(
@@ -83,9 +80,12 @@ def test_signer_from_key_bytes(patch_default_backend, patch_serialization, patch
8380
assert signer.key is patch_serialization.load_der_private_key.return_value
8481

8582

86-
def test_signer_key_bytes(patch_default_backend, patch_serialization, patch_build_hasher):
83+
def test_signer_key_bytes(patch_default_backend, patch_serialization, patch_build_hasher, patch_ec):
84+
patch_ec.EllipticCurve.__abstractmethods__ = set()
85+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve)
86+
algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
8787
private_key = MagicMock()
88-
signer = Signer(MagicMock(), key=private_key)
88+
signer = Signer(algorithm, key=private_key)
8989

9090
test = signer.key_bytes()
9191

@@ -98,30 +98,45 @@ def test_signer_key_bytes(patch_default_backend, patch_serialization, patch_buil
9898

9999

100100
def test_signer_encoded_public_key(
101-
patch_default_backend, patch_serialization, patch_build_hasher, patch_ecc_encode_compressed_point, patch_base64
101+
patch_default_backend,
102+
patch_serialization,
103+
patch_build_hasher,
104+
patch_ecc_encode_compressed_point,
105+
patch_base64,
106+
patch_ec
102107
):
103108
patch_ecc_encode_compressed_point.return_value = sentinel.compressed_point
104109
patch_base64.b64encode.return_value = sentinel.encoded_point
105110
private_key = MagicMock()
106111

107-
signer = Signer(MagicMock(), key=private_key)
112+
patch_ec.EllipticCurve.__abstractmethods__ = set()
113+
114+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve)
115+
algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
116+
117+
signer = Signer(algorithm, key=private_key)
108118
test_key = signer.encoded_public_key()
109119

110120
patch_ecc_encode_compressed_point.assert_called_once_with(private_key)
111121
patch_base64.b64encode.assert_called_once_with(sentinel.compressed_point)
112122
assert test_key == sentinel.encoded_point
113123

114124

115-
def test_signer_update(patch_default_backend, patch_serialization, patch_build_hasher):
116-
signer = Signer(MagicMock(), key=MagicMock())
125+
def test_signer_update(patch_default_backend, patch_serialization, patch_build_hasher, patch_ec):
126+
patch_ec.EllipticCurve.__abstractmethods__ = set()
127+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve)
128+
algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
129+
signer = Signer(algorithm, key=MagicMock())
117130
signer.update(sentinel.data)
118131
patch_build_hasher.return_value.update.assert_called_once_with(sentinel.data)
119132

120133

121134
def test_signer_finalize(
122-
patch_default_backend, patch_serialization, patch_build_hasher, patch_ecc_static_length_signature
135+
patch_default_backend, patch_serialization, patch_build_hasher, patch_ecc_static_length_signature, patch_ec
123136
):
124-
algorithm = MagicMock()
137+
patch_ec.EllipticCurve.__abstractmethods__ = set()
138+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve)
139+
algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
125140
private_key = MagicMock()
126141

127142
signer = Signer(algorithm, key=private_key)

test/unit/test_crypto_authentication_verifier.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import aws_encryption_sdk.internal.crypto.authentication
1919
from aws_encryption_sdk.internal.crypto.authentication import Verifier
2020
from aws_encryption_sdk.internal.defaults import ALGORITHM
21+
from cryptography.hazmat.primitives.asymmetric import ec
2122

2223
from .test_crypto import VALUES
2324

@@ -89,12 +90,16 @@ def test_verifier_from_encoded_point(
8990
patch_ecc_public_numbers_from_compressed_point,
9091
patch_base64,
9192
patch_build_hasher,
93+
patch_ec
9294
):
9395
mock_point_instance = MagicMock()
9496
mock_point_instance.public_key.return_value = sentinel.public_key
9597
patch_ecc_public_numbers_from_compressed_point.return_value = mock_point_instance
9698
patch_base64.b64decode.return_value = sentinel.compressed_point
97-
algorithm = MagicMock()
99+
100+
patch_ec.EllipticCurve.__abstractmethods__ = set()
101+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve)
102+
algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
98103

99104
verifier = Verifier.from_encoded_point(algorithm=algorithm, encoded_point=sentinel.encoded_point)
100105

test/unit/test_crypto_elliptic_curve.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
import pytest
1717
from cryptography.hazmat.primitives.asymmetric import ec
18-
from cryptography.utils import InterfaceNotImplemented
1918
from mock import MagicMock, sentinel
2019
from pytest_mock import mocker # noqa pylint: disable=unused-import
2120

@@ -72,12 +71,6 @@ def patch_ecc_decode_compressed_point(mocker):
7271
yield aws_encryption_sdk.internal.crypto.elliptic_curve._ecc_decode_compressed_point
7372

7473

75-
@pytest.yield_fixture
76-
def patch_verify_interface(mocker):
77-
mocker.patch.object(aws_encryption_sdk.internal.crypto.elliptic_curve, "verify_interface")
78-
yield aws_encryption_sdk.internal.crypto.elliptic_curve.verify_interface
79-
80-
8174
@pytest.yield_fixture
8275
def patch_ecc_curve_parameters(mocker):
8376
mocker.patch.object(aws_encryption_sdk.internal.crypto.elliptic_curve, "_ECC_CURVE_PARAMETERS")
@@ -374,23 +367,24 @@ def test_ecc_public_numbers_from_compressed_point(patch_ec, patch_ecc_decode_com
374367
assert test == sentinel.public_numbers_instance
375368

376369

377-
def test_generate_ecc_signing_key_supported(patch_default_backend, patch_ec, patch_verify_interface):
370+
def test_generate_ecc_signing_key_supported(patch_default_backend, patch_ec):
378371
patch_ec.generate_private_key.return_value = sentinel.raw_signing_key
379-
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info)
372+
patch_ec.EllipticCurve.__abstractmethods__ = set()
373+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve)
380374
mock_algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
381375

382376
test_signing_key = generate_ecc_signing_key(algorithm=mock_algorithm)
383377

384-
patch_verify_interface.assert_called_once_with(patch_ec.EllipticCurve, mock_algorithm_info)
385378
patch_ec.generate_private_key.assert_called_once_with(
386379
curve=sentinel.algorithm_info, backend=patch_default_backend.return_value
387380
)
388381
assert test_signing_key is sentinel.raw_signing_key
389382

390383

391-
def test_generate_ecc_signing_key_unsupported(patch_default_backend, patch_ec, patch_verify_interface):
392-
patch_verify_interface.side_effect = InterfaceNotImplemented
393-
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info)
384+
def test_generate_ecc_signing_key_unsupported(patch_default_backend, patch_ec):
385+
patch_ec.generate_private_key.return_value = sentinel.raw_signing_key
386+
patch_ec.EllipticCurve.__abstractmethods__ = set("notName")
387+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_ec.EllipticCurve)
394388
mock_algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
395389

396390
with pytest.raises(NotSupportedError) as excinfo:

test/unit/test_crypto_prehashing_authenticator.py

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
# language governing permissions and limitations under the License.
1313
"""Unit test suite for ``aws_encryption_sdk.internal.crypto._PrehashingAuthenticater``."""
1414
import pytest
15-
from cryptography.utils import InterfaceNotImplemented
1615
from mock import MagicMock, sentinel
1716
from pytest_mock import mocker # noqa pylint: disable=unused-import
1817

@@ -35,12 +34,6 @@ def patch_build_hasher(mocker):
3534
yield _PrehashingAuthenticator._build_hasher
3635

3736

38-
@pytest.yield_fixture
39-
def patch_cryptography_utils_verify_interface(mocker):
40-
mocker.patch.object(aws_encryption_sdk.internal.crypto.authentication, "verify_interface")
41-
yield aws_encryption_sdk.internal.crypto.authentication.verify_interface
42-
43-
4437
@pytest.yield_fixture
4538
def patch_cryptography_ec(mocker):
4639
mocker.patch.object(aws_encryption_sdk.internal.crypto.authentication, "ec")
@@ -71,23 +64,25 @@ def test_init(patch_set_signature_type, patch_build_hasher):
7164

7265

7366
def test_set_signature_type_elliptic_curve(
74-
patch_build_hasher, patch_cryptography_utils_verify_interface, patch_cryptography_ec
67+
patch_build_hasher, patch_cryptography_ec
7568
):
76-
mock_algorithm = MagicMock()
69+
patch_cryptography_ec.generate_private_key.return_value = sentinel.raw_signing_key
70+
patch_cryptography_ec.EllipticCurve.__abstractmethods__ = set()
71+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_cryptography_ec.EllipticCurve)
72+
mock_algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
7773
test = _PrehashingAuthenticator(algorithm=mock_algorithm, key=sentinel.key)
7874

79-
patch_cryptography_utils_verify_interface.assert_called_once_with(
80-
patch_cryptography_ec.EllipticCurve, mock_algorithm.signing_algorithm_info
81-
)
8275
assert test._signature_type is patch_cryptography_ec.EllipticCurve
8376

8477

8578
def test_set_signature_type_unknown(
86-
patch_build_hasher, patch_cryptography_utils_verify_interface, patch_cryptography_ec
79+
patch_build_hasher, patch_cryptography_ec
8780
):
88-
patch_cryptography_utils_verify_interface.side_effect = InterfaceNotImplemented
81+
patch_cryptography_ec.EllipticCurve.__abstractmethods__ = set("invalidSetup")
82+
mock_algorithm_info = MagicMock(return_value=sentinel.algorithm_info, spec=patch_cryptography_ec.EllipticCurve)
83+
mock_algorithm = MagicMock(signing_algorithm_info=mock_algorithm_info)
8984
with pytest.raises(NotSupportedError) as excinfo:
90-
_PrehashingAuthenticator(algorithm=MagicMock(), key=sentinel.key)
85+
_PrehashingAuthenticator(algorithm=mock_algorithm, key=sentinel.key)
9186

9287
excinfo.match(r"Unsupported signing algorithm info")
9388

0 commit comments

Comments
 (0)