Skip to content

Commit d46c79d

Browse files
authored
Merge pull request #81 from mattsb42-aws/dev-78
add minimum key size checks and warnings
2 parents 80465a4 + eabde32 commit d46c79d

20 files changed

+166
-96
lines changed

.travis.yml

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,45 @@ matrix:
44
include:
55
# CPython 2.7
66
- python: 2.7
7-
env: TOXENV=py27-local-slow
7+
env: TOXENV=py27-travis-local-slow
88
- python: 2.7
9-
env: TOXENV=py27-integ-slow
9+
env: TOXENV=py27-travis-integ-slow
10+
- python: 2.7
11+
env: TOXENV=py27-travis-isolation
1012
# CPython 3.4
1113
- python: 3.4
12-
env: TOXENV=py34-local-slow
14+
env: TOXENV=py34-travis-local-slow
15+
- python: 3.4
16+
env: TOXENV=py34-travis-integ-slow
1317
- python: 3.4
14-
env: TOXENV=py34-integ-slow
18+
env: TOXENV=py34-travis-isolation
1519
# CPython 3.5
1620
- python: 3.5
17-
env: TOXENV=py35-local-slow
21+
env: TOXENV=py35-travis-local-slow
1822
- python: 3.5
19-
env: TOXENV=py35-integ-slow
23+
env: TOXENV=py35-travis-integ-slow
24+
- python: 3.5
25+
env: TOXENV=py35-travis-isolation
2026
# CPython 3.6
2127
- python: 3.6
22-
env: TOXENV=py36-local-slow
28+
env: TOXENV=py36-travis-local-slow
29+
- python: 3.6
30+
env: TOXENV=py36-travis-integ-slow
2331
- python: 3.6
24-
env: TOXENV=py36-integ-slow
32+
env: TOXENV=py36-travis-isolation
2533
# CPython 3.7
2634
# xenial + sudo are currently needed to get 3.7
2735
# https://github.com/travis-ci/travis-ci/issues/9815
2836
- python: 3.7
29-
env: TOXENV=py37-local-slow
37+
env: TOXENV=py37-travis-local-slow
38+
dist: xenial
39+
sudo: true
40+
- python: 3.7
41+
env: TOXENV=py37-travis-integ-slow
3042
dist: xenial
3143
sudo: true
3244
- python: 3.7
33-
env: TOXENV=py37-integ-slow
45+
env: TOXENV=py37-travis-isolation
3446
dist: xenial
3547
sudo: true
3648
# Upstream tests

examples/__init__.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright 2018 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.
13+
"""Stub to allow relative imports of examples from tests."""
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
"""
2+
Helper utilities for use while testing examples.
3+
"""
4+
import os
5+
import sys
6+
7+
os.environ["AWS_ENCRYPTION_SDK_EXAMPLES_TESTING"] = "yes"
8+
sys.path.extend([os.sep.join([os.path.dirname(__file__), "..", "..", "test", "integration"])])
9+
10+
from integration_test_utils import cmk_arn, ddb_table_name # noqa pylint: disable=unused-import

examples/test/test_aws_kms_encrypted_examples.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,10 @@
1111
# ANY KIND, either express or implied. See the License for the specific
1212
# language governing permissions and limitations under the License.
1313
"""Test ``aws_kms_encrypted_*`` examples."""
14-
import os
15-
import sys
16-
17-
sys.path.extend(
18-
[ # noqa
19-
os.sep.join([os.path.dirname(__file__), "..", "..", "test", "integration"]),
20-
os.sep.join([os.path.dirname(__file__), "..", "src"]),
21-
]
22-
)
23-
2414
import pytest
2515

26-
import aws_kms_encrypted_client # noqa
27-
import aws_kms_encrypted_item # noqa
28-
import aws_kms_encrypted_resource # noqa
29-
import aws_kms_encrypted_table # noqa
30-
from integration_test_utils import cmk_arn, ddb_table_name # noqa pylint: disable=unused-import
16+
from ..src import aws_kms_encrypted_client, aws_kms_encrypted_item, aws_kms_encrypted_resource, aws_kms_encrypted_table
17+
from .examples_test_utils import cmk_arn, ddb_table_name # noqa pylint: disable=unused-import
3118

3219
pytestmark = [pytest.mark.examples]
3320

examples/test/test_most_recent_provider_encrypted_examples.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,15 @@
1111
# ANY KIND, either express or implied. See the License for the specific
1212
# language governing permissions and limitations under the License.
1313
"""Test most recent provider examples."""
14-
import os
15-
import sys
16-
17-
sys.path.extend(
18-
[ # noqa
19-
os.sep.join([os.path.dirname(__file__), "..", "..", "test", "integration"]),
20-
os.sep.join([os.path.dirname(__file__), "..", "src"]),
21-
]
22-
)
2314
import uuid
2415

2516
import boto3
2617
import pytest
2718

2819
from dynamodb_encryption_sdk.material_providers.store.meta import MetaStore
29-
import most_recent_provider_encrypted_table # noqa
30-
from integration_test_utils import cmk_arn, ddb_table_name # noqa pylint: disable=unused-import
20+
21+
from ..src import most_recent_provider_encrypted_table
22+
from .examples_test_utils import cmk_arn, ddb_table_name # noqa pylint: disable=unused-import
3123

3224
pytestmark = [pytest.mark.examples]
3325

examples/test/test_wrapped_encrypted_examples.py

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,12 @@
1111
# ANY KIND, either express or implied. See the License for the specific
1212
# language governing permissions and limitations under the License.
1313
"""Test ``wrapped_*_encrypted_*`` examples."""
14-
import os
15-
import sys
16-
17-
sys.path.extend(
18-
[ # noqa
19-
os.sep.join([os.path.dirname(__file__), "..", "..", "test", "integration"]),
20-
os.sep.join([os.path.dirname(__file__), "..", "src"]),
21-
]
22-
)
23-
2414
import pytest
2515

2616
from dynamodb_encryption_sdk.delegated_keys.jce import JceNameLocalDelegatedKey
27-
import wrapped_rsa_encrypted_table # noqa
28-
import wrapped_symmetric_encrypted_table # noqa
29-
from integration_test_utils import ddb_table_name # noqa pylint: disable=unused-import
17+
18+
from ..src import wrapped_rsa_encrypted_table, wrapped_symmetric_encrypted_table
19+
from .examples_test_utils import ddb_table_name # noqa pylint: disable=unused-import
3020

3121
pytestmark = [pytest.mark.examples]
3222

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ markers =
2727
slow: mark a test as being known to take a long time to complete (order 5s < t < 60s)
2828
veryslow: mark a test as being known to take a very long time to complete (order t > 60s)
2929
nope: mark a test as being so slow that it should only be very infrequently (order t > 30m)
30+
travis_isolation: mark a test that crashes Travis CI when run with other tests
3031
log_level=NOTSET
3132

3233
# Flake8 Configuration

src/dynamodb_encryption_sdk/internal/crypto/jce_bridge/authentication.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
from dynamodb_encryption_sdk.exceptions import InvalidAlgorithmError, SignatureVerificationError, SigningError
2929
from dynamodb_encryption_sdk.identifiers import LOGGER_NAME, EncryptionKeyType, KeyEncodingType
30+
from dynamodb_encryption_sdk.internal.identifiers import MinimumKeySizes
3031
from dynamodb_encryption_sdk.internal.validators import callable_validator
3132

3233
from .primitives import load_rsa_key
@@ -37,7 +38,6 @@
3738
# We only actually need these imports when running the mypy checks
3839
pass
3940

40-
4141
__all__ = ("JavaAuthenticator", "JavaMac", "JavaSignature", "JAVA_AUTHENTICATOR")
4242
_LOGGER = logging.getLogger(LOGGER_NAME)
4343

@@ -138,6 +138,9 @@ def load_key(self, key, key_type, key_encoding):
138138
if not (key_type is EncryptionKeyType.SYMMETRIC and key_encoding is KeyEncodingType.RAW):
139139
raise ValueError("Key type must be symmetric and encoding must be raw.")
140140

141+
if len(key) * 8 < MinimumKeySizes.HMAC.value:
142+
_LOGGER.warning("HMAC keys smaller than %d bits are unsafe" % MinimumKeySizes.HMAC.value)
143+
141144
return key
142145

143146
def validate_algorithm(self, algorithm):

src/dynamodb_encryption_sdk/internal/crypto/jce_bridge/primitives.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
WrappingError,
3636
)
3737
from dynamodb_encryption_sdk.identifiers import LOGGER_NAME, EncryptionKeyType, KeyEncodingType
38+
from dynamodb_encryption_sdk.internal.identifiers import MinimumKeySizes
3839
from dynamodb_encryption_sdk.internal.validators import callable_validator
3940

4041
try: # Python 3.5.0 and 3.5.1 have incompatible typing modules
@@ -451,7 +452,12 @@ def load_rsa_key(key, key_type, key_encoding):
451452
if key_type is EncryptionKeyType.PRIVATE:
452453
kwargs["password"] = None
453454

454-
return loader(**kwargs)
455+
loaded_key = loader(**kwargs)
456+
457+
if loaded_key.key_size < MinimumKeySizes.RSA.value:
458+
_LOGGER.warning("RSA keys smaller than %d bits are unsafe" % MinimumKeySizes.RSA.value)
459+
460+
return loaded_key
455461

456462

457463
_KEY_LOADERS = {rsa: load_rsa_key}

src/dynamodb_encryption_sdk/internal/identifiers.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,21 @@
3232
"SignatureValues",
3333
"MaterialDescriptionKeys",
3434
"MaterialDescriptionValues",
35+
"MinimumKeySizes",
3536
)
3637

3738
#: Encoding to use for all text values.
3839
#: This is noted here for consistency but should not be changed.
3940
TEXT_ENCODING = "utf-8"
4041

4142

43+
class MinimumKeySizes(Enum):
44+
"""Minimum safe key sizes for algorithms."""
45+
46+
RSA = 2048
47+
HMAC = 128
48+
49+
4250
class ReservedAttributes(Enum):
4351
"""Item attributes reserved for use by DynamoDBEncryptionClient"""
4452

0 commit comments

Comments
 (0)