Project

Profile

Help

Task #3639

closed

Story #3637: As a user, I can run pulp in a FIPS-enabled environment

Confirm that django works in a FIPS-enabled environment

Added by daviddavis over 6 years ago. Updated over 5 years ago.

Status:
CLOSED - COMPLETE
Priority:
Normal
Assignee:
Category:
-
Sprint/Milestone:
-
Start date:
Due date:
% Done:

0%

Estimated time:
Platform Release:
Groomed:
No
Sprint Candidate:
No
Tags:
Pulp 2
Sprint:
Sprint 38
Quarter:

Actions #1

Updated by daviddavis over 6 years ago

Looks like this causes problems in Pulp:

May 16 17:28:18 pulp2.dev pulp[7767]: django.request:ERROR: (7767-40896) Internal Server Error: /pulp/api/v2/repositories/
May 16 17:28:18 pulp2.dev pulp[7767]: django.request:ERROR: (7767-40896) Traceback (most recent call last):
May 16 17:28:18 pulp2.dev pulp[7767]: django.request:ERROR: (7767-40896)   File "/usr/lib/python2.7/site-packages/django/core/handlers/base.py", line 131, in get_response
May 16 17:28:18 pulp2.dev pulp[7767]: django.request:ERROR: (7767-40896)     response = middleware_method(request, response)
May 16 17:28:18 pulp2.dev pulp[7767]: django.request:ERROR: (7767-40896)   File "/usr/lib/python2.7/site-packages/django/middleware/http.py", line 23, in process_response
May 16 17:28:18 pulp2.dev pulp[7767]: django.request:ERROR: (7767-40896)     set_response_etag(response)
May 16 17:28:18 pulp2.dev pulp[7767]: django.request:ERROR: (7767-40896)   File "/usr/lib/python2.7/site-packages/django/utils/cache.py", line 109, in set_response_etag
May 16 17:28:18 pulp2.dev pulp[7767]: django.request:ERROR: (7767-40896)     response['ETag'] = quote_etag(hashlib.md5(response.content).hexdigest())
May 16 17:28:18 pulp2.dev pulp[7767]: django.request:ERROR: (7767-40896) ValueError: error:060800A3:digital envelope routines:EVP_DigestInit_ex:disabled for fips
Actions #2

Updated by daviddavis over 6 years ago

I made this temporary fix in /usr/lib/python2.7/site-packages/django/utils/cache.py to work around this:

# response['ETag'] = quote_etag(hashlib.md5(response.content).hexdigest())
response['ETag'] = quote_etag(hashlib.md5(response.content, usedforsecurity=False).hexdigest())
Actions #3

Updated by daviddavis over 6 years ago

  • Sprint set to Sprint 38
Actions #4

Updated by daviddavis over 6 years ago

I see three possible ways to patch this:

1. Rescue ValueError and then call md5 with the usedforsecurity flag set to False
2. Switch to a different hashing method (e.g. sha256)
3. Create an md5() function like we did here: https://git.io/vh0wj

I'm leaning towards the first option given that it's simple and has a small footprint. Also, option 2 might have unintended consequences or even bugs.

Thoughts?

Actions #5

Updated by dalley over 6 years ago

I'm fine with option 1.

Normally I would prefer option 2, but since Django 1.x is on maintenence-only mode, I expect that they wouldn't accept it even if it did work perfectly.

Actions #6

Updated by ttereshc over 6 years ago

For option 1 we'll need to catch a very specific ValueError, just ValueError is not good enough.
Say, it was triggered by a non-FIPS problem, then we would catch ValueError and try to pass usedforsecurity flag to the md5 function which potentially doesn't support it (if it's not a FIPS machine).

I agree not to go with option 2 because we won't be able to merge it into upstream Django.

I think either option 1 and checking a FIPS specific error code if it's there or option 3.

Actions #7

Updated by daviddavis over 6 years ago

Here's a patch that combines options 1 and 3:

diff --git a/django/utils/cache.py b/django/utils/cache.py
index 0f6232b51b..73f496e0f9 100644
--- a/django/utils/cache.py
+++ b/django/utils/cache.py
@@ -19,6 +19,7 @@ An example: i18n middleware would need to distinguish caches by the
 from __future__ import unicode_literals

 import hashlib
+import inspect
 import logging
 import re
 import time
@@ -106,7 +107,16 @@ def get_max_age(response):

 def set_response_etag(response):
     if not response.streaming:
-        response['ETag'] = quote_etag(hashlib.md5(response.content).hexdigest())
+        try:
+            md5_hash = hashlib.md5(response.content)
+        except ValueError as e:
+            if 'usedforsecurity' in inspect.getargspec(hashlib.new)[0]:
+                md5_hash = hashlib.md5(response.content, usedforsecurity=False)
+            else:
+                raise e
+
+        response['ETag'] = quote_etag(md5_hash.hexdigest())
+
     return response
Actions #8

Updated by ttereshc over 6 years ago

+1 from me.
Thanks @daviddavis for the patch!

Actions #9

Updated by daviddavis over 6 years ago

  • Status changed from NEW to ASSIGNED
  • Assignee set to daviddavis

Added by daviddavis over 6 years ago

Revision 918573a1 | View on GitHub

Adding a patch to django for FIPS compatibility

Also, bumping the django version to the latest 1.11.z release.

fixes #3639 https://pulp.plan.io/issues/3639

Added by daviddavis over 6 years ago

Revision 918573a1 | View on GitHub

Adding a patch to django for FIPS compatibility

Also, bumping the django version to the latest 1.11.z release.

fixes #3639 https://pulp.plan.io/issues/3639

Actions #10

Updated by daviddavis over 6 years ago

  • Status changed from ASSIGNED to POST
Actions #11

Updated by daviddavis over 6 years ago

  • Status changed from POST to MODIFIED
Actions #12

Updated by daviddavis over 6 years ago

  • Status changed from MODIFIED to CLOSED - COMPLETE
Actions #13

Updated by bmbouter over 5 years ago

  • Tags Pulp 2 added

Also available in: Atom PDF