Skip to content

Commit 8027d90

Browse files
committed
Replace md5 with oslo version
md5 is not an approved algorithm in FIPS mode, and trying to instantiate a hashlib.md5() will fail when the system is running in FIPS mode. md5 is allowed when in a non-security context. There is a plan to add a keyword parameter (usedforsecurity) to hashlib.md5() to annotate whether or not the instance is being used in a security context. In the case where it is not, the instantiation of md5 will be allowed. See https://bugs.python.org/issue9216 for more details. Some downstream python versions already support this parameter. To support these versions, a new encapsulation of md5() has been added to oslo_utils. See https://review.opendev.org/#/c/750031/ This patch is to replace the instances of hashlib.md5() with this new encapsulation, adding an annotation indicating whether the usage is a security context or not. Reviewers need to pay particular attention as to whether the keyword parameter (usedforsecurity) is set correctly. It looks like the usage of md5() here is solely to determine a checksum of an image. With this patch and the dependent patch for glance_store, all the unit and functional tests pass on a FIPS enabled system. Depends-On: https://review.opendev.org/#/c/756157 Depends-On: https://review.opendev.org/#/c/760160 Change-Id: I3b6d78d9792d4655bf0f4989cf82aced3f27491b
1 parent c0e54c0 commit 8027d90

File tree

5 files changed

+39
-23
lines changed

5 files changed

+39
-23
lines changed

glance/image_cache/__init__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@
1717
LRU Cache for Image Data
1818
"""
1919

20-
import hashlib
21-
2220
from oslo_config import cfg
2321
from oslo_log import log as logging
2422
from oslo_utils import encodeutils
2523
from oslo_utils import excutils
2624
from oslo_utils import importutils
25+
from oslo_utils.secretutils import md5
2726
from oslo_utils import units
2827

2928
from glance.common import exception
@@ -347,7 +346,7 @@ def get_caching_iter(self, image_id, image_checksum, image_iter):
347346

348347
def cache_tee_iter(self, image_id, image_iter, image_checksum):
349348
try:
350-
current_checksum = hashlib.md5()
349+
current_checksum = md5(usedforsecurity=False)
351350

352351
with self.driver.open_for_write(image_id) as cache_file:
353352
for chunk in image_iter:

glance/tests/functional/v2/test_images.py

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import uuid
2222

2323
from oslo_serialization import jsonutils
24+
from oslo_utils.secretutils import md5
2425
from oslo_utils import units
2526
import requests
2627
import six
@@ -206,7 +207,8 @@ def test_image_import_using_glance_direct(self):
206207
status='active',
207208
max_sec=10,
208209
delay_sec=0.2)
209-
expect_c = six.text_type(hashlib.md5(image_data).hexdigest())
210+
expect_c = six.text_type(md5(image_data,
211+
usedforsecurity=False).hexdigest())
210212
expect_h = six.text_type(hashlib.sha512(image_data).hexdigest())
211213
func_utils.verify_image_hashes_and_status(self,
212214
image_id,
@@ -349,7 +351,8 @@ def test_image_import_using_web_download(self):
349351
delay_sec=0.2,
350352
start_delay_sec=1)
351353
with requests.get(image_data_uri) as r:
352-
expect_c = six.text_type(hashlib.md5(r.content).hexdigest())
354+
expect_c = six.text_type(md5(r.content,
355+
usedforsecurity=False).hexdigest())
353356
expect_h = six.text_type(hashlib.sha512(r.content).hexdigest())
354357
func_utils.verify_image_hashes_and_status(self,
355358
image_id,
@@ -726,7 +729,8 @@ def test_image_lifecycle(self):
726729
response = requests.put(path, headers=headers, data=image_data)
727730
self.assertEqual(http.NO_CONTENT, response.status_code)
728731

729-
expect_c = six.text_type(hashlib.md5(image_data).hexdigest())
732+
expect_c = six.text_type(md5(image_data,
733+
usedforsecurity=False).hexdigest())
730734
expect_h = six.text_type(hashlib.sha512(image_data).hexdigest())
731735
func_utils.verify_image_hashes_and_status(self, image_id, expect_c,
732736
expect_h, 'active')
@@ -1165,7 +1169,8 @@ def test_hidden_images(self):
11651169
image_data = b'ZZZZZ'
11661170
response = requests.put(path, headers=headers, data=image_data)
11671171
self.assertEqual(http.NO_CONTENT, response.status_code)
1168-
expect_c = six.text_type(hashlib.md5(image_data).hexdigest())
1172+
expect_c = six.text_type(md5(image_data,
1173+
usedforsecurity=False).hexdigest())
11691174
expect_h = six.text_type(hashlib.sha512(image_data).hexdigest())
11701175
func_utils.verify_image_hashes_and_status(self,
11711176
image_id,
@@ -1178,7 +1183,8 @@ def test_hidden_images(self):
11781183
image_data = b'WWWWW'
11791184
response = requests.put(path, headers=headers, data=image_data)
11801185
self.assertEqual(http.NO_CONTENT, response.status_code)
1181-
expect_c = six.text_type(hashlib.md5(image_data).hexdigest())
1186+
expect_c = six.text_type(md5(image_data,
1187+
usedforsecurity=False).hexdigest())
11821188
expect_h = six.text_type(hashlib.sha512(image_data).hexdigest())
11831189
func_utils.verify_image_hashes_and_status(self,
11841190
image2_id,
@@ -4621,7 +4627,8 @@ def test_image_import_using_glance_direct(self):
46214627
status='active',
46224628
max_sec=15,
46234629
delay_sec=0.2)
4624-
expect_c = six.text_type(hashlib.md5(image_data).hexdigest())
4630+
expect_c = six.text_type(md5(image_data,
4631+
usedforsecurity=False).hexdigest())
46254632
expect_h = six.text_type(hashlib.sha512(image_data).hexdigest())
46264633
func_utils.verify_image_hashes_and_status(self,
46274634
image_id,
@@ -4784,7 +4791,8 @@ def test_image_import_using_glance_direct_different_backend(self):
47844791
status='active',
47854792
max_sec=15,
47864793
delay_sec=0.2)
4787-
expect_c = six.text_type(hashlib.md5(image_data).hexdigest())
4794+
expect_c = six.text_type(md5(image_data,
4795+
usedforsecurity=False).hexdigest())
47884796
expect_h = six.text_type(hashlib.sha512(image_data).hexdigest())
47894797
func_utils.verify_image_hashes_and_status(self,
47904798
image_id,
@@ -4948,7 +4956,8 @@ def test_image_import_using_web_download(self):
49484956
delay_sec=0.2,
49494957
start_delay_sec=1)
49504958
with requests.get(image_data_uri) as r:
4951-
expect_c = six.text_type(hashlib.md5(r.content).hexdigest())
4959+
expect_c = six.text_type(md5(r.content,
4960+
usedforsecurity=False).hexdigest())
49524961
expect_h = six.text_type(hashlib.sha512(r.content).hexdigest())
49534962
func_utils.verify_image_hashes_and_status(self,
49544963
image_id,
@@ -5111,7 +5120,8 @@ def test_image_import_using_web_download_different_backend(self):
51115120
delay_sec=0.2,
51125121
start_delay_sec=1)
51135122
with requests.get(image_data_uri) as r:
5114-
expect_c = six.text_type(hashlib.md5(r.content).hexdigest())
5123+
expect_c = six.text_type(md5(r.content,
5124+
usedforsecurity=False).hexdigest())
51155125
expect_h = six.text_type(hashlib.sha512(r.content).hexdigest())
51165126
func_utils.verify_image_hashes_and_status(self,
51175127
image_id,
@@ -5273,7 +5283,8 @@ def test_image_import_multi_stores(self):
52735283
delay_sec=0.2,
52745284
start_delay_sec=1)
52755285
with requests.get(image_data_uri) as r:
5276-
expect_c = six.text_type(hashlib.md5(r.content).hexdigest())
5286+
expect_c = six.text_type(md5(r.content,
5287+
usedforsecurity=False).hexdigest())
52775288
expect_h = six.text_type(hashlib.sha512(r.content).hexdigest())
52785289
func_utils.verify_image_hashes_and_status(self,
52795290
image_id,
@@ -5435,7 +5446,8 @@ def test_copy_image_lifecycle(self):
54355446
delay_sec=0.2,
54365447
start_delay_sec=1)
54375448
with requests.get(image_data_uri) as r:
5438-
expect_c = six.text_type(hashlib.md5(r.content).hexdigest())
5449+
expect_c = six.text_type(md5(r.content,
5450+
usedforsecurity=False).hexdigest())
54395451
expect_h = six.text_type(hashlib.sha512(r.content).hexdigest())
54405452
func_utils.verify_image_hashes_and_status(self,
54415453
image_id,
@@ -5630,7 +5642,8 @@ def test_copy_image_revert_lifecycle(self):
56305642
delay_sec=0.2,
56315643
start_delay_sec=1)
56325644
with requests.get(image_data_uri) as r:
5633-
expect_c = six.text_type(hashlib.md5(r.content).hexdigest())
5645+
expect_c = six.text_type(md5(r.content,
5646+
usedforsecurity=False).hexdigest())
56345647
expect_h = six.text_type(hashlib.sha512(r.content).hexdigest())
56355648
func_utils.verify_image_hashes_and_status(self,
56365649
image_id,
@@ -5888,7 +5901,8 @@ def test_image_import_multi_stores_specifying_all_stores(self):
58885901
delay_sec=0.2,
58895902
start_delay_sec=1)
58905903
with requests.get(image_data_uri) as r:
5891-
expect_c = six.text_type(hashlib.md5(r.content).hexdigest())
5904+
expect_c = six.text_type(md5(r.content,
5905+
usedforsecurity=False).hexdigest())
58925906
expect_h = six.text_type(hashlib.sha512(r.content).hexdigest())
58935907
func_utils.verify_image_hashes_and_status(self,
58945908
image_id,
@@ -6029,7 +6043,8 @@ def test_image_lifecycle(self):
60296043
response = requests.put(path, headers=headers, data=image_data)
60306044
self.assertEqual(http.NO_CONTENT, response.status_code)
60316045

6032-
expect_c = six.text_type(hashlib.md5(image_data).hexdigest())
6046+
expect_c = six.text_type(md5(image_data,
6047+
usedforsecurity=False).hexdigest())
60336048
expect_h = six.text_type(hashlib.sha512(image_data).hexdigest())
60346049
func_utils.verify_image_hashes_and_status(self,
60356050
image_id,
@@ -6202,7 +6217,8 @@ def test_image_lifecycle_different_backend(self):
62026217
response = requests.put(path, headers=headers, data=image_data)
62036218
self.assertEqual(http.NO_CONTENT, response.status_code)
62046219

6205-
expect_c = six.text_type(hashlib.md5(image_data).hexdigest())
6220+
expect_c = six.text_type(md5(image_data,
6221+
usedforsecurity=False).hexdigest())
62066222
expect_h = six.text_type(hashlib.sha512(image_data).hexdigest())
62076223
func_utils.verify_image_hashes_and_status(self,
62086224
image_id,
@@ -6738,7 +6754,8 @@ def _create_and_import_image_data(self):
67386754
delay_sec=0.2,
67396755
start_delay_sec=1)
67406756
with requests.get(image_data_uri) as r:
6741-
expect_c = six.text_type(hashlib.md5(r.content).hexdigest())
6757+
expect_c = six.text_type(md5(r.content,
6758+
usedforsecurity=False).hexdigest())
67426759
expect_h = six.text_type(hashlib.sha512(r.content).hexdigest())
67436760
func_utils.verify_image_hashes_and_status(self,
67446761
image_id,

glance/tests/unit/test_image_cache.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515

1616
from contextlib import contextmanager
1717
import datetime
18-
import hashlib
1918
import os
2019
import time
2120

2221
import fixtures
22+
from oslo_utils import secretutils
2323
from oslo_utils import units
2424
import six
2525
# NOTE(jokke): simplified transition to py3, behaves like py2 xrange
@@ -409,7 +409,7 @@ def test_gate_caching_iter_good_checksum(self):
409409
image = b"12345678990abcdefghijklmnop"
410410
image_id = 123
411411

412-
md5 = hashlib.md5()
412+
md5 = secretutils.md5(usedforsecurity=False)
413413
md5.update(image)
414414
checksum = md5.hexdigest()
415415

lower-constraints.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ oslo.reports==1.18.0
6969
oslo.serialization==2.25.0
7070
oslo.service==1.41.1
7171
oslo.upgradecheck==0.1.0
72-
oslo.utils==3.40.2
72+
oslo.utils==4.7.0
7373
oslotest==3.2.0
7474
osprofiler==1.4.0
7575
Paste==2.0.2

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ oslo.config>=5.2.0 # Apache-2.0
1919
oslo.concurrency>=3.26.0 # Apache-2.0
2020
oslo.context>=2.22.0 # Apache-2.0
2121
oslo.upgradecheck>=0.1.0 # Apache-2.0
22-
oslo.utils>=3.40.2 # Apache-2.0
22+
oslo.utils>=4.7.0 # Apache-2.0
2323
stevedore!=3.0.0,>=1.20.0 # Apache-2.0
2424
futurist>=1.2.0 # Apache-2.0
2525
taskflow>=4.0.0 # Apache-2.0

0 commit comments

Comments
 (0)