From 0fe30b0440270a1175cbf53007ed6fb534e16825 Mon Sep 17 00:00:00 2001 From: Bert Blommers <bblommers@users.noreply.github.com> Date: Fri, 3 Jun 2022 09:41:30 +0000 Subject: [PATCH] MD5 - set usedforsecurity-parameter for all uses (#5190) --- moto/cognitoidp/models.py | 6 +++--- moto/ec2/utils.py | 4 ++-- moto/efs/models.py | 4 ++-- moto/glacier/models.py | 3 ++- moto/iam/models.py | 4 ++-- moto/kinesis/models.py | 4 ++-- moto/s3/models.py | 7 +++---- moto/sqs/models.py | 5 +++-- moto/utilities/utils.py | 14 ++++++++++++++ 9 files changed, 33 insertions(+), 18 deletions(-) diff --git a/moto/cognitoidp/models.py b/moto/cognitoidp/models.py index 7c8a8e5cc..57a1f9c28 100644 --- a/moto/cognitoidp/models.py +++ b/moto/cognitoidp/models.py @@ -1,5 +1,4 @@ import datetime -import hashlib import json import os import time @@ -31,6 +30,7 @@ from .utils import ( PAGINATION_MODEL, ) from moto.utilities.paginator import paginate +from moto.utilities.utils import md5_hash class UserStatus(str, enum.Enum): @@ -595,11 +595,11 @@ class CognitoIdpUserPoolDomain(BaseModel): def _distribution_name(self): if self.custom_domain_config and "CertificateArn" in self.custom_domain_config: - unique_hash = hashlib.md5( + unique_hash = md5_hash( self.custom_domain_config["CertificateArn"].encode("utf-8") ).hexdigest() return f"{unique_hash[:16]}.cloudfront.net" - unique_hash = hashlib.md5(self.user_pool_id.encode("utf-8")).hexdigest() + unique_hash = md5_hash(self.user_pool_id.encode("utf-8")).hexdigest() return f"{unique_hash[:16]}.amazoncognito.com" def to_json(self, extended=True): diff --git a/moto/ec2/utils.py b/moto/ec2/utils.py index 1d7a5f1e8..08ddcddf2 100644 --- a/moto/ec2/utils.py +++ b/moto/ec2/utils.py @@ -1,5 +1,4 @@ import base64 -import hashlib import fnmatch import random import re @@ -12,6 +11,7 @@ from cryptography.hazmat.primitives.asymmetric import rsa from moto.core import get_account_id from moto.iam import iam_backends +from moto.utilities.utils import md5_hash EC2_RESOURCE_TO_PREFIX = { "customer-gateway": "cgw", @@ -651,7 +651,7 @@ def rsa_public_key_fingerprint(rsa_public_key): encoding=serialization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo, ) - fingerprint_hex = hashlib.md5(key_data).hexdigest() + fingerprint_hex = md5_hash(key_data).hexdigest() fingerprint = re.sub(r"([a-f0-9]{2})(?!$)", r"\1:", fingerprint_hex) return fingerprint diff --git a/moto/efs/models.py b/moto/efs/models.py index 29a4ebf01..375968562 100644 --- a/moto/efs/models.py +++ b/moto/efs/models.py @@ -7,7 +7,6 @@ https://docs.aws.amazon.com/efs/latest/ug/whatisefs.html import json import time from copy import deepcopy -from hashlib import md5 from moto.core import get_account_id, BaseBackend, BaseModel, CloudFormationModel from moto.core.utils import ( @@ -32,6 +31,7 @@ from moto.efs.exceptions import ( SecurityGroupLimitExceeded, ) from moto.utilities.tagging_service import TaggingService +from moto.utilities.utils import md5_hash def _lookup_az_id(az_name): @@ -382,7 +382,7 @@ class EFSBackend(BaseBackend): if max_items < len(corpus): new_corpus = corpus[max_items:] new_corpus_dict = [c.info_json() for c in new_corpus] - new_hash = md5(json.dumps(new_corpus_dict).encode("utf-8")) + new_hash = md5_hash(json.dumps(new_corpus_dict).encode("utf-8")) next_marker = new_hash.hexdigest() self.next_markers[next_marker] = new_corpus else: diff --git a/moto/glacier/models.py b/moto/glacier/models.py index a9fb35286..7066c219a 100644 --- a/moto/glacier/models.py +++ b/moto/glacier/models.py @@ -4,6 +4,7 @@ import datetime from moto.core import get_account_id, BaseBackend, BaseModel from moto.core.utils import BackendDict +from moto.utilities.utils import md5_hash from .utils import get_job_id @@ -117,7 +118,7 @@ class Vault(BaseModel): return d def create_archive(self, body, description): - archive_id = hashlib.md5(body).hexdigest() + archive_id = md5_hash(body).hexdigest() self.archives[archive_id] = {} self.archives[archive_id]["archive_id"] = archive_id self.archives[archive_id]["body"] = body diff --git a/moto/iam/models.py b/moto/iam/models.py index cecf2cc57..0f857be71 100644 --- a/moto/iam/models.py +++ b/moto/iam/models.py @@ -1,5 +1,4 @@ import base64 -import hashlib import os import random import string @@ -22,6 +21,7 @@ from moto.core.utils import ( iso_8601_datetime_with_milliseconds, ) from moto.iam.policy_validation import IAMPolicyDocumentValidator +from moto.utilities.utils import md5_hash from .aws_managed_policies import aws_managed_policies_data from .exceptions import ( @@ -1014,7 +1014,7 @@ class SshPublicKey(BaseModel): self.user_name = user_name self.ssh_public_key_body = ssh_public_key_body self.ssh_public_key_id = "APKA" + random_access_key() - self.fingerprint = hashlib.md5(ssh_public_key_body.encode()).hexdigest() + self.fingerprint = md5_hash(ssh_public_key_body.encode()).hexdigest() self.status = "Active" self.upload_date = datetime.utcnow() diff --git a/moto/kinesis/models.py b/moto/kinesis/models.py index f772d304c..4e6c21958 100644 --- a/moto/kinesis/models.py +++ b/moto/kinesis/models.py @@ -4,12 +4,12 @@ import re import itertools from operator import attrgetter -from hashlib import md5 from moto.core import BaseBackend, BaseModel, CloudFormationModel from moto.core.utils import unix_time, BackendDict from moto.core import get_account_id from moto.utilities.paginator import paginate +from moto.utilities.utils import md5_hash from .exceptions import ( ConsumerNotFound, StreamNotFoundError, @@ -363,7 +363,7 @@ class Stream(CloudFormationModel): raise InvalidArgumentError("explicit_hash_key") else: - key = int(md5(partition_key.encode("utf-8")).hexdigest(), 16) + key = int(md5_hash(partition_key.encode("utf-8")).hexdigest(), 16) for shard in self.shards.values(): if shard.starting_hash <= key < shard.ending_hash: diff --git a/moto/s3/models.py b/moto/s3/models.py index 82fb4dbb4..75596bb6a 100644 --- a/moto/s3/models.py +++ b/moto/s3/models.py @@ -2,7 +2,6 @@ import json import os import base64 import datetime -import hashlib import copy import itertools import codecs @@ -33,7 +32,7 @@ from moto.core.utils import ( ) from moto.cloudwatch.models import MetricDatum from moto.utilities.tagging_service import TaggingService -from moto.utilities.utils import LowercaseDict +from moto.utilities.utils import LowercaseDict, md5_hash from moto.s3.exceptions import ( AccessDeniedByLock, BucketAlreadyExists, @@ -213,7 +212,7 @@ class FakeKey(BaseModel): @property def etag(self): if self._etag is None: - value_md5 = hashlib.md5() + value_md5 = md5_hash() self._value_buffer.seek(0) while True: block = self._value_buffer.read(16 * 1024 * 1024) # read in 16MB chunks @@ -376,7 +375,7 @@ class FakeMultipart(BaseModel): if count == 0: raise MalformedXML - etag = hashlib.md5() + etag = md5_hash() etag.update(bytes(md5s)) return total, "{0}-{1}".format(etag.hexdigest(), count) diff --git a/moto/sqs/models.py b/moto/sqs/models.py index efc0c5f07..d0528d79a 100644 --- a/moto/sqs/models.py +++ b/moto/sqs/models.py @@ -20,6 +20,7 @@ from moto.core.utils import ( tags_from_cloudformation_tags_list, BackendDict, ) +from moto.utilities.utils import md5_hash from .utils import generate_receipt_handle from .exceptions import ( MessageAttributesInvalid, @@ -85,14 +86,14 @@ class Message(BaseModel): @property def body_md5(self): - md5 = hashlib.md5() + md5 = md5_hash() md5.update(self._body.encode("utf-8")) return md5.hexdigest() @property def attribute_md5(self): - md5 = hashlib.md5() + md5 = md5_hash() for attrName in sorted(self.message_attributes.keys()): self.validate_attribute_name(attrName) diff --git a/moto/utilities/utils.py b/moto/utilities/utils.py index 006235956..636e71e1e 100644 --- a/moto/utilities/utils.py +++ b/moto/utilities/utils.py @@ -1,4 +1,5 @@ import json +import hashlib import random import string import pkgutil @@ -57,6 +58,19 @@ def filter_resources(resources, filters, attr_pairs): return result +def md5_hash(data=None): + """ + MD5-hashing for non-security usecases. + Required for Moto to work in FIPS-enabled systems + """ + args = (data,) if data else () + try: + return hashlib.md5(*args, usedforsecurity=False) + except TypeError: + # The usedforsecurity-parameter is only available as of Python 3.9 + return hashlib.md5(*args) + + class LowercaseDict(MutableMapping): """A dictionary that lowercases all keys"""